summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2022-08-23 19:27:27 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2022-08-23 19:27:27 +0200
commitd193fa690415333420b435edb5782789a6f3ea57 (patch)
tree3dc441811f7b2cfc3e95458d33b0843c0af95ee0
parent361356b08003f5e3c606e16eeb6a17fe02ff2726 (diff)
downloadlibpciaccess-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.c60
-rw-r--r--src/x86_pci.c8
-rw-r--r--src/x86_pci.h2
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 */