bug-hurd
[Top][All Lists]
Advanced

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

[PATCH 3/5] acpi: Convert translator to an emulated mach device


From: Damien Zammit
Subject: [PATCH 3/5] acpi: Convert translator to an emulated mach device
Date: Sun, 04 Sep 2022 03:47:19 +0000

---
 acpi/Makefile  |  12 +--
 acpi/acpifs.c  |  34 +++++---
 acpi/acpifs.h  |   6 +-
 acpi/main.c    | 206 +++++++++++++++++++++++++++++++++++++++++++------
 acpi/options.c |  20 +++++
 acpi/options.h |   8 ++
 6 files changed, 243 insertions(+), 43 deletions(-)

diff --git a/acpi/Makefile b/acpi/Makefile
index f6a9bfad..4d0965c7 100644
--- a/acpi/Makefile
+++ b/acpi/Makefile
@@ -22,15 +22,15 @@ PORTDIR = $(srcdir)/port

 SRCS           = main.c netfs_impl.c acpi.c \
                  acpifs.c ncache.c options.c func_files.c acpi-ops.c \
-                 acpiServer.c
+                 acpiServer.c startup_notifyServer.c

 MIGSRCS        =
 OBJS           = $(patsubst %.S,%.o,$(patsubst %.c,%.o, $(SRCS) $(MIGSRCS)))

-HURDLIBS= fshelp ports shouldbeinlibc netfs iohelp ihash
+HURDLIBS= fshelp ports shouldbeinlibc netfs iohelp ihash machdev trivfs
 LDLIBS = -lpthread -lacpica

-target = acpi
+target = acpi acpi.static

 include ../Makeconf

@@ -40,9 +40,3 @@ acpi-MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h

 # cpp doesn't automatically make dependencies for -imacros dependencies. argh.
 acpi_S.h acpiServer.c: mig-mutate.h
-       cat $(top_srcdir)/hurd/acpi.defs \
-                | ${CC} -E -x c - -o - -imacros 
$(top_srcdir)/acpi/mig-mutate.h \
-                | mig -cc cat - /dev/null -prefix S_ -subrprefix __ \
-                        -user /dev/null \
-                        -server acpiServer.c \
-                        -sheader acpi_S.h
diff --git a/acpi/acpifs.c b/acpi/acpifs.c
index 2b5fbc00..75cc2e28 100644
--- a/acpi/acpifs.c
+++ b/acpi/acpifs.c
@@ -81,16 +81,19 @@ alloc_file_system (struct acpifs **fs)
 }

 error_t
