armv8: Kernel expects core data also on BSP
authorDaniel Schwyn <daniel.schwyn@inf.ethz.ch>
Fri, 7 Jun 2019 15:48:45 +0000 (17:48 +0200)
committerDaniel Schwyn <daniel.schwyn@inf.ethz.ch>
Fri, 27 Sep 2019 07:55:33 +0000 (09:55 +0200)
Signed-off-by: Daniel Schwyn <daniel.schwyn@inf.ethz.ch>

include/target/aarch64/barrelfish_kpi/arm_core_data.h
kernel/arch/armv8/boot/boot_entry.S
kernel/arch/armv8/boot/boot_generic.c
kernel/arch/armv8/init.c
kernel/arch/armv8/startup_arch.c
kernel/include/arch/armv8/init.h
tools/hagfish/Hagfish.efi

index 32085a4..04fce4f 100644 (file)
@@ -24,7 +24,8 @@ struct armv8_coredata_elf {
     uint32_t    shndx;
 };
 
-#define ARMV8_BOOTMAGIC_PSCI 0xb001b001
+#define ARMV8_BOOTMAGIC_BSP     0xb001b000
+#define ARMV8_BOOTMAGIC_PSCI    0xb001b001
 #define ARMV8_BOOTMAGIC_PARKING 0xb001b002
 
 struct armv8_coredata_memreg
index 97839c0..e10e121 100644 (file)
@@ -33,7 +33,7 @@
     EFI Boot:
     Started by: UEFI (hagfish)
     X0 Value: MULTIBOOT2_BOOTLOADER_MAGIC
-
+    X1 Value: Pointer to ARMV8 core data
 
     PSCI Boot:
     Started by: Running kernel
@@ -49,18 +49,13 @@ boot_entry_bsp:
      /* Calling the boot initialization function for the BSP core.
 
       void boot_bsp_init(uint32_t magic,
-                         lpaddr_t pointer,
-                         lpaddr_t kernel_stack_top)
+                         lpaddr_t pointer)
 
       The function arguments are as follows:
       magic: register x0
       pointer: register x1
-      kernel_stack_top: register x2
     */
 
-    /* store the stack pointer at x2 */
-    mov x2, sp
-
     /* branch to the C function */
     b boot_bsp_init
 
index 5c13a73..4987dee 100644 (file)
@@ -32,9 +32,9 @@
 
 void eret(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3);
 
-void boot_bsp_init(uint32_t magic, lpaddr_t pointer, lpaddr_t stack)
+void boot_bsp_init(uint32_t magic, lpaddr_t pointer)
     __attribute__((noreturn));
-void boot_app_init(lpaddr_t context)
+void boot_app_init(lpaddr_t pointer)
     __attribute__((noreturn));
 
 /* low level debugging facilities */
@@ -97,7 +97,7 @@ static void debug_print_string(char *str)
 #endif
 
 
-void (*cpu_driver_entry)(uint32_t magic, lpaddr_t pointer, lpaddr_t stack);
+void (*cpu_driver_entry)(lvaddr_t pointer);
 
 static void configure_tcr(void) {
     armv8_TCR_EL1_t tcr_el1 = armv8_TCR_EL1_rd(NULL);
@@ -274,23 +274,9 @@ static void configure_spsr(uint8_t el) {
     }
 }
 
-static void configure_ttbr1(uint8_t el)
+static void configure_ttbr1(lpaddr_t addr)
 {
-    lpaddr_t ttbr1_el1;
-    switch(el) {
-    case 3:
-        ttbr1_el1= armv8_TTBR0_EL3_rawrd(NULL);
-        break;
-    case 2:
-        ttbr1_el1= armv8_TTBR0_EL2_rawrd(NULL);
-        break;
-    case 1:
-        ttbr1_el1= armv8_TTBR0_EL1_rawrd(NULL);
-        break;
-    default:
-        return;
-    }
-    armv8_TTBR1_EL1_rawwr(NULL, ttbr1_el1);
+    armv8_TTBR1_EL1_rawwr(NULL, addr);
 }
 
 static void configure_mair(void)
