diff options
author | Matthieu Herrb <matthieu@herrb.eu> | 2022-05-01 20:05:59 +0200 |
---|---|---|
committer | Matthieu Herrb <matthieu@herrb.eu> | 2022-05-01 20:05:59 +0200 |
commit | e458df41cce8695617872b27823e03047e796b9a (patch) | |
tree | 1b1fc91e23e5329b1ab0877f1148340cda3937e4 /src | |
parent | ad97bd48fc501a869f59f8c03236bb9c8b12a14f (diff) | |
parent | 22a93f8b9b4a79eefbdd0b2c412526f6141ac7a8 (diff) |
Merge remote-tracking branch 'origin/master' into obsd
Diffstat (limited to 'src')
-rw-r--r-- | src/Doxyfile | 2 | ||||
-rw-r--r-- | src/common_io.c | 2 | ||||
-rw-r--r-- | src/hurd_pci.c | 166 | ||||
-rw-r--r-- | src/linux_sysfs.c | 6 | ||||
-rw-r--r-- | src/x86_pci.c | 23 | ||||
-rw-r--r-- | src/x86_pci.h | 8 |
6 files changed, 167 insertions, 40 deletions
diff --git a/src/Doxyfile b/src/Doxyfile index 1185875..2f5d557 100644 --- a/src/Doxyfile +++ b/src/Doxyfile @@ -385,7 +385,7 @@ SHOW_DIRECTORIES = YES # version control system). Doxygen will invoke the program by executing (via # popen()) the command <command> <input-file>, where <command> is the value of # the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file -# provided by doxygen. Whatever the progam writes to standard output +# provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = diff --git a/src/common_io.c b/src/common_io.c index e9586ad..ad7d809 100644 --- a/src/common_io.c +++ b/src/common_io.c @@ -13,7 +13,7 @@ * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY, + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN diff --git a/src/hurd_pci.c b/src/hurd_pci.c index 40c9925..2d10c5c 100644 --- a/src/hurd_pci.c +++ b/src/hurd_pci.c @@ -55,6 +55,7 @@ /* File names */ #define FILE_CONFIG_NAME "config" +#define FILE_REGION_NAME "region" #define FILE_ROM_NAME "rom" /* Level in the fs tree */ @@ -68,6 +69,7 @@ typedef enum { struct pci_system_hurd { struct pci_system system; + mach_port_t root; }; static int @@ -149,8 +151,129 @@ pci_device_hurd_probe(struct pci_device *dev) return 0; } +static void +pci_system_hurd_destroy(void) +{ + struct pci_system_hurd *pci_sys_hurd = (struct pci_system_hurd *)pci_sys; + + x86_disable_io(); + mach_port_deallocate(mach_task_self(), pci_sys_hurd->root); +} + +static int +pci_device_hurd_map_range(struct pci_device *dev, + struct pci_device_mapping *map) +{ + struct pci_system_hurd *pci_sys_hurd = (struct pci_system_hurd *)pci_sys; + int err = 0; + file_t file = MACH_PORT_NULL; + memory_object_t robj, wobj, pager; + vm_offset_t offset; + vm_prot_t prot = VM_PROT_READ; + const struct pci_mem_region * const region = &dev->regions[map->region]; + int flags = O_RDONLY; + char server[NAME_MAX]; + + if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE) { + prot |= VM_PROT_WRITE; + flags = O_RDWR; + } + + snprintf(server, NAME_MAX, "%04x/%02x/%02x/%01u/%s%01u", + dev->domain, dev->bus, dev->dev, dev->func, + FILE_REGION_NAME, map->region); + + file = file_name_lookup_under (pci_sys_hurd->root, server, flags, 0); + if (! MACH_PORT_VALID (file)) { + return errno; + } + + err = io_map (file, &robj, &wobj); + mach_port_deallocate (mach_task_self(), file); + if (err) + return err; + + switch (prot & (VM_PROT_READ|VM_PROT_WRITE)) { + case VM_PROT_READ: + pager = robj; + if (wobj != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self(), wobj); + break; + case VM_PROT_READ|VM_PROT_WRITE: + if (robj == wobj) { + if (robj == MACH_PORT_NULL) + return EPERM; + + pager = wobj; + /* Remove extra reference. */ + mach_port_deallocate (mach_task_self (), pager); + } + else { + if (robj != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self (), robj); + if (wobj != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self (), wobj); + + return EPERM; + } + break; + default: + return EINVAL; + } + + offset = map->base - region->base_addr; + err = vm_map (mach_task_self (), (vm_address_t *)&map->memory, map->size, + 0, 1, + pager, /* a memory object proxy containing only the region */ + offset, /* offset from region start */ + 0, prot, VM_PROT_ALL, VM_INHERIT_SHARE); + mach_port_deallocate (mach_task_self(), pager); + + return err; +} + +static int +pci_device_hurd_unmap_range(struct pci_device *dev, + struct pci_device_mapping *map) +{ + int err; + err = pci_device_generic_unmap_range(dev, map); + map->memory = NULL; + + return err; +} + +static int +pci_device_hurd_map_legacy(struct pci_device *dev, pciaddr_t base, + pciaddr_t size, unsigned map_flags, void **addr) +{ + struct pci_device_mapping map; + int err; + + map.base = base; + map.size = size; + map.flags = map_flags; + err = pci_device_hurd_map_range(dev, &map); + *addr = map.memory; + + return err; +} + +static int +pci_device_hurd_unmap_legacy(struct pci_device *dev, void *addr, + pciaddr_t size) +{ + struct pci_device_mapping map; + + map.size = size; + map.flags = 0; + map.memory = addr; + + return pci_device_hurd_unmap_range(dev, &map); +} + /* - * Read `nbytes' bytes from `reg' in device's configuretion space + * Read `nbytes' bytes from `reg' in device's configuration space * and store them in `buf'. * * It's assumed that `nbytes' bytes are allocated in `buf' @@ -339,7 +462,8 @@ enum_devices(mach_port_t pci_port, const char *parent, int domain, if (lev > LEVEL_FUNC + 1) { return 0; } - cwd_port = file_name_lookup_under (pci_port, parent, O_DIRECTORY | O_RDWR | O_EXEC, 0); + cwd_port = file_name_lookup_under (pci_port, parent, + O_DIRECTORY | O_RDONLY | O_EXEC, 0); if (cwd_port == MACH_PORT_NULL) { return 0; } @@ -391,7 +515,7 @@ enum_devices(mach_port_t pci_port, const char *parent, int domain, snprintf(server, NAME_MAX, "./%04x/%02x/%02x/%01u/%s", domain, bus, dev, func, entry->d_name); - device_port = file_name_lookup_under(pci_port, server, O_RDWR, 0); + device_port = file_name_lookup_under(pci_port, server, O_RDONLY, 0); if (device_port == MACH_PORT_NULL) { return 0; } @@ -461,17 +585,18 @@ enum_devices(mach_port_t pci_port, const char *parent, int domain, pci_sys->num_devices++; } } + mach_port_deallocate (mach_task_self (), cwd_port); return 0; } static const struct pci_system_methods hurd_pci_methods = { - .destroy = pci_system_x86_destroy, + .destroy = pci_system_hurd_destroy, .destroy_device = pci_device_hurd_destroy_device, .read_rom = pci_device_hurd_read_rom, .probe = pci_device_hurd_probe, - .map_range = pci_device_x86_map_range, - .unmap_range = pci_device_x86_unmap_range, + .map_range = pci_device_hurd_map_range, + .unmap_range = pci_device_hurd_unmap_range, .read = pci_device_hurd_read, .write = pci_device_hurd_write, .fill_capabilities = pci_fill_capabilities_generic, @@ -483,8 +608,8 @@ static const struct pci_system_methods hurd_pci_methods = { .write32 = pci_device_x86_write32, .write16 = pci_device_x86_write16, .write8 = pci_device_x86_write8, - .map_legacy = pci_device_x86_map_legacy, - .unmap_legacy = pci_device_x86_unmap_legacy, + .map_legacy = pci_device_hurd_map_legacy, + .unmap_legacy = pci_device_hurd_unmap_legacy, }; /* Get the name of the server using libpciaccess if any */ @@ -496,7 +621,8 @@ pci_system_hurd_create(void) { int err; struct pci_system_hurd *pci_sys_hurd; - mach_port_t device_master, pci_port; + mach_port_t device_master; + mach_port_t pci_port = MACH_PORT_NULL; mach_port_t root = MACH_PORT_NULL; if (&netfs_server_name && netfs_server_name @@ -523,25 +649,29 @@ pci_system_hurd_create(void) pci_sys->num_devices = 0; - if ((err = get_privileged_ports (NULL, &device_master)) || (device_master == MACH_PORT_NULL)) { - pci_system_cleanup(); - return err; + err = get_privileged_ports (NULL, &device_master); + + if(!err && device_master != MACH_PORT_NULL) { + err = device_open (device_master, D_READ, "pci", &pci_port); + mach_port_deallocate (mach_task_self (), device_master); } - err = device_open (device_master, D_READ|D_WRITE, "pci", &pci_port); - if (!err) { - root = file_name_lookup_under (pci_port, ".", O_DIRECTORY | O_RDWR | O_EXEC, 0); + if (!err && pci_port != MACH_PORT_NULL) { + root = file_name_lookup_under (pci_port, ".", O_DIRECTORY | O_RDONLY | O_EXEC, 0); + device_close (pci_port); + mach_port_deallocate (mach_task_self (), pci_port); } - if (!root) { - root = file_name_lookup (_SERVERS_BUS_PCI, O_RDWR, 0); + if (root == MACH_PORT_NULL) { + root = file_name_lookup (_SERVERS_BUS_PCI, O_RDONLY, 0); } - if (!root) { + if (root == MACH_PORT_NULL) { pci_system_cleanup(); return errno; } + pci_sys_hurd->root = root; err = enum_devices (root, ".", -1, -1, -1, -1, LEVEL_DOMAIN); if (err) { pci_system_cleanup(); diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c index d022644..d79404e 100644 --- a/src/linux_sysfs.c +++ b/src/linux_sysfs.c @@ -336,9 +336,9 @@ pci_device_linux_sysfs_probe( struct pci_device * dev ) dev->regions[i].size = (high_addr - dev->regions[i].base_addr) + 1; - dev->regions[i].is_IO = (flags & 0x01); - dev->regions[i].is_64 = (flags & 0x04); - dev->regions[i].is_prefetchable = (flags & 0x08); + dev->regions[i].is_IO = (flags & 0x01) != 0; + dev->regions[i].is_64 = (flags & 0x04) != 0; + dev->regions[i].is_prefetchable = (flags & 0x08) != 0; } } diff --git a/src/x86_pci.c b/src/x86_pci.c index 565dbc8..86be0e7 100644 --- a/src/x86_pci.c +++ b/src/x86_pci.c @@ -263,6 +263,7 @@ map_dev_mem(void **dest, size_t mem_offset, size_t mem_size, int write) } err = device_open (master_device, mode, "mem", &devmem); + mach_port_deallocate (mach_task_self (), master_device); if (err) return err; @@ -270,17 +271,21 @@ map_dev_mem(void **dest, size_t mem_offset, size_t mem_size, int write) if (mem_size % pagesize) mem_size += pagesize - (mem_size % pagesize); - /* XXX: Mach should be fixed into supporting non-zero offset */ - err = device_map (devmem, prot, 0x0, mem_offset + mem_size, &pager, 0); + err = device_map (devmem, prot, mem_offset, mem_size, &pager, 0); + device_close (devmem); + mach_port_deallocate (mach_task_self (), devmem); if (err) return err; err = vm_map (mach_task_self (), (vm_address_t *)dest, mem_size, (vm_address_t) 0, /* mask */ 1, /* anywhere? */ - pager, mem_offset, + pager, 0, 0, /* copy */ prot, VM_PROT_ALL, VM_INHERIT_SHARE); + mach_port_deallocate (mach_task_self (), pager); + if (err) + return err; return err; #else @@ -908,19 +913,19 @@ pci_device_x86_unmap_range(struct pci_device *dev, #else -int +static int pci_device_x86_map_range(struct pci_device *dev, struct pci_device_mapping *map) { int err; - if ( (err = map_dev_mem(&map->memory, map->base, - map->size, map->flags & PCI_DEV_MAP_FLAG_WRITABLE)) ) + if ( (err = map_dev_mem(&map->memory, map->base, map->size, + map->flags & PCI_DEV_MAP_FLAG_WRITABLE))) return err; return 0; } -int +static int pci_device_x86_unmap_range(struct pci_device *dev, struct pci_device_mapping *map) { @@ -1099,7 +1104,7 @@ pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg, outb(data, reg + handle->base); } -int +static int pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base, pciaddr_t size, unsigned map_flags, void **addr) { @@ -1115,7 +1120,7 @@ pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base, return err; } -int +static int pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr, pciaddr_t size) { diff --git a/src/x86_pci.h b/src/x86_pci.h index 22c9318..d36b48a 100644 --- a/src/x86_pci.h +++ b/src/x86_pci.h @@ -63,10 +63,6 @@ int x86_enable_io(void); int x86_disable_io(void); void pci_system_x86_destroy(void); -int pci_device_x86_map_range(struct pci_device *dev, - struct pci_device_mapping *map); -int pci_device_x86_unmap_range(struct pci_device *dev, - struct pci_device_mapping *map); struct pci_io_handle *pci_device_x86_open_legacy_io(struct pci_io_handle *ret, struct pci_device *dev, pciaddr_t base, pciaddr_t size); void pci_device_x86_close_io(struct pci_device *dev, @@ -80,9 +76,5 @@ void pci_device_x86_write16(struct pci_io_handle *handle, uint32_t reg, uint16_t data); void pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg, uint8_t data); -int pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base, - pciaddr_t size, unsigned map_flags, void **addr); -int pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr, - pciaddr_t size); #endif /* X86_PCI_H */ |