imx8x: Boot second core
authorLukas Humbel <lukas.humbel@inf.ethz.ch>
Fri, 15 Nov 2019 16:08:44 +0000 (17:08 +0100)
committerLukas Humbel <lukas.humbel@inf.ethz.ch>
Mon, 18 Nov 2019 11:56:43 +0000 (12:56 +0100)
Signed-off-by: Lukas Humbel <lukas.humbel@inf.ethz.ch>

13 files changed:
errors/errno.fugu
hake/menu.lst.armv8_imx8x
kernel/arch/arm/gic_v3.c
usr/acpi/acpi_debug.h
usr/drivers/cpuboot/arch/armv8/boot_arch.c
usr/drivers/cpuboot/main.c
usr/kaluga/armv7.c
usr/kaluga/armv8.c
usr/kaluga/armv8_imx8x.c
usr/kaluga/start_cpu.c
usr/kaluga/start_cpu.h
usr/kaluga/x86.c
usr/skb/programs/plat_imx8x.pl [new file with mode: 0644]

index 02ee403..d5a186a 100755 (executable)
@@ -1048,6 +1048,7 @@ errors kaluga  KALUGA_ERR_ {
     failure DRIVER_ALREADY_STARTED "Driver for this type of device is already running.",
     failure DRIVER_NOT_AUTO        "Driver not declared as auto in menu.lst.",
     failure WAITING_FOR_ACPI       "Unable to wait for ACPI",
+    failure WATCHING_FOR_SPAWNDS   "Unable to watch for spawnds",
     failure QUERY_LOCAL_APIC       "Unable to query local APIC.",
     failure UNKNOWN_PLATFORM       "Unable to initialize platform",
     failure CAP_ACQUIRE            "Unable to acquire capabilities for driver",
index 209e659..b581dad 100644 (file)
@@ -24,7 +24,7 @@ modulenounzip /eclipseclp_ramfs.cpio.gz nospawn
 modulenounzip /skb_ramfs.cpio.gz nospawn
 
 # Drivers
-#module /armv8/sbin/corectrl auto
+module /armv8/sbin/corectrl auto
 #module /armv8/sbin/pci auto
 module /armv8/sbin/serial_lpuart auto 
 module /armv8/sbin/pl390_dist auto 
index 38e6564..2d4c221 100644 (file)
@@ -47,8 +47,6 @@ void gic_init(void)
     lvaddr_t gic_dist = local_phys_to_mem(platform_gic_distributor_base);
     gic_v3_dist_initialize(&gic_v3_dist_dev, (char *)gic_dist);
 
-    printf("%s: dist:%lx\n", __func__, gic_dist);
-
     printk(LOG_NOTE, "GICD IIDR "
             "implementer=0x%x, revision=0x%x, variant=0x%x,prodid=0x%x\n",
             gic_v3_dist_GICD_IIDR_Implementer_rdf(&gic_v3_dist_dev),
index aea5f52..f1af033 100644 (file)
@@ -23,4 +23,4 @@
 #define ACPI_DEBUG(x...) ((void)0)
 #endif
 
-#endif // ACPI_DEBUG_H_
\ No newline at end of file
+#endif // ACPI_DEBUG_H_
index 8028a0d..0d35b96 100644 (file)
@@ -575,6 +575,10 @@ static errval_t get_boot_protocol(coreid_t core_id, uint32_t *parking_version,
                   parked_address);
 
     if (*parking_version) {
+        err = connect_to_acpi();
+        if (err_is_fail(err)) {
+            USER_PANIC_ERR(err, "connect to acpi failed.");
+        }
         struct acpi_binding* acl = get_acpi_binding();
 
         err = slot_alloc(&parking_page->cap);
index b75237b..08839cc 100644 (file)
@@ -74,7 +74,8 @@ static void initialize(void)
     vfs_init();
     bench_init();
 
-#if defined(__aarch64__) || (defined(__x86__) && !defined(__k1om__))
+#if (defined(__x86__) && !defined(__k1om__))
+    // ARMv8 is doing this only on demand (on the parking boot protocol)
     err = connect_to_acpi();
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "connect to acpi failed.");
index 420ad4e..be226b8 100644 (file)
@@ -327,7 +327,7 @@ errval_t arch_startup(char * add_device_db_file)
 
     KALUGA_DEBUG("Kaluga: wait_for_all_spawnds\n");
 
-    err = wait_for_all_spawnds();
+    err = wait_for_all_spawnds(0);
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "Unable to wait for spawnds failed.");
     }
index 5ea819d..e7d6778 100644 (file)
@@ -69,7 +69,7 @@ static errval_t armv8_startup_common(void)
 
     KALUGA_DEBUG("Kaluga: wait_for_all_spawnds\n");
 
-    err = wait_for_all_spawnds();
+    err = wait_for_all_spawnds(1);
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "Unable to wait for spawnds failed.");
     }
