Neat! :D
Joan Lledó, le dim. 12 déc. 2021 14:08:17 +0100, a ecrit: > From: Joan Lledó <jlle...@member.fsf.org> > > * pci-arbiter/Makefile: > * Add device_map.c to sources > * pci-arbiter/device_map.c: > * pci-arbiter/device_map.h: > * New module for device mapping > * Relies on libpciaccess mapping methods > * pci-arbiter/func_files.c: > * io_region_file(): Use the new device mapping module > * pci-arbiter/netfs_impl.c: > * Implements netfs_get_filemap(): > * Uses the device mapping module to map the region to the > arbiter space > * Calls the kernel RPC vm_region_create_proxy() to obtain the > memory object proxy > * Only region files are mapped for now > --- > pci-arbiter/Makefile | 2 +- > pci-arbiter/device_map.c | 38 ++++++++++++++++++++++++++++++++++ > pci-arbiter/device_map.h | 32 +++++++++++++++++++++++++++++ > pci-arbiter/func_files.c | 16 ++++++--------- > pci-arbiter/netfs_impl.c | 44 ++++++++++++++++++++++++++++++++++++---- > 5 files changed, 117 insertions(+), 15 deletions(-) > create mode 100644 pci-arbiter/device_map.c > create mode 100644 pci-arbiter/device_map.h > > diff --git a/pci-arbiter/Makefile b/pci-arbiter/Makefile > index d3d205ec..821c3ca9 100644 > --- a/pci-arbiter/Makefile > +++ b/pci-arbiter/Makefile > @@ -22,7 +22,7 @@ PORTDIR = $(srcdir)/port > > SRCS = main.c pci-ops.c netfs_impl.c \ > pcifs.c ncache.c options.c func_files.c \ > - pciServer.c startup_notifyServer.c > + device_map.c pciServer.c startup_notifyServer.c > OBJS = $(SRCS:.c=.o) $(MIGSTUBS) > > HURDLIBS= fshelp ports shouldbeinlibc netfs iohelp ihash trivfs machdev > diff --git a/pci-arbiter/device_map.c b/pci-arbiter/device_map.c > new file mode 100644 > index 00000000..216adfb9 > --- /dev/null > +++ b/pci-arbiter/device_map.c > @@ -0,0 +1,38 @@ > +/* > + Copyright (C) 2021 Free Software Foundation, Inc. > + > + This file is part of the GNU Hurd. > + > + The GNU Hurd is free software; you can redistribute it and/or > + modify it under the terms of the GNU General Public License as > + published by the Free Software Foundation; either version 2, or (at > + your option) any later version. > + > + The GNU Hurd is distributed in the hope that it will be useful, but > + WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. > +*/ > + > +/* Implementation for device memory mapping functions */ > + > +#include <pciaccess.h> > + > +#include "device_map.h" > + > +error_t > +device_map_region (struct pci_device *device, struct pci_mem_region *region) > +{ > + error_t err = 0; > + > + if (region->memory == 0) > + { > + err = pci_device_map_range (device, region->base_addr, region->size, > + PCI_DEV_MAP_FLAG_WRITABLE, ®ion->memory); > + } > + > + return err; > +} > diff --git a/pci-arbiter/device_map.h b/pci-arbiter/device_map.h > new file mode 100644 > index 00000000..9062e901 > --- /dev/null > +++ b/pci-arbiter/device_map.h > @@ -0,0 +1,32 @@ > +/* > + Copyright (C) 2021 Free Software Foundation, Inc. > + > + This file is part of the GNU Hurd. > + > + The GNU Hurd is free software; you can redistribute it and/or > + modify it under the terms of the GNU General Public License as > + published by the Free Software Foundation; either version 2, or (at > + your option) any later version. > + > + The GNU Hurd is distributed in the hope that it will be useful, but > + WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. > +*/ > + > +/* Header for device memory mapping functions */ > + > +#ifndef DEVICE_MAP_H > +#define DEVICE_MAP_H > + > +#include <hurd.h> > + > +#include <pciaccess.h> > + > +error_t device_map_region (struct pci_device *device, > + struct pci_mem_region *region); > + > +#endif /* DEVICE_MAP_H */ > diff --git a/pci-arbiter/func_files.c b/pci-arbiter/func_files.c > index d7d8c5d5..81ebfded 100644 > --- a/pci-arbiter/func_files.c > +++ b/pci-arbiter/func_files.c > @@ -30,6 +30,8 @@ > > #include <pciaccess.h> > > +#include "device_map.h" > + > /* Read or write a block of data from/to the configuration space */ > static error_t > config_block_op (struct pci_device *dev, off_t offset, size_t * len, > @@ -202,16 +204,10 @@ io_region_file (struct pcifs_dirent * e, off_t offset, > size_t * len, > region_block_ioport_op (region->base_addr, offset, len, data, read); > else > { > - /* First check whether the region is already mapped */ > - if (region->memory == 0) > - { > - /* Not mapped, try to map it now */ > - err = > - pci_device_map_range (e->device, region->base_addr, region->size, > - PCI_DEV_MAP_FLAG_WRITABLE, ®ion->memory); > - if (err) > - return err; > - } > + /* Ensure the region is mapped */ > + err = device_map_region (e->device, region); > + if (err) > + return err; > if (read) > memcpy (data, region->memory + offset, *len); > else > diff --git a/pci-arbiter/netfs_impl.c b/pci-arbiter/netfs_impl.c > index 9a4b4d30..8b4bd22b 100644 > --- a/pci-arbiter/netfs_impl.c > +++ b/pci-arbiter/netfs_impl.c > @@ -29,11 +29,16 @@ > #include <unistd.h> > #include <sys/mman.h> > #include <hurd/netfs.h> > +#include <hurd/paths.h> > +#include <mach/mach4.h> > +#include <device/device.h> > + > +#include <pciaccess.h> > > #include "pcifs.h" > #include "ncache.h" > -#include <pciaccess.h> > #include "func_files.h" > +#include "device_map.h" > > #define DIRENTS_CHUNK_SIZE (8*1024) > /* Returned directory entries are aligned to blocks this many bytes long. > @@ -564,12 +569,43 @@ netfs_node_norefs (struct node *node) > destroy_node (node); > } > > -/* Return a memory object proxy port (send right) for the file contents of > NP. > - PROT is the maximum allowable access. On errors, return MACH_PORT_NULL and > - set errno. */ > mach_port_t > netfs_get_filemap (struct node *node, vm_prot_t prot) > { > + error_t err; > + memory_object_t proxy; > + vm_prot_t max_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); > + region = &node->nn->ln->device->regions[reg_num]; > + > + /* Ensure the region is mapped */ > + err = device_map_region (node->nn->ln->device, region); > + if (err) > + return err; > + > + /* 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)region->memory, > + max_prot, region->size, &proxy); > + if (err) > + goto error; > + > + return proxy; > + > +error: > errno = EOPNOTSUPP; > return MACH_PORT_NULL; > } > -- > 2.31.1