mbed-os5 only for TYBLE16
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core/tfm_core.c@0:5b88d5760320, 2019-12-17 (annotated)
- Committer:
- kenjiArai
- Date:
- Tue Dec 17 23:23:45 2019 +0000
- Revision:
- 0:5b88d5760320
mbed-os5 only for TYBLE16
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:5b88d5760320 | 1 | /* |
kenjiArai | 0:5b88d5760320 | 2 | * Copyright (c) 2017-2019, Arm Limited. All rights reserved. |
kenjiArai | 0:5b88d5760320 | 3 | * |
kenjiArai | 0:5b88d5760320 | 4 | * SPDX-License-Identifier: BSD-3-Clause |
kenjiArai | 0:5b88d5760320 | 5 | * |
kenjiArai | 0:5b88d5760320 | 6 | */ |
kenjiArai | 0:5b88d5760320 | 7 | |
kenjiArai | 0:5b88d5760320 | 8 | #include <stdio.h> |
kenjiArai | 0:5b88d5760320 | 9 | #include "region_defs.h" |
kenjiArai | 0:5b88d5760320 | 10 | #include "tfm_core.h" |
kenjiArai | 0:5b88d5760320 | 11 | #include "tfm_internal.h" |
kenjiArai | 0:5b88d5760320 | 12 | #include "tfm_api.h" |
kenjiArai | 0:5b88d5760320 | 13 | #include "platform/include/tfm_spm_hal.h" |
kenjiArai | 0:5b88d5760320 | 14 | #include "secure_utilities.h" |
kenjiArai | 0:5b88d5760320 | 15 | #include "secure_fw/spm/spm_api.h" |
kenjiArai | 0:5b88d5760320 | 16 | #include "secure_fw/include/tfm_spm_services_api.h" |
kenjiArai | 0:5b88d5760320 | 17 | #ifdef TFM_PSA_API |
kenjiArai | 0:5b88d5760320 | 18 | #include "psa_client.h" |
kenjiArai | 0:5b88d5760320 | 19 | #include "psa_service.h" |
kenjiArai | 0:5b88d5760320 | 20 | #include "tfm_thread.h" |
kenjiArai | 0:5b88d5760320 | 21 | #include "tfm_wait.h" |
kenjiArai | 0:5b88d5760320 | 22 | #include "tfm_message_queue.h" |
kenjiArai | 0:5b88d5760320 | 23 | #include "tfm_spm.h" |
kenjiArai | 0:5b88d5760320 | 24 | #endif |
kenjiArai | 0:5b88d5760320 | 25 | |
kenjiArai | 0:5b88d5760320 | 26 | /* |
kenjiArai | 0:5b88d5760320 | 27 | * Avoids the semihosting issue |
kenjiArai | 0:5b88d5760320 | 28 | * FixMe: describe 'semihosting issue' |
kenjiArai | 0:5b88d5760320 | 29 | */ |
kenjiArai | 0:5b88d5760320 | 30 | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) |
kenjiArai | 0:5b88d5760320 | 31 | __asm(" .global __ARM_use_no_argv\n"); |
kenjiArai | 0:5b88d5760320 | 32 | #endif |
kenjiArai | 0:5b88d5760320 | 33 | |
kenjiArai | 0:5b88d5760320 | 34 | #if defined ( __GNUC__ ) |
kenjiArai | 0:5b88d5760320 | 35 | /* The macro cmse_nsfptr_create defined in the gcc library uses the non-standard |
kenjiArai | 0:5b88d5760320 | 36 | * gcc C lanuage extension 'typeof'. TF-M is built with '-std=c99' so typeof |
kenjiArai | 0:5b88d5760320 | 37 | * cannot be used in the code. As a workaround cmse_nsfptr_create is redefined |
kenjiArai | 0:5b88d5760320 | 38 | * here to use only standard language elements. */ |
kenjiArai | 0:5b88d5760320 | 39 | #undef cmse_nsfptr_create |
kenjiArai | 0:5b88d5760320 | 40 | #define cmse_nsfptr_create(p) ((intptr_t) (p) & ~1) |
kenjiArai | 0:5b88d5760320 | 41 | #endif |
kenjiArai | 0:5b88d5760320 | 42 | |
kenjiArai | 0:5b88d5760320 | 43 | #ifndef TFM_LVL |
kenjiArai | 0:5b88d5760320 | 44 | #error TFM_LVL is not defined! |
kenjiArai | 0:5b88d5760320 | 45 | #endif |
kenjiArai | 0:5b88d5760320 | 46 | #if (TFM_LVL != 1) && (TFM_LVL != 2) && (TFM_LVL != 3) |
kenjiArai | 0:5b88d5760320 | 47 | #error Only TFM_LVL 1, 2 and 3 are supported! |
kenjiArai | 0:5b88d5760320 | 48 | #endif |
kenjiArai | 0:5b88d5760320 | 49 | |
kenjiArai | 0:5b88d5760320 | 50 | #ifndef TFM_PSA_API |
kenjiArai | 0:5b88d5760320 | 51 | /* Macros to pick linker symbols and allow to form the partition data base */ |
kenjiArai | 0:5b88d5760320 | 52 | #define REGION(a, b, c) a##b##c |
kenjiArai | 0:5b88d5760320 | 53 | #define REGION_NAME(a, b, c) REGION(a, b, c) |
kenjiArai | 0:5b88d5760320 | 54 | #define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c) |
kenjiArai | 0:5b88d5760320 | 55 | |
kenjiArai | 0:5b88d5760320 | 56 | REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base); |
kenjiArai | 0:5b88d5760320 | 57 | REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit); |
kenjiArai | 0:5b88d5760320 | 58 | #endif |
kenjiArai | 0:5b88d5760320 | 59 | |
kenjiArai | 0:5b88d5760320 | 60 | void configure_ns_code(void) |
kenjiArai | 0:5b88d5760320 | 61 | { |
kenjiArai | 0:5b88d5760320 | 62 | /* SCB_NS.VTOR points to the Non-secure vector table base address */ |
kenjiArai | 0:5b88d5760320 | 63 | SCB_NS->VTOR = tfm_spm_hal_get_ns_VTOR(); |
kenjiArai | 0:5b88d5760320 | 64 | |
kenjiArai | 0:5b88d5760320 | 65 | /* Setups Main stack pointer of the non-secure code */ |
kenjiArai | 0:5b88d5760320 | 66 | uint32_t ns_msp = tfm_spm_hal_get_ns_MSP(); |
kenjiArai | 0:5b88d5760320 | 67 | |
kenjiArai | 0:5b88d5760320 | 68 | __TZ_set_MSP_NS(ns_msp); |
kenjiArai | 0:5b88d5760320 | 69 | |
kenjiArai | 0:5b88d5760320 | 70 | /* Get the address of non-secure code entry point to jump there */ |
kenjiArai | 0:5b88d5760320 | 71 | uint32_t entry_ptr = tfm_spm_hal_get_ns_entry_point(); |
kenjiArai | 0:5b88d5760320 | 72 | |
kenjiArai | 0:5b88d5760320 | 73 | /* Clears LSB of the function address to indicate the function-call |
kenjiArai | 0:5b88d5760320 | 74 | * will perform the switch from secure to non-secure |
kenjiArai | 0:5b88d5760320 | 75 | */ |
kenjiArai | 0:5b88d5760320 | 76 | ns_entry = (nsfptr_t) cmse_nsfptr_create(entry_ptr); |
kenjiArai | 0:5b88d5760320 | 77 | } |
kenjiArai | 0:5b88d5760320 | 78 | |
kenjiArai | 0:5b88d5760320 | 79 | int32_t tfm_core_init(void) |
kenjiArai | 0:5b88d5760320 | 80 | { |
kenjiArai | 0:5b88d5760320 | 81 | /* Enables fault handlers */ |
kenjiArai | 0:5b88d5760320 | 82 | enable_fault_handlers(); |
kenjiArai | 0:5b88d5760320 | 83 | |
kenjiArai | 0:5b88d5760320 | 84 | /* Configures the system reset request properties */ |
kenjiArai | 0:5b88d5760320 | 85 | system_reset_cfg(); |
kenjiArai | 0:5b88d5760320 | 86 | |
kenjiArai | 0:5b88d5760320 | 87 | /* Configures debug authentication */ |
kenjiArai | 0:5b88d5760320 | 88 | tfm_spm_hal_init_debug(); |
kenjiArai | 0:5b88d5760320 | 89 | |
kenjiArai | 0:5b88d5760320 | 90 | __enable_irq(); |
kenjiArai | 0:5b88d5760320 | 91 | |
kenjiArai | 0:5b88d5760320 | 92 | LOG_MSG("Secure image initializing!"); |
kenjiArai | 0:5b88d5760320 | 93 | |
kenjiArai | 0:5b88d5760320 | 94 | #ifdef TFM_CORE_DEBUG |
kenjiArai | 0:5b88d5760320 | 95 | printf("TFM level is: %d\r\n", TFM_LVL); |
kenjiArai | 0:5b88d5760320 | 96 | #endif |
kenjiArai | 0:5b88d5760320 | 97 | |
kenjiArai | 0:5b88d5760320 | 98 | tfm_core_validate_boot_data(); |
kenjiArai | 0:5b88d5760320 | 99 | |
kenjiArai | 0:5b88d5760320 | 100 | tfm_spm_hal_init_isolation_hw(); |
kenjiArai | 0:5b88d5760320 | 101 | |
kenjiArai | 0:5b88d5760320 | 102 | configure_ns_code(); |
kenjiArai | 0:5b88d5760320 | 103 | |
kenjiArai | 0:5b88d5760320 | 104 | /* Configures all interrupts to retarget NS state, except for |
kenjiArai | 0:5b88d5760320 | 105 | * secure peripherals |
kenjiArai | 0:5b88d5760320 | 106 | */ |
kenjiArai | 0:5b88d5760320 | 107 | nvic_interrupt_target_state_cfg(); |
kenjiArai | 0:5b88d5760320 | 108 | /* Enable secure peripherals interrupts */ |
kenjiArai | 0:5b88d5760320 | 109 | nvic_interrupt_enable(); |
kenjiArai | 0:5b88d5760320 | 110 | |
kenjiArai | 0:5b88d5760320 | 111 | #ifdef TFM_PSA_API |
kenjiArai | 0:5b88d5760320 | 112 | /* FixMe: In case of IPC messaging, scratch area must not be referenced |
kenjiArai | 0:5b88d5760320 | 113 | * These variables should be removed when all obsolete references are |
kenjiArai | 0:5b88d5760320 | 114 | * removed from the codebase |
kenjiArai | 0:5b88d5760320 | 115 | */ |
kenjiArai | 0:5b88d5760320 | 116 | tfm_scratch_area = NULL; |
kenjiArai | 0:5b88d5760320 | 117 | tfm_scratch_area_size = 0; |
kenjiArai | 0:5b88d5760320 | 118 | #else |
kenjiArai | 0:5b88d5760320 | 119 | tfm_scratch_area = |
kenjiArai | 0:5b88d5760320 | 120 | (uint8_t *)®ION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base); |
kenjiArai | 0:5b88d5760320 | 121 | tfm_scratch_area_size = |
kenjiArai | 0:5b88d5760320 | 122 | (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit) - |
kenjiArai | 0:5b88d5760320 | 123 | (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base); |
kenjiArai | 0:5b88d5760320 | 124 | #endif |
kenjiArai | 0:5b88d5760320 | 125 | return 0; |
kenjiArai | 0:5b88d5760320 | 126 | } |
kenjiArai | 0:5b88d5760320 | 127 | |
kenjiArai | 0:5b88d5760320 | 128 | static int32_t tfm_core_set_secure_exception_priorities(void) |
kenjiArai | 0:5b88d5760320 | 129 | { |
kenjiArai | 0:5b88d5760320 | 130 | uint32_t VECTKEY; |
kenjiArai | 0:5b88d5760320 | 131 | SCB_Type *scb = SCB; |
kenjiArai | 0:5b88d5760320 | 132 | uint32_t AIRCR; |
kenjiArai | 0:5b88d5760320 | 133 | |
kenjiArai | 0:5b88d5760320 | 134 | /* Set PRIS flag is AIRCR */ |
kenjiArai | 0:5b88d5760320 | 135 | AIRCR = scb->AIRCR; |
kenjiArai | 0:5b88d5760320 | 136 | VECTKEY = (~AIRCR & SCB_AIRCR_VECTKEYSTAT_Msk); |
kenjiArai | 0:5b88d5760320 | 137 | scb->AIRCR = SCB_AIRCR_PRIS_Msk | |
kenjiArai | 0:5b88d5760320 | 138 | VECTKEY | |
kenjiArai | 0:5b88d5760320 | 139 | (AIRCR & ~SCB_AIRCR_VECTKEY_Msk); |
kenjiArai | 0:5b88d5760320 | 140 | |
kenjiArai | 0:5b88d5760320 | 141 | /* FixMe: Explicitly set secure fault and Secure SVC priority to highest */ |
kenjiArai | 0:5b88d5760320 | 142 | |
kenjiArai | 0:5b88d5760320 | 143 | /* |
kenjiArai | 0:5b88d5760320 | 144 | * Set secure PendSV priority to the lowest in SECURE state. |
kenjiArai | 0:5b88d5760320 | 145 | * |
kenjiArai | 0:5b88d5760320 | 146 | * IMPORTANT NOTE: |
kenjiArai | 0:5b88d5760320 | 147 | * |
kenjiArai | 0:5b88d5760320 | 148 | * Although the priority of the secure PendSV must be the lowest possible |
kenjiArai | 0:5b88d5760320 | 149 | * among other interrupts in the Secure state, it must be ensured that |
kenjiArai | 0:5b88d5760320 | 150 | * PendSV is not preempted nor masked by Non-Secure interrupts to ensure |
kenjiArai | 0:5b88d5760320 | 151 | * the integrity of the Secure operation. |
kenjiArai | 0:5b88d5760320 | 152 | * When AIRCR.PRIS is set, the Non-Secure execution can act on |
kenjiArai | 0:5b88d5760320 | 153 | * FAULTMASK_NS, PRIMASK_NS or BASEPRI_NS register to boost its priority |
kenjiArai | 0:5b88d5760320 | 154 | * number up to the value 0x80. |
kenjiArai | 0:5b88d5760320 | 155 | * For this reason, set the priority of the PendSV interrupt to the next |
kenjiArai | 0:5b88d5760320 | 156 | * priority level configurable on the platform, just below 0x80. |
kenjiArai | 0:5b88d5760320 | 157 | */ |
kenjiArai | 0:5b88d5760320 | 158 | NVIC_SetPriority(PendSV_IRQn, (1 << (__NVIC_PRIO_BITS - 1)) - 1); |
kenjiArai | 0:5b88d5760320 | 159 | |
kenjiArai | 0:5b88d5760320 | 160 | return TFM_SUCCESS; |
kenjiArai | 0:5b88d5760320 | 161 | } |
kenjiArai | 0:5b88d5760320 | 162 | |
kenjiArai | 0:5b88d5760320 | 163 | void tfm_core_spm_request_handler(const struct tfm_exc_stack_t *svc_ctx) |
kenjiArai | 0:5b88d5760320 | 164 | { |
kenjiArai | 0:5b88d5760320 | 165 | uint32_t *res_ptr = (uint32_t *)&svc_ctx->R0; |
kenjiArai | 0:5b88d5760320 | 166 | |
kenjiArai | 0:5b88d5760320 | 167 | /* FixMe: check if caller partition is permitted to make an SPM request */ |
kenjiArai | 0:5b88d5760320 | 168 | |
kenjiArai | 0:5b88d5760320 | 169 | switch (svc_ctx->R0) { |
kenjiArai | 0:5b88d5760320 | 170 | case TFM_SPM_REQUEST_RESET_VOTE: |
kenjiArai | 0:5b88d5760320 | 171 | /* FixMe: this is a placeholder for checks to be performed before |
kenjiArai | 0:5b88d5760320 | 172 | * allowing execution of reset |
kenjiArai | 0:5b88d5760320 | 173 | */ |
kenjiArai | 0:5b88d5760320 | 174 | *res_ptr = TFM_SUCCESS; |
kenjiArai | 0:5b88d5760320 | 175 | break; |
kenjiArai | 0:5b88d5760320 | 176 | default: |
kenjiArai | 0:5b88d5760320 | 177 | *res_ptr = TFM_ERROR_INVALID_PARAMETER; |
kenjiArai | 0:5b88d5760320 | 178 | } |
kenjiArai | 0:5b88d5760320 | 179 | } |
kenjiArai | 0:5b88d5760320 | 180 | |
kenjiArai | 0:5b88d5760320 | 181 | int main(void) |
kenjiArai | 0:5b88d5760320 | 182 | { |
kenjiArai | 0:5b88d5760320 | 183 | if (tfm_core_init() != 0) { |
kenjiArai | 0:5b88d5760320 | 184 | /* Placeholder for error handling, currently ignored. */ |
kenjiArai | 0:5b88d5760320 | 185 | } |
kenjiArai | 0:5b88d5760320 | 186 | |
kenjiArai | 0:5b88d5760320 | 187 | if (tfm_spm_db_init() != SPM_ERR_OK) { |
kenjiArai | 0:5b88d5760320 | 188 | /* Placeholder for error handling, currently ignored. */ |
kenjiArai | 0:5b88d5760320 | 189 | } |
kenjiArai | 0:5b88d5760320 | 190 | |
kenjiArai | 0:5b88d5760320 | 191 | tfm_spm_hal_setup_isolation_hw(); |
kenjiArai | 0:5b88d5760320 | 192 | |
kenjiArai | 0:5b88d5760320 | 193 | #ifndef TFM_PSA_API |
kenjiArai | 0:5b88d5760320 | 194 | tfm_spm_partition_set_state(TFM_SP_CORE_ID, SPM_PARTITION_STATE_RUNNING); |
kenjiArai | 0:5b88d5760320 | 195 | |
kenjiArai | 0:5b88d5760320 | 196 | extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[]; |
kenjiArai | 0:5b88d5760320 | 197 | uint32_t psp_stack_bottom = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Base; |
kenjiArai | 0:5b88d5760320 | 198 | |
kenjiArai | 0:5b88d5760320 | 199 | __set_PSPLIM(psp_stack_bottom); |
kenjiArai | 0:5b88d5760320 | 200 | |
kenjiArai | 0:5b88d5760320 | 201 | if (tfm_spm_partition_init() != SPM_ERR_OK) { |
kenjiArai | 0:5b88d5760320 | 202 | /* Certain systems might refuse to boot altogether if partitions fail |
kenjiArai | 0:5b88d5760320 | 203 | * to initialize. This is a placeholder for such an error handler |
kenjiArai | 0:5b88d5760320 | 204 | */ |
kenjiArai | 0:5b88d5760320 | 205 | } |
kenjiArai | 0:5b88d5760320 | 206 | |
kenjiArai | 0:5b88d5760320 | 207 | /* |
kenjiArai | 0:5b88d5760320 | 208 | * Prioritise secure exceptions to avoid NS being able to pre-empt |
kenjiArai | 0:5b88d5760320 | 209 | * secure SVC or SecureFault. Do it before PSA API initialization. |
kenjiArai | 0:5b88d5760320 | 210 | */ |
kenjiArai | 0:5b88d5760320 | 211 | tfm_core_set_secure_exception_priorities(); |
kenjiArai | 0:5b88d5760320 | 212 | |
kenjiArai | 0:5b88d5760320 | 213 | /* We close the TFM_SP_CORE_ID partition, because its only purpose is |
kenjiArai | 0:5b88d5760320 | 214 | * to be able to pass the state checks for the tests started from secure. |
kenjiArai | 0:5b88d5760320 | 215 | */ |
kenjiArai | 0:5b88d5760320 | 216 | tfm_spm_partition_set_state(TFM_SP_CORE_ID, SPM_PARTITION_STATE_CLOSED); |
kenjiArai | 0:5b88d5760320 | 217 | tfm_spm_partition_set_state(TFM_SP_NON_SECURE_ID, |
kenjiArai | 0:5b88d5760320 | 218 | SPM_PARTITION_STATE_RUNNING); |
kenjiArai | 0:5b88d5760320 | 219 | |
kenjiArai | 0:5b88d5760320 | 220 | #ifdef TFM_CORE_DEBUG |
kenjiArai | 0:5b88d5760320 | 221 | /* Jumps to non-secure code */ |
kenjiArai | 0:5b88d5760320 | 222 | LOG_MSG("Jumping to non-secure code..."); |
kenjiArai | 0:5b88d5760320 | 223 | #endif |
kenjiArai | 0:5b88d5760320 | 224 | |
kenjiArai | 0:5b88d5760320 | 225 | jump_to_ns_code(); |
kenjiArai | 0:5b88d5760320 | 226 | #else |
kenjiArai | 0:5b88d5760320 | 227 | /* |
kenjiArai | 0:5b88d5760320 | 228 | * Prioritise secure exceptions to avoid NS being able to pre-empt |
kenjiArai | 0:5b88d5760320 | 229 | * secure SVC or SecureFault. Do it before PSA API initialization. |
kenjiArai | 0:5b88d5760320 | 230 | */ |
kenjiArai | 0:5b88d5760320 | 231 | tfm_core_set_secure_exception_priorities(); |
kenjiArai | 0:5b88d5760320 | 232 | tfm_spm_init(); |
kenjiArai | 0:5b88d5760320 | 233 | #endif |
kenjiArai | 0:5b88d5760320 | 234 | } |