index cfccdfd..c3f4d1b 100644 (file)
@@ -8,6 +8,10 @@
 #include "kaluga.h"
 #include <pci/pci.h>
 
+// For booting cores
+#include <hw_records_arch.h>
+#include <barrelfish/cpu_arch.h>
+
 static errval_t armv8_startup_common_noacpi(void)
 {
     errval_t err = SYS_ERR_OK;
@@ -27,11 +31,9 @@ static errval_t armv8_startup_common_noacpi(void)
         USER_PANIC_ERR(err, "Device DB not loaded.");
     }
 
-    KALUGA_DEBUG("Kaluga: watch_for_cores\n");
-
-    err = watch_for_cores();
+    err = skb_execute("[plat_imx8x].");
     if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "Watching cores.");
+        USER_PANIC_ERR(err, "Plat imx8x not loaded.");
     }
 
     KALUGA_DEBUG("Kaluga: pci_root_bridge\n");
@@ -48,14 +50,6 @@ static errval_t armv8_startup_common_noacpi(void)
         USER_PANIC_ERR(err, "Watching PCI devices.");
     }
 
-    KALUGA_DEBUG("Kaluga: wait for spawnd\n");
-    //TODO: Change this once we have support for multiple cores
-    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;
 }
 
@@ -258,6 +252,45 @@ start_int_route_domains(void)
    
 }
 
+extern size_t cpu_count;
+
+static errval_t start_cores(void){
+    /* We can't discover cores an ARMv8 embedded platforms. This 
+     * works similar to armv7 startup. */
+    errval_t err;
+    KALUGA_DEBUG("Kaluga: start_cores\n");
+
+    err = skb_execute_query("findall(mpid(X), arm_mpid(X), Li), write(Li).");
+    if (err_is_fail(err)) {
+        USER_PANIC_SKB_ERR(err, "Finding cores.");
+    }
+    int id;
+    struct list_parser_status skb_list;
+    skb_read_list_init(&skb_list);
+    size_t skb_cpus = 0;
+    while(skb_read_list(&skb_list, "mpid(%d)", &id)) {
+        skb_cpus++;
+        err = oct_set(HW_PROCESSOR_ARMV8_RECORD_FORMAT, id, id,
+                id, id, CURRENT_CPU_TYPE, id, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                0, id);
+        if(err_is_fail(err)){
+            USER_PANIC_ERR(err, "oct_set core");
+        }
+    }
+    cpu_count = skb_cpus;
+
+    err = watch_for_cores();
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Watching cores.");
+    }
+
+    err = wait_for_all_spawnds(0);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Unable to wait for spawnds failed.");
+    }
+    return err;
+}
+
 errval_t imx8x_startup(void)
 {
     errval_t err;
@@ -266,6 +299,11 @@ errval_t imx8x_startup(void)
         USER_PANIC_ERR(err, "startup common");
     }
 
