/* * Copyright (c) 2006-2019, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2019-10-28 tyx the first version. */ #include #ifdef ARM_CM33_ENABLE_TRUSTZONE extern void TZ_InitContextSystem_S(void); extern rt_uint32_t TZ_AllocModuleContext_S (rt_uint32_t module); extern rt_uint32_t TZ_FreeModuleContext_S(rt_uint32_t id); extern rt_uint32_t TZ_LoadContext_S(rt_uint32_t id); extern rt_uint32_t TZ_StoreContext_S(rt_uint32_t id); #else void TZ_InitContextSystem_S(void){} rt_uint32_t TZ_AllocModuleContext_S (rt_uint32_t module){return 0;} rt_uint32_t TZ_FreeModuleContext_S(rt_uint32_t id) {return 0;} rt_uint32_t TZ_LoadContext_S(rt_uint32_t id){return 0;}; rt_uint32_t TZ_StoreContext_S(rt_uint32_t id){return 0;}; #endif extern int tzcall(int id, rt_ubase_t arg0, rt_ubase_t arg1, rt_ubase_t arg2); #define TZ_INIT_CONTEXT_ID (0x1001) #define TZ_ALLOC_CONTEXT_ID (0x1002) #define TZ_FREE_CONTEXT_ID (0x1003) rt_ubase_t rt_trustzone_current_context; #if defined(__CC_ARM) static __inline rt_uint32_t __get_IPSR(void) { register rt_uint32_t result __asm("ipsr"); return(result); } #elif defined(__CLANG_ARM) __attribute__((always_inline)) static __inline rt_uint32_t __get_IPSR(void) { rt_uint32_t result; __asm volatile ("MRS %0, ipsr" : "=r" (result) ); return(result); } #elif defined(__IAR_SYSTEMS_ICC__) _Pragma("inline=forced") static inline int __get_IPSR(int value) { rt_uint32_t result; asm("MRS %0, ipsr" : "=r"(result)); return result; } #elif defined(__GNUC__) __attribute__((always_inline)) static inline rt_uint32_t __get_IPSR(void) { rt_uint32_t result; __asm volatile ("MRS %0, ipsr" : "=r" (result) ); return(result); } #endif void rt_trustzone_init(void) { static rt_uint8_t _init; if (_init) return; tzcall(TZ_INIT_CONTEXT_ID, 0, 0, 0); _init = 1; } rt_err_t rt_trustzone_enter(rt_ubase_t module) { rt_trustzone_init(); if (tzcall(TZ_ALLOC_CONTEXT_ID, module, 0, 0)) { return RT_EOK; } return -RT_ERROR; } rt_err_t rt_trustzone_exit(void) { tzcall(TZ_FREE_CONTEXT_ID, 0, 0, 0); return RT_EOK; } void rt_trustzone_context_store(rt_ubase_t context) { TZ_StoreContext_S(context); } void rt_trustzone_context_load(rt_ubase_t context) { TZ_LoadContext_S(context); } int rt_secure_svc_handle(int svc_id, rt_ubase_t arg0, rt_ubase_t arg1, rt_ubase_t arg2) { rt_ubase_t tmp; int res = 0; switch (svc_id) { case TZ_INIT_CONTEXT_ID: TZ_InitContextSystem_S(); break; case TZ_ALLOC_CONTEXT_ID: res = TZ_AllocModuleContext_S(arg0); if (res <= 0) { rt_kprintf("Alloc Context Failed\n"); } else { rt_trustzone_current_context = res; TZ_LoadContext_S(res); } break; case TZ_FREE_CONTEXT_ID: TZ_FreeModuleContext_S(rt_trustzone_current_context); rt_trustzone_current_context = 0; break; } return res; }