diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2022-08-23 19:27:27 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2022-08-23 19:27:27 +0200 |
commit | d193fa690415333420b435edb5782789a6f3ea57 (patch) | |
tree | 3dc441811f7b2cfc3e95458d33b0843c0af95ee0 | |
parent | 361356b08003f5e3c606e16eeb6a17fe02ff2726 (diff) | |
download | libpciaccess-d193fa690415333420b435edb5782789a6f3ea57.tar.gz |
hurd: Fix pci_device_hurd_map_legacy
It was not passing a proper region number to pci_device_hurd_map_range,
and that would not make sense anyway since the rom is not a region for
instance, and the video memory, interrupt vector etc. aren't a region or
the rom.
So this uses pci_device_hurd_map_range for the rom, and
pci_system_x86_map_dev_mem for non-rom. Unfortunately pci-arbiter
currently cannot get the rom_base from libpciaccess, so we can only
guess that we are trying to map a rom.
-rw-r--r-- | src/hurd_pci.c | 60 | ||||
-rw-r--r-- | src/x86_pci.c | 8 | ||||
-rw-r--r-- | src/x86_pci.h | 2 |
3 files changed, 56 insertions, 14 deletions
diff --git a/src/hurd_pci.c b/src/hurd_pci.c index 2d10c5c..8653e1b 100644 --- a/src/hurd_pci.c +++ b/src/hurd_pci.c @@ -58,6 +58,8 @@ #define FILE_REGION_NAME "region" #define FILE_ROM_NAME "rom" +#define LEGACY_REGION -1 + /* Level in the fs tree */ typedef enum { LEVEL_NONE, @@ -164,13 +166,27 @@ static int pci_device_hurd_map_range(struct pci_device *dev, struct pci_device_mapping *map) { +#if 0 + struct pci_device_private *d = (struct pci_device_private *)dev; +#endif 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]; + const struct pci_mem_region *region; + const struct pci_mem_region rom_region = { +#if 0 + /* FIXME: We should be doing this: */ + .base_addr = d->rom_base, + /* But currently pci-arbiter cannot get rom_base from libpciaccess, so we + are here assuming the caller is mapping from the rom base */ +#else + .base_addr = map->base, +#endif + .size = dev->rom_size, + }; int flags = O_RDONLY; char server[NAME_MAX]; @@ -179,9 +195,20 @@ pci_device_hurd_map_range(struct pci_device *dev, 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); + if (map->region != LEGACY_REGION) { + region = &dev->regions[map->region]; + snprintf(server, NAME_MAX, "%04x/%02x/%02x/%01u/%s%01u", + dev->domain, dev->bus, dev->dev, dev->func, + FILE_REGION_NAME, map->region); + } else { + region = &rom_region; + snprintf(server, NAME_MAX, "%04x/%02x/%02x/%01u/%s", + dev->domain, dev->bus, dev->dev, dev->func, + FILE_ROM_NAME); + if (map->base < region->base_addr || + map->base + map->size > region->base_addr + region->size) + return EINVAL; + } file = file_name_lookup_under (pci_sys_hurd->root, server, flags, 0); if (! MACH_PORT_VALID (file)) { @@ -250,13 +277,25 @@ pci_device_hurd_map_legacy(struct pci_device *dev, pciaddr_t base, 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; + if (base >= 0xC0000 && base < 0x100000) { + /* FIXME: We would rather know for sure from d->rom_base whether this is + the ROM or not but currently pci-arbiter cannot get rom_base from + libpciaccess, so we are here assuming the caller is mapping from the + rom base */ + map.base = base; + map.size = size; + map.flags = map_flags; + map.region = LEGACY_REGION; + err = pci_device_hurd_map_range(dev, &map); + *addr = map.memory; - return err; + if (!err) + return 0; + } + + /* This is probably not the ROM, this is probably something like VRam or + the interrupt table, just map it by hand. */ + return pci_system_x86_map_dev_mem(addr, base, size, !!(map_flags & PCI_DEV_MAP_FLAG_WRITABLE)); } static int @@ -267,6 +306,7 @@ pci_device_hurd_unmap_legacy(struct pci_device *dev, void *addr, map.size = size; map.flags = 0; + map.region = LEGACY_REGION; map.memory = addr; return pci_device_hurd_unmap_range(dev, &map); diff --git a/src/x86_pci.c b/src/x86_pci.c index 86be0e7..dfe3fa3 100644 --- a/src/x86_pci.c +++ b/src/x86_pci.c @@ -240,8 +240,8 @@ sort_devices(void) #include <device/device.h> #endif -static int -map_dev_mem(void **dest, size_t mem_offset, size_t mem_size, int write) +int +pci_system_x86_map_dev_mem(void **dest, size_t mem_offset, size_t mem_size, int write) { #if defined(__GNU__) int err; @@ -543,7 +543,7 @@ pci_device_x86_read_rom(struct pci_device *dev, void *buffer) struct pci_device_private *d = (struct pci_device_private *)dev; int err; - if ( (err = map_dev_mem(&bios, d->rom_base, dev->rom_size, 0)) ) + if ( (err = pci_system_x86_map_dev_mem(&bios, d->rom_base, dev->rom_size, 0)) ) return err; memcpy(buffer, bios, dev->rom_size); @@ -918,7 +918,7 @@ 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, + if ( (err = pci_system_x86_map_dev_mem(&map->memory, map->base, map->size, map->flags & PCI_DEV_MAP_FLAG_WRITABLE))) return err; diff --git a/src/x86_pci.h b/src/x86_pci.h index d36b48a..b550e3d 100644 --- a/src/x86_pci.h +++ b/src/x86_pci.h @@ -76,5 +76,7 @@ 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_system_x86_map_dev_mem(void **dest, size_t mem_offset, size_t mem_size, + int write); #endif /* X86_PCI_H */ |