Yatharth Kochar | 5d36121 | 2016-06-28 17:07:09 +0100 | [diff] [blame] | 1 | /* |
Antonio Nino Diaz | 3c817f4 | 2018-03-21 10:49:27 +0000 | [diff] [blame] | 2 | * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. |
Yatharth Kochar | 5d36121 | 2016-06-28 17:07:09 +0100 | [diff] [blame] | 3 | * |
dp-arm | fa3cf0b | 2017-05-03 09:38:09 +0100 | [diff] [blame] | 4 | * SPDX-License-Identifier: BSD-3-Clause |
Yatharth Kochar | 5d36121 | 2016-06-28 17:07:09 +0100 | [diff] [blame] | 5 | */ |
| 6 | |
| 7 | #include <arch.h> |
| 8 | #include <asm_macros.S> |
Antonio Nino Diaz | e0f9063 | 2018-12-14 00:18:21 +0000 | [diff] [blame] | 9 | #include <bl1/bl1.h> |
| 10 | #include <common/bl_common.h> |
dp-arm | cdd03cb | 2017-02-15 11:07:55 +0000 | [diff] [blame] | 11 | #include <context.h> |
Antonio Nino Diaz | e0f9063 | 2018-12-14 00:18:21 +0000 | [diff] [blame] | 12 | #include <lib/xlat_tables/xlat_tables.h> |
Antonio Nino Diaz | 3c817f4 | 2018-03-21 10:49:27 +0000 | [diff] [blame] | 13 | #include <smccc_helpers.h> |
| 14 | #include <smccc_macros.S> |
Yatharth Kochar | 5d36121 | 2016-06-28 17:07:09 +0100 | [diff] [blame] | 15 | |
| 16 | .globl bl1_aarch32_smc_handler |
| 17 | |
| 18 | |
| 19 | func bl1_aarch32_smc_handler |
dp-arm | cdd03cb | 2017-02-15 11:07:55 +0000 | [diff] [blame] | 20 | /* On SMC entry, `sp` points to `smc_ctx_t`. Save `lr`. */ |
| 21 | str lr, [sp, #SMC_CTX_LR_MON] |
| 22 | |
Yatharth Kochar | 5d36121 | 2016-06-28 17:07:09 +0100 | [diff] [blame] | 23 | /* ------------------------------------------------ |
| 24 | * SMC in BL1 is handled assuming that the MMU is |
| 25 | * turned off by BL2. |
| 26 | * ------------------------------------------------ |
| 27 | */ |
| 28 | |
| 29 | /* ---------------------------------------------- |
dp-arm | cdd03cb | 2017-02-15 11:07:55 +0000 | [diff] [blame] | 30 | * Detect if this is a RUN_IMAGE or other SMC. |
Yatharth Kochar | 5d36121 | 2016-06-28 17:07:09 +0100 | [diff] [blame] | 31 | * ---------------------------------------------- |
| 32 | */ |
dp-arm | cdd03cb | 2017-02-15 11:07:55 +0000 | [diff] [blame] | 33 | mov lr, #BL1_SMC_RUN_IMAGE |
| 34 | cmp lr, r0 |
| 35 | bne smc_handler |
Yatharth Kochar | 5d36121 | 2016-06-28 17:07:09 +0100 | [diff] [blame] | 36 | |
| 37 | /* ------------------------------------------------ |
| 38 | * Make sure only Secure world reaches here. |
| 39 | * ------------------------------------------------ |
| 40 | */ |
| 41 | ldcopr r8, SCR |
| 42 | tst r8, #SCR_NS_BIT |
| 43 | blne report_exception |
| 44 | |
| 45 | /* --------------------------------------------------------------------- |
| 46 | * Pass control to next secure image. |
| 47 | * Here it expects r1 to contain the address of a entry_point_info_t |
| 48 | * structure describing the BL entrypoint. |
| 49 | * --------------------------------------------------------------------- |
| 50 | */ |
| 51 | mov r8, r1 |
| 52 | mov r0, r1 |
| 53 | bl bl1_print_next_bl_ep_info |
| 54 | |
| 55 | #if SPIN_ON_BL1_EXIT |
| 56 | bl print_debug_loop_message |
| 57 | debug_loop: |
| 58 | b debug_loop |
| 59 | #endif |
| 60 | |
| 61 | mov r0, r8 |
| 62 | bl bl1_plat_prepare_exit |
| 63 | |
| 64 | stcopr r0, TLBIALL |
| 65 | dsb sy |
| 66 | isb |
| 67 | |
| 68 | /* |
| 69 | * Extract PC and SPSR based on struct `entry_point_info_t` |
| 70 | * and load it in LR and SPSR registers respectively. |
| 71 | */ |
| 72 | ldr lr, [r8, #ENTRY_POINT_INFO_PC_OFFSET] |
| 73 | ldr r1, [r8, #(ENTRY_POINT_INFO_PC_OFFSET + 4)] |
Bryan O'Donoghue | adfa8b0 | 2019-03-12 12:09:51 +0000 | [diff] [blame] | 74 | msr spsr_xc, r1 |
Yatharth Kochar | 5d36121 | 2016-06-28 17:07:09 +0100 | [diff] [blame] | 75 | |
Etienne Carriere | 094041d | 2018-02-02 13:16:18 +0100 | [diff] [blame] | 76 | /* Some BL32 stages expect lr_svc to provide the BL33 entry address */ |
| 77 | cps #MODE32_svc |
| 78 | ldr lr, [r8, #ENTRY_POINT_INFO_LR_SVC_OFFSET] |
| 79 | cps #MODE32_mon |
| 80 | |
Yatharth Kochar | 5d36121 | 2016-06-28 17:07:09 +0100 | [diff] [blame] | 81 | add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET |
| 82 | ldm r8, {r0, r1, r2, r3} |
Madhukar Pappireddy | fcbcd6f | 2020-02-26 12:37:05 -0600 | [diff] [blame] | 83 | exception_return |
Yatharth Kochar | 5d36121 | 2016-06-28 17:07:09 +0100 | [diff] [blame] | 84 | endfunc bl1_aarch32_smc_handler |
dp-arm | cdd03cb | 2017-02-15 11:07:55 +0000 | [diff] [blame] | 85 | |
| 86 | /* ----------------------------------------------------- |
| 87 | * Save Secure/Normal world context and jump to |
| 88 | * BL1 SMC handler. |
| 89 | * ----------------------------------------------------- |
| 90 | */ |
| 91 | func smc_handler |
| 92 | /* ----------------------------------------------------- |
| 93 | * Save the GP registers. |
| 94 | * ----------------------------------------------------- |
| 95 | */ |
Antonio Nino Diaz | 3c817f4 | 2018-03-21 10:49:27 +0000 | [diff] [blame] | 96 | smccc_save_gp_mode_regs |
dp-arm | cdd03cb | 2017-02-15 11:07:55 +0000 | [diff] [blame] | 97 | |
| 98 | /* |
| 99 | * `sp` still points to `smc_ctx_t`. Save it to a register |
| 100 | * and restore the C runtime stack pointer to `sp`. |
| 101 | */ |
| 102 | mov r6, sp |
| 103 | ldr sp, [r6, #SMC_CTX_SP_MON] |
| 104 | |
| 105 | ldr r0, [r6, #SMC_CTX_SCR] |
| 106 | and r7, r0, #SCR_NS_BIT /* flags */ |
| 107 | |
| 108 | /* Switch to Secure Mode */ |
| 109 | bic r0, #SCR_NS_BIT |
| 110 | stcopr r0, SCR |
| 111 | isb |
| 112 | |
| 113 | /* If caller is from Secure world then turn on the MMU */ |
| 114 | tst r7, #SCR_NS_BIT |
| 115 | bne skip_mmu_on |
| 116 | |
| 117 | /* Turn on the MMU */ |
| 118 | mov r0, #DISABLE_DCACHE |
Antonio Nino Diaz | 128de8d | 2018-08-07 19:59:49 +0100 | [diff] [blame] | 119 | bl enable_mmu_svc_mon |
dp-arm | cdd03cb | 2017-02-15 11:07:55 +0000 | [diff] [blame] | 120 | |
| 121 | /* Enable the data cache. */ |
| 122 | ldcopr r9, SCTLR |
| 123 | orr r9, r9, #SCTLR_C_BIT |
| 124 | stcopr r9, SCTLR |
| 125 | isb |
| 126 | |
| 127 | skip_mmu_on: |
| 128 | /* Prepare arguments for BL1 SMC wrapper. */ |
| 129 | ldr r0, [r6, #SMC_CTX_GPREG_R0] /* smc_fid */ |
| 130 | mov r1, #0 /* cookie */ |
| 131 | mov r2, r6 /* handle */ |
| 132 | mov r3, r7 /* flags */ |
| 133 | bl bl1_smc_wrapper |
| 134 | |
| 135 | /* Get the smc_context for next BL image */ |
| 136 | bl smc_get_next_ctx |
| 137 | mov r4, r0 |
| 138 | |
| 139 | /* Only turn-off MMU if going to secure world */ |
| 140 | ldr r5, [r4, #SMC_CTX_SCR] |
| 141 | tst r5, #SCR_NS_BIT |
| 142 | bne skip_mmu_off |
| 143 | |
| 144 | /* Disable the MMU */ |
| 145 | bl disable_mmu_icache_secure |
| 146 | stcopr r0, TLBIALL |
| 147 | dsb sy |
| 148 | isb |
| 149 | |
| 150 | skip_mmu_off: |
| 151 | /* ----------------------------------------------------- |
| 152 | * Do the transition to next BL image. |
| 153 | * ----------------------------------------------------- |
| 154 | */ |
| 155 | mov r0, r4 |
| 156 | monitor_exit |
| 157 | endfunc smc_handler |