diff options
author | Joan Lledó <jlledom@member.fsf.org> | 2022-08-15 18:15:20 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2022-08-15 20:33:03 +0200 |
commit | 8171d2aa48184a4d1ed1299e1c87f1b898371688 (patch) | |
tree | 3fae659c5065eccf4a45864fca2e0038d76c4465 /pci-arbiter | |
parent | b6509385bb1dd2a6d47401465bfb98b6339c5c2b (diff) | |
download | hurd-8171d2aa48184a4d1ed1299e1c87f1b898371688.tar.gz hurd-8171d2aa48184a4d1ed1299e1c87f1b898371688.tar.bz2 hurd-8171d2aa48184a4d1ed1299e1c87f1b898371688.zip |
Implement mapping for ROM files
* pci-arbiter/device_map.h:
* pci-arbiter/device_map.c:
* New function: device_map_rom
* Copies the whole rom in the arbiter space.
* pci-arbiter/pcifs.h:
* struct pcifs_dirent:
* New field to store the mapping address for each device rom.
o pci-arbiter/func_files.h:
* pci-arbiter/func_files.c:
* read_rom_file:
* Retrieves the rom contents from the local space instead of
libpciaccess.
* pci-arbiter/netfs_impl.c:
* netfs_attempt_read:get_filemap_region
* Update call to read_rom_file.
* get_filemap_region:
* Uses the old code at netfs_get_filemap to get a proxy to
the device memory region.
* get_filemap_rom:
* Returns a proxy to the locally mapped device rom.
* netfs_get_filemap:
* Checks the requested file to map and calls get_filemap_rom,
get_filemap_region or returns en error.
Message-Id: <20220815161520.6059-2-jlledom@mailfence.com>
Diffstat (limited to 'pci-arbiter')
-rw-r--r-- | pci-arbiter/device_map.c | 23 | ||||
-rw-r--r-- | pci-arbiter/device_map.h | 1 | ||||
-rw-r--r-- | pci-arbiter/func_files.c | 24 | ||||
-rw-r--r-- | pci-arbiter/func_files.h | 2 | ||||
-rw-r--r-- | pci-arbiter/netfs_impl.c | 68 | ||||
-rw-r--r-- | pci-arbiter/pcifs.h | 7 |
6 files changed, 98 insertions, 27 deletions
diff --git a/pci-arbiter/device_map.c b/pci-arbiter/device_map.c index 1627746d..284d6e93 100644 --- a/pci-arbiter/device_map.c +++ b/pci-arbiter/device_map.c @@ -47,3 +47,26 @@ device_map_region (struct pci_device *device, struct pci_mem_region *region, return err; } + +error_t +device_map_rom (struct pci_device *device, void **addr) +{ + error_t err = 0; + vm_address_t fullrom; + + if (*addr == 0) + { + err = vm_allocate (mach_task_self (), &fullrom, device->rom_size, 1); + if (err) + return ENOMEM; + + err = pci_device_read_rom (device, (void *) fullrom); + if (err) + return err; + + /* Return */ + *addr = (void *) fullrom; + } + + return err; +} diff --git a/pci-arbiter/device_map.h b/pci-arbiter/device_map.h index 0d92650c..ccdf482e 100644 --- a/pci-arbiter/device_map.h +++ b/pci-arbiter/device_map.h @@ -28,5 +28,6 @@ error_t device_map_region (struct pci_device *device, struct pci_mem_region *region, void **addr); +error_t device_map_rom (struct pci_device *device, void **addr); #endif /* DEVICE_MAP_H */ diff --git a/pci-arbiter/func_files.c b/pci-arbiter/func_files.c index 40706135..27a72209 100644 --- a/pci-arbiter/func_files.c +++ b/pci-arbiter/func_files.c @@ -104,28 +104,28 @@ io_config_file (struct pci_device * dev, off_t offset, size_t * len, /* Read the mapped ROM */ error_t -read_rom_file (struct pci_device * dev, off_t offset, size_t * len, +read_rom_file (struct pcifs_dirent * e, off_t offset, size_t * len, void *data) { - void *fullrom; + error_t err; /* This should never happen */ - assert_backtrace (dev != 0); + assert_backtrace (e->device != 0); /* Don't exceed the ROM size */ - if (offset > dev->rom_size) + if (offset > e->device->rom_size) return EINVAL; - if ((offset + *len) > dev->rom_size) - *len = dev->rom_size - offset; + if ((offset + *len) > e->device->rom_size) + *len = e->device->rom_size - offset; - /* Grab the full rom first */ - fullrom = calloc(1, dev->rom_size); - pci_device_read_rom(dev, fullrom); + /* Ensure the rom is mapped */ + err = device_map_rom (e->device, &e->rom_map); + if (err) + return err; - /* Return the requested amount */ - memcpy (data, fullrom + offset, *len); + /* Return the requested tange */ + memcpy (data, e->rom_map + offset, *len); - free(fullrom); return 0; } diff --git a/pci-arbiter/func_files.h b/pci-arbiter/func_files.h index 03cafee1..cf77374a 100644 --- a/pci-arbiter/func_files.h +++ b/pci-arbiter/func_files.h @@ -40,7 +40,7 @@ typedef int (*pci_io_op_t) (struct pci_device *dev, void *data, error_t io_config_file (struct pci_device * dev, off_t offset, size_t * len, void *data, pci_io_op_t op); -error_t read_rom_file (struct pci_device *dev, off_t offset, size_t * len, +error_t read_rom_file (struct pcifs_dirent * e, off_t offset, size_t * len, void *data); error_t io_region_file (struct pcifs_dirent *e, off_t offset, size_t * len, diff --git a/pci-arbiter/netfs_impl.c b/pci-arbiter/netfs_impl.c index b2630f01..b66f0019 100644 --- a/pci-arbiter/netfs_impl.c +++ b/pci-arbiter/netfs_impl.c @@ -509,7 +509,7 @@ netfs_attempt_read (struct iouser * cred, struct node * node, } else if (!strncmp (node->nn->ln->name, FILE_ROM_NAME, NAME_SIZE)) { - err = read_rom_file (node->nn->ln->device, offset, len, data); + err = read_rom_file (node->nn->ln, offset, len, data); if (!err) /* Update atime */ UPDATE_TIMES (node->nn->ln, TOUCH_ATIME); @@ -569,8 +569,8 @@ netfs_node_norefs (struct node *node) destroy_node (node); } -mach_port_t -netfs_get_filemap (struct node *node, vm_prot_t prot) +static mach_port_t +get_filemap_region (struct node *node, vm_prot_t prot) { error_t err; memory_object_t proxy; @@ -578,13 +578,6 @@ netfs_get_filemap (struct node *node, vm_prot_t prot) size_t reg_num; struct pci_mem_region *region; - /* Only regions files can be mapped */ - if (strncmp - (node->nn->ln->name, FILE_REGION_NAME, strlen (FILE_REGION_NAME))) - { - goto error; - } - /* Get region info */ reg_num = strtol (&node->nn->ln->name[strlen (node->nn->ln->name) - 1], 0, 16); @@ -594,14 +587,42 @@ netfs_get_filemap (struct node *node, vm_prot_t prot) err = device_map_region (node->nn->ln->device, region, &node->nn->ln->region_maps[reg_num]); if (err) - return err; + goto error; /* Create a new memory object proxy with the required protection */ max_prot = (VM_PROT_READ | VM_PROT_WRITE) & prot; err = - vm_region_create_proxy(mach_task_self (), - (vm_address_t)node->nn->ln->region_maps[reg_num], - max_prot, region->size, &proxy); + vm_region_create_proxy (mach_task_self (), + (vm_address_t) node->nn->ln->region_maps[reg_num], + max_prot, region->size, &proxy); + if (err) + goto error; + + return proxy; + +error: + errno = EOPNOTSUPP; + return MACH_PORT_NULL; +} + +static mach_port_t +get_filemap_rom (struct node *node, vm_prot_t prot) +{ + error_t err; + memory_object_t proxy; + vm_prot_t max_prot; + + /* Ensure the rom is mapped */ + err = device_map_rom (node->nn->ln->device, &node->nn->ln->rom_map); + if (err) + goto error; + + /* Create a new memory object proxy with the required protection */ + max_prot = (VM_PROT_READ) & prot; + err = + vm_region_create_proxy (mach_task_self (), + (vm_address_t) node->nn->ln->rom_map, + max_prot, node->nn->ln->device->rom_size, &proxy); if (err) goto error; @@ -611,3 +632,22 @@ error: errno = EOPNOTSUPP; return MACH_PORT_NULL; } + +mach_port_t +netfs_get_filemap (struct node *node, vm_prot_t prot) +{ + /* Only region and rom files can be mapped */ + if (!strncmp + (node->nn->ln->name, FILE_REGION_NAME, strlen (FILE_REGION_NAME))) + { + return get_filemap_region (node, prot); + } + + if (!strncmp (node->nn->ln->name, FILE_ROM_NAME, strlen (FILE_ROM_NAME))) + { + return get_filemap_rom (node, prot); + } + + errno = EOPNOTSUPP; + return MACH_PORT_NULL; +} diff --git a/pci-arbiter/pcifs.h b/pci-arbiter/pcifs.h index 050c9e32..373dd4bd 100644 --- a/pci-arbiter/pcifs.h +++ b/pci-arbiter/pcifs.h @@ -98,6 +98,13 @@ struct pcifs_dirent * Only when a device is present */ void *region_maps[6]; + + /* + * Address where the rom is mapped + * + * Only when a device is present + */ + void *rom_map; }; /* |