imx8x: Hack kaluga to pass startup, and add startd
authorLukas Humbel <lukas.humbel@inf.ethz.ch>
Thu, 7 Nov 2019 10:57:08 +0000 (11:57 +0100)
committerLukas Humbel <lukas.humbel@inf.ethz.ch>
Thu, 7 Nov 2019 10:57:08 +0000 (11:57 +0100)
Kaluga for imx8x works quite differently, due to limited
supported for the platform and we are in process of rewriting it anyway.
startd is needed, otherwise our test binaries are not properly started.

Signed-off-by: Lukas Humbel <lukas.humbel@inf.ethz.ch>

hake/menu.lst.armv8_imx8x
tools/harness/machines/imx8x.py
usr/kaluga/Hakefile
usr/kaluga/armv8.c
usr/kaluga/armv8_imx8x.c [new file with mode: 0644]
usr/kaluga/armv8_imx8x.h [new file with mode: 0644]
usr/kaluga/boot_modules.h
usr/kaluga/driver_startup.c
usr/kaluga/main.c
usr/kaluga/start_cpu.c

index 34c9beb..e4604ad 100644 (file)
@@ -16,7 +16,7 @@ module /armv8/sbin/skb boot
 module /armv8/sbin/kaluga boot
 module /armv8/sbin/spawnd boot
 module /armv8/sbin/proc_mgmt boot
-#module /armv8/sbin/startd boot
+module /armv8/sbin/startd boot
 #module /armv8/sbin/acpi boot
 
 # ramfs contents
index 1ef8235..538d8d9 100644 (file)
@@ -39,6 +39,7 @@ class ColibriMachine(ARMMachineBase):
         m.add_module("skb", ["boot"])
         m.add_module("kaluga", ["boot"])
         m.add_module("spawnd", ["boot"])
+        m.add_module("startd", ["boot"])
         m.add_module("proc_mgmt", ["boot"])
         m.add_module("/eclipseclp_ramfs.cpio.gz", ["nospawn"])
         m.add_module("/skb_ramfs.cpio.gz", ["nospawn"])
index 813af3c..7a52148 100644 (file)
@@ -56,7 +56,7 @@ let commonCFiles = [ "boot_modules.c",
                                                "int_route_client", "queue_service"],
                       architectures = [ "armv7" ] },
   build application { target = "kaluga",
-                      cFiles = commonCFiles ++ [ "start_pci.c", "armv8.c" ],
+                      cFiles = commonCFiles ++ [ "start_pci.c", "armv8.c", "armv8_imx8x.c" ],
                       flounderDefs = [ "monitor" , "pci", "kaluga"],
                       flounderBindings = [ "octopus", "pci", "kaluga"],
                       flounderExtraDefs = [ ("monitor_blocking",["rpcclient"]) ],
index fbf709b..5ea819d 100644 (file)
@@ -18,6 +18,7 @@
 #include <barrelfish_kpi/platform.h>
 #include <if/monitor_blocking_defs.h>
 #include "kaluga.h"
+#include "armv8_imx8x.h"
 
 
 static errval_t armv8_startup_common(void)
@@ -168,6 +169,8 @@ errval_t arch_startup(char * add_device_db_file)
     case PI_PLATFORM_CN88XX:
         debug_printf("Kaluga running on CN88xx\n");
         return cn88xx_startup();
+    case PI_PLATFORM_IMX8X:
+        return imx8x_startup();
     }
 
     return KALUGA_ERR_UNKNOWN_PLATFORM;
