2 * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
6 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU General Public License 2.
8 * Please see the COPYING-GPL-2 file for details.
10 #include <l4/sys/capability>
12 #include <l4/re/util/cap_alloc>
13 #include <l4/re/namespace>
15 #include <l4/re/error_helper>
16 #include <l4/re/dataspace>
17 #include <l4/util/kip.h>
18 #include <l4/cxx/std_exc_io>
21 #include "hw_root_bus.h"
22 #include "hw_device.h"
28 #include "vbus_factory.h"
29 #include "phys_space.h"
43 #ifdef SUPPORT_LEGACY_CFG
44 #include "cfg_parser.h"
51 #include "lua_glue.swg.h"
53 int luaopen_Io(lua_State *);
55 static const luaL_Reg libs[] =
58 {LUA_STRLIBNAME, luaopen_string },
59 {LUA_LOADLIBNAME, luaopen_package},
60 {LUA_DBLIBNAME, luaopen_debug},
61 {LUA_TABLIBNAME, luaopen_table},
65 using L4Re::Util::Auto_cap;
67 class Io_config_x : public Io_config
71 : _do_transparent_msi(false), _verbose_lvl(1) {}
73 bool transparent_msi(Hw::Device *) const
74 { return _do_transparent_msi; }
76 bool legacy_ide_resources(Hw::Device *) const
79 bool expansion_rom(Hw::Device *) const
82 void set_transparent_msi(bool v) { _do_transparent_msi = v; }
84 int verbose() const { return _verbose_lvl; }
85 void inc_verbosity() { ++_verbose_lvl; }
88 bool _do_transparent_msi;
92 static Io_config_x _my_cfg __attribute__((init_priority(30000)));
93 Io_config *Io_config::cfg = &_my_cfg;
99 static Hw::Root_bus _sb("System Bus");
110 template< typename X >
111 char const *type_name(X const &x)
113 char *n = const_cast<char *>(typeid(x).name());
118 static void dump(Device *d)
120 Device::iterator i = Device::iterator(0, d, 100);
121 for (; i != d->end(); ++i)
123 for (int x = 0; x < i->depth(); ++x)
125 printf("%s: %s \"%s\"\n",
126 type_name(*i), i->name(),
127 i->hid() ? i->hid() : "");
128 if (dlevel(DBG_INFO))
129 i->dump(i->depth() * 2);
130 if (dlevel(DBG_DEBUG))
131 for (Resource_list::const_iterator r = i->resources()->begin();
132 r != i->resources()->end(); ++r)
134 (*r)->dump(i->depth() * 2 + 2);
138 void dump_devs(Device *d);
139 int add_vbus(Vi::Device *dev);
141 void dump_devs(Device *d) { dump(d); }
146 icu = L4Re::Env::env()->get_cap<L4::Icu>("icu");
151 int add_vbus(Vi::Device *dev)
153 Vi::System_bus *b = dynamic_cast<Vi::System_bus*>(dev);
156 d_printf(DBG_ERR, "ERROR: found non system-bus device as root device, ignored\n");
160 b->request_child_resources();
161 b->allocate_pending_child_resources();
162 b->setup_resources();
163 if (!registry->register_obj(b, b->name()).is_valid())
165 d_printf(DBG_WARN, "WARNING: Service registration failed: '%s'\n", b->name());
172 struct Add_system_bus
174 void operator () (Vi::Device *dev)
176 Vi::System_bus *b = dynamic_cast<Vi::System_bus*>(dev);
179 d_printf(DBG_ERR, "ERROR: found non system-bus device as root device, ignored\n");
183 b->request_child_resources();
184 b->allocate_pending_child_resources();
185 b->setup_resources();
186 if (!registry->register_obj(b, b->name()).is_valid())
188 d_printf(DBG_WARN, "WARNING: Service registration failed: '%s'\n", b->name());
195 #ifdef SUPPORT_LEGACY_CFG
197 print_cfg_error(char const *cfg, char const *lua_err, char const *msg, int err)
200 d_printf(DBG_ERR, "%s: error using as lua config: %s\n", cfg, lua_err);
203 d_printf(DBG_ERR, "%s: error (legacy format): %s (errno=%d)\n", cfg, msg, err);
211 read_config(char const *cfg_file, lua_State *lua)
213 d_printf(DBG_INFO, "Loading: config '%s'\n", cfg_file);
215 char const *lua_err = 0;
216 int err = luaL_loadfile(lua, cfg_file);
221 if ((err = lua_pcall(lua, 0, LUA_MULTRET, 0)))
223 lua_err = lua_tostring(lua, -1);
224 d_printf(DBG_ERR, "%s: error executing lua config: %s\n", cfg_file, lua_err);
225 lua_pop(lua, lua_gettop(lua));
228 lua_pop(lua, lua_gettop(lua));
232 lua_err = lua_tostring(lua, -1);
233 lua_pop(lua, lua_gettop(lua));
236 d_printf(DBG_ERR, "%s: out of memory while loading file\n", cfg_file);
239 lua_err = lua_tostring(lua, -1);
240 d_printf(DBG_ERR, "%s: cannot open/read file: %s\n", cfg_file, lua_err);
243 d_printf(DBG_ERR, "%s: unknown error: %s\n", cfg_file, lua_err);
246 #ifdef SUPPORT_LEGACY_CFG
247 // try old school config file parser
248 int fd = open(cfg_file, O_RDONLY);
251 print_cfg_error(cfg_file, lua_err, "failed to open", errno);
255 print_cfg_error(cfg_file, lua_err, "cannot stat file", errno);
257 void *adr = mmap(NULL, sd.st_size, PROT_READ, MAP_SHARED, fd, 0);
258 if (adr == MAP_FAILED)
259 print_cfg_error(cfg_file, lua_err, "cannot mmap file", errno);
261 char const *config_file = (char const *)adr;
262 Vi::Device *vdev = 0;
263 int parse_errors = 0;
264 cfg::Scanner s(config_file, config_file + sd.st_size, cfg_file);
265 cfg::Parser p(&s, 0, vdev, system_bus(), parse_errors);
268 munmap(adr, sd.st_size);
270 if (parse_errors > 0)
271 print_cfg_error(cfg_file, lua_err, "parse errors", parse_errors);
276 std::for_each(Vi::Device::iterator(0, vdev, 0), Vi::Device::end(), Add_system_bus());
278 if (dlevel(DBG_DEBUG))
283 d_printf(DBG_ERR, "%s: error using as lua config: %s\n", cfg_file, lua_err);
291 arg_init(int argc, char * const *argv, Io_config_x *cfg)
299 OPT_TRANSPARENT_MSI = 1,
302 struct option opts[] =
304 { "verbose", 0, 0, 'v' },
305 { "transparent-msi", 0, 0, OPT_TRANSPARENT_MSI },
309 c = getopt_long(argc, argv, "v", opts, &optidx);
316 _my_cfg.inc_verbosity();
318 case OPT_TRANSPARENT_MSI:
319 d_printf(DBG_INFO, "Enabling transparent MSIs\n");
320 cfg->set_transparent_msi(true);
329 run(int argc, char * const *argv)
331 int argfileidx = arg_init(argc, argv, &_my_cfg);
333 printf("Io service\n");
334 set_debug_level(Io_config::cfg->verbose());
336 d_printf(DBG_INFO, "Verboseness level: %d\n", Io_config::cfg->verbose());
340 if (dlevel(DBG_DEBUG))
341 Phys_space::space.dump();
343 #if defined(ARCH_x86) || defined(ARCH_amd64)
344 bool is_ux = l4util_kip_kernel_is_ux(l4re_kip());
345 //res_get_ioport(0xcf8, 4);
346 res_get_ioport(0, 16);
352 system_bus()->plugin();
354 #if defined(ARCH_x86) || defined(ARCH_amd64)
356 ux_setup(system_bus());
359 lua_State *lua = luaL_newstate();
363 printf("ERROR: cannot allocate Lua state\n");
368 lua_setglobal(lua, "Io");
370 for (int i = 0; libs[i].func; ++i)
373 lua_pushcfunction(lua, libs[i].func);
374 lua_pushstring(lua,libs[i].name);
378 luaL_requiref(lua, libs[i].name, libs[i].func, 1);
385 for (; argfileidx < argc; ++argfileidx)
386 read_config(argv[argfileidx], lua);
388 if (dlevel(DBG_DEBUG))
390 printf("Real Hardware -----------------------------------\n");
394 fprintf(stderr, "Ready. Waiting for request.\n");
401 main(int argc, char * const *argv)
405 return run(argc, argv);
407 catch (L4::Runtime_error &e)
409 std::cerr << "FATAL uncought exception: " << e
410 << "\nterminating...\n";
415 std::cerr << "FATAL uncought exception of unknown type\n"
416 << "terminating...\n";