A more generic way of passing caps to user-space drivers.
[barrelfish] / usr / kaluga / main.c
1 /**
2  * \file
3  * \brief Device manager for Barrelfish.
4  *
5  * Interacts with the SKB / PCI to start cores, drivers etc.
6  *
7  */
8
9 /*
10  * Copyright (c) 2007, 2008, 2009, 2010, ETH Zurich.
11  * All rights reserved.
12  *
13  * This file is distributed under the terms in the attached LICENSE file.
14  * If you do not find this file, copies can be found by writing to:
15  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
16  */
17
18 #include <stdlib.h>
19 #include <stdbool.h>
20 #include <stdio.h>
21 #include <assert.h>
22 #include <string.h>
23 #include <errors/errno.h>
24
25 #include <barrelfish/barrelfish.h>
26 #include <barrelfish/cpu_arch.h>
27 #include <barrelfish/nameservice_client.h>
28
29 #include <if/monitor_defs.h>
30
31 #include <vfs/vfs.h>
32 #include <octopus/octopus.h>
33 #include <skb/skb.h>
34
35 #include "kaluga.h"
36
37 coreid_t my_core_id = 0; // Core ID
38 uint32_t my_arch_id = 0; // APIC ID
39
40 extern char **environ;
41
42
43 static void add_start_function_overrides(void)
44 {
45     set_start_function("e1000n", start_networking);
46     set_start_function("rtl8029", start_networking);
47
48     // OMAP4 drivers
49     set_start_function("fdif", start_omap);
50     set_start_function("mmchs", start_omap);
51 }
52
53 static void parse_arguments(int argc, char** argv)
54 {
55     for (int i = 1; i < argc; i++) {
56         if (strncmp(argv[i], "apicid=", sizeof("apicid")) == 0) {
57             my_arch_id = strtol(argv[i] + sizeof("apicid"), NULL, 10);
58         }
59         else if(strcmp(argv[i], "boot") == 0) {
60             // ignored
61         }
62     }
63 }
64
65 static inline errval_t wait_for_pci(void)
66 {
67     iref_t iref;
68     return nameservice_blocking_lookup("pci_discovery_done", &iref);
69 }
70
71 int main(int argc, char** argv)
72 {
73     vfs_init();
74     init_environ();
75
76     errval_t err;
77
78     my_core_id = disp_get_core_id();
79     parse_arguments(argc, argv);
80
81     err = oct_init();
82     if (err_is_fail(err)) {
83         USER_PANIC_ERR(err, "Initialize octopus service.");
84     }
85
86     err = init_boot_modules();
87     if (err_is_fail(err)) {
88         USER_PANIC_ERR(err, "Parse boot modules.");
89     }
90     add_start_function_overrides();
91
92 #ifdef __x86__
93     // We need to run on core 0
94     // (we are responsible for booting all the other cores)
95     assert(my_core_id == BSP_CORE_ID);
96     printf("Kaluga running on x86.\n");
97
98     err = skb_client_connect();
99     if (err_is_fail(err)) {
100         USER_PANIC_ERR(err, "Connect to SKB.");
101     }
102
103     // Make sure the driver db is loaded
104     err = skb_execute("[device_db].");
105     if (err_is_fail(err)) {
106         USER_PANIC_ERR(err, "Device DB not loaded.");
107     }
108
109     // The current boot protocol needs us to have
110     // knowledge about how many CPUs are available at boot
111     // time in order to start-up properly.
112     char* record = NULL;
113     err = oct_barrier_enter("barrier.acpi", &record, 2);
114
115     err = watch_for_cores();
116     if (err_is_fail(err)) {
117         USER_PANIC_ERR(err, "Watching cores.");
118     }
119
120     err = watch_for_pci_root_bridge();
121     if (err_is_fail(err)) {
122         USER_PANIC_ERR(err, "Watching PCI root bridges.");
123     }
124
125     err = watch_for_pci_devices();
126     if (err_is_fail(err)) {
127         USER_PANIC_ERR(err, "Watching PCI devices.");
128     }
129
130     // XXX: This is a bit silly, I add this record
131     // because it was previously in spawnd so
132     // there may be code out there who relies on this
133     // It might be better to get rid of this completely
134     err = oct_set("all_spawnds_up { iref: 0 }");
135     assert(err_is_ok(err));
136 #else
137     printf("Kaluga running on ARM.\n");
138     err = init_cap_manager();
139     assert(err_is_ok(err));
140
141     struct module_info* mi = find_module("fdif");
142     err = mi->start_function(0, mi, "hw.arm.omap44xx.fdif {}");
143     assert(err_is_ok(err));
144 #endif
145
146     THCFinish();
147     return EXIT_SUCCESS;
148 }
149
150
151