/*
- * (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.
#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; }
Hw::Device *
system_bus()
{
- static Hw::Root_bus _sb("System Bus");
- return &_sb;
+ return hw_system_bus();
}
Hw_icu *
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()
{
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
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;
}
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
}
{
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 },
};
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;
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)
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();
}
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;
}