bug-hurd
[Top][All Lists]
Advanced

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

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


From: Damien Zammit
Subject: [PATCH v2 3/4] acpi: Convert translator to an emulated mach device
Date: Mon, 12 Sep 2022 10:40:04 +0000

This makes acpi usable as a bootstrap translator.
---
 acpi/Makefile  |   6 +-
 acpi/acpifs.c  |  37 +++++++----
 acpi/acpifs.h  |   6 +-
 acpi/main.c    | 172 ++++++++++++++++++++++++++++++++++++++++++++++---
 acpi/options.c |  20 ++++++
 acpi/options.h |   8 +++
 6 files changed, 225 insertions(+), 24 deletions(-)

diff --git a/acpi/Makefile b/acpi/Makefile
index 76f27aef..ceccb351 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 $(libacpica_LIBS)

-target = acpi
+target = acpi acpi.static

 include ../Makeconf

diff --git a/acpi/acpifs.c b/acpi/acpifs.c
index 2b5fbc00..1b9fbcf2 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,30 @@ 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)
+    {
+      free(fs->entries);
+      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 fc46f4f2..e10bf399 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,6 +50,8 @@ volatile struct mapped_time_value *acpifs_maptime;

 struct acpifs *fs;

+static mach_port_t acpi_control_port;
+
 int
 netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t * outp)
 {
@@ -56,7 +63,8 @@ netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t * 
outp)
       (routine = netfs_fsys_server_routine (inp)) ||
       (routine = ports_interrupt_server_routine (inp)) ||
       (routine = netfs_ifsock_server_routine (inp)) ||
-      (routine = acpi_server_routine (inp)))
+      (routine = acpi_server_routine (inp)) ||
+      (routine = startup_notify_server_routine (inp)))
     {
       (*routine) (inp, outp);
       return TRUE;
@@ -65,23 +73,144 @@ netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t 
* outp)
     return FALSE;
 }

+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)
+{
+  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, "acpi", 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(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
 main (int argc, char **argv)
 {
   error_t err;
   mach_port_t bootstrap;
+  mach_port_t next_task;
+  pthread_t t, mt;
+  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 +220,24 @@ 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)
+    machdev_trivfs_server_startup (bootstrap);
+
+  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 +251,16 @@ main (int argc, char **argv)
   if (err)
     error (1, err, "setting permissions");

-  netfs_server_loop (); /* Never returns.  */
+  if (next_task != MACH_PORT_NULL)
+    {
+      err = pthread_create (&mt, NULL, machdev_trivfs_server_loop, NULL);
+      if (err)
+        error(1, err, "creating machdev_trivfs_server_loop thread");
+      pthread_detach (mt);
+    }
+
+  netfs_server_func (NULL);

+  /* Never reached */
   return 0;
 }
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]