@@ -444,40 +430,37 @@ static void configure_el1_traps(void)
     armv8_CPACR_EL1_FPEN_wrf(NULL, armv8_fpen_trap_none);
 }
 
-static void drop_to_el2(uint32_t magic, lpaddr_t pointer, lpaddr_t stack)
+static void drop_to_el2(struct armv8_core_data *pointer)
 {
     /* write the stack pointer for EL1 */
-    armv8_SP_EL1_wr(NULL, stack + KERNEL_OFFSET);
+    armv8_SP_EL1_wr(NULL, pointer->cpu_driver_stack + KERNEL_OFFSET);
 
     /* Set the jump target */
     armv8_ELR_EL3_wr(NULL, (uint64_t)cpu_driver_entry);
 
     /* call exception return */
-    eret(magic, pointer + KERNEL_OFFSET, stack + KERNEL_OFFSET, 0);
+    eret((lpaddr_t)pointer + KERNEL_OFFSET, 0, 0, 0);
 }
 
-static void drop_to_el1(uint32_t magic, lpaddr_t pointer, lpaddr_t stack)
+static void drop_to_el1(struct armv8_core_data *pointer)
 {
     /* write the stack pointer for EL1 */
-    armv8_SP_EL1_wr(NULL, stack + KERNEL_OFFSET);
+    armv8_SP_EL1_wr(NULL, pointer->cpu_driver_stack + KERNEL_OFFSET);
 
     /* Set the jump target */
     armv8_ELR_EL2_wr(NULL, (uint64_t)cpu_driver_entry);
 
     /* call exception return */
-    eret(magic, pointer + KERNEL_OFFSET, stack + KERNEL_OFFSET, 0);
+    eret((lpaddr_t)pointer + KERNEL_OFFSET, 0, 0, 0);
 }
 
-static void jump_to_cpudriver(uint32_t magic, lpaddr_t pointer, lpaddr_t stack)
+static void jump_to_cpudriver(struct armv8_core_data *pointer)
 {
     // We are in EL1, so call arch_init directly.
 
-    // we may need to re set the stack pointer
-    uint64_t sp = sysreg_read_sp();
-    if (sp < KERNEL_OFFSET) {
-        sysreg_write_sp(sp + KERNEL_OFFSET);
-    }
-    cpu_driver_entry(magic, pointer + KERNEL_OFFSET, stack + KERNEL_OFFSET);
+    // Re-set the stack pointer
+    sysreg_write_sp(pointer->cpu_driver_stack + KERNEL_OFFSET);
+    cpu_driver_entry((lpaddr_t)pointer + KERNEL_OFFSET);
 
 }
 
@@ -496,19 +479,19 @@ static void jump_to_cpudriver(uint32_t magic, lpaddr_t pointer, lpaddr_t stack)
    Generic timer initialized and enabled
    >= 128KiB stack
    ACPI tables available
-   Register x0 contains the multiboot magic value
-   Register x1 contains a pointer to multiboot image
-   Register x1 contains a pointer to top entry in the kernel stack
+   Register x0 contains a pointer to ARMv8 core data
  */
