2 * Copyright (c) 2016, ETH Zurich.
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.
13 #include <barrelfish/barrelfish.h>
14 #include <barrelfish/spawn_client.h>
16 #include <pci/pci.h> // for pci_address
19 #include <if/monitor_blocking_defs.h>
23 #include <if/monitor_blocking_defs.h>
28 #if defined(__x86__) || defined(__ARM_ARCH_8A__)
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.
38 USER_PANIC("Could not allocate argv memory");
41 (*argv)[new_size-1] = new_arg;
42 (*argv)[new_size] = NULL;
45 errval_t default_start_function(coreid_t where,
46 struct module_info* mi,
47 char* record, struct driver_argument * arg)
50 errval_t err = SYS_ERR_OK;
54 * XXX: there may be more device using this driver, so starting it a second time
58 return KALUGA_ERR_DRIVER_ALREADY_STARTED;
61 core = where + get_core_id_offset(mi);
63 if (!is_auto_driver(mi)) {
64 return KALUGA_ERR_DRIVER_NOT_AUTO;
67 // Construct additional command line arguments containing pci-id.
68 // We need one extra entry for the new argument.
71 argv = malloc((argc+1) * sizeof(char *)); // +1 for trailing NULL
73 memcpy(argv, mi->argv, (argc+1) * sizeof(char *));
74 assert(argv[argc] == NULL);
76 uint64_t vendor_id, device_id, bus, dev, fun;
77 err = oct_read(record, "_ { bus: %d, device: %d, function: %d, vendor: %d, device_id: %d }",
78 &bus, &dev, &fun, &vendor_id, &device_id);
80 char * int_arg_str = NULL;
81 if(arg != NULL && arg->int_arg.model != 0){
82 // This mallocs int_arg_str
83 int_startup_argument_to_string(&(arg->int_arg), &int_arg_str);
84 KALUGA_DEBUG("Adding int_arg_str: %s\n", int_arg_str);
85 argv_push(&argc, &argv, int_arg_str);
88 char * pci_arg_str = NULL;
90 // We assume that we're starting a device if the query above succeeds
91 // and therefore append the pci vendor and device id to the argument
93 pci_arg_str = malloc(26);
94 // Make sure pci vendor and device id fit into our argument
95 assert(vendor_id < 0xFFFF && device_id < 0xFFFF);
96 snprintf(pci_arg_str, 26, "%04"PRIx64":%04"PRIx64":%04"PRIx64":%04"
97 PRIx64":%04"PRIx64, vendor_id, device_id, bus, dev, fun);
99 argv_push(&argc, &argv, pci_arg_str);
103 //err = spawn_program(core, mi->path, argv,
104 // environ, 0, get_did_ptr(mi));
106 struct capref arg_cap = NULL_CAP;
108 arg_cap = arg->arg_caps;
110 err = spawn_program_with_caps(core, mi->path, argv,
111 environ, NULL_CAP, arg_cap, 0, get_did_ptr(mi));
113 if (err_is_fail(err)) {
114 DEBUG_ERR(err, "Spawning %s failed.", mi->path);
125 errval_t start_networking(coreid_t core,
126 struct module_info* driver,
127 char* record, struct driver_argument * arg)
129 assert(driver != NULL);
130 errval_t err = SYS_ERR_OK;
133 /* check if we are using the supplied pci address of eth0 */
135 if (eth0.bus != 0xff || eth0.device != 0xff || eth0.function != 0xff) {
136 err = oct_read(record, "_ { bus: %d, device: %d, function: %d, vendor: %d, device_id: %d }",
137 &bus, &dev, &fun, &vendor_id, &device_id);
138 assert(err_is_ok(err));
140 if ((eth0.bus != (uint8_t)bus)
141 | (eth0.device != (uint8_t)dev)
142 | (eth0.function != (uint8_t)fun)) {
143 printf("start_networking: skipping card %" PRIu64 ":%" PRIu64 ":%"
144 PRIu64"\n", bus, dev, fun);
145 printf("eth0 %" PRIu8 ":%" PRIu8 ":%"
146 PRIu8"\n", eth0.bus, eth0.device, eth0.function);
147 return KALUGA_ERR_DRIVER_NOT_AUTO;
153 if (is_started(driver)) {
154 printf("Already started %s\n", driver->binary);
155 return KALUGA_ERR_DRIVER_ALREADY_STARTED;
158 if (!is_auto_driver(driver)) {
159 printf("Not auto %s\n", driver->binary);
160 return KALUGA_ERR_DRIVER_NOT_AUTO;
164 if (!(strcmp(driver->binary, "net_sockets_server") == 0)) {
166 err = default_start_function(core, driver, record, arg);
167 if (err_is_fail(err)) {
168 DEBUG_ERR(err, "Spawning %s failed.", driver->path);
172 // cards with driver in seperate process
173 struct module_info* net_sockets = find_module("net_sockets_server");
174 if (net_sockets == NULL) {
175 printf("Net sockets server not found\n");
176 return KALUGA_ERR_DRIVER_NOT_AUTO;
179 uint64_t vendor_id, device_id, bus, dev, fun;
180 err = oct_read(record, "_ { bus: %d, device: %d, function: %d, vendor: %d, device_id: %d }",
181 &bus, &dev, &fun, &vendor_id, &device_id);
183 char* pci_arg_str = malloc(26);
184 snprintf(pci_arg_str, 26, "%04"PRIx64":%04"PRIx64":%04"PRIx64":%04"
185 PRIx64":%04"PRIx64, vendor_id, device_id, bus, dev, fun);
187 // Spawn net_sockets_server
188 net_sockets->argv[0] = "net_sockets_server";
189 net_sockets->argv[1] = "auto";
190 net_sockets->argv[2] = driver->binary;
191 net_sockets->argv[3] = pci_arg_str;
193 err = spawn_program(core, net_sockets->path, net_sockets->argv, environ, 0,
194 get_did_ptr(net_sockets));
197 // TODO currently only for e1000, might be other cards that
198 // start the driver by creating a queue
199 for (int i = 0; i < driver->argc; i++) {
200 printf("argv[%d]=%s \n", i, driver->argv[i]);
203 if (!(driver->argc > 2)) {
204 driver->argv[driver->argc] = "e1000";
208 // All cards that start the driver by creating a device queue
209 err = default_start_function(core, driver, record, arg);
215 /* errval_t start_usb_manager(void) */
218 /* struct module_info* driver = find_module("usb_manager"); */
219 /* if (driver == NULL || !is_auto_driver(driver)) { */
220 /* KALUGA_DEBUG("NGD_mng not found or not declared as auto."); */
221 /* return KALUGA_ERR_DRIVER_NOT_AUTO; */
224 /* debug_printf("doing pandaboard related setup...\n"); */
227 /* struct monitor_binding *cl = get_monitor_blocking_binding(); */
228 /* assert(cl != NULL); */
230 /* // Request I/O Cap */
231 /* struct capref requested_caps; */
232 /* errval_t error_code; */
234 /* err = cl->rpc_tx_vtbl.get_io_cap(cl, &requested_caps, &error_code); */
235 /* assert(err_is_ok(err) && err_is_ok(error_code)); */
237 /* // Copy into correct slot */
239 /* struct capref device_range_cap = NULL_CAP; */
241 /* err = slot_alloc(&device_range_cap); */
242 /* if (err_is_fail(err)) { */
243 /* printf("slot alloc failed. Step 1\n"); */
246 /* struct capref tiler_cap = NULL_CAP; */
248 /* err = slot_alloc(&tiler_cap); */
249 /* if (err_is_fail(err)) { */
250 /* DEBUG_ERR(err, "slot_alloc failed. Step 1\n"); */
254 /* err = cap_retype(device_range_cap, requested_caps, ObjType_DevFrame, 29); */
256 /* struct capref l3_ocm_ram = NULL_CAP; */
258 /* err = slot_alloc(&l3_ocm_ram); */
259 /* if (err_is_fail(err)) { */
260 /* DEBUG_ERR(err, "slot_alloc failed. Step 2\n"); */
264 /* err = cap_retype(l3_ocm_ram, device_range_cap, ObjType_DevFrame, 26); */
265 /* if (err_is_fail(err)) { */
266 /* DEBUG_ERR(err, "failed to retype the dev cap. Step 3\n"); */
270 /* struct capref l3_config_registers_cap; */
271 /* err = slot_alloc(&l3_config_registers_cap); */
272 /* if (err_is_fail(err)) { */
273 /* DEBUG_ERR(err, "slot alloc failed. Step 4\n"); */
277 /* struct capref l4_domains_cap; */
278 /* err = slot_alloc(&l4_domains_cap); */
279 /* if (err_is_fail(err)) { */
280 /* DEBUG_ERR(err, "slot_alloc failed. Step 5\n"); */
284 /* struct capref emif_registers_cap; */
285 /* err = slot_alloc(&emif_registers_cap); */
286 /* if (err_is_fail(err)) { */
287 /* DEBUG_ERR(err, "slot_alloc failed. Step 6\n"); */
291 /* struct capref gpmc_iss_cap; */
292 /* err = slot_alloc(&gpmc_iss_cap); */
293 /* if (err_is_fail(err)) { */
294 /* DEBUG_ERR(err, "slot_alloc failed. Step 7\n"); */
298 /* struct capref l3_emu_m3_sgx_cap; */
299 /* err = slot_alloc(&l3_emu_m3_sgx_cap); */
300 /* if (err_is_fail(err)) { */
301 /* DEBUG_ERR(err, "slot_alloc failed. Step 8\n"); */
305 /* struct capref display_iva_cap; */
306 /* err = slot_alloc(&display_iva_cap); */
307 /* if (err_is_fail(err)) { */
308 /* DEBUG_ERR(err, "slot_alloc failed. Step 9\n"); */
311 /* struct capref tmp_cap = display_iva_cap; */
312 /* tmp_cap.slot++; */
313 /* cap_delete(tmp_cap); */
315 /* struct capref l4_PER_domain_cap; */
316 /* err = slot_alloc(&l4_PER_domain_cap); */
317 /* if (err_is_fail(err)) { */
318 /* DEBUG_ERR(err, "slot_alloc failed. Step 12\n"); */
322 /* struct capref l4_ABE_domain_cap; */
323 /* err = slot_alloc(&l4_ABE_domain_cap); */
324 /* if (err_is_fail(err)) { */
325 /* DEBUG_ERR(err, "slot_alloc failed. Step 11\n"); */
329 /* struct capref l4_CFG_domain_cap; */
330 /* err = slot_alloc(&l4_CFG_domain_cap); */
331 /* if (err_is_fail(err)) { */
332 /* DEBUG_ERR(err, "slot_alloc failed. Step 12\n"); */
336 /* err = cap_retype(l4_PER_domain_cap, l4_domains_cap, ObjType_DevFrame, 24); */
337 /* if (err_is_fail(err)) { */
338 /* DEBUG_ERR(err, "failed to retype the cap. Step 13\n"); */
341 /* tmp_cap = l4_CFG_domain_cap; */
342 /* tmp_cap.slot++; */
343 /* cap_delete(tmp_cap); */
345 /* struct frame_identity frameid; // = { 0, 0 }; */
347 /* err = invoke_frame_identify(l4_CFG_domain_cap, &frameid); */
348 /* if (err_is_fail(err)) { */
349 /* DEBUG_ERR(err, "could not identify the frame. Step 14\n"); */
352 /* // get the 32 bit */
353 /* uint32_t last = (uint32_t) (0xFFFFFFFF & (frameid.base)); */
354 /* uint32_t size2 = frameid.bits; */
356 /* /\* the L4 CFG domain cap must have address 0x4A000000 *\/ */
357 /* assert(last == 0x4a000000); */
359 /* /\* the size of the L4 CFG domain is 16k *\/ */
360 /* assert(((1 << size2) / 1024) == (16 * 1024)); */
362 /* #define USB_SUBSYSTEM_L4_OFFSET 0x00062000 */
363 /* //#define USB_OHCI_OFFSET (0x000A9000-USB_SUBSYSTEM_L4_OFFSET) */
364 /* #define USB_OHCI_OFFSET 0x00002800 */
365 /* #define USB_EHCI_OFFSET 0x00002C00 */
367 /* #define USB_ARM_EHCI_IRQ 109 */
369 /* uint32_t tmp = (uint32_t) USB_EHCI_OFFSET + USB_SUBSYSTEM_L4_OFFSET; */
372 /* uint8_t offset = 0; */
373 /* driver->cmdargs = buf; */
374 /* driver->argc = 3; */
375 /* driver->argv[0] = driver->cmdargs+0; */
377 /* snprintf(buf+offset, 255-offset, "ehci\0"); */
378 /* offset += strlen(driver->argv[0])+1; */
379 /* driver->argv[1] = driver->cmdargs+offset; */
380 /* snprintf(buf+offset, 255-offset, "%u\0", tmp); */
381 /* offset += strlen(driver->argv[1])+1; */
382 /* driver->argv[2] = driver->cmdargs+offset; */
383 /* snprintf(buf+offset, 255-offset, "%u\0", USB_ARM_EHCI_IRQ); */
385 /* err = SYS_ERR_OK; */
386 /* coreid_t core = 0; */
388 /* if (is_started(driver)) { */
389 /* debug_printf("driver is already started..."); */
390 /* return KALUGA_ERR_DRIVER_ALREADY_STARTED; */
393 /* err = spawn_program_with_caps(core, driver->path, driver->argv, environ, */
394 /* NULL_CAP, l4_CFG_domain_cap, 0, &driver->did); */
395 /* if (err_is_fail(err)) { */
396 /* DEBUG_ERR(err, "Spawning %s failed.", driver->path); */