summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoan Lledó <jlledom@member.fsf.org>2021-04-05 10:48:24 +0200
committerJoan Lledó <jlledom@member.fsf.org>2021-11-21 11:40:17 +0100
commit3445a3454607d0ec23d8fa68aff65c7bdffafc8b (patch)
tree80d5b97896b7b24c416e3e80fac9060908cda341
parent06306619c45ae5c7eefcde9ea01edf99ac034e60 (diff)
pci_arbiter: new module for device mapping
Relies on libpciaccess mapping methods
-rw-r--r--pci-arbiter/Makefile2
-rw-r--r--pci-arbiter/device_map.c38
-rw-r--r--pci-arbiter/device_map.h32
-rw-r--r--pci-arbiter/func_files.c16
-rw-r--r--pci-arbiter/netfs_impl.c45
-rw-r--r--pci-arbiter/pcifs.c4
6 files changed, 96 insertions, 41 deletions
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, &region->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, &region->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 afbfce94..9a55a0e7 100644
--- a/pci-arbiter/netfs_impl.c
+++ b/pci-arbiter/netfs_impl.c
@@ -33,10 +33,12 @@
#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.
@@ -571,10 +573,8 @@ mach_port_t
netfs_get_filemap (struct node *node, vm_prot_t prot)
{
error_t err;
- mach_port_t master_device, devmem;
- memory_object_t default_pager, proxy;
- dev_mode_t mode;
- vm_prot_t mprot, max_prot;
+ memory_object_t pager, proxy;
+ vm_prot_t max_prot;
size_t reg_num, count;
struct pci_mem_region *region;
memory_object_t objects[1];
@@ -594,34 +594,19 @@ netfs_get_filemap (struct node *node, vm_prot_t prot)
strtol (&node->nn->ln->name[strlen (node->nn->ln->name) - 1], 0, 16);
region = &node->nn->ln->device->regions[reg_num];
- /* Get our port to the default pager */
- err = get_privileged_ports (NULL, &master_device);
- if (err == EPERM)
- {
- default_pager = file_name_lookup (_SERVERS_DEFPAGER, O_EXEC, 0);
- if (default_pager == MACH_PORT_NULL)
- goto error;
- }
- else if (err)
- goto error;
- else
- {
- mode = D_READ | D_WRITE;
- mprot = VM_PROT_READ | VM_PROT_WRITE;
- err = device_open (master_device, mode, "mem", &devmem);
- if (err)
- goto error;
- err = device_map (devmem, mprot, 0x0, region->base_addr * region->size,
- &default_pager, 0);
- if (err)
- goto error;
- }
- if (default_pager == MACH_PORT_NULL)
- goto error;
+ /* Ensure the region is mapped */
+ err = device_map_region (node->nn->ln->device, region);
+ if (err)
+ return err;
+
+ /* Get the pager which we are creating a proxy from */
+ pager =
+ ((struct pci_user_data *) node->nn->ln->device->user_data)->
+ pagers[reg_num];
/* Get all params to create the proxy */
max_prot = (VM_PROT_READ | VM_PROT_WRITE) & prot;
- objects[0] = default_pager;
+ objects[0] = pager;
offsets[0] = 0;
starts[0] = region->base_addr;
lens[0] = region->size;
diff --git a/pci-arbiter/pcifs.c b/pci-arbiter/pcifs.c
index 3b13e437..530e838d 100644
--- a/pci-arbiter/pcifs.c
+++ b/pci-arbiter/pcifs.c
@@ -30,6 +30,7 @@
#include "ncache.h"
#include "func_files.h"
+#include "device_map.h"
static error_t
create_dir_entry (int32_t domain, int16_t bus, int16_t dev,
@@ -325,6 +326,9 @@ create_fs_tree (struct pcifs * fs)
return err;
}
}
+ /* Allocate some space so libpciaccess can store the pagers */
+ device->user_data =
+ (intptr_t) calloc (1, sizeof (struct pci_user_data));
/* Create rom entry */
if (device->rom_size)