+    err = start_cores();
+    if(err_is_fail(err)) {
+        USER_PANIC_ERR(err, "start cores");
+    }
+
     err = start_int_route_domains();
     if(err_is_fail(err)) {
         USER_PANIC_ERR(err, "start int_route");
index 10d27e4..1e4e1f1 100644 (file)
@@ -54,13 +54,16 @@ static void cpu_change_event(octopus_mode_t mode, const char* record, void* stat
 
         /* find the corectrl module for the given cpu type */
         struct module_info* mi = find_corectrl_for_cpu_type((enum cpu_type)type);
-        if (mi != NULL) {
-            err = mi->start_function(0, mi, (CONST_CAST)record, NULL);
-            if (err_is_fail(err)) {
-                printf("Boot driver not found. Do not boot discovered CPU %"PRIu64".\n",
-                       barrelfish_id);
-                goto out;
-            }
+        if(mi == NULL){
+            debug_printf("corectrl module not found!\n");
+            err = KALUGA_ERR_MODULE_NOT_FOUND;
+            goto out;
+        }
+        err = mi->start_function(0, mi, (CONST_CAST)record, NULL);
+        if (err_is_fail(err)) {
+            debug_printf("Boot driver not found. Do not boot discovered CPU %"
+                   PRIu64".\n", barrelfish_id);
+            goto out;
         }
     }
     if (mode & OCT_ON_DEL) {
@@ -161,7 +164,20 @@ errval_t start_boot_driver(coreid_t where, struct module_info* mi,
         argv[argc] = barrelfish_id_s;
         argc += 1;
         // Copy kernel args over to new core
-        struct module_info* cpu_module = find_module("cpu");
+        char * cpu_binary = "cpu";
+
+        // Check if we get a cpu binary from the skb
+        err = skb_execute_query("cpu_driver(X),write(X).");
+        if(err_is_ok(err)){
+            cpu_binary = rindex(skb_get_output(), '/');
+            if(cpu_binary) cpu_binary++;
+        }
+
+        struct module_info* cpu_module = find_module(cpu_binary);
+        if(cpu_module == NULL){
+            debug_printf("Module %s not found\n", cpu_binary);
+            return KALUGA_ERR_MODULE_NOT_FOUND;
+        }
         if (cpu_module != NULL && strlen(cpu_module->args) > 1) {
             KALUGA_DEBUG("%s:%s:%d: Boot with cpu arg %s and barrelfish_id_s=%s\n",
                          __FILE__, __FUNCTION__, __LINE__, cpu_module->args, barrelfish_id_s);
@@ -218,6 +234,7 @@ errval_t start_boot_driver(coreid_t where, struct module_info* mi,
     // cap in octopus, and delete it when the matching spawnd is up
     char spawnd[32];
     snprintf(spawnd, 32, "spawn.%s", barrelfish_id_s);
+    KALUGA_DEBUG("Waiting until %s is up!\n", spawnd);
     struct inheritcn_del_st *tstate = calloc(1, sizeof(*tstate));
     tstate->capref = inheritcn_cap;
     tstate->coreid = barrelfish_id;
@@ -252,7 +269,7 @@ static void spawnd_change_event(octopus_mode_t mode, const char* record,
 
 extern size_t cpu_count;
 
-errval_t wait_for_all_spawnds(void)
+errval_t wait_for_all_spawnds(int use_acpi)
 {
     // Note: The whole wait for all_spawnds_up thing is a hack.
     // Our overall design goal is a system where cores
@@ -263,13 +280,13 @@ errval_t wait_for_all_spawnds(void)
     // otherwise. Therefore we need to fix those parts first.
     errval_t err;
     char* record = NULL;
-#if !defined(__ARM_ARCH_7A__)
-    KALUGA_DEBUG("Waiting for acpi");
-    err = oct_wait_for(&record, "acpi { iref: _ }");
-    if (err_is_fail(err)) {
-        return err_push(err, KALUGA_ERR_WAITING_FOR_ACPI);
+    if(use_acpi){
+        KALUGA_DEBUG("Waiting for acpi");
+        err = oct_wait_for(&record, "acpi { iref: _ }");
+        if (err_is_fail(err)) {
+            return err_push(err, KALUGA_ERR_WAITING_FOR_ACPI);
+        }
     }
-#endif
 
     // No we should be able to get core count
     // of all cores to estimate the amount of
@@ -293,7 +310,7 @@ errval_t wait_for_all_spawnds(void)
     octopus_trigger_id_t tid;
     err = oct_trigger_existing_and_watch(spawnds, spawnd_change_event, (void*)count, &tid);
     if (err_is_fail(err)) {
-        return err_push(err, KALUGA_ERR_QUERY_LOCAL_APIC);
+        return err_push(err, KALUGA_ERR_WATCHING_FOR_SPAWNDS);
     }
 
     return oct_wait_for(&record, "all_spawnds_up { iref: 0 }");
index b4b20d3..7111663 100644 (file)
@@ -6,7 +6,7 @@
 struct int_startup_argument;
 
 errval_t watch_for_cores(void);
-errval_t wait_for_all_spawnds(void);
+errval_t wait_for_all_spawnds(int use_acpi);
 errval_t start_boot_driver(coreid_t where,
                            struct module_info* mi,
                            char* record, struct driver_argument * int_arg);
index 5d15edf..dede752 100644 (file)
@@ -189,7 +189,7 @@ errval_t arch_startup(char * add_device_db_file)
 
     KALUGA_DEBUG("Kaluga: wait_for_all_spawnds\n");
 
-    err = wait_for_all_spawnds();
+    err = wait_for_all_spawnds(1);
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "Unable to wait for spawnds failed.");
     }
@@ -241,7 +241,7 @@ errval_t arch_startup(char * add_device_db_file)
         }
     }
 
-    err = wait_for_all_spawnds();
+    err = wait_for_all_spawnds(1);
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "Unable to wait for spawnds failed.");
     }
diff --git a/usr/skb/programs/plat_imx8x.pl b/usr/skb/programs/plat_imx8x.pl
new file mode 100644 (file)
index 0000000..f91ac8c
--- /dev/null
@@ -0,0 +1,28 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Copyright (c) 2017, 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, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Statically-initialised hardware facts for the ThunderX CN88xx SoC
+boot_driver("/armv8/sbin/boot_armv8_generic").
+cpu_driver("/armv8/sbin/cpu_imx8x").
+monitor("/armv8/sbin/monitor").
+
+
+% boot dirver entry points
+entry_symbol(armBootBSP, "boot_entry_bsp").
+entry_symbol(armBootPSCI, "boot_entry_psci").
+entry_symbol(armBootParking, "boot_entry_parking").
+
+% Core boot information
+arm_mpid(0).
+arm_mpid(1).
+%arm_mpid(2).
+%arm_mpid(3).
+boot_driver_entry(_, armBootPSCI).
+psci_use_hvc(0).
+