From b261eb886e4ee068515484727955e416517a03b4 Mon Sep 17 00:00:00 2001 From: Damien Zammit Date: Tue, 9 Mar 2021 00:04:56 +1100 Subject: pci-arbiter: Introduce machdev into this server * pci-arbiter/Makefile Add machdev lib and simplify * pci-arbiter/main.c (pci_device_{open,close,shutdown}): New methods (netfs_server_func): Thread the demuxer loop (pcifs_startup): Custom startup method (main): Use machdev for server and detach worker threads * pci-arbiter/options.{c,h} Add disk-server-task and priv ports * pci-arbiter/startup-ops.c Delete file Message-Id: <20210308130457.693821-4-damien@zamaudio.com> --- pci-arbiter/main.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 179 insertions(+), 8 deletions(-) (limited to 'pci-arbiter/main.c') diff --git a/pci-arbiter/main.c b/pci-arbiter/main.c index 181bdee2..efb9f65c 100644 --- a/pci-arbiter/main.c +++ b/pci-arbiter/main.c @@ -24,7 +24,12 @@ #include #include #include +#include #include +#include +#include +#include +#include #include #include @@ -34,7 +39,9 @@ #include "libnetfs/fsys_S.h" #include "libports/interrupt_S.h" #include "libnetfs/ifsock_S.h" +#include "libmachdev/machdev.h" #include +#include #include "pcifs.h" #include "startup.h" @@ -46,6 +53,96 @@ int netfs_maxsymlinks = 0; char *netfs_server_name = "pci-arbiter"; char *netfs_server_version = HURD_VERSION; +static mach_port_t pci_control_port; + + +static io_return_t +pci_device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type, + dev_mode_t mode, char *name, device_t * devp, + mach_msg_type_name_t * devicePoly) +{ + io_return_t err = D_SUCCESS; + mach_port_t dev_master, root; + string_t retry_name; + retry_type retry; + uid_t idlist[] = {0, 0, 0}; + + if (strncmp(name, "pci", 3)) + err = D_NO_SUCH_DEVICE; + + /* Fall back to opening kernel device master */ + if (err) + { + err = get_privileged_ports(NULL, &dev_master); + if (err) + return err; + if (dev_master == MACH_PORT_NULL) + return D_NO_SUCH_DEVICE; + err = device_open (dev_master, mode, name, devp); + if (err) + return err; + *devicePoly = MACH_MSG_TYPE_MOVE_SEND; + return D_SUCCESS; + } + + err = fsys_getroot(pci_control_port, MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND, + idlist, 3, idlist, 3, 0, + &retry, retry_name, &root); + if (err) + return err; + + *devp = root; + *devicePoly = MACH_MSG_TYPE_COPY_SEND; + return D_SUCCESS; +} + +static io_return_t +pci_device_close (void *d) +{ + ports_port_deref (&pci_control_port); + return 0; +} + +static void +pci_device_shutdown (mach_port_t dosync_handle) +{ + struct port_info *inpi = ports_lookup_port (netfs_port_bucket, dosync_handle, + pci_shutdown_notify_class); + + if (!inpi) + return; + + // Free all libpciaccess resources + pci_system_cleanup (); + + ports_port_deref (inpi); + + ports_destroy_right (&pci_control_port); + + netfs_shutdown (FSYS_GOAWAY_FORCE); +} + +static struct machdev_device_emulation_ops pci_arbiter_emulation_ops = { + NULL, + NULL, + NULL, + NULL, + pci_device_open, + pci_device_close, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + pci_device_shutdown, +}; + int netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t * outp) { @@ -67,24 +164,82 @@ netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t * outp) return FALSE; } +static void * +netfs_server_func (void *arg) +{ + error_t err; + + do + { + ports_manage_port_operations_multithread (netfs_port_bucket, + netfs_demuxer, + 1000 * 60 * 2, /* two minutes thread */ + 1000 * 60 * 10,/* ten minutes server */ + 0); + err = netfs_shutdown (0); + } + while (err); + return NULL; +} + + +static mach_port_t +pcifs_startup(mach_port_t bootstrap, int flags) +{ + error_t err; + mach_port_t realnode; + struct port_info *newpi; + + err = ports_create_port (netfs_control_class, netfs_port_bucket, + sizeof (struct port_info), &newpi); + if (!err) + { + pci_control_port = ports_get_send_right (newpi); + err = fsys_startup (bootstrap, flags, pci_control_port, MACH_MSG_TYPE_COPY_SEND, + &realnode); + assert_perror_backtrace (err); + } + if (err) + error (11, err, "Translator startup failure: fsys_startup"); + + return realnode; +} + int main (int argc, char **argv) { error_t err; mach_port_t bootstrap; + mach_port_t disk_server_task; + pthread_t t, nt; /* Parse options */ alloc_file_system (&fs); argp_parse (netfs_runtime_argp, argc, argv, 0, 0, 0); + disk_server_task = fs->params.disk_server_task; - task_get_bootstrap_port (mach_task_self (), &bootstrap); - if (bootstrap == MACH_PORT_NULL) - error (1, 0, "must be started as a translator"); - + if (disk_server_task != MACH_PORT_NULL) + { + machdev_register (&pci_arbiter_emulation_ops); + machdev_device_init (); + machdev_trivfs_init (disk_server_task, "pci", "/servers/bus/pci", &bootstrap); + err = pthread_create (&t, NULL, machdev_server, NULL); + if (err) + error (1, err, "Creating machdev thread"); + pthread_detach (t); + } + else + { + task_get_bootstrap_port (mach_task_self (), &bootstrap); + if (bootstrap == MACH_PORT_NULL) + error (1, 0, "must be started as a translator"); + } /* Initialize netfs and start the translator. */ netfs_init (); err = maptime_map (0, 0, &pcifs_maptime); + if (err) + err = maptime_map (1, 0, &pcifs_maptime); if (err) error (1, err, "mapping time"); @@ -93,8 +248,18 @@ main (int argc, char **argv) if (err) error (1, err, "Starting the PCI system"); - /* Create the PCI filesystem */ - err = init_file_system (netfs_startup (bootstrap, O_READ), fs); + if (disk_server_task != MACH_PORT_NULL) + machdev_trivfs_server(bootstrap); + /* Timer started, quickly do all these next, before we call rump_init */ + + /* Create the root node first */ + err = init_root_node (); + if (err) + error (1, err, "Creating the root node"); + + pcifs_startup (bootstrap, O_READ); + + err = init_file_system (fs); if (err) error (1, err, "Creating the PCI filesystem"); @@ -108,13 +273,19 @@ main (int argc, char **argv) if (err) error (1, err, "Setting permissions"); + err = pthread_create (&nt, NULL, netfs_server_func, NULL); + if (err) + error (1, err, "Creating netfs loop thread"); + pthread_detach (nt); + /* * Ask init to tell us when the system is going down, * so we can try to be friendly to our correspondents on the network. */ arrange_shutdown_notification (); - netfs_server_loop (); /* Never returns. */ - + /* Let the other threads do their job */ + pthread_exit(NULL); + /* Never reached */ return 0; } -- cgit v1.2.3