diff --git a/usr/kaluga/armv8_imx8x.c b/usr/kaluga/armv8_imx8x.c
new file mode 100644 (file)
index 0000000..70a295d
--- /dev/null
@@ -0,0 +1,198 @@
+#include <armv8_imx8x.h>
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/nameservice_client.h>
+#include <skb/skb.h>
+#include <barrelfish_kpi/platform.h>
+#include <if/monitor_blocking_defs.h>
+#include "kaluga.h"
+
+static errval_t armv8_startup_common_noacpi(void)
+{
+    errval_t err = SYS_ERR_OK;
+
+    // We need to run on core 0
+    // (we are responsible for booting all the other cores)
+    assert(my_core_id == BSP_CORE_ID);
+
+    err = skb_client_connect();
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Connect to SKB.");
+    }
+
+    // Make sure the driver db is loaded
+    err = skb_execute("[device_db].");
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Device DB not loaded.");
+    }
+
+    KALUGA_DEBUG("Kaluga: watch_for_cores\n");
+
+    err = watch_for_cores();
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Watching cores.");
+    }
+
+    KALUGA_DEBUG("Kaluga: pci_root_bridge\n");
+
+    err = watch_for_pci_root_bridge();
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Watching PCI root bridges.");
+    }
+
+    KALUGA_DEBUG("Kaluga: pci_devices\n");
+
+    err = watch_for_pci_devices();
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Watching PCI devices.");
+    }
+
+    KALUGA_DEBUG("Kaluga: wait for spawnd\n");
+    err = nameservice_blocking_lookup("spawn.0", NULL);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "wait for spawnd");
+    }
+    err = oct_set("all_spawnds_up { iref: 0 }");
+    assert(err_is_ok(err));
+    return SYS_ERR_OK;
+}
+
+static inline errval_t
+invoke_monitor_create_cap(uint64_t *raw, capaddr_t caddr, int level, capaddr_t slot, coreid_t owner)
+{
+    struct capref my_cap_kernel = {
+        .cnode = cnode_task,
+        .slot  = TASKCN_SLOT_KERNELCAP
+    };
+    return cap_invoke6(my_cap_kernel, KernelCmd_Create_cap, caddr, level, slot,
+                       owner, (uintptr_t)raw).error;
+}
+
+static errval_t imx8x_get_device_cap(lpaddr_t address, size_t size, struct capref *devframe) {
+    KALUGA_DEBUG("HACK: Forging cap directly in kaluga....\n");
+    errval_t err;
+    err = slot_alloc(devframe);
+    assert(err_is_ok(err));
+    capaddr_t caddr = get_cnode_addr(*devframe);
+    uint8_t level = get_cnode_level(*devframe);
+    size_t  slot  = devframe->slot;
+
+    assert(address % 4096 == 0);
+    assert(size % 4096 == 0);
+
+    struct capability the_cap = {
+        .type = ObjType_DevFrame,
+        .rights = CAPRIGHTS_ALLRIGHTS,
+        .u.devframe.base = address,
+        .u.devframe.bytes = size
+    };
+
+    return invoke_monitor_create_cap((uint64_t*)&the_cap, caddr, level, slot, disp_get_core_id());
+}
+__attribute__((used))
+static errval_t start_gpio(char*name, lpaddr_t address)
+
+{   errval_t err;
+    struct module_info *mi;
+    mi = find_module("imx8x_gpio");
+    if(mi == NULL){
+        KALUGA_DEBUG("imx8x_gpio not found, not starting\n");
+        return KALUGA_ERR_MODULE_NOT_FOUND;
+    }
+    struct driver_argument arg;
+    init_driver_argument(&arg);
+    arg.module_name = "imx8x_gpio_module";
+    struct capref device_frame;
+    err = imx8x_get_device_cap(address, 0x1000, &device_frame);
+    if(err_is_fail(err)){
+        USER_PANIC_ERR(err, "get_device_cap");
+    }
+    KALUGA_DEBUG("get_device_cap worked\n");
+    //transfer destination
+    struct capref cap = {
+            .cnode = (&arg)->argnode_ref,
+            .slot = DRIVERKIT_ARGCN_SLOT_BAR0
+    };
+    err = cap_copy(cap, device_frame);
+    if(err_is_fail(err)){
+        USER_PANIC_ERR(err, "get_device_cap");
+    }
+    err = default_start_function_pure(0, mi, name, &arg);
+    if(err_is_fail(err)){
+        USER_PANIC_ERR(err, "get_device_cap");
+    }
+    return err;
+} 
+
+__attribute__((used))
+static errval_t imx8x_serial_kernel(void)
+
+{   errval_t err;
+    struct module_info *mi;
+    mi = find_module("serial_kernel");
+    struct driver_argument arg;
+    init_driver_argument(&arg);
+    arg.flags = 1; // disable interrupt
+    arg.module_name = "serial_kernel";
+    err = default_start_function_pure(0, mi,"serial_kernel {}", &arg);
+    return err;
+} 
+//serial_lpuart
+__attribute__((used))
+static errval_t start_serial_lpuart(lpaddr_t address)
+
+{   errval_t err;
+    struct module_info *mi;
+    mi = find_module("serial_lpuart");
+    if(mi == NULL){
+        KALUGA_DEBUG("serial_lpuart not found, not starting");
+        return KALUGA_ERR_MODULE_NOT_FOUND;
+    }
+    struct driver_argument arg;
+    init_driver_argument(&arg);
+    arg.module_name = "serial_lpuart";
+    struct capref device_frame;
+    err = imx8x_get_device_cap(address, 0x00010000, &device_frame);
+    if(err_is_fail(err)){
+        USER_PANIC_ERR(err, "get_device_cap");
+    }
+    KALUGA_DEBUG("get_device_cap worked\n");
+    //transfer destination
+    struct capref cap = {
+            .cnode = (&arg)->argnode_ref,
+            .slot = DRIVERKIT_ARGCN_SLOT_BAR0
+    };
+    err = cap_copy(cap, device_frame);
+    if(err_is_fail(err)){
+        USER_PANIC_ERR(err, "get_device_cap");
+    }
+    // Store capability in driver_argument: See add_mem_args in start_pci.c lines 197 and following
+    err = default_start_function_pure(0, mi, "serial_lpuart {}", &arg);
+    if(err_is_fail(err)){
+        USER_PANIC_ERR(err, "get_device_cap");
+    }
+    return err;
+} 
+
+errval_t imx8x_startup(void)
+{
+    errval_t err;
+    err = armv8_startup_common_noacpi();
+    if(err_is_fail(err)){
+        USER_PANIC_ERR(err, "startup common");
+    }
+    err = start_gpio("imx8x.gpio1 {}", 0x5D090000);
+    if(err_is_fail(err) && err_no(err) != KALUGA_ERR_MODULE_NOT_FOUND) {
+        USER_PANIC_ERR(err, "gpio1 start");
+    }
+    err = start_gpio("imx8x.gpio2 {}", 0x5D0B0000);
+    if(err_is_fail(err) && err_no(err) != KALUGA_ERR_MODULE_NOT_FOUND) {
+        USER_PANIC_ERR(err, "gpio2 start");
+    }
+
+    err = start_serial_lpuart(0x5A090000);
+    if(err_is_fail(err) && err_no(err) != KALUGA_ERR_MODULE_NOT_FOUND) {
+        USER_PANIC_ERR(err, "imx8x serial lpuart");
+    }
+
+    return SYS_ERR_OK;
+}
diff --git a/usr/kaluga/armv8_imx8x.h b/usr/kaluga/armv8_imx8x.h
new file mode 100644 (file)
index 0000000..9af0962
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef ARMV8_IMX8X_H_
+#define ARMV8_IMX8X_H_
+
+#include <errors/errno.h>
+
+errval_t imx8x_startup(void);
+
+#endif
index 43d21cb..0f02671 100644 (file)
@@ -12,6 +12,7 @@ struct driver_argument {
     struct int_startup_argument int_arg;
     struct cnoderef argnode_ref;
     char* module_name;
+    uint64_t flags;
 };
 typedef errval_t(*module_start_fn)(coreid_t where, struct module_info* mi,
         char* record, struct driver_argument * int_arg);
