diff options
author | Alan Coopersmith <alan.coopersmith@oracle.com> | 2012-04-18 15:30:30 -0700 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2012-04-23 19:37:26 -0700 |
commit | d50292ca8cbbaa5e0c92627f3d7813194c7c83ac (patch) | |
tree | 4f24fc36016bea00dc7cb603850a7c0635bbe500 | |
parent | 2ff2996dcb4cfd83da6df4504b68b492b983204b (diff) |
Solaris: Implement map_legacy & legacy_io functions
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Jay Cotton <jay.cotton@oracle.com>
-rw-r--r-- | src/solx_devfs.c | 137 |
1 files changed, 135 insertions, 2 deletions
diff --git a/src/solx_devfs.c b/src/solx_devfs.c index 2079df0..4069dc2 100644 --- a/src/solx_devfs.c +++ b/src/solx_devfs.c @@ -1,6 +1,6 @@ /* * (C) Copyright IBM Corporation 2006 - * Copyright (c) 2007, 2009, 2011, Oracle and/or its affiliates. + * Copyright (c) 2007, 2009, 2011, 2012, Oracle and/or its affiliates. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -38,6 +38,11 @@ #include <libdevinfo.h> #include "pci_tools.h" +#ifdef __x86 +# include <sys/sysi86.h> +# include <sys/psw.h> +#endif + #include "pciaccess.h" #include "pciaccess_private.h" @@ -1122,7 +1127,125 @@ pci_device_solx_devfs_write( struct pci_device * dev, const void * data, return (err); } +static struct pci_io_handle * +pci_device_solx_devfs_open_legacy_io(struct pci_io_handle *ret, + struct pci_device *dev, + pciaddr_t base, pciaddr_t size) +{ +#ifdef __x86 + if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) == 0) { + ret->base = base; + ret->size = size; + return ret; + } +#endif + return NULL; +} + +static uint32_t +pci_device_solx_devfs_read32(struct pci_io_handle *handle, uint32_t reg) +{ +#ifdef __x86 + uint16_t port = (uint16_t) (handle->base + reg); + uint32_t ret; + __asm__ __volatile__("inl %1,%0":"=a"(ret):"d"(port)); + return ret; +#else + return *(uint32_t *)((uintptr_t)handle->memory + reg); +#endif +} +static uint16_t +pci_device_solx_devfs_read16(struct pci_io_handle *handle, uint32_t reg) +{ +#ifdef __x86 + uint16_t port = (uint16_t) (handle->base + reg); + uint16_t ret; + __asm__ __volatile__("inw %1,%0":"=a"(ret):"d"(port)); + return ret; +#else + return *(uint16_t *)((uintptr_t)handle->memory + reg); +#endif +} + +static uint8_t +pci_device_solx_devfs_read8(struct pci_io_handle *handle, uint32_t reg) +{ +#ifdef __x86 + uint16_t port = (uint16_t) (handle->base + reg); + uint8_t ret; + __asm__ __volatile__("inb %1,%0":"=a"(ret):"d"(port)); + return ret; +#else + return *(uint8_t *)((uintptr_t)handle->memory + reg); +#endif +} + +static void +pci_device_solx_devfs_write32(struct pci_io_handle *handle, uint32_t reg, + uint32_t data) +{ +#ifdef __x86 + uint16_t port = (uint16_t) (handle->base + reg); + __asm__ __volatile__("outl %0,%1"::"a"(data), "d"(port)); +#else + *(uint16_t *)((uintptr_t)handle->memory + reg) = data; +#endif +} + +static void +pci_device_solx_devfs_write16(struct pci_io_handle *handle, uint32_t reg, + uint16_t data) +{ +#ifdef __x86 + uint16_t port = (uint16_t) (handle->base + reg); + __asm__ __volatile__("outw %0,%1"::"a"(data), "d"(port)); +#else + *(uint8_t *)((uintptr_t)handle->memory + reg) = data; +#endif +} + +static void +pci_device_solx_devfs_write8(struct pci_io_handle *handle, uint32_t reg, + uint8_t data) +{ +#ifdef __x86 + uint16_t port = (uint16_t) (handle->base + reg); + __asm__ __volatile__("outb %0,%1"::"a"(data), "d"(port)); +#else + *(uint32_t *)((uintptr_t)handle->memory + reg) = data; +#endif +} + +static int +pci_device_solx_devfs_map_legacy(struct pci_device *dev, pciaddr_t base, + pciaddr_t size, unsigned map_flags, + void **addr) +{ + int err; + struct pci_device_mapping map = { + .base = base, + .size = size, + .flags = map_flags, + }; + + err = pci_device_solx_devfs_map_range(dev, &map); + if (err == 0) + *addr = map.memory; + return err; +} + +static int +pci_device_solx_devfs_unmap_legacy(struct pci_device *dev, + void *addr, pciaddr_t size) +{ + struct pci_device_mapping map = { + .memory = addr, + .size = size, + }; + + return pci_device_generic_unmap_range(dev, &map); +} static const struct pci_system_methods solx_devfs_methods = { .destroy = pci_system_solx_devfs_destroy, @@ -1135,7 +1258,17 @@ static const struct pci_system_methods solx_devfs_methods = { .read = pci_device_solx_devfs_read, .write = pci_device_solx_devfs_write, - .fill_capabilities = pci_fill_capabilities_generic + .fill_capabilities = pci_fill_capabilities_generic, + + .open_legacy_io = pci_device_solx_devfs_open_legacy_io, + .read32 = pci_device_solx_devfs_read32, + .read16 = pci_device_solx_devfs_read16, + .read8 = pci_device_solx_devfs_read8, + .write32 = pci_device_solx_devfs_write32, + .write16 = pci_device_solx_devfs_write16, + .write8 = pci_device_solx_devfs_write8, + .map_legacy = pci_device_solx_devfs_map_legacy, + .unmap_legacy = pci_device_solx_devfs_unmap_legacy, }; /* |