1/* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors. 4 */ 5 6#include <arch.h> 7#include <asm_macros.S> 8#include <rmm_el3_ifc.h> 9#include <sizes.h> 10#include <smc.h> 11#include <xlat_tables.h> 12 13#define RMM_STACK_SIZE (SZ_4K * RMM_NUM_PAGES_PER_STACK) 14 15.globl rmm_entry 16 17/* 18 * Initialize essential R-EL2 sysregs and C runtime environment 19 */ 20.macro rmm_el2_init_env _vector, _is_cold_boot_flag, _warm_boot 21 22 /* 23 * Stash arguments from previous boot stage 24 */ 25 mov x20, x0 26 mov x21, x1 27 mov x22, x2 28 mov x23, x3 29 30 mov_imm x1, SCTLR_EL2_INIT 31 msr sctlr_el2, x1 32 33 mov_imm x2, HCR_EL2_INIT 34 msr hcr_el2, x2 35 36 mov_imm x3, CPTR_EL2_INIT 37 msr cptr_el2, x3 38 39 mov_imm x4, ICC_SRE_EL2_INIT 40 msr ICC_SRE_EL2, x4 41 42 isb 43 44 ldr x1, \_is_cold_boot_flag 45 cbz x1, 1f 46 47 /* 48 * As PIE is enabled, fixup the Global Descriptor Table only 49 * once during cold boot. This is needed before accessing any 50 * symbol addresses. 51 */ 52 bl fixup_gdt_reloc 53 54 /* Cold and warm boot need to go through this path */ 551: 56 /* Early validate and init CPU Id */ 57 mov x0, x20 58 bl rmm_el3_ifc_validate_cpuid 59 60 /* Setup stack on this CPU. X0 already contains the CPU Id */ 61 bl rmm_get_my_stack 62 mov sp, x0 63 64 /* 65 * Setup exception vectors 66 */ 67 adrp x3, \_vector 68 add x3, x3, :lo12:\_vector 69 msr vbar_el2, x3 70 isb 71 72 /* 73 * Find out whether this is a cold or warm boot 74 */ 75 ldr x1, \_is_cold_boot_flag 76 cbnz x1, 2f 77 78 /* 79 * Restore arguments in preparation for the warm boot path 80 */ 81 mov x0, x20 82 mov x1, x21 83 mov x2, x22 84 mov x3, x23 85 b \_warm_boot 86 872: 88 /* 89 * Update cold boot flag to indicate cold boot is done 90 */ 91 adr x2, \_is_cold_boot_flag 92 str xzr, [x2] 93 94 /* 95 * Initialize BSS section 96 */ 97 adrp x0, bss_start 98 add x0, x0, :lo12:bss_start 99 adrp x1, bss_end 100 add x1, x1, :lo12:bss_end 101 sub x2, x1, x0 102 mov x1, xzr 103 bl memset 104 105 /* 106 * Restore args received from previous BL image 107 */ 108 mov x0, x20 109 mov x1, x21 110 mov x2, x22 111 mov x3, x23 112.endm 113 114/* 115 * This is the main entry for both Primary and secondary PEs. 116 */ 117func rmm_entry 118 119 rmm_el2_init_env el2_vectors, cold_boot_flag, skip_to_warmboot 120 121 /* 122 * Initialize platform specific peripherals like UART and 123 * xlat tables. 124 */ 125 bl plat_setup 126 bl xlat_enable_mmu_el2 127 128 bl rmm_main 129 b smc_ret 130 131skip_to_warmboot: 132 /* 133 * Carry on with the rest of the RMM warmboot path 134 */ 135 bl plat_warmboot_setup 136 bl xlat_enable_mmu_el2 137 138 bl rmm_warmboot_main 139smc_ret: 140 mov_imm x0, SMC_RMM_BOOT_COMPLETE 141 mov_imm x1, E_RMM_BOOT_SUCCESS 142 smc #0 143 144 /* Jump to the SMC handler post-init */ 145 b rmm_handler 146 147 /* 148 * Flag to mark if it is a cold boot. 149 * 1: cold boot, 0: warmboot. 150 */ 151.align 3 152cold_boot_flag: 153 .dword 1 154endfunc rmm_entry 155 156/* 157 * Return the stack for a given PE index in x0 158 * stack-start stack_end 159 * o--sz---o....o--sz---o--sz---o--sz---o 160 * ^\_____/^....^\_____/^\_____/^\_____/^ 161 * id = (MAX_CPU-1) 2 1 0 162 * Arg : x0 - CPU position 163 * sz: RMM_STACK_SIZE bytes. 164 */ 165func rmm_get_my_stack 166#ifndef NDEBUG 167 cmp x0, #MAX_CPUS 168 ASM_ASSERT lo 169#endif 170 adrp x1, stack_end 171 add x1, x1, :lo12:stack_end 172 mov x2, #(RMM_STACK_SIZE) /* stack size per CPU */ 173 umsubl x0, w0, w2, x1 174 ret 175endfunc rmm_get_my_stack 176