index 89be420..5a33fea 100644 (file)
@@ -135,6 +135,7 @@ errval_t
 default_start_function_pure(coreid_t where, struct module_info* mi, char* record,
                            struct driver_argument* arg) {
 
+    assert(mi != NULL);
     struct domain_instance* inst;
     errval_t err;
 
@@ -159,6 +160,7 @@ default_start_function_pure(coreid_t where, struct module_info* mi, char* record
     struct driver_instance* drv =
         ddomain_create_driver_instance(arg->module_name, oct_id);
 
+    drv->flags = arg->flags;
     drv->args = (char*[]){NULL,NULL,NULL,NULL};
     drv->argcn_cap = arg->arg_caps;
     return ddomain_instantiate_driver(inst, drv);
index a304c5c..f1224f4 100644 (file)
@@ -77,7 +77,8 @@ static void add_start_function_overrides(void)
 
 }
 
-static void parse_arguments(int argc, char** argv, char ** add_device_db_file, size_t *cpu_count)
+static void parse_arguments(int argc, char** argv, char ** add_device_db_file,
+        size_t *cpu_count)
 {
     for (int i = 1; i < argc; i++) {
         if (strncmp(argv[i], "apicid=", 7) == 0) {
index db7a93a..10d27e4 100644 (file)
@@ -274,16 +274,19 @@ errval_t wait_for_all_spawnds(void)
     // No we should be able to get core count
     // of all cores to estimate the amount of
     // spawnd's we have to expect (one per core)
-    char** names;
-    size_t count;
-    err = oct_get_names(&names, &count, processor_regex);
-    if (err_is_fail(err)) {
-        return err_push(err, KALUGA_ERR_QUERY_LOCAL_APIC);
-    }
-    oct_free_names(names, count);
 
+    size_t count;
     if (cpu_count) {
+        KALUGA_DEBUG("CPU count override to %d\n", cpu_count);
         count = cpu_count;
+    } else {
+        char** names;
+    
+        err = oct_get_names(&names, &count, processor_regex);
+        if (err_is_fail(err)) {
+            return err_push(err, KALUGA_ERR_QUERY_LOCAL_APIC);
+        }
+        oct_free_names(names, count);
     }
 
     static char* spawnds = "r'spawn.[0-9]+' { iref: _ }";