]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/io/server/src/main.cc
update
[l4.git] / l4 / pkg / io / server / src / main.cc
1 /*
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)
5  *
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.
9  */
10 #include <l4/sys/capability>
11 #include <l4/re/env>
12 #include <l4/re/util/cap_alloc>
13 #include <l4/re/namespace>
14 #include <l4/sys/icu>
15 #include <l4/re/error_helper>
16 #include <l4/re/dataspace>
17 #include <l4/util/kip.h>
18 #include <l4/cxx/iostream>
19
20 #include "main.h"
21 #include "hw_root_bus.h"
22 #include "hw_device.h"
23 #include "server.h"
24 #include "res.h"
25 #include "pci.h"
26 #include "__acpi.h"
27 #include "vbus.h"
28 #include "vbus_factory.h"
29 #include "phys_space.h"
30 #include "ux.h"
31 #include "cfg.h"
32
33 #include <cstdio>
34 #include <typeinfo>
35 #include <algorithm>
36 #include <string>
37 #include <getopt.h>
38 #include <sys/mman.h>
39 #include <sys/stat.h>
40 #include <stdio.h>
41 #include <fcntl.h>
42
43 #include "cfg_parser.h"
44
45 using L4Re::Util::Auto_cap;
46
47 class Io_config_x : public Io_config
48 {
49 public:
50   Io_config_x() : _do_transparent_msi(false) {}
51
52   bool transparent_msi(Hw::Device *) const
53   { return _do_transparent_msi; }
54
55   bool legacy_ide_resources(Hw::Device *) const
56   { return true; }
57
58   bool expansion_rom(Hw::Device *) const
59   { return false; }
60
61   void set_transparent_msi(bool v) { _do_transparent_msi = v; }
62
63   int verbose() const { return _verbose_lvl; }
64   void inc_verbosity() { ++_verbose_lvl; }
65
66 private:
67   bool _do_transparent_msi;
68   int _verbose_lvl;
69 };
70
71 static Io_config_x _my_cfg __attribute__((init_priority(30000)));
72 Io_config *Io_config::cfg = &_my_cfg;
73
74
75 Hw::Device *
76 system_bus()
77 {
78   static Hw::Root_bus _sb("System Bus");
79   return &_sb;
80 }
81
82 Hw_icu *
83 system_icu()
84 {
85   static Hw_icu _icu;
86   return &_icu;
87 }
88
89 template< typename X >
90 char const *type_name(X const &x)
91 {
92   char *n = const_cast<char *>(typeid(x).name());
93   strtol(n, &n, 0);
94   return n;
95 }
96
97 void dump(Device *d)
98 {
99   Device::iterator i = Device::iterator(0, d, 100);
100   for (; i != d->end(); ++i)
101     {
102       for (int x = 0; x < i->depth(); ++x)
103         printf("  ");
104       printf("%s: %s \"%s\"\n",
105              type_name(*i), i->name(),
106              i->hid() ? i->hid() : "");
107       if (dlevel(DBG_INFO))
108         i->dump(i->depth() * 2);
109       if (dlevel(DBG_DEBUG))
110         for (Resource_list::iterator r = i->resources()->begin();
111              r != i->resources()->end(); ++r)
112           if (*r)
113             r->dump(i->depth() * 2 + 2);
114     }
115 }
116
117
118 Hw_icu::Hw_icu()
119 {
120   icu = L4Re::Env::env()->get_cap<L4::Icu>("icu");
121   if (icu.is_valid())
122     icu->info(&info);
123 }
124
125
126
127 struct Add_system_bus
128 {
129   void operator () (Vi::Device *dev)
130   {
131     Vi::System_bus *b = dynamic_cast<Vi::System_bus*>(dev);
132     if (!b)
133       {
134         d_printf(DBG_ERR, "ERROR: found non system-bus device as root device, ignored\n");
135         return;
136       }
137
138     b->request_child_resources();
139     b->allocate_pending_child_resources();
140     b->setup_resources();
141     if (!registry->register_obj(b, b->name()).is_valid())
142       {
143         d_printf(DBG_WARN, "WARNING: Service registration failed: '%s'\n", b->name());
144         return;
145       }
146   }
147 };
148
149 static void
150 read_config(char const *cfg_file)
151 {
152   Vi::Device *vdev = 0;
153
154   d_printf(DBG_INFO, "Loading: config '%s'\n", cfg_file);
155
156
157   int fd = open(cfg_file, O_RDONLY);
158
159   if (fd < 0)
160     {
161       d_printf(DBG_ERR, "ERROR: failed to open config file '%s'\n", cfg_file);
162       exit(1);
163     }
164
165   struct stat sd;
166   if (fstat(fd, &sd))
167     {
168       d_printf(DBG_ERR, "ERROR: failed to stat config file '%s'\n", cfg_file);
169       exit(1);
170     }
171
172   void *adr = mmap(NULL, sd.st_size, PROT_READ, MAP_SHARED, fd, 0);
173   if (adr == MAP_FAILED)
174     {
175       d_printf(DBG_ERR, "ERROR: failed to mmap config file '%s'\n", cfg_file);
176       exit(1);
177     }
178
179   char const *config_file = (char const *)adr;
180
181   cfg::Scanner s(config_file, config_file + sd.st_size, cfg_file);
182   cfg::Parser p(&s, 0, vdev, system_bus());
183   p.parse();
184
185   munmap(adr, sd.st_size);
186
187   if (!vdev)
188     return;
189
190   std::for_each(Vi::Device::iterator(0, vdev, 0), Vi::Device::end(), Add_system_bus());
191
192   if (dlevel(DBG_DEBUG))
193     dump(vdev);
194 }
195
196
197
198 static int
199 arg_init(int argc, char * const *argv, Io_config_x *cfg)
200 {
201   while (1)
202     {
203       int optidx = 0;
204       int c;
205
206       struct option opts[] =
207       {
208         { "verbose",         0, 0, 'v' },
209         { "transparent-msi", 0, 0, 1 },
210         { 0, 0, 0, 0 },
211       };
212
213       c = getopt_long(argc, argv, "v", opts, &optidx);
214       if (c == -1)
215         break;
216
217       switch (c)
218         {
219         case 'v':
220           _my_cfg.inc_verbosity();
221           break;
222         case 1:
223           d_printf(DBG_INFO, "Enabling transparent MSIs\n");
224           cfg->set_transparent_msi(true);
225           break;
226         }
227     }
228   return optind;
229 }
230
231 static
232 int
233 run(int argc, char * const *argv)
234 {
235   int argfileidx = arg_init(argc, argv, &_my_cfg);
236
237   printf("Io service\n");
238   set_debug_level(Io_config::cfg->verbose());
239
240   d_printf(DBG_ERR, "Verboseness level: %d\n", Io_config::cfg->verbose());
241
242   res_init();
243
244   if (dlevel(DBG_DEBUG))
245     Phys_space::space.dump();
246
247 #if defined(ARCH_x86) || defined(ARCH_amd64)
248   bool is_ux = l4util_kip_kernel_is_ux(l4re_kip());
249   //res_get_ioport(0xcf8, 4);
250   res_get_ioport(0, 16);
251
252   if (!is_ux)
253     acpica_init();
254 #endif
255
256   system_bus()->plugin();
257
258 #if defined(ARCH_x86) || defined(ARCH_amd64)
259   if (is_ux)
260     ux_setup(system_bus());
261 #endif
262
263   for (; argfileidx < argc; ++argfileidx)
264     read_config(argv[argfileidx]);
265
266   if (dlevel(DBG_DEBUG))
267     {
268       printf("Real Hardware -----------------------------------\n");
269       dump(system_bus());
270     }
271
272   fprintf(stderr, "Ready. Waiting for request.\n");
273   server_loop();
274
275   return 0;
276 }
277
278 int
279 main(int argc, char * const *argv)
280 {
281   try
282     {
283       return run(argc, argv);
284     }
285   catch (L4::Runtime_error &e)
286     {
287       L4::cerr << "FATAL uncought exception: " << e
288                << "\nterminating...\n";
289
290     }
291   catch (...)
292     {
293       L4::cerr << "FATAL uncought exception of unknown type\n"
294                << "terminating...\n";
295     }
296   return -1;
297 }