]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/io/server/src/main.cc
update
[l4.git] / l4 / pkg / io / server / src / main.cc
index 82f81de5380d395ece71793cdefdcf3f64a16731..1abdda2d4cfdd284a159ac646e17a42e14222960 100644 (file)
@@ -1,5 +1,8 @@
 /*
- * (c) 2010 Technische Universität Dresden
+ * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
+ *          Alexander Warg <warg@os.inf.tu-dresden.de>
+ *     economic rights: Technische Universität Dresden (Germany)
+ *
  * This file is part of TUD:OS and distributed under the terms of the
  * GNU General Public License 2.
  * Please see the COPYING-GPL-2 file for details.
@@ -12,7 +15,7 @@
 #include <l4/re/error_helper>
 #include <l4/re/dataspace>
 #include <l4/util/kip.h>
-#include <l4/cxx/iostream>
+#include <l4/cxx/std_exc_io>
 
 #include "main.h"
 #include "hw_root_bus.h"
 #include "server.h"
 #include "res.h"
 #include "pci.h"
+#include "platform_control.h"
 #include "__acpi.h"
-#include "vbus.h"
-#include "vbus_factory.h"
+#include "virt/vbus.h"
+#include "virt/vbus_factory.h"
 #include "phys_space.h"
 #include "ux.h"
 #include "cfg.h"
 #include <stdio.h>
 #include <fcntl.h>
 
+#ifdef SUPPORT_LEGACY_CFG
 #include "cfg_parser.h"
+#endif
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+#include "lua_glue.swg.h"
+
+namespace {
+
+static Hw::Root_bus *
+hw_system_bus()
+{
+  static Hw::Root_bus _sb("System Bus");
+  return &_sb;
+}
+
+static Platform_control *
+platform_control()
+{
+  static Platform_control pfc(hw_system_bus());
+  return &pfc;
+}
+
+
+struct Virtual_sbus : Vi::System_bus
+{
+  Virtual_sbus() : Vi::System_bus(platform_control()) {}
+};
+
+static Vi::Dev_factory_t<Virtual_sbus> __sb_root_factory("System_bus");
+
+}
+
+int luaopen_Io(lua_State *);
+
+static const luaL_Reg libs[] =
+{
+  {"", luaopen_base },
+  {LUA_STRLIBNAME, luaopen_string },
+  {LUA_LOADLIBNAME, luaopen_package},
+  {LUA_DBLIBNAME, luaopen_debug},
+  {LUA_TABLIBNAME, luaopen_table},
+  { NULL, NULL }
+};
 
 using L4Re::Util::Auto_cap;
 
 class Io_config_x : public Io_config
 {
 public:
-  Io_config_x() : _do_transparent_msi(false) {}
+  Io_config_x()
+  : _do_transparent_msi(false), _verbose_lvl(1) {}
 
   bool transparent_msi(Hw::Device *) const
   { return _do_transparent_msi; }
@@ -72,8 +123,7 @@ Io_config *Io_config::cfg = &_my_cfg;
 Hw::Device *
 system_bus()
 {
-  static Hw::Root_bus _sb("System Bus");
-  return &_sb;
+  return hw_system_bus();
 }
 
 Hw_icu *
@@ -91,25 +141,37 @@ char const *type_name(X const &x)
   return n;
 }
 
-void dump(Device *d)
+static void dump(Device *d)
 {
   Device::iterator i = Device::iterator(0, d, 100);
   for (; i != d->end(); ++i)
     {
-      for (int x = 0; x < i->depth(); ++x)
-       printf("  ");
-      printf("%s: %s \"%s\"\n",
-             type_name(*i), i->name(),
-             i->hid() ? i->hid() : "");
-      if (Io_config::cfg->verbose() >= 1)
-        i->dump(i->depth() * 2);
-      if (Io_config::cfg->verbose() >= 2)
-        for (Resource_list::iterator r = i->resources()->begin();
-             r != i->resources()->end(); ++r)
-          r->dump(i->depth() * 2 + 2);
+      int indent = i->depth() * 2;
+      if (dlevel(DBG_INFO))
+        i->dump(indent);
+      if (dlevel(DBG_DEBUG))
+        {
+          printf("%*.s  Resources: ==== start ====\n", indent, " ");
+          for (Resource_list::const_iterator r = i->resources()->begin();
+               r != i->resources()->end(); ++r)
+            if (*r)
+              (*r)->dump(indent + 2);
+          printf("%*.s  Resources: ===== end =====\n", indent, " ");
+        }
     }
 }
 
+static void check_conflicts(Hw::Device *d)
+{
+  for (auto i = Hw::Device::iterator(0, d, 100); i != d->end(); ++i)
+    (*i)->check_conflicts();
+}
+
+void dump_devs(Device *d);
+int add_vbus(Vi::Device *dev);
+
+void dump_devs(Device *d) { dump(d); }
+
 
 Hw_icu::Hw_icu()
 {
@@ -118,6 +180,25 @@ Hw_icu::Hw_icu()
     icu->info(&info);
 }
 
+int add_vbus(Vi::Device *dev)
+{
+  Vi::System_bus *b = dynamic_cast<Vi::System_bus*>(dev);
+  if (!b)
+    {
+      d_printf(DBG_ERR, "ERROR: found non system-bus device as root device, ignored\n");
+      return -1;
+    }
+
+  b->request_child_resources();
+  b->allocate_pending_child_resources();
+  b->setup_resources();
+  if (!registry->register_obj(b, b->name()).is_valid())
+    {
+      d_printf(DBG_WARN, "WARNING: Service registration failed: '%s'\n", b->name());
+      return -1;
+    }
+  return 0;
+}
 
 
 struct Add_system_bus
@@ -127,7 +208,7 @@ struct Add_system_bus
     Vi::System_bus *b = dynamic_cast<Vi::System_bus*>(dev);
     if (!b)
       {
-        printf("ERROR: found non system-bus device as root device, ignored\n");
+        d_printf(DBG_ERR, "ERROR: found non system-bus device as root device, ignored\n");
        return;
       }
 
@@ -136,58 +217,104 @@ struct Add_system_bus
     b->setup_resources();
     if (!registry->register_obj(b, b->name()).is_valid())
       {
-       printf("Service registration failed: '%s'\n", b->name());
+       d_printf(DBG_WARN, "WARNING: Service registration failed: '%s'\n", b->name());
        return;
       }
   }
 };
 
+
+#ifdef SUPPORT_LEGACY_CFG
 static void
-read_config(char const *cfg_file)
+print_cfg_error(char const *cfg, char const *lua_err, char const *msg, int err)
 {
-  Vi::Device *vdev = 0;
+  if (lua_err)
+    d_printf(DBG_ERR, "%s: error using as lua config: %s\n", cfg, lua_err);
 
-  if (Io_config::cfg->verbose() >= 2)
-    printf("Loading: config '%s'\n", cfg_file);
+  if (msg)
+    d_printf(DBG_ERR, "%s: error (legacy format): %s (errno=%d)\n", cfg, msg, err);
 
+  if (errno < 0)
+    exit(1);
+}
+#endif
 
-  int fd = open(cfg_file, O_RDONLY);
+static int
+read_config(char const *cfg_file, lua_State *lua)
+{
+  d_printf(DBG_INFO, "Loading: config '%s'\n", cfg_file);
 
-  if (fd < 0)
+  char const *lua_err = 0;
+  int err = luaL_loadfile(lua, cfg_file);
+
+  switch (err)
     {
-      printf("failed to open config file '%s'\n", cfg_file);
+    case 0:
+      if ((err = lua_pcall(lua, 0, LUA_MULTRET, 0)))
+        {
+          lua_err = lua_tostring(lua, -1);
+          d_printf(DBG_ERR, "%s: error executing lua config: %s\n", cfg_file, lua_err);
+          lua_pop(lua, lua_gettop(lua));
+          return -1;
+        }
+      lua_pop(lua, lua_gettop(lua));
+      return 0;
+      break;
+    case LUA_ERRSYNTAX:
+      lua_err = lua_tostring(lua, -1);
+      lua_pop(lua, lua_gettop(lua));
+      break;
+    case LUA_ERRMEM:
+      d_printf(DBG_ERR, "%s: out of memory while loading file\n", cfg_file);
+      exit(1);
+    case LUA_ERRFILE:
+      lua_err = lua_tostring(lua, -1);
+      d_printf(DBG_ERR, "%s: cannot open/read file: %s\n", cfg_file, lua_err);
+      exit(1);
+    default:
+      d_printf(DBG_ERR, "%s: unknown error: %s\n", cfg_file, lua_err);
       exit(1);
     }
+#ifdef SUPPORT_LEGACY_CFG
+  // try old school config file parser
+  int fd = open(cfg_file, O_RDONLY);
+
+  if (fd < 0)
+    print_cfg_error(cfg_file, lua_err, "failed to open", errno);
 
   struct stat sd;
   if (fstat(fd, &sd))
-    {
-      printf("failed to stat config file '%s'\n", cfg_file);
-      exit(1);
-    }
+    print_cfg_error(cfg_file, lua_err, "cannot stat file", errno);
 
   void *adr = mmap(NULL, sd.st_size, PROT_READ, MAP_SHARED, fd, 0);
   if (adr == MAP_FAILED)
-    {
-      printf("failed to mmap config file '%s'\n", cfg_file);
-      exit(1);
-    }
+    print_cfg_error(cfg_file, lua_err, "cannot mmap file", errno);
 
   char const *config_file = (char const *)adr;
-
+  Vi::Device *vdev = 0;
+  int parse_errors = 0;
   cfg::Scanner s(config_file, config_file + sd.st_size, cfg_file);
-  cfg::Parser p(&s, 0, vdev, system_bus());
+  cfg::Parser p(&s, 0, vdev, system_bus(), parse_errors);
   p.parse();
 
   munmap(adr, sd.st_size);
 
+  if (parse_errors > 0)
+    print_cfg_error(cfg_file, lua_err, "parse errors", parse_errors);
+
   if (!vdev)
-    return;
+    return 0;
 
-  if (Io_config::cfg->verbose() >= 1)
+  std::for_each(Vi::Device::iterator(0, vdev, 0), Vi::Device::end(), Add_system_bus());
+
+  if (dlevel(DBG_DEBUG))
     dump(vdev);
 
-  std::for_each(Vi::Device::iterator(0, vdev, 0), Vi::Device::end(), Add_system_bus());
+  return 0;
+#else
+  d_printf(DBG_ERR, "%s: error using as lua config: %s\n", cfg_file, lua_err);
+  return -1;
+#endif
 }
 
 
@@ -199,11 +326,19 @@ arg_init(int argc, char * const *argv, Io_config_x *cfg)
     {
       int optidx = 0;
       int c;
+      enum
+      {
+        OPT_TRANSPARENT_MSI   = 1,
+        OPT_TRACE             = 2,
+        OPT_ACPI_DEBUG        = 3,
+      };
 
       struct option opts[] =
       {
-        { "verbose",         0, 0, 'v' },
-        { "transparent-msi", 0, 0, 1 },
+        { "verbose",           0, 0, 'v' },
+        { "transparent-msi",   0, 0, OPT_TRANSPARENT_MSI },
+        { "trace",             1, 0, OPT_TRACE },
+        { "acpi-debug-level",  1, 0, OPT_ACPI_DEBUG },
         { 0, 0, 0, 0 },
       };
 
@@ -214,12 +349,26 @@ arg_init(int argc, char * const *argv, Io_config_x *cfg)
       switch (c)
         {
         case 'v':
-          _my_cfg.inc_verbosity();
+          cfg->inc_verbosity();
           break;
-        case 1:
-         printf("Enabling transparent MSIs\n");
+        case OPT_TRANSPARENT_MSI:
+         d_printf(DBG_INFO, "Enabling transparent MSIs\n");
           cfg->set_transparent_msi(true);
           break;
+        case OPT_TRACE:
+          {
+            unsigned trace_mask = strtol(optarg, 0, 0);
+            set_trace_mask(trace_mask);
+            printf("Set trace mask to 0x%08x\n", trace_mask);
+            break;
+          }
+        case OPT_ACPI_DEBUG:
+          {
+            l4_uint32_t acpi_debug_level = strtol(optarg, 0, 0);
+            acpi_set_debug_level(acpi_debug_level);
+            printf("Set acpi debug level to 0x%08x\n", acpi_debug_level);
+            break;
+          }
         }
     }
   return optind;
@@ -232,13 +381,13 @@ run(int argc, char * const *argv)
   int argfileidx = arg_init(argc, argv, &_my_cfg);
 
   printf("Io service\n");
+  set_debug_level(Io_config::cfg->verbose());
 
-  if (Io_config::cfg->verbose())
-    printf("Verboseness level: %d\n", Io_config::cfg->verbose());
+  d_printf(DBG_INFO, "Verboseness level: %d\n", Io_config::cfg->verbose());
 
   res_init();
 
-  if (Io_config::cfg->verbose() > 1)
+  if (dlevel(DBG_DEBUG))
     Phys_space::space.dump();
 
 #if defined(ARCH_x86) || defined(ARCH_amd64)
@@ -257,15 +406,47 @@ run(int argc, char * const *argv)
     ux_setup(system_bus());
 #endif
 
+  lua_State *lua = luaL_newstate();
+
+  if (!lua)
+    {
+      printf("ERROR: cannot allocate Lua state\n");
+      exit(1);
+    }
+
+  lua_newtable(lua);
+  lua_setglobal(lua, "Io");
+
+  for (int i = 0; libs[i].func; ++i)
+    {
+#if 1 // lua 5.1
+      lua_pushcfunction(lua, libs[i].func);
+      lua_pushstring(lua,libs[i].name);
+      lua_call(lua, 1, 0);
+#endif
+#if 0  // lua 5.2
+      luaL_requiref(lua, libs[i].name, libs[i].func, 1);
+      lua_pop(lua, 1);
+#endif
+    }
+
+  luaopen_Io(lua);
+
   for (; argfileidx < argc; ++argfileidx)
-    read_config(argv[argfileidx]);
+    read_config(argv[argfileidx], lua);
 
-  if (Io_config::cfg->verbose() >= 1)
+  if (dlevel(DBG_DEBUG))
     {
       printf("Real Hardware -----------------------------------\n");
       dump(system_bus());
     }
 
+  check_conflicts(system_bus());
+
+  if (!registry->register_obj(platform_control(), "platform_ctl"))
+    d_printf(DBG_WARN, "warning: could not register control interface at"
+                       " cap 'platform_ctl'\n");
+
   fprintf(stderr, "Ready. Waiting for request.\n");
   server_loop();
 
@@ -281,14 +462,14 @@ main(int argc, char * const *argv)
     }
   catch (L4::Runtime_error &e)
     {
-      L4::cerr << "FATAL uncought exception: " << e
-               << "\nterminating...\n";
+      std::cerr << "FATAL uncaught exception: " << e
+                << "\nterminating...\n";
 
     }
   catch (...)
     {
-      L4::cerr << "FATAL uncought exception of unknown type\n"
-               << "terminating...\n";
+      std::cerr << "FATAL uncaught exception of unknown type\n"
+                << "terminating...\n";
     }
   return -1;
 }