851b9e328484b012adf0d3b9ca6ca42076f5a53e
[barrelfish] / usr / kaluga / start_pci.c
1 /**
2  * \file
3  * \brief Code responsible for booting application cores
4  */
5
6 /*
7  * Copyright (c) 2007, 2008, 2009, 2010, ETH Zurich.
8  * All rights reserved.
9  *
10  * This file is distributed under the terms in the attached LICENSE file.
11  * If you do not find this file, copies can be found by writing to:
12  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13  */
14
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <assert.h>
19
20 #include <barrelfish/barrelfish.h>
21
22 #include <octopus/octopus.h>
23 #include <if/octopus_thc.h>
24 #include <skb/skb.h>
25 #include <thc/thc.h>
26
27 #include "kaluga.h"
28
29 static struct capref all_irq_cap;
30
31 static void pci_change_event(octopus_mode_t mode, char* device_record, void* st);
32
33 static void spawnd_up_event(octopus_mode_t mode, char* spawnd_record, void* st)
34 {
35     assert(mode & OCT_ON_SET);
36     uint64_t iref;
37     errval_t err = oct_read(spawnd_record, "_ { iref: %d }", &iref);
38     if (err_is_fail(err)) {
39         USER_PANIC_ERR(err, "Failed to read iref from spawnd record?");
40     }
41
42     // Pass the iref as state, this tells pci_change_event that we
43     // don't need to look again for the spawnd iref
44     // XXX: Pointer
45     pci_change_event(OCT_ON_SET, st, (void*)(uintptr_t)iref);
46     free(spawnd_record);
47 }
48
49 static errval_t wait_for_spawnd(coreid_t core, void* state)
50 {
51     // Check if the core we're spawning on is already up...
52     struct octopus_thc_client_binding_t* cl = oct_get_thc_client();
53     errval_t error_code;
54     octopus_trigger_t t = oct_mktrigger(OCT_ERR_NO_RECORD,
55             octopus_BINDING_EVENT, OCT_ON_SET, spawnd_up_event, state);
56
57     // Construct service name
58     static char* format = "spawn.%"PRIuCOREID" { iref: _ }";
59     int length = snprintf(NULL, 0, format, core);
60     char* query = malloc(length+1);
61     snprintf(query, length+1, format, core);
62
63     errval_t err = cl->call_seq.get(cl, query, t, NULL, NULL, &error_code);
64     free(query);
65
66     if (err_is_fail(err)) {
67         return err;
68     }
69
70     return error_code;
71 }
72
73 static void pci_change_event(octopus_mode_t mode, char* device_record, void* st)
74 {
75     errval_t err;
76     char intcaps_debug_msg[100];
77     char *binary_name = NULL;
78     strcpy(intcaps_debug_msg, "none");
79     if (mode & OCT_ON_SET) {
80         KALUGA_DEBUG("pci_change_event: device_record: %s\n", device_record);
81         uint64_t vendor_id, device_id, bus, dev, fun;
82         err = oct_read(device_record, "_ { vendor: %d, device_id: %d, bus: %d, device: %d,"
83                 " function: %d }",
84                 &vendor_id, &device_id, &bus, &dev, &fun);
85         if (err_is_fail(err)) {
86             USER_PANIC_ERR(err, "Got malformed device record?");
87         }
88         
89         /* duplicate device record as we may need it for later */
90         device_record = strdup(device_record);
91         assert(device_record);
92         
93
94         // Ask the SKB which binary and where to start it...
95         static char* query = "find_pci_driver(pci_card(%"PRIu64", %"PRIu64", _, _, _), Driver),"
96                              "writeln(Driver).";
97         err = skb_execute_query(query, vendor_id, device_id);
98         if (err_no(err) == SKB_ERR_EXECUTION) {
99             KALUGA_DEBUG("No PCI driver found for: VendorId=0x%"PRIx64", "
100                          "DeviceId=0x%"PRIx64"\n",
101                     vendor_id, device_id);
102             goto out;
103         }
104         else if (err_is_fail(err)) {
105             DEBUG_SKB_ERR(err, "Failed to query SKB.\n");
106             goto out;
107         }
108
109         // XXX: Find better way to parse binary name from SKB
110         binary_name = malloc(strlen(skb_get_output()));
111         coreid_t core;
112         uint8_t multi;
113         uint8_t int_model_in;
114         struct int_startup_argument int_arg;
115         int_arg.int_range_start = 1000;
116         int_arg.int_range_end = 1004;
117         coreid_t offset;
118         err = skb_read_output("driver(%"SCNu8", %"SCNu8", %"SCNu8", %[^,], "
119                 "%"SCNu8")", &core, &multi, &offset, binary_name, &int_model_in);
120         if(err_is_fail(err)){
121             USER_PANIC_SKB_ERR(err, "Could not parse SKB output.\n");
122         }
123         int_arg.model = int_model_in;
124
125         struct driver_argument driver_arg;
126         driver_arg.int_arg = int_arg;
127         // TODO: every driver should specify the int_model in device_db
128         // until then, we treat them like legacy, so they can use the standard
129         // pci client functionality.
130         if(int_arg.model == INT_MODEL_LEGACY || int_arg.model == INT_MODEL_NONE){
131             KALUGA_DEBUG("Starting driver (%s) with legacy interrupts\n", binary_name);
132             // No controller has to instantiated, but we need to get caps for the int numbers
133             err = skb_execute_query("get_pci_legacy_int_range(addr(%"PRIu64",%"PRIu64",%"PRIu64"),Li),"
134                     "writeln(Li).", bus, dev, fun);
135             KALUGA_DEBUG("(Driver=%s,bus=%"PRIu64",dev=%"PRIu64",fun=%"PRIu64") "
136                     "int_range skb reply: %s\n",
137                     binary_name, bus, dev, fun, skb_get_output() );
138
139             // For debugging
140             strncpy(intcaps_debug_msg, skb_get_output(), sizeof(intcaps_debug_msg));
141             char * nl = strchr(intcaps_debug_msg, '\n');
142             if(nl) *nl = '\0';
143             intcaps_debug_msg[99] = '\0';
144
145             uint64_t start=0, end=0;
146             err = skb_read_output("%"SCNu64", %"SCNu64, &start, &end);
147             if(err_is_fail(err)){
148                 DEBUG_SKB_ERR(err, "Could not parse SKB output. Not starting driver.\n");
149                 goto out;
150             }
151
152             struct cnoderef argnode_ref;
153             err = cnode_create_l2(&driver_arg.arg_caps, &argnode_ref);
154             if(err_is_fail(err)){
155                 USER_PANIC_ERR(err, "Could not cnode_create_l2");
156             }
157
158             struct capref cap;
159             cap.cnode = argnode_ref;
160             cap.slot = 0;
161             //err = sys_debug_create_irq_src_cap(cap, start, end);
162             err = cap_retype(cap, all_irq_cap, start, ObjType_IRQSrc, 
163                     end, 1);
164             if(err_is_fail(err)){
165                 USER_PANIC_ERR(err, "Could not create int_src cap");
166             }
167         } else if(int_arg.model == INT_MODEL_MSI){
168             KALUGA_DEBUG("Starting driver (%s) with MSI interrupts\n", binary_name);
169             // TODO instantiate controller
170         } else if(int_arg.model == INT_MODEL_MSIX){
171             KALUGA_DEBUG("Starting driver (%s) with MSI-x interrupts\n", binary_name);
172             // TODO instantiate controller
173         } else {
174             KALUGA_DEBUG("No interrupt model specified for %s. No interrupts for this driver.\n",
175                     binary_name);
176         }
177
178         struct module_info* mi = find_module(binary_name);
179         if (mi == NULL) {
180             KALUGA_DEBUG("Driver %s not loaded. Ignore.\n", binary_name);
181             goto out;
182         }
183
184         set_multi_instance(mi, multi);
185         set_core_id_offset(mi, offset);
186
187         // Wait until the core where we start the driver
188         // is ready
189         if (st == NULL && core != my_core_id) {
190             err = wait_for_spawnd(core, device_record);
191             if (err_no(err) == OCT_ERR_NO_RECORD) {
192                 KALUGA_DEBUG("Core where driver %s runs is not up yet.\n",
193                         mi->binary);
194                 // Don't want to free device record yet...
195                 return;
196             }
197             else if (err_is_fail(err)) {
198                 DEBUG_ERR(err, "Waiting for core %d failed?\n", core);
199                 goto out;
200             }
201         }
202
203         // If we've come here the core where we spawn the driver
204         // is already up
205         printf("Kaluga: Starting \"%s\" for (bus=%"PRIu64",dev=%"PRIu64",fun=%"PRIu64")"
206                ", intcaps: %s, on core %"PRIuCOREID"\n",
207                binary_name, bus, dev, fun, intcaps_debug_msg, core);
208
209         err = mi->start_function(core, mi, device_record, &driver_arg);
210         switch (err_no(err)) {
211         case SYS_ERR_OK:
212             KALUGA_DEBUG("Spawned PCI driver: %s\n", mi->binary);
213             set_started(mi);
214             break;
215
216         case KALUGA_ERR_DRIVER_ALREADY_STARTED:
217             KALUGA_DEBUG("%s already running.\n", mi->binary);
218             break;
219
220         case KALUGA_ERR_DRIVER_NOT_AUTO:
221             KALUGA_DEBUG("%s not declared as auto, ignore.\n", mi->binary);
222             break;
223
224         default:
225             DEBUG_ERR(err, "Unhandled error while starting %s\n", mi->binary);
226             break;
227         }
228     }
229
230 out:
231     free(device_record);
232     free(binary_name);
233 }
234
235 errval_t watch_for_pci_devices(void)
236 {
237     static char* pci_device  = "r'hw\\.pci\\.device\\.[0-9]+' { "
238                                " bus: _, device: _, function: _, vendor: _,"
239                                " device_id: _, class: _, subclass: _, "
240                                " prog_if: _ }";
241     octopus_trigger_id_t tid;
242     return oct_trigger_existing_and_watch(pci_device, pci_change_event, NULL, &tid);
243 }
244
245 static void bridge_change_event(octopus_mode_t mode, char* bridge_record, void* st)
246 {
247     if (mode & OCT_ON_SET) {
248         // No need to ask the SKB as we always start pci for
249         // in case we find a root bridge
250         struct module_info* mi = find_module("pci");
251         if (mi == NULL) {
252             KALUGA_DEBUG("PCI driver not found or not declared as auto.");
253             return;
254         }
255
256         // XXX: always spawn on my_core_id; otherwise we need to check that
257         // the other core is already up
258         errval_t err = mi->start_function(my_core_id, mi, bridge_record, NULL);
259         switch (err_no(err)) {
260         case SYS_ERR_OK:
261             KALUGA_DEBUG("Spawned PCI bus driver: %s\n", mi->binary);
262             set_started(mi);
263             break;
264
265         case KALUGA_ERR_DRIVER_ALREADY_STARTED:
266             KALUGA_DEBUG("%s already running.\n", mi->binary);
267             break;
268
269         case KALUGA_ERR_DRIVER_NOT_AUTO:
270             KALUGA_DEBUG("%s not declared as auto, ignore.\n", mi->binary);
271             break;
272
273         default:
274             DEBUG_ERR(err, "Unhandled error while starting %s\n", mi->binary);
275             break;
276         }
277     }
278 }
279
280 errval_t watch_for_pci_root_bridge(void)
281 {
282
283 #if !defined(__ARM_ARCH_8A__)
284     // TODO: Get all_irq_cap from somewhere and remove sys_debug call
285     errval_t err;
286     err = slot_alloc(&all_irq_cap);
287     assert(err_is_ok(err));
288     err = sys_debug_create_irq_src_cap(all_irq_cap, 0, 65536);
289     assert(err_is_ok(err));
290     
291 #endif
292     static char* root_bridge = "r'hw\\.pci\\.rootbridge\\.[0-9]+' { "
293                                " bus: _, device: _, function: _, maxbus: _,"
294                                " acpi_node: _ }";
295     octopus_trigger_id_t tid;
296     return oct_trigger_existing_and_watch(root_bridge, bridge_change_event,
297             NULL, &tid);
298 }