3 * \brief Code responsible for booting application cores
7 * Copyright (c) 2007, 2008, 2009, 2010, ETH Zurich.
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.
20 #include <barrelfish/barrelfish.h>
22 #include <octopus/octopus.h>
27 static void pci_change_event(octopus_mode_t mode, char* device_record, void* st);
29 static void spawnd_up_event(octopus_mode_t mode, char* spawnd_record, void* st)
31 assert(mode & OCT_ON_SET);
33 errval_t err = oct_read(spawnd_record, "_ { iref: %d }", &iref);
34 if (err_is_fail(err)) {
35 USER_PANIC_ERR(err, "Failed to read iref from spawnd record?");
38 // Pass the iref as state, this tells pci_change_event that we
39 // don't need to look again for the spawnd iref
40 pci_change_event(OCT_ON_SET, st, (void*)iref);
44 static errval_t wait_for_spawnd(coreid_t core, void* state)
46 // Check if the core we're spawning on is already up...
47 struct octopus_thc_client_binding_t* cl = oct_get_thc_client();
48 char* iref_record = NULL;
49 octopus_trigger_id_t tid;
51 octopus_trigger_t t = oct_mktrigger(OCT_ERR_NO_RECORD,
52 octopus_BINDING_EVENT, OCT_ON_SET, spawnd_up_event, state);
54 // Construct service name
55 static char* format = "spawn.%hhu { iref: _ }";
56 int length = snprintf(NULL, 0, format, core);
57 char* query = malloc(length+1);
58 snprintf(query, length+1, format, core);
60 errval_t err = cl->call_seq.get(cl, query, t, &iref_record, &tid, &error_code);
64 if (err_is_fail(err)) {
71 static void pci_change_event(octopus_mode_t mode, char* device_record, void* st)
74 if (mode & OCT_ON_SET) {
75 uint64_t vendor_id, device_id;
76 err = oct_read(device_record, "_ { vendor: %d, device_id: %d }",
77 &vendor_id, &device_id);
78 if (err_is_fail(err)) {
79 USER_PANIC_ERR(err, "Got malformed device record?");
82 // Ask the SKB which binary and where to start it...
83 static char* query = "find_pci_driver(pci_card(%lu, %lu, _, _, _), Driver),"
85 err = skb_execute_query(query, vendor_id, device_id);
86 if (err_no(err) == SKB_ERR_EXECUTION) {
87 KALUGA_DEBUG("No PCI driver found for: VendorId=0x%lx, "
89 vendor_id, device_id);
92 else if (err_is_fail(err)) {
93 DEBUG_ERR(err, "Failed to query SKB.\n");
97 // XXX: Find better way to parse binary name from SKB
98 char* binary_name = malloc(strlen(skb_get_output()));
100 skb_read_output("driver(%hhu, %s)", &core, binary_name);
101 *strrchr(binary_name, ')') = '\0';
103 struct module_info* mi = find_module(binary_name);
106 KALUGA_DEBUG("Driver %s not loaded. Ignore.", binary_name);
110 // Wait until the core where we start the driver
112 if (st == NULL && core != my_core_id) {
113 err = wait_for_spawnd(core, device_record);
114 if (err_no(err) == OCT_ERR_NO_RECORD) {
115 KALUGA_DEBUG("Core where driver %s runs is not up yet.\n",
117 // Don't want to free device record yet...
120 else if (err_is_fail(err)) {
121 DEBUG_ERR(err, "Waiting for core %d failed?\n", core);
126 // If we've come here the core where we spawn the driver
128 err = mi->start_function(core, mi, device_record);
129 switch (err_no(err)) {
131 KALUGA_DEBUG("Spawned PCI driver: %s\n", mi->binary);
134 case KALUGA_ERR_DRIVER_ALREADY_STARTED:
135 KALUGA_DEBUG("%s already running.\n", mi->binary);
138 case KALUGA_ERR_DRIVER_NOT_AUTO:
139 KALUGA_DEBUG("%s not declared as auto, ignore.\n", mi->binary);
143 DEBUG_ERR(err, "Unhandled error while starting %s\n", mi->binary);
152 errval_t watch_for_pci_devices(void)
154 static char* pci_device = "r'hw\\.pci\\.device\\.[0-9]+' { "
155 " bus: _, device: _, function: _, vendor: _,"
156 " device_id: _, class: _, subclass: _, "
158 octopus_trigger_id_t tid;
159 return trigger_existing_and_watch(pci_device, pci_change_event, NULL, &tid);
162 static void bridge_change_event(octopus_mode_t mode, char* bridge_record, void* st)
164 if (mode & OCT_ON_SET) {
165 // No need to ask the SKB as we always start pci for
166 // in case we find a root bridge
167 struct module_info* mi = find_module("pci");
169 KALUGA_DEBUG("PCI driver not found or not declared as auto.");
173 // XXX: always spawn on my_core_id; otherwise we need to check that
174 // the other core is already up
175 errval_t err = mi->start_function(my_core_id, mi, bridge_record);
176 switch (err_no(err)) {
178 KALUGA_DEBUG("Spawned PCI bus driver: %s\n", mi->binary);
181 case KALUGA_ERR_DRIVER_ALREADY_STARTED:
182 KALUGA_DEBUG("%s already running.\n", mi->binary);
185 case KALUGA_ERR_DRIVER_NOT_AUTO:
186 KALUGA_DEBUG("%s not declared as auto, ignore.\n", mi->binary);
190 DEBUG_ERR(err, "Unhandled error while starting %s\n", mi->binary);
199 errval_t watch_for_pci_root_bridge(void)
201 static char* root_bridge = "r'hw\\.pci\\.rootbridge\\.[0-9]+' { "
202 " bus: _, device: _, function: _, maxbus: _,"
204 octopus_trigger_id_t tid;
205 return trigger_existing_and_watch(root_bridge, bridge_change_event,