bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Implement mapping for ROM files


From: Joan Lledó
Subject: [PATCH] Implement mapping for ROM files
Date: Mon, 15 Aug 2022 18:15:20 +0200

From: Joan Lledó <jlledom@member.fsf.org>

* 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.
---
 pci-arbiter/device_map.c | 23 ++++++++++++++
 pci-arbiter/device_map.h |  1 +
 pci-arbiter/func_files.c | 24 +++++++-------
 pci-arbiter/func_files.h |  2 +-
 pci-arbiter/netfs_impl.c | 68 +++++++++++++++++++++++++++++++---------
 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;
 };
 
 /*
-- 
2.36.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]