-static void boot_generic_init(uint32_t magic, lpaddr_t pointer, lpaddr_t stack) {
+static void boot_generic_init(struct armv8_core_data *core_data) {
+
+    cpu_driver_entry = (void *)core_data->cpu_driver_entry;
 
     uint8_t el = armv8_CurrentEL_EL_rdf(NULL);
 
     /* Configure the EL1 translation regime. */
     configure_tcr();
 
-    /* Copy the current TTBR for EL1. */
-    configure_ttbr1(el);
+    /* Configure the kernel page tables for EL1. */
+    configure_ttbr1(core_data->page_table_root);
 
     /* configure memory attributes */
     configure_mair();
@@ -526,14 +509,14 @@ static void boot_generic_init(uint32_t magic, lpaddr_t pointer, lpaddr_t stack)
     case 3:
         configure_el3_traps();
         configure_el2_traps();
-        drop_to_el2(magic, pointer, stack);
+        drop_to_el2(core_data);
         break;
     case 2:
         configure_el2_traps();
-        drop_to_el1(magic, pointer, stack);
+        drop_to_el1(core_data);
         break;
     case 1:
-        jump_to_cpudriver(magic, pointer, stack);
+        jump_to_cpudriver(core_data);
         break;
     default:
         break;
@@ -548,15 +531,12 @@ static void boot_generic_init(uint32_t magic, lpaddr_t pointer, lpaddr_t stack)
  * This function is intended to bring the core to the same state as if it
  * has been booted by the UEFI boot loader.
  */
-void boot_app_init(lpaddr_t state)
+void boot_app_init(lpaddr_t pointer)
 {
-
     debug_uart_initialize();
     debug_print_string("APP BOOTING\n");
 
-    struct armv8_core_data *cd = (struct armv8_core_data *)state;
-
-    cpu_driver_entry = (void *)cd->cpu_driver_entry;
+    struct armv8_core_data *core_data = (struct armv8_core_data *)pointer;
 
     uint8_t current_el = armv8_CurrentEL_EL_rdf(NULL);
 
@@ -569,7 +549,7 @@ void boot_app_init(lpaddr_t state)
     armv8_disable_interrupts();
 
     /* set the ttbr0/1 */
-    armv8_set_ttbr0(current_el, cd->page_table_root);
+    armv8_set_ttbr0(current_el, core_data->page_table_root);
 
     /* set the TCR */
     armv8_set_tcr(current_el);
@@ -584,7 +564,7 @@ void boot_app_init(lpaddr_t state)
     armv8_invalidate_icache();
     armv8_instruction_synchronization_barrier();
 
-    boot_generic_init(cd->boot_magic, state, cd->cpu_driver_stack);
+    boot_generic_init(core_data);
 
     while(1) {
         __asm volatile("wfi \n");
@@ -606,34 +586,26 @@ void boot_app_init(lpaddr_t state)
    >= 128KiB stack
    ACPI tables available
    Register x0 contains the multiboot magic value
-   Register x1 contains a pointer to multiboot image
-   Register x1 contains a pointer to top entry in the kernel stack
+   Register x1 contains a pointer to ARMv8 core data
  */
 void
-boot_bsp_init(uint32_t magic, lpaddr_t pointer, lpaddr_t stack) {
+boot_bsp_init(uint32_t magic, lpaddr_t pointer) {
 
     debug_uart_initialize();
     debug_print_string("BSP BOOTING\n");
 
     /* Boot magic must be set */
     if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
+        debug_print_string("Invalid bootloader magic\n");
         goto stop;
     }
 
-    /*
-     * get the first entry in the multiboot structure, this holds a pointer
-     * to the CPU driver entry point
-     */
-    struct multiboot_tag_efi64 *tag;
-    tag = (void *)pointer + 8;
-    if (tag->type == MULTIBOOT_TAG_TYPE_EFI64) {
-        cpu_driver_entry = (void *)tag->pointer;
-    }
+    struct armv8_core_data *core_data = (struct armv8_core_data *)pointer;
 
     /* disable interrupts */
     armv8_disable_interrupts();
     
-    boot_generic_init(magic, pointer, stack);
+    boot_generic_init(core_data);
 
     stop:
     while(1) {
index 5b5e085..9325598 100644 (file)
@@ -106,8 +106,7 @@ bool arch_core_is_bsp(void)
  * @param Entry point to architecture specific initialization
  *
  * @param magic     Magic value to tell the kernel it was started by multiboot
- * @param pointer   Pointer to the multiboot structure
- * @param stack     Pointer to the stack
+ * @param pointer   Pointer to the ARMv8 core data
  *
  * ASSUMPTIONS:
  *   - the execution starts in HIGH addresses (e.g. > KERNEL_OFFSET)
@@ -115,88 +114,59 @@ bool arch_core_is_bsp(void)
  *   - ARM exception level is EL1 (privileged)
  */
 void
-arch_init(uint32_t magic, void *pointer, uintptr_t stack) {
+arch_init(struct armv8_core_data *core_data) {
     global = &global_temp;
     memset(&global->locks, 0, sizeof(global->locks));
 
-    switch (magic) {
-    case MULTIBOOT2_BOOTLOADER_MAGIC:
-        {
-        my_core_id = 0;
+    armv8_glbl_core_data = core_data;
 
-        uint32_t size = *(uint32_t *)pointer - 8;
-        struct multiboot_tag_string *kernel_cmd;
-        struct multiboot_tag *tag;
+    my_core_id = armv8_glbl_core_data->dst_core_id;
 
-        // get the first header tag
-        tag = (struct multiboot_tag *)(pointer + 8);
+    /* parse the cmdline */
+    kernel_command_line = (const char *)armv8_glbl_core_data->cpu_driver_cmdline;
+    parse_commandline(kernel_command_line, cmdargs);
 
-        // get the kernel cmdline. this may contain address which UART/GIC to use
-        kernel_cmd = multiboot2_find_cmdline(tag, size);
-        if (kernel_cmd == NULL) {
-            panic("Multiboot did not contain an kernel CMD line\n");
-        }
-
-        // parse the cmdline
-        kernel_command_line = (const char *)kernel_cmd->string;
-        parse_commandline(kernel_cmd->string, cmdargs);
-
-        // initialize the serial console.
-        serial_init(serial_console_port, false);
-//        serial_console_init(false);
-
-        struct multiboot_tag_efi_mmap *mmap = (struct multiboot_tag_efi_mmap *)
-                multiboot2_find_tag(tag, size, MULTIBOOT_TAG_TYPE_EFI_MMAP);
-        if (!mmap) {
-            panic("Multiboot image does not have EFI mmap!");
-        } else {
-            printf("Found EFI mmap: %p\n", mmap);
-        }
-
-        mmap_find_memory(mmap);
-
-        armv8_glbl_core_data->multiboot_image.base  = mem_to_local_phys((lvaddr_t)tag);
-        armv8_glbl_core_data->multiboot_image.length = size;
-        armv8_glbl_core_data->efi_mmap = mem_to_local_phys((lvaddr_t) mmap);
+    /* initialize the serial console */
+    serial_console_init(false);
 
-        armv8_glbl_core_data->cpu_driver_stack = stack;
+    /* store the stack pointers */
+    kernel_stack = local_phys_to_mem(core_data->cpu_driver_stack);
+    kernel_stack_top = local_phys_to_mem(core_data->cpu_driver_stack_limit);
 
-        kernel_stack = stack;
-        kernel_stack_top = stack + 16 - KERNEL_STACK_SIZE;
-        break;
-    }
-    case ARMV8_BOOTMAGIC_PSCI :
-        serial_init(serial_console_port, false);
-
-        struct armv8_core_data *core_data = (struct armv8_core_data*)pointer;
-        armv8_glbl_core_data = core_data;
-        global = (struct global *)core_data->cpu_driver_globals_pointer;
+    switch (armv8_glbl_core_data->boot_magic) {
+        case ARMV8_BOOTMAGIC_BSP:
+            assert(my_core_id == 0);
+            MSG("Barrelfish CPU driver starting on ARMv8 (BSP)\n");
 
-        kernel_stack = stack;
-        kernel_stack_top = local_phys_to_mem(core_data->cpu_driver_stack_limit);
+            struct multiboot_info *multiboot = (struct multiboot_info *)
+                local_phys_to_mem(armv8_glbl_core_data->multiboot_image.base);
+            struct multiboot_tag_efi_mmap *mmap = (struct multiboot_tag_efi_mmap *)
+                multiboot2_find_tag(multiboot->tags, multiboot->total_size - 8, MULTIBOOT_TAG_TYPE_EFI_MMAP);
 
-        my_core_id = core_data->dst_core_id;
+            mmap_find_memory(mmap);
+            break;
+        case ARMV8_BOOTMAGIC_PSCI :
+        case ARMV8_BOOTMAGIC_PARKING :
+            assert(my_core_id != 0);
 
-        MSG("ARMv8 Core magic...\n");
+            global = (struct global *)core_data->cpu_driver_globals_pointer;
 
-        break;
-    default: {
-        serial_init(serial_console_port, false);
+            MSG("Barrelfish CPU driver starting on ARMv8 (APP) \n");
 
-        serial_console_putchar('x');
-        serial_console_putchar('x');
-        serial_console_putchar('\n');
+            break;
+        default: {
+            serial_console_putchar('x');
+            serial_console_putchar('x');
+            serial_console_putchar('\n');
 
-        panic("Implement AP booting!");
-        __asm volatile ("wfi":::);
-        break;
-    }
+            panic("Implement AP booting!");
+            __asm volatile ("wfi":::);
+            break;
+        }
     }
 
-
-    MSG("Barrelfish CPU driver starting on ARMv8\n");
     MSG("Global data at %p\n", global);
-    MSG("Multiboot record at %p\n", pointer);
+
     MSG("Kernel stack at 0x%016" PRIxPTR ".. 0x%016" PRIxPTR "\n",
         kernel_stack_top, kernel_stack);
     MSG("Kernel first byte at 0x%" PRIxPTR "\n", &kernel_first_byte);
@@ -220,7 +190,7 @@ arch_init(uint32_t magic, void *pointer, uintptr_t stack) {
     coreboot_set_spawn_handler(CPU_ARM8, platform_boot_core);
 
     MSG("Calling arm_kernel_startup\n");
-    arm_kernel_startup(pointer);
+    arm_kernel_startup();
     while (1) {
         __asm volatile ("wfi":::);
     }
index 60bec45..132813d 100644 (file)
@@ -717,7 +717,7 @@ struct dcb *spawn_app_init(struct armv8_core_data *core_data,
 
 }
 
-void arm_kernel_startup(void *pointer)
+void arm_kernel_startup(void)
 {
     /* Initialize the core_data */
     /* Used when bringing up other cores, must be at consistent global address
@@ -741,22 +741,17 @@ void arm_kernel_startup(void *pointer)
         init_dcb = spawn_bsp_init(BSP_INIT_MODULE_NAME);
     } else {
         MSG("Doing non-BSP related bootup \n");
-        struct armv8_core_data *core_data = (struct armv8_core_data *)pointer;
-
-        my_core_id = core_data->dst_core_id;
-
+        
         /* Initialize the allocator */
-
-
-        app_alloc_phys_start = (core_data->memory.base);
-        app_alloc_phys_end   = (core_data->memory.length + app_alloc_phys_start);
+        app_alloc_phys_start = (armv8_glbl_core_data->memory.base);
+        app_alloc_phys_end   = (armv8_glbl_core_data->memory.length + app_alloc_phys_start);
 
         MSG("Memory: %lx, %lx, size=%zu kB\n", app_alloc_phys_start, app_alloc_phys_end,
             (app_alloc_phys_end - app_alloc_phys_start + 1) >> 10);
 
-        kcb_current= (struct kcb *)local_phys_to_mem(core_data->kcb);
+        kcb_current= (struct kcb *)local_phys_to_mem(armv8_glbl_core_data->kcb);
 
-        init_dcb = spawn_app_init(core_data, APP_INIT_MODULE_NAME);
+        init_dcb = spawn_app_init(armv8_glbl_core_data, APP_INIT_MODULE_NAME);
     }
     // enable interrupt forwarding to cpu
 
index 89064c1..fddc9ea 100644 (file)
 
 #ifndef __ASSEMBLER__
 
+struct armv8_core_data;
+
 /*
  * \brief Main entry point to C from boot[.S|.c]
  */
-void arch_init(uint32_t magic, void *pointer, uintptr_t stack) __attribute__((noreturn));
+void arch_init(struct armv8_core_data *pointer) __attribute__((noreturn));
 
 /*
  * Checking code for, e.g., platform-specific callouts
@@ -30,7 +32,7 @@ extern bool cpu_is_bsp(void);
 /*
  * Second-stage startup
  */
-void  arm_kernel_startup(void *pointer) __attribute__((noreturn));
+void  arm_kernel_startup(void) __attribute__((noreturn));
 
 #endif // __ASSEMBLER__
 
index 704dc0d..a669770 100644 (file)
Binary files a/tools/hagfish/Hagfish.efi and b/tools/hagfish/Hagfish.efi differ