-init_file_system (file_t underlying_node, struct acpifs *fs)
+init_root_node (file_t underlying_node)
 {
   error_t err;
   struct node *np;
-  io_statbuf_t underlying_node_stat;
+  io_statbuf_t underlying_node_stat = { 0 };

-  /* Initialize status from underlying node.  */
-  err = io_stat (underlying_node, &underlying_node_stat);
-  if (err)
-    return err;
+  if (underlying_node != MACH_PORT_NULL)
+    {
+      /* Initialize status from underlying node.  */
+      err = io_stat (underlying_node, &underlying_node_stat);
+      if (err)
+       return err;
+    }

   np = netfs_make_node_alloc (sizeof (struct netnode));
   if (!np)
@@ -106,18 +109,27 @@ init_file_system (file_t underlying_node, struct acpifs 
*fs)
   fshelp_touch (&np->nn_stat, TOUCH_ATIME | TOUCH_MTIME | TOUCH_CTIME,
                acpifs_maptime);

+  netfs_root_node = np;
+  return 0;
+}
+
+error_t
+init_file_system (struct acpifs *fs)
+{
+  error_t err;
+  struct node *np = netfs_root_node;
+
   fs->entries = calloc (1, sizeof (struct acpifs_dirent));
   if (!fs->entries)
-    {
-      free (fs->entries);
-      return ENOMEM;
-    }
+    return ENOMEM;

   /* Create the root entry */
   err = create_dir_entry ("", 0, 0, np->nn_stat, np, fs->entries);
+  if (err)
+    return err;

   fs->num_entries = 1;
-  fs->root = netfs_root_node = np;
+  fs->root = np;
   fs->root->nn->ln = fs->entries;
   pthread_mutex_init (&fs->node_cache_lock, 0);

diff --git a/acpi/acpifs.h b/acpi/acpifs.h
index 4597e1b0..e4ab0d95 100644
--- a/acpi/acpifs.h
+++ b/acpi/acpifs.h
@@ -97,6 +97,9 @@ struct acpifs
   size_t node_cache_max;
   pthread_mutex_t node_cache_lock;

+  /* Next bootstrap task */
+  mach_port_t next_task;
+
   struct acpifs_perm perm;

   struct acpifs_dirent *entries;
@@ -138,7 +141,8 @@ extern volatile struct mapped_time_value *acpifs_maptime;

 /* FS manipulation functions */
 error_t alloc_file_system (struct acpifs **fs);
-error_t init_file_system (file_t underlying_node, struct acpifs *fs);
+error_t init_file_system (struct acpifs *fs);
+error_t init_root_node (file_t underlying_node);
 error_t create_fs_tree (struct acpifs *fs);
 error_t fs_set_permissions (struct acpifs *fs);
 error_t entry_check_perms (struct iouser *user, struct acpifs_dirent *e,
diff --git a/acpi/main.c b/acpi/main.c
index 9cb6f3a1..c5de2742 100644
--- a/acpi/main.c
+++ b/acpi/main.c
@@ -25,14 +25,19 @@
 #include <version.h>
 #include <argp.h>
 #include <hurd/netfs.h>
+#include <hurd/fsys.h>

 #include "acpi_S.h"
+#include "startup_notify_S.h"
 #include "libnetfs/io_S.h"
 #include "libnetfs/fs_S.h"
 #include "libports/notify_S.h"
 #include "libnetfs/fsys_S.h"
 #include "libports/interrupt_S.h"
 #include "libnetfs/ifsock_S.h"
+#include "libmachdev/machdev.h"
+#include <device/device.h>
+#include <pthread.h>
 #include <acpi/acpi_init.h>
 #include <acpifs.h>

@@ -45,24 +50,110 @@ volatile struct mapped_time_value *acpifs_maptime;

 struct acpifs *fs;

-int
-netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t * outp)
+static mach_port_t acpi_control_port;
+
+
+static io_return_t
+acpi_device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type,
+                 dev_mode_t mode, const char *name, device_t * devp,
+                 mach_msg_type_name_t * devicePoly)
 {
-  mig_routine_t routine;
+  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 ((routine = netfs_io_server_routine (inp)) ||
-      (routine = netfs_fs_server_routine (inp)) ||
-      (routine = ports_notify_server_routine (inp)) ||
-      (routine = netfs_fsys_server_routine (inp)) ||
-      (routine = ports_interrupt_server_routine (inp)) ||
-      (routine = netfs_ifsock_server_routine (inp)) ||
-      (routine = S_acpi_server_routine (inp)))
+  if (strncmp(name, "acpi", 3))
+    err = D_NO_SUCH_DEVICE;
+
+  /* Fall back to opening kernel device master */
+  if (err)
     {
-      (*routine) (inp, outp);
-      return TRUE;
+      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;
     }
-  else
-    return FALSE;
+
+  err = fsys_getroot(acpi_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 struct machdev_device_emulation_ops acpi_emulation_ops = {
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  acpi_device_open,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+};
+
+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
+acpifs_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)
+    error (11, err, "Translator startup failure: acpifs_startup");
+
+  acpi_control_port = ports_get_send_right (newpi);
+
+  if (bootstrap != MACH_PORT_NULL)
+    {
+      err = fsys_startup (bootstrap, flags, acpi_control_port, 
MACH_MSG_TYPE_COPY_SEND,
+                          &realnode);
+      assert_perror_backtrace (err);
+    }
+
+  return realnode;
 }

 int
