139ac3f84SAndrew Jones/* 239ac3f84SAndrew Jones * Boot entry point and assembler functions for aarch64 tests. 339ac3f84SAndrew Jones * 449f758b8SAndrew Jones * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com> 539ac3f84SAndrew Jones * 649f758b8SAndrew Jones * This work is licensed under the terms of the GNU GPL, version 2. 739ac3f84SAndrew Jones */ 839ac3f84SAndrew Jones#define __ASSEMBLY__ 962bdc67fSAndrew Jones#include <auxinfo.h> 1039ac3f84SAndrew Jones#include <asm/asm-offsets.h> 11b5f659beSAlexandru Elisei#include <asm/assembler.h> 127ee966e9SAndrew Jones#include <asm/ptrace.h> 13db328a24SAndrew Jones#include <asm/page.h> 14db328a24SAndrew Jones#include <asm/pgtable-hwdef.h> 15993c37beSAndrew Jones#include <asm/thread_info.h> 161dd3501aSAlexandru Elisei#include <asm/sysreg.h> 17993c37beSAndrew Jones 18993c37beSAndrew Jones.macro zero_range, tmp1, tmp2 19993c37beSAndrew Jones9998: cmp \tmp1, \tmp2 20993c37beSAndrew Jones b.eq 9997f 21993c37beSAndrew Jones stp xzr, xzr, [\tmp1], #16 22993c37beSAndrew Jones b 9998b 23993c37beSAndrew Jones9997: 24993c37beSAndrew Jones.endm 2539ac3f84SAndrew Jones 2639ac3f84SAndrew Jones.section .init 2739ac3f84SAndrew Jones 28f6416021SAndrew Jones/* 29f6416021SAndrew Jones * Bootloader params are in x0-x3. See kernel doc 30f6416021SAndrew Jones * Documentation/arm64/booting.txt 31f6416021SAndrew Jones */ 3239ac3f84SAndrew Jones.globl start 3339ac3f84SAndrew Jonesstart: 34f6416021SAndrew Jones /* get our base address */ 35f6416021SAndrew Jones adrp x4, start 36f6416021SAndrew Jones add x4, x4, :lo12:start 37f6416021SAndrew Jones 3839ac3f84SAndrew Jones /* 39f6416021SAndrew Jones * Update all R_AARCH64_RELATIVE relocations using the table 40f6416021SAndrew Jones * of Elf64_Rela entries between reloc_start/end. The build 41f6416021SAndrew Jones * will not emit other relocation types. 42f6416021SAndrew Jones * 43f6416021SAndrew Jones * struct Elf64_Rela { 44f6416021SAndrew Jones * uint64_t r_offset; 45f6416021SAndrew Jones * uint64_t r_info; 46f6416021SAndrew Jones * int64_t r_addend; 47f6416021SAndrew Jones * } 4839ac3f84SAndrew Jones */ 49f6416021SAndrew Jones adrp x5, reloc_start 50f6416021SAndrew Jones add x5, x5, :lo12:reloc_start 51f6416021SAndrew Jones adrp x6, reloc_end 52f6416021SAndrew Jones add x6, x6, :lo12:reloc_end 53f6416021SAndrew Jones1: 54f6416021SAndrew Jones cmp x5, x6 55f6416021SAndrew Jones b.hs 1f 56f6416021SAndrew Jones ldr x7, [x5] // r_offset 57f6416021SAndrew Jones ldr x8, [x5, #16] // r_addend 58f6416021SAndrew Jones add x8, x8, x4 // val = base + r_addend 59f6416021SAndrew Jones str x8, [x4, x7] // base[r_offset] = val 60f6416021SAndrew Jones add x5, x5, #24 61f6416021SAndrew Jones b 1b 62f6416021SAndrew Jones 63f6416021SAndrew Jones1: 64993c37beSAndrew Jones /* zero BSS */ 65993c37beSAndrew Jones adrp x4, bss 66993c37beSAndrew Jones add x4, x4, :lo12:bss 67993c37beSAndrew Jones adrp x5, ebss 68993c37beSAndrew Jones add x5, x5, :lo12:ebss 69993c37beSAndrew Jones zero_range x4, x5 70993c37beSAndrew Jones 71993c37beSAndrew Jones /* zero and set up stack */ 72993c37beSAndrew Jones adrp x5, stacktop 73993c37beSAndrew Jones add x5, x5, :lo12:stacktop 74993c37beSAndrew Jones sub x4, x5, #THREAD_SIZE 75993c37beSAndrew Jones zero_range x4, x5 7610b65ce7SAlexandru Elisei 7710b65ce7SAlexandru Elisei /* set SCTLR_EL1 to a known value */ 7810b65ce7SAlexandru Elisei ldr x4, =INIT_SCTLR_EL1_MMU_OFF 7910b65ce7SAlexandru Elisei msr sctlr_el1, x4 8010b65ce7SAlexandru Elisei isb 8110b65ce7SAlexandru Elisei 821693644dSAndrew Jones mov x4, #1 831693644dSAndrew Jones msr spsel, x4 8463ab2d70SPaolo Bonzini adrp x4, stackptr 8563ab2d70SPaolo Bonzini add sp, x4, :lo12:stackptr 8639ac3f84SAndrew Jones 87f6416021SAndrew Jones /* enable FP/ASIMD */ 88f6416021SAndrew Jones mov x4, #(3 << 20) 89f6416021SAndrew Jones msr cpacr_el1, x4 9039ac3f84SAndrew Jones 9139ac3f84SAndrew Jones /* set up exception handling */ 927ee966e9SAndrew Jones bl exceptions_init 9339ac3f84SAndrew Jones 9439ac3f84SAndrew Jones /* complete setup */ 95*5a2a7371SAndrew Jones adrp x1, stacktop 96*5a2a7371SAndrew Jones add x1, x1, :lo12:stacktop // x1 is the base of free memory 97f6416021SAndrew Jones bl setup // x0 is the addr of the dtb 9839ac3f84SAndrew Jones 9939ac3f84SAndrew Jones /* run the test */ 10063ab2d70SPaolo Bonzini adrp x0, __argc 101364bb39dSAndrew Jones ldr w0, [x0, :lo12:__argc] 10263ab2d70SPaolo Bonzini adrp x1, __argv 10363ab2d70SPaolo Bonzini add x1, x1, :lo12:__argv 10463ab2d70SPaolo Bonzini adrp x2, __environ 10563ab2d70SPaolo Bonzini add x2, x2, :lo12:__environ 10639ac3f84SAndrew Jones bl main 10739ac3f84SAndrew Jones bl exit 10839ac3f84SAndrew Jones b halt 10939ac3f84SAndrew Jones 11039ac3f84SAndrew Jones.text 11139ac3f84SAndrew Jones 11262bdc67fSAndrew Jonesget_mmu_off: 11362bdc67fSAndrew Jones adrp x0, auxinfo 11462bdc67fSAndrew Jones ldr x0, [x0, :lo12:auxinfo + 8] 11562bdc67fSAndrew Jones and x0, x0, #AUXINFO_MMU_OFF 11662bdc67fSAndrew Jones ret 11762bdc67fSAndrew Jones 11868ea0e0bSAndrew Jones.globl secondary_entry 11968ea0e0bSAndrew Jonessecondary_entry: 12068ea0e0bSAndrew Jones /* Enable FP/ASIMD */ 12168ea0e0bSAndrew Jones mov x0, #(3 << 20) 12268ea0e0bSAndrew Jones msr cpacr_el1, x0 12368ea0e0bSAndrew Jones 12468ea0e0bSAndrew Jones /* set up exception handling */ 12568ea0e0bSAndrew Jones bl exceptions_init 12668ea0e0bSAndrew Jones 12762bdc67fSAndrew Jones /* enable the MMU unless requested off */ 12862bdc67fSAndrew Jones bl get_mmu_off 12962bdc67fSAndrew Jones cbnz x0, 1f 13063ab2d70SPaolo Bonzini adrp x0, mmu_idmap 13163ab2d70SPaolo Bonzini ldr x0, [x0, :lo12:mmu_idmap] 13268ea0e0bSAndrew Jones bl asm_mmu_enable 13368ea0e0bSAndrew Jones 13462bdc67fSAndrew Jones1: 13568ea0e0bSAndrew Jones /* set the stack */ 13663ab2d70SPaolo Bonzini adrp x0, secondary_data 13763ab2d70SPaolo Bonzini ldr x0, [x0, :lo12:secondary_data] 13868ea0e0bSAndrew Jones mov sp, x0 13968ea0e0bSAndrew Jones 14068ea0e0bSAndrew Jones /* finish init in C code */ 14168ea0e0bSAndrew Jones bl secondary_cinit 14268ea0e0bSAndrew Jones 14368ea0e0bSAndrew Jones /* x0 is now the entry function, run it */ 144543ce33cSAndrew Jones blr x0 1459246de4cSAndrew Jones b do_idle 14668ea0e0bSAndrew Jones 14739ac3f84SAndrew Jones.globl halt 14839ac3f84SAndrew Joneshalt: 14939ac3f84SAndrew Jones1: wfi 15039ac3f84SAndrew Jones b 1b 1517ee966e9SAndrew Jones 1527ee966e9SAndrew Jones/* 153db328a24SAndrew Jones * asm_mmu_enable 154db328a24SAndrew Jones * Inputs: 155db328a24SAndrew Jones * x0 is the base address of the translation table 156db328a24SAndrew Jones * Outputs: none 157db328a24SAndrew Jones * 158db328a24SAndrew Jones * Adapted from 159db328a24SAndrew Jones * arch/arm64/kernel/head.S 160db328a24SAndrew Jones * arch/arm64/mm/proc.S 161db328a24SAndrew Jones */ 162db328a24SAndrew Jones 163db328a24SAndrew Jones/* 164db328a24SAndrew Jones * Memory region attributes for LPAE: 165db328a24SAndrew Jones * 166db328a24SAndrew Jones * n = AttrIndx[2:0] 167db328a24SAndrew Jones * n MAIR 168db328a24SAndrew Jones * DEVICE_nGnRnE 000 00000000 169db328a24SAndrew Jones * DEVICE_nGnRE 001 00000100 170db328a24SAndrew Jones * DEVICE_GRE 010 00001100 171db328a24SAndrew Jones * NORMAL_NC 011 01000100 172db328a24SAndrew Jones * NORMAL 100 11111111 173cc70e4b6SNikos Nikoleris * NORMAL_WT 101 10111011 174cc70e4b6SNikos Nikoleris * DEVICE_nGRE 110 00001000 175db328a24SAndrew Jones */ 176db328a24SAndrew Jones#define MAIR(attr, mt) ((attr) << ((mt) * 8)) 177db328a24SAndrew Jones 178a2d06852SNikos Nikoleris#if PAGE_SIZE == SZ_64K 179a2d06852SNikos Nikoleris#define TCR_TG_FLAGS TCR_TG0_64K | TCR_TG1_64K 180a2d06852SNikos Nikoleris#elif PAGE_SIZE == SZ_16K 181a2d06852SNikos Nikoleris#define TCR_TG_FLAGS TCR_TG0_16K | TCR_TG1_16K 182a2d06852SNikos Nikoleris#elif PAGE_SIZE == SZ_4K 183a2d06852SNikos Nikoleris#define TCR_TG_FLAGS TCR_TG0_4K | TCR_TG1_4K 184a2d06852SNikos Nikoleris#endif 185a2d06852SNikos Nikoleris 186db328a24SAndrew Jones.globl asm_mmu_enable 187db328a24SAndrew Jonesasm_mmu_enable: 18842d51704SAlexandru Elisei tlbi vmalle1 // invalidate I + D TLBs 18942d51704SAlexandru Elisei dsb nsh 190db328a24SAndrew Jones 191db328a24SAndrew Jones /* TCR */ 192db328a24SAndrew Jones ldr x1, =TCR_TxSZ(VA_BITS) | \ 193a2d06852SNikos Nikoleris TCR_TG_FLAGS | \ 194db328a24SAndrew Jones TCR_IRGN_WBWA | TCR_ORGN_WBWA | \ 1958425ac5cSAlexandru Elisei TCR_SHARED | \ 1968425ac5cSAlexandru Elisei TCR_EPD1 197d140ad48SAndrew Jones mrs x2, id_aa64mmfr0_el1 198db328a24SAndrew Jones bfi x1, x2, #32, #3 199db328a24SAndrew Jones msr tcr_el1, x1 200db328a24SAndrew Jones 201db328a24SAndrew Jones /* MAIR */ 202db328a24SAndrew Jones ldr x1, =MAIR(0x00, MT_DEVICE_nGnRnE) | \ 203db328a24SAndrew Jones MAIR(0x04, MT_DEVICE_nGnRE) | \ 204db328a24SAndrew Jones MAIR(0x0c, MT_DEVICE_GRE) | \ 205db328a24SAndrew Jones MAIR(0x44, MT_NORMAL_NC) | \ 206cc70e4b6SNikos Nikoleris MAIR(0xff, MT_NORMAL) | \ 207cc70e4b6SNikos Nikoleris MAIR(0xbb, MT_NORMAL_WT) | \ 208cc70e4b6SNikos Nikoleris MAIR(0x08, MT_DEVICE_nGRE) 209db328a24SAndrew Jones msr mair_el1, x1 210db328a24SAndrew Jones 211db328a24SAndrew Jones /* TTBR0 */ 212db328a24SAndrew Jones msr ttbr0_el1, x0 213db328a24SAndrew Jones isb 214db328a24SAndrew Jones 215db328a24SAndrew Jones /* SCTLR */ 216db328a24SAndrew Jones mrs x1, sctlr_el1 217db328a24SAndrew Jones orr x1, x1, SCTLR_EL1_C 218db328a24SAndrew Jones orr x1, x1, SCTLR_EL1_I 219db328a24SAndrew Jones orr x1, x1, SCTLR_EL1_M 220db328a24SAndrew Jones msr sctlr_el1, x1 221db328a24SAndrew Jones isb 222db328a24SAndrew Jones 223db328a24SAndrew Jones ret 224db328a24SAndrew Jones 225e27b176bSAndrew Jones.globl asm_mmu_disable 226e27b176bSAndrew Jonesasm_mmu_disable: 227e27b176bSAndrew Jones mrs x0, sctlr_el1 228e27b176bSAndrew Jones bic x0, x0, SCTLR_EL1_M 229e27b176bSAndrew Jones msr sctlr_el1, x0 230e27b176bSAndrew Jones isb 231410b3bf0SAlexandru Elisei 232410b3bf0SAlexandru Elisei /* Clean + invalidate the entire memory */ 233410b3bf0SAlexandru Elisei adrp x0, __phys_offset 234410b3bf0SAlexandru Elisei ldr x0, [x0, :lo12:__phys_offset] 235410b3bf0SAlexandru Elisei adrp x1, __phys_end 236410b3bf0SAlexandru Elisei ldr x1, [x1, :lo12:__phys_end] 237b5f659beSAlexandru Elisei sub x1, x1, x0 238410b3bf0SAlexandru Elisei dcache_by_line_op civac, sy, x0, x1, x2, x3 239410b3bf0SAlexandru Elisei 240e27b176bSAndrew Jones ret 241e27b176bSAndrew Jones 242db328a24SAndrew Jones/* 2437ee966e9SAndrew Jones * Vectors 2442da0f98cSAndrew Jones */ 2452da0f98cSAndrew Jones 2462da0f98cSAndrew Jonesexceptions_init: 2472da0f98cSAndrew Jones adrp x4, vector_table 2482da0f98cSAndrew Jones add x4, x4, :lo12:vector_table 2492da0f98cSAndrew Jones msr vbar_el1, x4 2502da0f98cSAndrew Jones isb 2512da0f98cSAndrew Jones ret 2522da0f98cSAndrew Jones 2532da0f98cSAndrew Jones/* 2542da0f98cSAndrew Jones * Vector stubs 2557ee966e9SAndrew Jones * Adapted from arch/arm64/kernel/entry.S 2567ee966e9SAndrew Jones */ 2577ee966e9SAndrew Jones.macro vector_stub, name, vec 2587ee966e9SAndrew Jones\name: 2597ee966e9SAndrew Jones stp x0, x1, [sp, #-S_FRAME_SIZE]! 2607ee966e9SAndrew Jones stp x2, x3, [sp, #16] 2617ee966e9SAndrew Jones stp x4, x5, [sp, #32] 2627ee966e9SAndrew Jones stp x6, x7, [sp, #48] 2637ee966e9SAndrew Jones stp x8, x9, [sp, #64] 2647ee966e9SAndrew Jones stp x10, x11, [sp, #80] 2657ee966e9SAndrew Jones stp x12, x13, [sp, #96] 2667ee966e9SAndrew Jones stp x14, x15, [sp, #112] 2677ee966e9SAndrew Jones stp x16, x17, [sp, #128] 2687ee966e9SAndrew Jones stp x18, x19, [sp, #144] 2697ee966e9SAndrew Jones stp x20, x21, [sp, #160] 2707ee966e9SAndrew Jones stp x22, x23, [sp, #176] 2717ee966e9SAndrew Jones stp x24, x25, [sp, #192] 2727ee966e9SAndrew Jones stp x26, x27, [sp, #208] 2737ee966e9SAndrew Jones stp x28, x29, [sp, #224] 2747ee966e9SAndrew Jones 2757ee966e9SAndrew Jones str x30, [sp, #S_LR] 2767ee966e9SAndrew Jones 2777ee966e9SAndrew Jones .if \vec >= 8 2787ee966e9SAndrew Jones mrs x1, sp_el0 2797ee966e9SAndrew Jones .else 2807ee966e9SAndrew Jones add x1, sp, #S_FRAME_SIZE 2817ee966e9SAndrew Jones .endif 2827ee966e9SAndrew Jones str x1, [sp, #S_SP] 2837ee966e9SAndrew Jones 2847ee966e9SAndrew Jones mrs x1, elr_el1 2857ee966e9SAndrew Jones mrs x2, spsr_el1 2867ee966e9SAndrew Jones stp x1, x2, [sp, #S_PC] 2877ee966e9SAndrew Jones 288f6d10793SAndrew Jones mov x0, \vec 2897ee966e9SAndrew Jones mov x1, sp 2907ee966e9SAndrew Jones mrs x2, esr_el1 2917ee966e9SAndrew Jones bl do_handle_exception 2927ee966e9SAndrew Jones 2937ee966e9SAndrew Jones ldp x1, x2, [sp, #S_PC] 2947ee966e9SAndrew Jones msr spsr_el1, x2 2957ee966e9SAndrew Jones msr elr_el1, x1 2967ee966e9SAndrew Jones 2977ee966e9SAndrew Jones .if \vec >= 8 2987ee966e9SAndrew Jones ldr x1, [sp, #S_SP] 2997ee966e9SAndrew Jones msr sp_el0, x1 3007ee966e9SAndrew Jones .endif 3017ee966e9SAndrew Jones 3027ee966e9SAndrew Jones ldr x30, [sp, #S_LR] 3037ee966e9SAndrew Jones 3047ee966e9SAndrew Jones ldp x28, x29, [sp, #224] 3057ee966e9SAndrew Jones ldp x26, x27, [sp, #208] 3067ee966e9SAndrew Jones ldp x24, x25, [sp, #192] 3077ee966e9SAndrew Jones ldp x22, x23, [sp, #176] 3087ee966e9SAndrew Jones ldp x20, x21, [sp, #160] 3097ee966e9SAndrew Jones ldp x18, x19, [sp, #144] 3107ee966e9SAndrew Jones ldp x16, x17, [sp, #128] 3117ee966e9SAndrew Jones ldp x14, x15, [sp, #112] 3127ee966e9SAndrew Jones ldp x12, x13, [sp, #96] 3137ee966e9SAndrew Jones ldp x10, x11, [sp, #80] 3147ee966e9SAndrew Jones ldp x8, x9, [sp, #64] 3157ee966e9SAndrew Jones ldp x6, x7, [sp, #48] 3167ee966e9SAndrew Jones ldp x4, x5, [sp, #32] 3177ee966e9SAndrew Jones ldp x2, x3, [sp, #16] 3187ee966e9SAndrew Jones ldp x0, x1, [sp], #S_FRAME_SIZE 3197ee966e9SAndrew Jones 3207ee966e9SAndrew Jones eret 3217ee966e9SAndrew Jones.endm 3227ee966e9SAndrew Jones 3237ee966e9SAndrew Jonesvector_stub el1t_sync, 0 3247ee966e9SAndrew Jonesvector_stub el1t_irq, 1 3257ee966e9SAndrew Jonesvector_stub el1t_fiq, 2 3267ee966e9SAndrew Jonesvector_stub el1t_error, 3 3277ee966e9SAndrew Jones 3287ee966e9SAndrew Jonesvector_stub el1h_sync, 4 3297ee966e9SAndrew Jonesvector_stub el1h_irq, 5 3307ee966e9SAndrew Jonesvector_stub el1h_fiq, 6 3317ee966e9SAndrew Jonesvector_stub el1h_error, 7 3327ee966e9SAndrew Jones 3337ee966e9SAndrew Jonesvector_stub el0_sync_64, 8 3347ee966e9SAndrew Jonesvector_stub el0_irq_64, 9 3357ee966e9SAndrew Jonesvector_stub el0_fiq_64, 10 3367ee966e9SAndrew Jonesvector_stub el0_error_64, 11 3377ee966e9SAndrew Jones 3387ee966e9SAndrew Jonesvector_stub el0_sync_32, 12 3397ee966e9SAndrew Jonesvector_stub el0_irq_32, 13 3407ee966e9SAndrew Jonesvector_stub el0_fiq_32, 14 3417ee966e9SAndrew Jonesvector_stub el0_error_32, 15 3427ee966e9SAndrew Jones 3437ee966e9SAndrew Jones.section .text.ex 3447ee966e9SAndrew Jones 3457ee966e9SAndrew Jones.macro ventry, label 3467ee966e9SAndrew Jones.align 7 3477ee966e9SAndrew Jones b \label 3487ee966e9SAndrew Jones.endm 3497ee966e9SAndrew Jones 3507ee966e9SAndrew Jones.align 11 3517ee966e9SAndrew Jonesvector_table: 3527ee966e9SAndrew Jones ventry el1t_sync // Synchronous EL1t 3537ee966e9SAndrew Jones ventry el1t_irq // IRQ EL1t 3547ee966e9SAndrew Jones ventry el1t_fiq // FIQ EL1t 3557ee966e9SAndrew Jones ventry el1t_error // Error EL1t 3567ee966e9SAndrew Jones 3577ee966e9SAndrew Jones ventry el1h_sync // Synchronous EL1h 3587ee966e9SAndrew Jones ventry el1h_irq // IRQ EL1h 3597ee966e9SAndrew Jones ventry el1h_fiq // FIQ EL1h 3607ee966e9SAndrew Jones ventry el1h_error // Error EL1h 3617ee966e9SAndrew Jones 3627ee966e9SAndrew Jones ventry el0_sync_64 // Synchronous 64-bit EL0 3637ee966e9SAndrew Jones ventry el0_irq_64 // IRQ 64-bit EL0 3647ee966e9SAndrew Jones ventry el0_fiq_64 // FIQ 64-bit EL0 3657ee966e9SAndrew Jones ventry el0_error_64 // Error 64-bit EL0 3667ee966e9SAndrew Jones 3677ee966e9SAndrew Jones ventry el0_sync_32 // Synchronous 32-bit EL0 3687ee966e9SAndrew Jones ventry el0_irq_32 // IRQ 32-bit EL0 3697ee966e9SAndrew Jones ventry el0_fiq_32 // FIQ 32-bit EL0 3707ee966e9SAndrew Jones ventry el0_error_32 // Error 32-bit EL0 371