kaluga: starting net_socket server for each of the cards.
[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     /*
54      *  XXX: there may be more device using this driver, so starting it a second time
55      *       may be needed.
56      */
57     if (!can_start(mi)) {
58         return KALUGA_ERR_DRIVER_ALREADY_STARTED;
59     }
60
61     core = where + get_core_id_offset(mi);
62
63     if (!is_auto_driver(mi)) {
64         return KALUGA_ERR_DRIVER_NOT_AUTO;
65     }
66
67     // Construct additional command line arguments containing pci-id.
68     // We need one extra entry for the new argument.
69     char **argv = NULL;
70     int argc = mi->argc;
71     argv = malloc((argc+1) * sizeof(char *)); // +1 for trailing NULL
72     assert(argv != NULL);
73     memcpy(argv, mi->argv, (argc+1) * sizeof(char *));
74     assert(argv[argc] == NULL);
75
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);
79
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);
86     }
87
88     char * pci_arg_str = NULL;
89     if (err_is_ok(err)) {
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
92         // list.
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);
98
99         argv_push(&argc, &argv, pci_arg_str);
100     }
101
102
103     //err = spawn_program(core, mi->path, argv,
104     //                environ, 0, get_did_ptr(mi));
105
106     struct capref arg_cap = NULL_CAP;
107     if(arg != NULL){
108        arg_cap = arg->arg_caps;
109     }
110     err = spawn_program_with_caps(core, mi->path, argv,
111                     environ, NULL_CAP, arg_cap, 0, get_did_ptr(mi));
112
113     if (err_is_fail(err)) {
114         DEBUG_ERR(err, "Spawning %s failed.", mi->path);
115     }
116
117     free(argv);
118     free(pci_arg_str);
119     free(int_arg_str);
120
121     return err;
122 }
123 #endif
124
125 errval_t start_networking(coreid_t core,
126                           struct module_info* driver,
127                           char* record, struct driver_argument * arg)
128 {
129     assert(driver != NULL);
130     errval_t err = SYS_ERR_OK;
131
132
133     /* check if we are using the supplied pci address of eth0 */
134     /*
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));
139
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;
148         }
149     }
150     */
151
152
153     if (is_started(driver)) {
154         printf("Already started %s\n", driver->binary);
155         return KALUGA_ERR_DRIVER_ALREADY_STARTED;
156     }
157
158     if (!is_auto_driver(driver)) {
159         printf("Not auto %s\n", driver->binary);
160         return KALUGA_ERR_DRIVER_NOT_AUTO;
161     }
162
163
164     if (!(strcmp(driver->binary, "net_sockets_server") == 0)) {
165         
166         err = default_start_function(core, driver, record, arg);
167         if (err_is_fail(err)) {
168             DEBUG_ERR(err, "Spawning %s failed.", driver->path);
169             return err;
170         }
171
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;
177         }
178
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);
182
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);
186
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;
192
193         err = spawn_program(core, net_sockets->path, net_sockets->argv, environ, 0,
194                             get_did_ptr(net_sockets));
195         free (pci_arg_str);
196     } else {
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]);
201         }        
202
203         if (!(driver->argc > 2)) {
204             driver->argv[driver->argc] = "e1000";        
205             driver->argc++;
206         }
207
208         // All cards that start the driver by creating a device queue
209         err = default_start_function(core, driver, record, arg);
210     }
211
212     return err;
213 }
214
215 /* errval_t start_usb_manager(void) */
216 /* { */
217
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; */
222 /*     } */
223
224 /*     debug_printf("doing pandaboard related setup...\n"); */
225 /*     errval_t err; */
226
227 /*     struct monitor_binding *cl = get_monitor_blocking_binding(); */
228 /*     assert(cl != NULL); */
229
230 /*     // Request I/O Cap */
231 /*     struct capref requested_caps; */
232 /*     errval_t error_code; */
233
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)); */
236
237 /*     // Copy into correct slot */
238
239 /*     struct capref device_range_cap = NULL_CAP; */
240
241 /*     err = slot_alloc(&device_range_cap); */
242 /*     if (err_is_fail(err)) { */
243 /*         printf("slot alloc failed. Step 1\n"); */
244 /*         return (err); */
245 /*     } */
246 /*     struct capref tiler_cap = NULL_CAP; */
247
248 /*     err = slot_alloc(&tiler_cap); */
249 /*     if (err_is_fail(err)) { */
250 /*         DEBUG_ERR(err, "slot_alloc failed. Step 1\n"); */
251 /*         return (err); */
252 /*     } */
253
254 /*     err = cap_retype(device_range_cap, requested_caps, ObjType_DevFrame, 29); */
255
256 /*     struct capref l3_ocm_ram = NULL_CAP; */
257
258 /*     err = slot_alloc(&l3_ocm_ram); */
259 /*     if (err_is_fail(err)) { */
260 /*         DEBUG_ERR(err, "slot_alloc failed. Step 2\n"); */
261 /*         return (err); */
262 /*     } */
263
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"); */
267 /*         return (err); */
268 /*     } */
269
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"); */
274 /*         return (err); */
275 /*     } */
276
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"); */
281 /*         return (err); */
282 /*     } */
283
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"); */
288 /*         return (err); */
289 /*     } */
290
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"); */
295 /*         return (err); */
296 /*     } */
297
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"); */
302 /*         return (err); */
303 /*     } */
304
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"); */
309 /*         return (err); */
310 /*     } */
311 /*     struct capref tmp_cap = display_iva_cap; */
312 /*     tmp_cap.slot++; */
313 /*     cap_delete(tmp_cap); */
314
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"); */
319 /*         return (err); */
320 /*     } */
321
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"); */
326 /*         return (err); */
327 /*     } */
328
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"); */
333 /*         return (err); */
334 /*     } */
335
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"); */
339 /*         return (err); */
340 /*     } */
341 /*     tmp_cap = l4_CFG_domain_cap; */
342 /*     tmp_cap.slot++; */
343 /*     cap_delete(tmp_cap); */
344
345 /*     struct frame_identity frameid;  // = {        0,        0    }; */
346
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"); */
350 /*     } */
351
352 /*     // get the 32 bit */
353 /*     uint32_t last = (uint32_t) (0xFFFFFFFF & (frameid.base)); */
354 /*     uint32_t size2 = frameid.bits; */
355
356 /*     /\* the L4 CFG domain cap must have address 0x4A000000 *\/ */
357 /*     assert(last == 0x4a000000); */
358
359 /*     /\* the size of the L4 CFG domain is 16k *\/ */
360 /*     assert(((1 << size2) / 1024) == (16 * 1024)); */
361
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 */
366
367 /* #define USB_ARM_EHCI_IRQ 109 */
368
369 /*     uint32_t tmp = (uint32_t) USB_EHCI_OFFSET + USB_SUBSYSTEM_L4_OFFSET; */
370
371 /*     char buf[255]; */
372 /*     uint8_t offset = 0; */
373 /*     driver->cmdargs = buf; */
374 /*     driver->argc = 3; */
375 /*     driver->argv[0] = driver->cmdargs+0; */
376
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); */
384
385 /*     err = SYS_ERR_OK; */
386 /*     coreid_t core = 0; */
387
388 /*     if (is_started(driver)) { */
389 /*         debug_printf("driver is already started..."); */
390 /*         return KALUGA_ERR_DRIVER_ALREADY_STARTED; */
391 /*     } */
392
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); */
397 /*         return err; */
398 /*     } */
399
400 /*     return err; */
401 /* } */