diff options
Diffstat (limited to 'src/arch/arm64/armv8')
-rw-r--r-- | src/arch/arm64/armv8/Makefile.inc | 3 | ||||
-rw-r--r-- | src/arch/arm64/armv8/bootblock.S | 36 | ||||
-rw-r--r-- | src/arch/arm64/armv8/cpu.S | 62 | ||||
-rw-r--r-- | src/arch/arm64/armv8/exception.c | 20 |
4 files changed, 59 insertions, 62 deletions
diff --git a/src/arch/arm64/armv8/Makefile.inc b/src/arch/arm64/armv8/Makefile.inc index 359a368ab9..f25a567b29 100644 --- a/src/arch/arm64/armv8/Makefile.inc +++ b/src/arch/arm64/armv8/Makefile.inc @@ -26,6 +26,9 @@ armv8_asm_flags = $(armv8_flags) ################################################################################ ifeq ($(CONFIG_ARCH_BOOTBLOCK_ARMV8_64),y) +ifneq ($(CONFIG_BOOTBLOCK_CUSTOM),y) +bootblock-y += bootblock.S +endif bootblock-y += cache.c bootblock-y += cache_helpers.S bootblock-y += cpu.S diff --git a/src/arch/arm64/armv8/bootblock.S b/src/arch/arm64/armv8/bootblock.S index a23a5f2788..4a9fea9af6 100644 --- a/src/arch/arm64/armv8/bootblock.S +++ b/src/arch/arm64/armv8/bootblock.S @@ -1,7 +1,7 @@ /* * Early initialization code for aarch64 (a.k.a. armv8) * - * Copyright 2013 Google Inc. + * Copyright 2015 Google Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -14,21 +14,23 @@ * GNU General Public License for more details. */ - .section ".id", "a", %progbits +#include <arch/asm.h> - .globl __id_start -__id_start: -ver: - .asciz COREBOOT_VERSION -vendor: - .asciz CONFIG_MAINBOARD_VENDOR -part: - .asciz CONFIG_MAINBOARD_PART_NUMBER -.long __id_end - ver /* Reverse offset to the vendor id */ -.long __id_end - vendor /* Reverse offset to the vendor id */ -.long __id_end - part /* Reverse offset to the part number */ -.long CONFIG_ROM_SIZE /* Size of this romimage */ - .globl __id_end +ENTRY(_start) + /* Initialize PSTATE, SCTLR and caches to clean state. */ + bl arm64_init_cpu -__id_end: -.previous + /* Initialize stack with sentinel value to later check overflow. */ + ldr x0, =_stack + ldr x1, =_estack + ldr x2, =0xdeadbeefdeadbeef +stack_init_loop: + stp x2, x2, [x0], #16 + cmp x0, x1 + bne stack_init_loop + + /* Leave a line of beef dead for easier visibility in stack dumps. */ + sub sp, x0, #16 + + bl main +ENDPROC(_start) diff --git a/src/arch/arm64/armv8/cpu.S b/src/arch/arm64/armv8/cpu.S index c248cb3a81..4713ca59f9 100644 --- a/src/arch/arm64/armv8/cpu.S +++ b/src/arch/arm64/armv8/cpu.S @@ -19,27 +19,40 @@ /* * Bring an ARMv8 processor we just gained control of (e.g. from IROM) into a - * known state regarding caches/SCTLR. Completely cleans and invalidates + * known state regarding caches/SCTLR/PSTATE. Completely cleans and invalidates * icache/dcache, disables MMU and dcache (if active), and enables unaligned - * accesses, icache and branch prediction (if inactive). Clobbers x4 and x5. + * accesses, icache and branch prediction (if inactive). Clobbers R22 and R23. */ -ENTRY(arm_init_caches) - /* w4: SCTLR, return address: x8 (stay valid for the whole function) */ - mov x8, x30 - /* XXX: Assume that we always start running at EL3 */ - mrs x4, sctlr_el3 +ENTRY(arm64_init_cpu) + /* Initialize PSTATE (unmask all exceptions, select SP_EL0). */ + msr SPSel, #0 + msr DAIFClr, #0xf - /* FIXME: How to enable branch prediction on ARMv8? */ + /* TODO: This is where we'd put non-boot CPUs into WFI if needed. */ + + /* x22: SCTLR, return address: x23 (callee-saved by subroutine) */ + mov x23, x30 + /* TODO: Assert that we always start running at EL3 */ + mrs x22, sctlr_el3 + + /* Activate ICache (12) already for speed during cache flush below. */ + orr x22, x22, #(1 << 12) + msr sctlr_el3, x22 + isb /* Flush and invalidate dcache */ mov x0, #DCCISW bl flush_dcache_all /* Deactivate MMU (0), Alignment Check (1) and DCache (2) */ - and x4, x4, # ~(1 << 0) & ~(1 << 1) & ~(1 << 2) - /* Activate ICache (12) already for speed */ - orr x4, x4, #(1 << 12) - msr sctlr_el3, x4 + and x22, x22, # ~(1 << 0) & ~(1 << 1) & ~(1 << 2) + /* Activate Stack Alignment (3) because why not */ + orr x22, x22, #(1 << 3) + /* Set to little-endian (25) */ + and x22, x22, # ~(1 << 25) + /* Deactivate write-xor-execute enforcement (19) */ + and x22, x22, # ~(1 << 19) + msr sctlr_el3, x22 /* Invalidate icache and TLB for good measure */ ic iallu @@ -47,26 +60,5 @@ ENTRY(arm_init_caches) dsb sy isb - ret x8 -ENDPROC(arm_init_caches) - -/* Based on u-boot transition.S */ -ENTRY(switch_el3_to_el2) - mov x0, #0x5b1 /* Non-secure EL0/EL1 | HVC | 64bit EL2 */ - msr scr_el3, x0 - msr cptr_el3, xzr /* Disable coprocessor traps to EL3 */ - mov x0, #0x33ff - msr cptr_el2, x0 /* Disable coprocessor traps to EL2 */ - - /* Return to the EL2_SP2 mode from EL3 */ - mov x0, sp - msr sp_el2, x0 /* Migrate SP */ - mrs x0, vbar_el3 - msr vbar_el2, x0 /* Migrate VBAR */ - mrs x0, sctlr_el3 - msr sctlr_el2, x0 /* Migrate SCTLR */ - mov x0, #0x3c9 - msr spsr_el3, x0 /* EL2_SP2 | D | A | I | F */ - msr elr_el3, x30 - eret -ENDPROC(switch_el3_to_el2) + ret x23 +ENDPROC(arm64_init_cpu) diff --git a/src/arch/arm64/armv8/exception.c b/src/arch/arm64/armv8/exception.c index afbaf6da78..35e3f7fac6 100644 --- a/src/arch/arm64/armv8/exception.c +++ b/src/arch/arm64/armv8/exception.c @@ -36,6 +36,8 @@ #include <console/console.h> #include <arch/lib_helpers.h> +uint8_t exception_stack[0x200] __attribute__((aligned(16))); + static const char *exception_names[NUM_EXC_VIDS] = { [EXC_VID_CUR_SP_EL0_SYNC] = "_sync_sp_el0", [EXC_VID_CUR_SP_EL0_IRQ] = "_irq_sp_el0", @@ -193,19 +195,17 @@ static uint64_t test_exception(void) return 0; } -void exception_hwinit(void) -{ - exc_set_vbar(); -} - void exception_init(void) { - /* Load the exception table. */ - exception_hwinit(); + /* Load the exception table and initialize SP_EL3. */ + exception_init_asm(exception_stack + ARRAY_SIZE(exception_stack)); printk(BIOS_DEBUG, "ARM64: Exception handlers installed.\n"); - printk(BIOS_DEBUG, "ARM64: Testing exception\n"); - test_exception(); - printk(BIOS_DEBUG, "ARM64: Done test exception\n"); + /* Only spend time testing on debug builds that are trying to detect more errors. */ + if (IS_ENABLED(CONFIG_FATAL_ASSERTS)) { + printk(BIOS_DEBUG, "ARM64: Testing exception\n"); + test_exception(); + printk(BIOS_DEBUG, "ARM64: Done test exception\n"); + } } |