Starting PCI.
authorGerd Zellweger <zgerd@student.ethz.ch>
Sat, 10 Mar 2012 18:53:09 +0000 (19:53 +0100)
committerGerd Zellweger <zgerd@student.ethz.ch>
Sat, 10 Mar 2012 18:53:09 +0000 (19:53 +0100)
12 files changed:
usr/kaluga/Hakefile
usr/kaluga/boot_modules.c
usr/kaluga/boot_modules.h [new file with mode: 0644]
usr/kaluga/driver_startup.c [new file with mode: 0644]
usr/kaluga/kaluga.h
usr/kaluga/main.c
usr/kaluga/start_cpu.c
usr/kaluga/start_cpu.h [new file with mode: 0644]
usr/kaluga/start_pci.c
usr/kaluga/start_pci.h [new file with mode: 0644]
usr/kaluga/start_pci_driver.c [deleted file]
usr/kaluga/startup.h [new file with mode: 0644]

index 538722f..7f56f5e 100644 (file)
@@ -12,7 +12,7 @@
 
 [ build application { target = "kaluga",
                       cFiles = [ "main.c", "queue.c", "boot_modules.c", "common.c",
-                                 "start_cpu.c", "start_pci.c", "start_pci_driver.c" ],
+                                 "start_cpu.c", "start_pci.c", "startup.c" ],
                          flounderDefs = [ "monitor" ],
                       flounderBindings = [ "dist2" ],
                       addLibraries = [ "skb", "dist2", "dist_parser", 
index e4d23bd..36b8ed2 100644 (file)
@@ -27,22 +27,6 @@ inline bool is_started(struct module_info* mi)
     return mi->did > 0;
 }
 
-static errval_t default_start_function(coreid_t where, struct module_info* mi,
-        char* record)
-{
-    errval_t err = SYS_ERR_OK;
-
-    if (!is_started(mi)) {
-        err = spawn_program(where, mi->path, mi->argv+1,
-                environ, 0, &mi->did);
-        if (err_is_fail(err)) {
-            DEBUG_ERR(err, "Spawning %s failed.", mi->path);
-        }
-    }
-
-    return err;
-}
-
 void set_start_function(char* binary, module_start_fn start_fn)
 {
     struct module_info* mi = find_module(binary);
diff --git a/usr/kaluga/boot_modules.h b/usr/kaluga/boot_modules.h
new file mode 100644 (file)
index 0000000..0ad2cd7
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef BOOT_MODULES_H_
+#define BOOT_MODULES_H_
+
+#include <barrelfish/barrelfish.h>
+
+struct module_info;
+typedef errval_t(*module_start_fn)(coreid_t where, struct module_info* mi,
+        char* record);
+
+struct module_info {
+    char* complete_line;
+    char* path;
+    char* binary;
+
+    char* cmdargs; // Used for pointers in argv
+    int argc;
+    char* argv[MAX_CMDLINE_ARGS + 1];
+
+    module_start_fn start_function;
+    domainid_t did;
+};
+
+
+void init_environ(void);
+errval_t init_boot_modules(void);
+struct module_info* find_module(char*);
+bool is_started(struct module_info*);
+bool is_auto_driver(struct module_info*);
+void set_start_function(char*, module_start_fn);
+
+#endif /* BOOT_MODULES_H_ */
diff --git a/usr/kaluga/driver_startup.c b/usr/kaluga/driver_startup.c
new file mode 100644 (file)
index 0000000..909b7de
--- /dev/null
@@ -0,0 +1,59 @@
+#include <stdio.h>
+#include <string.h>
+
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/spawn_client.h>
+
+#include "kaluga.h"
+
+extern char **environ;
+
+errval_t default_start_function(coreid_t where, struct module_info* mi,
+        char* record)
+{
+    errval_t err = SYS_ERR_OK;
+
+    if (!is_started(mi)) {
+        err = spawn_program(where, mi->path, mi->argv+1,
+                environ, 0, &mi->did);
+        if (err_is_fail(err)) {
+            DEBUG_ERR(err, "Spawning %s failed.", mi->path);
+        }
+    }
+
+    return err;
+}
+
+errval_t start_networking(coreid_t core, struct module_info* driver,
+        char* record)
+{
+    errval_t err = SYS_ERR_OK;
+
+    if (!is_started(driver)) {
+        err = spawn_program(core, driver->path, driver->argv+1,
+                environ, 0, &driver->did);
+        if (err_is_fail(err)) {
+            DEBUG_ERR(err, "Spawning %s failed.", driver->path);
+            return err;
+        }
+
+        struct module_info* netd = find_module("netd");
+        if (netd == NULL || !is_auto_driver(netd)) {
+            KALUGA_DEBUG("netd not found or not declared as auto. "
+                         "Driver will probably not work correctly.");
+            return err;
+        }
+
+        // XXX: Manually add cardname (overwrite first (auto) argument)
+        size_t name_len = strlen("cardname=")+strlen(driver->binary)+1;
+        char* cardname = malloc(name_len);
+        sprintf(cardname, "cardname=%s", driver->binary);
+        netd->argv[0] = cardname;
+        err = spawn_program(core, netd->path, netd->argv,
+                environ, 0, &netd->did);
+        free(cardname);
+    }
+
+    return err;
+
+}
index 9ef0373..b2582f7 100644 (file)
 #define TRIGGER_ALWAYS (DIST_PERSIST | DIST_ON_SET | DIST_ON_DEL | DIST_ALWAYS_SET)
 #define BSP_CORE_ID 0
 
-struct module_info;
-typedef errval_t(*module_start_fn)(coreid_t where, struct module_info* mi,
-        char* record);
-
-struct module_info {
-    char* complete_line;
-    char* path;
-    char* binary;
-
-    char* cmdargs; // Used for pointers in argv
-    int argc;
-    char* argv[MAX_CMDLINE_ARGS + 1];
-
-    module_start_fn start_function;
-    domainid_t did;
-};
-
 extern coreid_t my_core_id;
 extern uint32_t my_arch_id;
 
-
 errval_t trigger_existing_and_watch(const char*,
         trigger_handler_fn, void*,  dist2_trigger_id_t*);
 
-errval_t watch_for_cores(void);
-errval_t watch_for_pci_root_bridge(void);
-errval_t watch_for_pci_devices(void);
 
-void init_environ(void);
-errval_t init_boot_modules(void);
-struct module_info* find_module(char*);
-bool is_started(struct module_info*);
-bool is_auto_driver(struct module_info*);
-void set_start_function(char*, module_start_fn);
+#include "boot_modules.h"
+#include "start_pci.h"
+#include "start_cpu.h"
+#include "startup.h"
 
 #endif /* KALUGA_H_ */
index c246802..84aa074 100644 (file)
@@ -25,7 +25,6 @@
 #include <barrelfish/barrelfish.h>
 #include <barrelfish/cpu_arch.h>
 #include <barrelfish/nameservice_client.h>
-#include <barrelfish/spawn_client.h>
 
 #include <if/monitor_defs.h>
 
@@ -39,38 +38,6 @@ uint32_t my_arch_id = 0; // APIC ID
 
 extern char **environ;
 
-static errval_t start_networking(coreid_t core, struct module_info* driver,
-        char* record)
-{
-    errval_t err = SYS_ERR_OK;
-
-    if (!is_started(driver)) {
-        err = spawn_program(core, driver->path, driver->argv+1,
-                environ, 0, &driver->did);
-        if (err_is_fail(err)) {
-            DEBUG_ERR(err, "Spawning %s failed.", driver->path);
-            return err;
-        }
-
-        struct module_info* netd = find_module("netd");
-        if (netd == NULL || !is_auto_driver(netd)) {
-            KALUGA_DEBUG("netd not found. Driver will probably not work correctly.");
-            return err;
-        }
-
-        // XXX: Manually add cardname (overwrite first (auto) argument)
-        size_t name_len = strlen("cardname=")+strlen(driver->binary)+1;
-        char* cardname = malloc(name_len);
-        sprintf(cardname, "cardname=%s", driver->binary);
-        netd->argv[0] = cardname;
-        err = spawn_program(core, netd->path, netd->argv,
-                environ, 0, &netd->did);
-        free(cardname);
-    }
-
-    return err;
-
-}
 
 static void add_start_function_overrides(void)
 {
index fa2ba93..72caacf 100644 (file)
@@ -27,9 +27,9 @@
 
 #include "kaluga.h"
 
-// TODO: This is needed because of we have to send
+// TODO: Needed because of we have to send
 // boot_initialize_request after all cores have booted
-// It's is a hack (see monitors boot.c)
+// It's a hack (see monitors boot.c)
 static coreid_t cores_on_boot = 0;
 static coreid_t core_counter = 1; // BSP already up
 static bool cores_booted = false;
diff --git a/usr/kaluga/start_cpu.h b/usr/kaluga/start_cpu.h
new file mode 100644 (file)
index 0000000..60d991e
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef START_CPU_H_
+#define START_CPU_H_
+
+#include <errors/errno.h>
+
+errval_t watch_for_cores(void);
+
+#endif /* START_CPU_H_ */
index c0d5dbd..e3248ad 100644 (file)
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include <assert.h>
 
 #include <barrelfish/barrelfish.h>
-#include <barrelfish/spawn_client.h>
 
 #include <dist2/dist2.h>
 #include <skb/skb.h>
 
 #include "kaluga.h"
 
-static domainid_t pci_driver = 0;
-extern char **environ;
+static void pci_change_event(dist2_mode_t mode, char* device_record, void* st);
 
-static void bridge_change_event(dist2_mode_t mode, char* bridge_record, void* st)
+static void spawnd_up_event(dist2_mode_t mode, char* spawnd_record, void* st)
+{
+    assert(mode & DIST_ON_SET);
+    uint64_t iref;
+    errval_t err = dist_read(spawnd_record, "_ { iref: %d }", &iref);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Failed to read iref from spawnd record?");
+    }
+
+    // Pass the iref as state, this tells pci_change_event that we
+    // don't need to look again for the spawnd iref
+    pci_change_event(DIST_ON_SET, st, (void*)iref);
+    free(spawnd_record);
+}
+
+static errval_t wait_for_spawnd(coreid_t core, void* state)
 {
+    // Check if the core we're spawning on is already up...
+    struct dist2_thc_client_binding_t* cl = dist_get_thc_client();
+    char* iref_record = NULL;
+    dist2_trigger_id_t tid;
+    errval_t error_code;
+    dist2_trigger_t t = dist_mktrigger(DIST2_ERR_NO_RECORD,
+            dist2_BINDING_EVENT, DIST_ON_SET, spawnd_up_event, state);
+
+    // Construct service name
+    static char* format = "spawn.%hhu { iref: _ }";
+    int length = snprintf(NULL, 0, format, core);
+    char* query = malloc(length+1);
+    snprintf(query, length+1, format, core);
+
+    errval_t err = cl->call_seq.get(cl, query, t, &iref_record, &tid, &error_code);
+    free(query);
+    free(iref_record);
+
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    return error_code;
+}
+
+static void pci_change_event(dist2_mode_t mode, char* device_record, void* st)
+{
+    errval_t err;
     if (mode & DIST_ON_SET) {
-        if (pci_driver != 0) {
-            KALUGA_DEBUG("Got new root bridge, PCI driver is already running.");
+        uint64_t vendor_id, device_id;
+        err = dist_read(device_record, "_ { vendor: %d, device_id: %d }",
+                &vendor_id, &device_id);
+        if (err_is_fail(err)) {
+            USER_PANIC_ERR(err, "Got malformed device record?");
+        }
+
+        // Ask the SKB which binary and where to start it...
+        static char* query = "find_pci_driver(pci_card(%lu, %lu, _, _, _), Driver),"
+                             "writeln(Driver).";
+        err = skb_execute_query(query, vendor_id, device_id);
+        if (err_no(err) == SKB_ERR_EXECUTION) {
+            KALUGA_DEBUG("No PCI driver found for: VendorId=0x%lx, "
+                         "DeviceId=0x%lx\n",
+                    vendor_id, device_id);
             goto out;
         }
+        else if (err_is_fail(err)) {
+            DEBUG_ERR(err, "Failed to query SKB.\n");
+            goto out;
+        }
+
+        // XXX: Find better way to parse binary name from SKB
+        char* binary_name = malloc(strlen(skb_get_output()));
+        coreid_t core;
+        skb_read_output("driver(%hhu, %s)", &core, binary_name);
+        *strrchr(binary_name, ')') = '\0';
 
+        struct module_info* mi = find_module(binary_name);
+        free(binary_name);
+        if (mi == NULL || !is_auto_driver(mi)) {
+            KALUGA_DEBUG("PCI driver not found or not declared as auto.\n");
+            goto out;
+        }
+
+        if (st == NULL && core != my_core_id) {
+            err = wait_for_spawnd(core, device_record);
+            if (err_no(err) == DIST2_ERR_NO_RECORD) {
+                KALUGA_DEBUG("Core where driver %s runs is not up yet.\n",
+                        mi->binary);
+                // Don't want to free device record here...
+                return;
+            }
+            else if (err_is_fail(err)) {
+                DEBUG_ERR(err, "Waiting for core %d failed?\n", core);
+                goto out;
+            }
+        }
+
+        // If we've come here the core where we spawn the driver
+        // is already up
+        KALUGA_DEBUG("Spawn PCI driver: %s\n", mi->binary);
+        mi->start_function(core, mi, device_record);
+    }
+
+out:
+    free(device_record);
+}
+
+errval_t watch_for_pci_devices(void)
+{
+    static char* pci_device  = "r'hw\\.pci\\.device\\.[0-9]+' { "
+                               " bus: _, device: _, function: _, vendor: _,"
+                               " device_id: _, class: _, subclass: _, "
+                               " prog_if: _ }";
+    dist2_trigger_id_t tid;
+    return trigger_existing_and_watch(pci_device, pci_change_event, NULL, &tid);
+}
+
+static void bridge_change_event(dist2_mode_t mode, char* bridge_record, void* st)
+{
+    if (mode & DIST_ON_SET) {
         // No need to ask the SKB as we always start pci for
         // in case we find a root bridge
         struct module_info* mi = find_module("pci");
@@ -46,11 +155,7 @@ static void bridge_change_event(dist2_mode_t mode, char* bridge_record, void* st
         KALUGA_DEBUG("bridge_change_event: spawn mi->path: %s\n", mi->path);
         // XXX: always spawn on my_core_id; otherwise we need to check that
         // the other core is already up
-        errval_t err = spawn_program(my_core_id, mi->path, mi->argv+1,
-                environ, 0, &pci_driver);
-        if (err_is_fail(err)) {
-            DEBUG_ERR(err, "Spawning PCI driver failed.");
-        }
+        mi->start_function(my_core_id, mi, bridge_record);
     }
 
 out:
diff --git a/usr/kaluga/start_pci.h b/usr/kaluga/start_pci.h
new file mode 100644 (file)
index 0000000..dab72ff
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef START_PCI_H_
+#define START_PCI_H_
+
+#include <errors/errno.h>
+
+errval_t watch_for_pci_root_bridge(void);
+errval_t watch_for_pci_devices(void);
+
+#endif /* START_PCI_H_ */
diff --git a/usr/kaluga/start_pci_driver.c b/usr/kaluga/start_pci_driver.c
deleted file mode 100644 (file)
index 3cfd9f6..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
- * \file
- * \brief Code responsible for booting application cores
- */
-
-/*
- * Copyright (c) 2007, 2008, 2009, 2010, ETH Zurich.
- * All rights reserved.
- *
- * This file is distributed under the terms in the attached LICENSE file.
- * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-#include <barrelfish/barrelfish.h>
-
-#include <dist2/dist2.h>
-#include <skb/skb.h>
-
-#include "kaluga.h"
-
-static void pci_change_event(dist2_mode_t mode, char* device_record, void* st);
-
-static void spawnd_up_event(dist2_mode_t mode, char* spawnd_record, void* st)
-{
-    assert(mode & DIST_ON_SET);
-    uint64_t iref;
-    errval_t err = dist_read(spawnd_record, "_ { iref: %d }", &iref);
-    if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "Failed to read iref from spawnd record?");
-    }
-
-    // Pass the iref as state, this tells pci_change_event that we
-    // don't need to look again for the spawnd iref
-    pci_change_event(DIST_ON_SET, st, (void*)iref);
-    free(spawnd_record);
-}
-
-static errval_t wait_for_spawnd(coreid_t core, void* state)
-{
-    // Check if the core we're spawning on is already up...
-    struct dist2_thc_client_binding_t* cl = dist_get_thc_client();
-    char* iref_record = NULL;
-    dist2_trigger_id_t tid;
-    errval_t error_code;
-    dist2_trigger_t t = dist_mktrigger(DIST2_ERR_NO_RECORD,
-            dist2_BINDING_EVENT, DIST_ON_SET, spawnd_up_event, state);
-
-    // Construct service name
-    static char* format = "spawn.%hhu { iref: _ }";
-    int length = snprintf(NULL, 0, format, core);
-    char* query = malloc(length+1);
-    snprintf(query, length+1, format, core);
-
-    errval_t err = cl->call_seq.get(cl, query, t, &iref_record, &tid, &error_code);
-    free(query);
-    free(iref_record);
-
-    if (err_is_fail(err)) {
-        return err;
-    }
-
-    return error_code;
-}
-
-static void pci_change_event(dist2_mode_t mode, char* device_record, void* st)
-{
-    errval_t err;
-    if (mode & DIST_ON_SET) {
-        uint64_t vendor_id, device_id;
-        err = dist_read(device_record, "_ { vendor: %d, device_id: %d }",
-                &vendor_id, &device_id);
-        if (err_is_fail(err)) {
-            USER_PANIC_ERR(err, "Got malformed device record?");
-        }
-
-        // Ask the SKB which binary and where to start it...
-        static char* query = "find_pci_driver(pci_card(%lu, %lu, _, _, _), Driver),"
-                             "writeln(Driver).";
-        err = skb_execute_query(query, vendor_id, device_id);
-        if (err_no(err) == SKB_ERR_EXECUTION) {
-            KALUGA_DEBUG("No PCI driver found for: VendorId=0x%lx, "
-                         "DeviceId=0x%lx\n",
-                    vendor_id, device_id);
-            goto out;
-        }
-        else if (err_is_fail(err)) {
-            DEBUG_ERR(err, "Failed to query SKB.\n");
-            goto out;
-        }
-
-        // XXX: Find better way to parse binary name from SKB
-        char* binary_name = malloc(strlen(skb_get_output()));
-        coreid_t core;
-        skb_read_output("driver(%hhu, %s)", &core, binary_name);
-        *strrchr(binary_name, ')') = '\0';
-
-        struct module_info* mi = find_module(binary_name);
-        free(binary_name);
-        if (mi == NULL || !is_auto_driver(mi)) {
-            KALUGA_DEBUG("PCI driver not found or not declared as auto.\n");
-            goto out;
-        }
-
-        if (st == NULL && core != my_core_id) {
-            err = wait_for_spawnd(core, device_record);
-            if (err_no(err) == DIST2_ERR_NO_RECORD) {
-                KALUGA_DEBUG("Core where driver %s runs is not up yet.\n",
-                        mi->binary);
-                // Don't want to free device record here...
-                return;
-            }
-            else if (err_is_fail(err)) {
-                DEBUG_ERR(err, "Waiting for core %d failed?\n", core);
-                goto out;
-            }
-        }
-
-        // If we've come here the core where we spawn the driver
-        // is already up
-        KALUGA_DEBUG("Spawn PCI driver: %s\n", mi->binary);
-        mi->start_function(core, mi, device_record);
-    }
-
-out:
-    free(device_record);
-}
-
-errval_t watch_for_pci_devices(void)
-{
-    static char* pci_device  = "r'hw\\.pci\\.device\\.[0-9]+' { "
-                               " bus: _, device: _, function: _, vendor: _,"
-                               " device_id: _, class: _, subclass: _, "
-                               " prog_if: _ }";
-    dist2_trigger_id_t tid;
-    return trigger_existing_and_watch(pci_device, pci_change_event, NULL, &tid);
-}
diff --git a/usr/kaluga/startup.h b/usr/kaluga/startup.h
new file mode 100644 (file)
index 0000000..81bb269
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef CUSTOM_STARTUP_H_
+#define CUSTOM_STARTUP_H_
+
+#include <errors/errno.h>
+
+#include "boot_modules.h"
+
+errval_t default_start_function(coreid_t, struct module_info*, char*);
+errval_t start_networking(coreid_t, struct module_info*, char*);
+
+#endif /* CUSTOM_STARTUP_H_ */