@@ -70,18 +161,36 @@ main (int argc, char **argv)
 {
   error_t err;
   mach_port_t bootstrap;
+  mach_port_t next_task;
+  pthread_t t, nt;
+  file_t underlying_node = MACH_PORT_NULL;

   /* Parse options */
   alloc_file_system (&fs);
   argp_parse (netfs_runtime_argp, argc, argv, 0, 0, 0);
+  next_task = fs->next_task;

-  task_get_bootstrap_port (mach_task_self (), &bootstrap);
-  if (bootstrap == MACH_PORT_NULL)
-    error (1, 0, "must be started as a translator");
+  if (next_task != MACH_PORT_NULL)
+    {
+      /* We are a bootstrap process */

-  /* Initialize ACPI */
-  acpi_init();
+      machdev_register (&acpi_emulation_ops);
+      /* TODO: make libmachdev allow us to also run netfs on the translated 
path,
+       * so that we don't need a second acpi to serve /servers/acpi  */
+      machdev_trivfs_init (argc, argv, next_task, "acpi", NULL /* _SERVERS 
"acpi" */, &bootstrap);

+      machdev_device_init ();
+      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 ();

@@ -91,8 +200,34 @@ main (int argc, char **argv)
   if (err)
     error (1, err, "mapping time");

-  /* Create the ACPI filesystem */
-  err = init_file_system (netfs_startup (bootstrap, O_READ), fs);
+  /* Enable ACPI mode of machine */
+  acpi_init ();
+
+  if (next_task != MACH_PORT_NULL)
+    {
+      void *run_server(void *arg) {
+       machdev_trivfs_server(bootstrap);
+       return NULL;
+      }
+
+      pthread_t t;
+      pthread_create(&t, NULL, run_server, NULL);
+      pthread_detach(t);
+      /* Timer started, quickly do all these next, before we call rump_init */
+    }
+
+  if (next_task == MACH_PORT_NULL)
+    underlying_node = netfs_startup (bootstrap, O_READ);
+
+  /* Create the root node first */
+  err = init_root_node (underlying_node);
+  if (err)
+    error (1, err, "creating the root node");
+
+  if (next_task != MACH_PORT_NULL)
+    acpifs_startup (bootstrap, O_READ);
+
+  err = init_file_system (fs);
   if (err)
     error (1, err, "creating the ACPI filesystem");

@@ -106,7 +241,34 @@ main (int argc, char **argv)
   if (err)
     error (1, err, "setting permissions");

-  netfs_server_loop (); /* Never returns.  */
+  err = pthread_create (&nt, NULL, netfs_server_func, NULL);
+  if (err)
+    error (1, err, "creating netfs loop thread");
+  pthread_detach (nt);

+  /* Let the other threads do their job */
+  pthread_exit(NULL);
+  /* Never reached */
   return 0;
 }
+
+int
+netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t * outp)
+{
+  mig_routine_t routine;
+
+  if ((routine = netfs_io_server_routine (inp)) ||
+      (routine = netfs_fs_server_routine (inp)) ||
+      (routine = ports_notify_server_routine (inp)) ||
+      (routine = netfs_fsys_server_routine (inp)) ||
+      (routine = ports_interrupt_server_routine (inp)) ||
+      (routine = netfs_ifsock_server_routine (inp)) ||
+      (routine = acpi_server_routine (inp)) ||
+      (routine = startup_notify_server_routine (inp)))
+    {
+      (*routine) (inp, outp);
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
diff --git a/acpi/options.c b/acpi/options.c
index 8dbcd263..fb348679 100644
--- a/acpi/options.c
+++ b/acpi/options.c
@@ -64,6 +64,15 @@ parse_opt (int opt, char *arg, struct argp_state *state)
     case 'G':
       h->perm.gid = atoi (arg);
       break;
+    case 'N':
+      h->next_task = atoi (arg);
+      break;
+    case 'H':
+      h->host_priv_port = atoi (arg);
+      break;
+    case 'P':
+      h->dev_master_port = atoi (arg);
+      break;

     case ARGP_KEY_INIT:
       /* Initialize our parsing state.  */
@@ -74,6 +83,9 @@ parse_opt (int opt, char *arg, struct argp_state *state)
       h->ncache_len = NODE_CACHE_MAX;
       h->perm.uid = 0;
       h->perm.gid = 0;
+      h->next_task = MACH_PORT_NULL;
+      h->host_priv_port = MACH_PORT_NULL;
+      h->dev_master_port = MACH_PORT_NULL;
       state->hook = h;
       break;

@@ -84,6 +96,11 @@ parse_opt (int opt, char *arg, struct argp_state *state)
       /* Set cache len */
       fs->node_cache_max = h->ncache_len;

+      /* Set bootstrap ports */
+      fs->next_task = h->next_task;
+      _hurd_host_priv = h->host_priv_port;
+      _hurd_device_master = h->dev_master_port;
+
       if (fs->root)
        {
          /*
@@ -140,6 +157,9 @@ netfs_append_args (char **argz, size_t * argz_len)
   if (p->gid >= 0)
     ADD_OPT ("--gid=%u", p->gid);

+  if (fs->next_task != MACH_PORT_NULL)
+    ADD_OPT ("--next-task=%u", fs->next_task);
+
 #undef ADD_OPT
   return err;
 }
diff --git a/acpi/options.h b/acpi/options.h
index 36ccc48b..53c98ab1 100644
--- a/acpi/options.h
+++ b/acpi/options.h
@@ -36,6 +36,11 @@ struct parse_hook
 {
   struct acpifs_perm perm;
   size_t ncache_len;
+
+  /* Mach ports */
+  mach_port_t next_task;
+  mach_port_t host_priv_port;
+  mach_port_t dev_master_port;
 };

 /* ACPI translator options.  Used for both startup and runtime.  */
@@ -43,6 +48,9 @@ static const struct argp_option options[] = {
   {0, 0, 0, 0, "These apply to the whole acpi tree:", 1},
   {"uid", 'U', "UID", 0, "User ID to give permissions to"},
   {"gid", 'G', "GID", 0, "Group ID to give permissions to"},
+  {"next-task", 'N', "TASK", 0, "Next bootstrap task"},
+  {"host-priv-port", 'H', "PORT", 0, "Port for bootstrapping host"},
+  {"device-master-port", 'P', "PORT", 0, "Port for bootstrapping device 
master"},
   {0}
 };

--
2.34.1





reply via email to

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