09a7fcf63eae5f3de21d4fa90c29fd00d999e547
[barrelfish] / usr / kaluga / driver_startup.c
1 /*
2  * Copyright (c) 2016, ETH Zurich.
3  * All rights reserved.
4  *
5  * This file is distributed under the terms in the attached LICENSE file.
6  * If you do not find this file, copies can be found by writing to:
7  * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8  */
9
10 #include <stdio.h>
11 #include <string.h>
12
13 #include <barrelfish/barrelfish.h>
14 #include <barrelfish/spawn_client.h>
15
16 #include <pci/pci.h> // for pci_address
17
18 #ifdef __arm__
19 #include <if/monitor_blocking_defs.h>
20 #endif
21
22 #ifdef __aarch64__
23 #include <if/monitor_blocking_defs.h>
24 #endif
25
26 #include "kaluga.h"
27
28 #if defined(__x86__) || defined(__ARM_ARCH_8A__)
29
30 // Add an argument to argc/argv pair. argv must be mallocd!
31 static void argv_push(int * argc, char *** argv, char * new_arg){
32     int new_size = *argc + 1;
33     //char ** argv_old = *argv;
34     //*argv = malloc((new_size+1) * sizeof(char*));
35     //memcpy(*argv, argv_old, sizeof(char*) * (*argc + 1));
36     *argv = realloc(*argv, (new_size+1) * sizeof(char*)); // +1 for last NULL entry.
37     if(*argv == NULL){
38         USER_PANIC("Could not allocate argv memory");
39     }
40     *argc = new_size;
41     (*argv)[new_size-1] = new_arg;
42     (*argv)[new_size] = NULL;
43 }
44
45 errval_t default_start_function(coreid_t where,
46                                 struct module_info* mi,
47                                 char* record, struct driver_argument * arg)
48 {
49     assert(mi != NULL);
50     errval_t err = SYS_ERR_OK;
51     coreid_t core;
52     /*
53      *  XXX: there may be more device using this driver, so starting it a second time
54      *       may be needed.
55      */
56     if (!can_start(mi)) {
57         return KALUGA_ERR_DRIVER_ALREADY_STARTED;
58     }
59
60     core = where + get_core_id_offset(mi);
61
62     if (!is_auto_driver(mi)) {
63         return KALUGA_ERR_DRIVER_NOT_AUTO;
64     }
65
66     // Construct additional command line arguments containing pci-id.
67     // We need one extra entry for the new argument.
68     char **argv = NULL;
69     int argc = mi->argc;
70     argv = malloc((argc+1) * sizeof(char *)); // +1 for trailing NULL
71     assert(argv != NULL);
72     memcpy(argv, mi->argv, (argc+1) * sizeof(char *));
73     assert(argv[argc] == NULL);
74
75     uint64_t vendor_id, device_id, bus, dev, fun;
76     err = oct_read(record, "_ { bus: %d, device: %d, function: %d, vendor: %d, device_id: %d }",
77                     &bus, &dev, &fun, &vendor_id, &device_id);
78
79     char * int_arg_str = NULL;
80     if(arg != NULL && arg->int_arg.model != 0){
81         // This mallocs int_arg_str
82         int_startup_argument_to_string(&(arg->int_arg), &int_arg_str);
83         KALUGA_DEBUG("Adding int_arg_str: %s\n", int_arg_str);
84         argv_push(&argc, &argv, int_arg_str);
85     }
86
87     char * pci_arg_str = NULL;
88     if (err_is_ok(err)) {
89         // We assume that we're starting a device if the query above succeeds
90         // and therefore append the pci vendor and device id to the argument
91         // list.
92         pci_arg_str = malloc(26);
93         // Make sure pci vendor and device id fit into our argument
94         assert(vendor_id < 0xFFFF && device_id < 0xFFFF);
95         snprintf(pci_arg_str, 26, "%04"PRIx64":%04"PRIx64":%04"PRIx64":%04"
96                         PRIx64":%04"PRIx64, vendor_id, device_id, bus, dev, fun);
97
98         argv_push(&argc, &argv, pci_arg_str);
99     }
100
101
102     //err = spawn_program(core, mi->path, argv,
103     //                environ, 0, get_did_ptr(mi));
104
105     struct capref arg_cap = NULL_CAP;
106     if(arg != NULL){
107        arg_cap = arg->arg_caps;
108     }
109     err = spawn_program_with_caps(core, mi->path, argv,
110                     environ, NULL_CAP, arg_cap, 0, get_did_ptr(mi));
111
112     if (err_is_fail(err)) {
113         DEBUG_ERR(err, "Spawning %s failed.", mi->path);
114     }
115
116     free(argv);
117     free(pci_arg_str);
118     free(int_arg_str);
119
120     return err;
121 }
122 #endif
123
124 errval_t start_networking(coreid_t core,
125                           struct module_info* driver,
126                           char* record, struct driver_argument * arg)
127 {
128     assert(driver != NULL);
129     errval_t err = SYS_ERR_OK;
130
131     uint64_t vendor_id, device_id, bus, dev, fun;
132
133     /* check if we are using the supplied pci address of eth0 */
134     if (eth0.bus != 0xff || eth0.device != 0xff || eth0.function != 0xff) {
135         err = oct_read(record, "_ { bus: %d, device: %d, function: %d, vendor: %d, device_id: %d }",
136                             &bus, &dev, &fun, &vendor_id, &device_id);
137         assert(err_is_ok(err));
138
139         if ((eth0.bus != (uint8_t)bus)
140              | (eth0.device != (uint8_t)dev)
141              | (eth0.function != (uint8_t)fun)) {
142             KALUGA_DEBUG("start_networking: skipping card %" PRIu64 ":%" PRIu64 ":%"
143                          PRIu64"\n", bus, dev, fun);
144             return KALUGA_ERR_DRIVER_NOT_AUTO;
145         }
146     }
147
148     if (is_started(driver)) {
149         return KALUGA_ERR_DRIVER_ALREADY_STARTED;
150     }
151
152     if (!is_auto_driver(driver)) {
153         return KALUGA_ERR_DRIVER_NOT_AUTO;
154     }
155
156     struct module_info* netd = find_module("netd");
157     if (netd == NULL || !is_auto_driver(netd)) {
158         printf("Kaluga: netd not found or not declared as auto.\n");
159         return KALUGA_ERR_DRIVER_NOT_AUTO;
160     }
161
162     struct module_info* ngd_mng = find_module("NGD_mng");
163     if (ngd_mng == NULL || !is_auto_driver(ngd_mng)) {
164         printf("Kaluga: NGD_mng not found or not declared as auto.\n");
165         return KALUGA_ERR_DRIVER_NOT_AUTO;
166     }
167
168     err = default_start_function(core, driver, record, arg);
169     if (err_is_fail(err)) {
170         DEBUG_ERR(err, "Spawning %s failed.", driver->path);
171         return err;
172     }
173
174     // XXX: Manually add cardname (overwrite first (auto) argument)
175     // +Weird convention, e1000n binary but cardname=e1000
176     char* cardname = strcmp(driver->binary, "e1000n") == 0 ? "e1000" : driver->binary;
177
178     size_t name_len = strlen("cardname=") + strlen(cardname) + 1;
179     char* card_argument = malloc(name_len);
180     sprintf(card_argument, "cardname=%s", cardname);
181     printf("############# starting network with arguments %s\n", card_argument);
182
183     // Spawn netd and ngd_mng
184     netd->argv[0] = card_argument;
185     err = spawn_program(core, netd->path, netd->argv, environ, 0, get_did_ptr(netd));
186
187     ngd_mng->argv[0] = card_argument;
188     err = spawn_program(core, ngd_mng->path, ngd_mng->argv, environ, 0,
189                         get_did_ptr(ngd_mng));
190
191     free(card_argument);
192     return err;
193 }
194
195 /* errval_t start_usb_manager(void) */
196 /* { */
197
198 /*     struct module_info* driver = find_module("usb_manager"); */
199 /*     if (driver == NULL || !is_auto_driver(driver)) { */
200 /*         KALUGA_DEBUG("NGD_mng not found or not declared as auto."); */
201 /*         return KALUGA_ERR_DRIVER_NOT_AUTO; */
202 /*     } */
203
204 /*     debug_printf("doing pandaboard related setup...\n"); */
205 /*     errval_t err; */
206
207 /*     struct monitor_binding *cl = get_monitor_blocking_binding(); */
208 /*     assert(cl != NULL); */
209
210 /*     // Request I/O Cap */
211 /*     struct capref requested_caps; */
212 /*     errval_t error_code; */
213
214 /*     err = cl->rpc_tx_vtbl.get_io_cap(cl, &requested_caps, &error_code); */
215 /*     assert(err_is_ok(err) && err_is_ok(error_code)); */
216
217 /*     // Copy into correct slot */
218
219 /*     struct capref device_range_cap = NULL_CAP; */
220
221 /*     err = slot_alloc(&device_range_cap); */
222 /*     if (err_is_fail(err)) { */
223 /*         printf("slot alloc failed. Step 1\n"); */
224 /*         return (err); */
225 /*     } */
226 /*     struct capref tiler_cap = NULL_CAP; */
227
228 /*     err = slot_alloc(&tiler_cap); */
229 /*     if (err_is_fail(err)) { */
230 /*         DEBUG_ERR(err, "slot_alloc failed. Step 1\n"); */
231 /*         return (err); */
232 /*     } */
233
234 /*     err = cap_retype(device_range_cap, requested_caps, ObjType_DevFrame, 29); */
235
236 /*     struct capref l3_ocm_ram = NULL_CAP; */
237
238 /*     err = slot_alloc(&l3_ocm_ram); */
239 /*     if (err_is_fail(err)) { */
240 /*         DEBUG_ERR(err, "slot_alloc failed. Step 2\n"); */
241 /*         return (err); */
242 /*     } */
243
244 /*     err = cap_retype(l3_ocm_ram, device_range_cap, ObjType_DevFrame, 26); */
245 /*     if (err_is_fail(err)) { */
246 /*         DEBUG_ERR(err, "failed to retype the dev cap. Step 3\n"); */
247 /*         return (err); */
248 /*     } */
249
250 /*     struct capref l3_config_registers_cap; */
251 /*     err = slot_alloc(&l3_config_registers_cap); */
252 /*     if (err_is_fail(err)) { */
253 /*         DEBUG_ERR(err, "slot alloc failed. Step 4\n"); */
254 /*         return (err); */
255 /*     } */
256
257 /*     struct capref l4_domains_cap; */
258 /*     err = slot_alloc(&l4_domains_cap); */
259 /*     if (err_is_fail(err)) { */
260 /*         DEBUG_ERR(err, "slot_alloc failed. Step 5\n"); */
261 /*         return (err); */
262 /*     } */
263
264 /*     struct capref emif_registers_cap; */
265 /*     err = slot_alloc(&emif_registers_cap); */
266 /*     if (err_is_fail(err)) { */
267 /*         DEBUG_ERR(err, "slot_alloc failed. Step 6\n"); */
268 /*         return (err); */
269 /*     } */
270
271 /*     struct capref gpmc_iss_cap; */
272 /*     err = slot_alloc(&gpmc_iss_cap); */
273 /*     if (err_is_fail(err)) { */
274 /*         DEBUG_ERR(err, "slot_alloc failed. Step 7\n"); */
275 /*         return (err); */
276 /*     } */
277
278 /*     struct capref l3_emu_m3_sgx_cap; */
279 /*     err = slot_alloc(&l3_emu_m3_sgx_cap); */
280 /*     if (err_is_fail(err)) { */
281 /*         DEBUG_ERR(err, "slot_alloc failed. Step 8\n"); */
282 /*         return (err); */
283 /*     } */
284
285 /*     struct capref display_iva_cap; */
286 /*     err = slot_alloc(&display_iva_cap); */
287 /*     if (err_is_fail(err)) { */
288 /*         DEBUG_ERR(err, "slot_alloc failed. Step 9\n"); */
289 /*         return (err); */
290 /*     } */
291 /*     struct capref tmp_cap = display_iva_cap; */
292 /*     tmp_cap.slot++; */
293 /*     cap_delete(tmp_cap); */
294
295 /*     struct capref l4_PER_domain_cap; */
296 /*     err = slot_alloc(&l4_PER_domain_cap); */
297 /*     if (err_is_fail(err)) { */
298 /*         DEBUG_ERR(err, "slot_alloc failed. Step 12\n"); */
299 /*         return (err); */
300 /*     } */
301
302 /*     struct capref l4_ABE_domain_cap; */
303 /*     err = slot_alloc(&l4_ABE_domain_cap); */
304 /*     if (err_is_fail(err)) { */
305 /*         DEBUG_ERR(err, "slot_alloc failed. Step 11\n"); */
306 /*         return (err); */
307 /*     } */
308
309 /*     struct capref l4_CFG_domain_cap; */
310 /*     err = slot_alloc(&l4_CFG_domain_cap); */
311 /*     if (err_is_fail(err)) { */
312 /*         DEBUG_ERR(err, "slot_alloc failed. Step 12\n"); */
313 /*         return (err); */
314 /*     } */
315
316 /*     err = cap_retype(l4_PER_domain_cap, l4_domains_cap, ObjType_DevFrame, 24); */
317 /*     if (err_is_fail(err)) { */
318 /*         DEBUG_ERR(err, "failed to retype the cap. Step 13\n"); */
319 /*         return (err); */
320 /*     } */
321 /*     tmp_cap = l4_CFG_domain_cap; */
322 /*     tmp_cap.slot++; */
323 /*     cap_delete(tmp_cap); */
324
325 /*     struct frame_identity frameid;  // = {        0,        0    }; */
326
327 /*     err = invoke_frame_identify(l4_CFG_domain_cap, &frameid); */
328 /*     if (err_is_fail(err)) { */
329 /*         DEBUG_ERR(err, "could not identify the frame. Step 14\n"); */
330 /*     } */
331
332 /*     // get the 32 bit */
333 /*     uint32_t last = (uint32_t) (0xFFFFFFFF & (frameid.base)); */
334 /*     uint32_t size2 = frameid.bits; */
335
336 /*     /\* the L4 CFG domain cap must have address 0x4A000000 *\/ */
337 /*     assert(last == 0x4a000000); */
338
339 /*     /\* the size of the L4 CFG domain is 16k *\/ */
340 /*     assert(((1 << size2) / 1024) == (16 * 1024)); */
341
342 /* #define USB_SUBSYSTEM_L4_OFFSET 0x00062000 */
343 /* //#define USB_OHCI_OFFSET         (0x000A9000-USB_SUBSYSTEM_L4_OFFSET) */
344 /* #define USB_OHCI_OFFSET         0x00002800 */
345 /* #define USB_EHCI_OFFSET         0x00002C00 */
346
347 /* #define USB_ARM_EHCI_IRQ 109 */
348
349 /*     uint32_t tmp = (uint32_t) USB_EHCI_OFFSET + USB_SUBSYSTEM_L4_OFFSET; */
350
351 /*     char buf[255]; */
352 /*     uint8_t offset = 0; */
353 /*     driver->cmdargs = buf; */
354 /*     driver->argc = 3; */
355 /*     driver->argv[0] = driver->cmdargs+0; */
356
357 /*     snprintf(buf+offset, 255-offset, "ehci\0"); */
358 /*     offset += strlen(driver->argv[0])+1; */
359 /*     driver->argv[1] = driver->cmdargs+offset; */
360 /*     snprintf(buf+offset, 255-offset, "%u\0", tmp); */
361 /*     offset += strlen(driver->argv[1])+1; */
362 /*             driver->argv[2] = driver->cmdargs+offset; */
363 /*     snprintf(buf+offset, 255-offset, "%u\0", USB_ARM_EHCI_IRQ); */
364
365 /*     err = SYS_ERR_OK; */
366 /*     coreid_t core = 0; */
367
368 /*     if (is_started(driver)) { */
369 /*         debug_printf("driver is already started..."); */
370 /*         return KALUGA_ERR_DRIVER_ALREADY_STARTED; */
371 /*     } */
372
373 /*     err = spawn_program_with_caps(core, driver->path, driver->argv, environ, */
374 /*             NULL_CAP, l4_CFG_domain_cap, 0, &driver->did); */
375 /*     if (err_is_fail(err)) { */
376 /*         DEBUG_ERR(err, "Spawning %s failed.", driver->path); */
377 /*         return err; */
378 /*     } */
379
380 /*     return err; */
381 /* } */