diff options
Diffstat (limited to 'core/arch/arm/sm')
-rw-r--r-- | core/arch/arm/sm/psci.c | 166 | ||||
-rw-r--r-- | core/arch/arm/sm/sm.c | 58 | ||||
-rw-r--r-- | core/arch/arm/sm/sm_a32.S | 291 | ||||
-rw-r--r-- | core/arch/arm/sm/sm_private.h | 38 | ||||
-rw-r--r-- | core/arch/arm/sm/std_smc.c | 77 | ||||
-rw-r--r-- | core/arch/arm/sm/sub.mk | 3 |
6 files changed, 633 insertions, 0 deletions
diff --git a/core/arch/arm/sm/psci.c b/core/arch/arm/sm/psci.c new file mode 100644 index 0000000..b2bd645 --- /dev/null +++ b/core/arch/arm/sm/psci.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * All rights reserved. + * + * Peng Fan <peng.fan@nxp.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <console.h> +#include <kernel/generic_boot.h> +#include <kernel/thread.h> +#include <stdint.h> +#include <sm/optee_smc.h> +#include <sm/psci.h> +#include <sm/sm.h> +#include <trace.h> + +__weak uint32_t psci_version(void) +{ + return PSCI_VERSION_0_2; +} + +__weak int psci_cpu_suspend(uint32_t power_state __unused, + uintptr_t entry __unused, + uint32_t context_id __unused) +{ + return PSCI_RET_NOT_SUPPORTED; +} + +__weak int psci_cpu_off(void) +{ + return PSCI_RET_NOT_SUPPORTED; +} + +__weak int psci_cpu_on(uint32_t cpu_id __unused, uint32_t entry __unused, + uint32_t context_id __unused) +{ + return PSCI_RET_NOT_SUPPORTED; +} + +__weak int psci_affinity_info(uint32_t affinity __unused, + uint32_t lowest_affnity_level __unused) +{ + return PSCI_RET_NOT_SUPPORTED; +} + +__weak int psci_migrate(uint32_t cpu_id __unused) +{ + return PSCI_RET_NOT_SUPPORTED; +} + +__weak int psci_migrate_info_type(void) +{ + return PSCI_RET_NOT_SUPPORTED; +} + +__weak int psci_migrate_info_up_cpu(void) +{ + return PSCI_RET_NOT_SUPPORTED; +} + +__weak void psci_system_off(void) +{ +} + +__weak void psci_system_reset(void) +{ +} + +__weak int psci_features(uint32_t psci_fid __unused) +{ + return PSCI_RET_NOT_SUPPORTED; +} + +__weak int psci_node_hw_state(uint32_t cpu_id __unused, + uint32_t power_level __unused) +{ + return PSCI_RET_NOT_SUPPORTED; +} + +__weak int psci_stat_residency(uint32_t cpu_id __unused, + uint32_t power_state __unused) +{ + return PSCI_RET_NOT_SUPPORTED; +} + +__weak int psci_stat_count(uint32_t cpu_id __unused, + uint32_t power_state __unused) +{ + return PSCI_RET_NOT_SUPPORTED; +} + +void tee_psci_handler(struct thread_smc_args *args) +{ + uint32_t smc_fid = args->a0; + uint32_t a1 = args->a1; + uint32_t a2 = args->a2; + uint32_t a3 = args->a3; + + switch (smc_fid) { + case PSCI_VERSION: + args->a0 = psci_version(); + break; + case PSCI_CPU_SUSPEND: + args->a0 = psci_cpu_suspend(a1, a2, a3); + break; + case PSCI_CPU_OFF: + args->a0 = psci_cpu_off(); + break; + case PSCI_CPU_ON: + args->a0 = psci_cpu_on(a1, a2, a3); + break; + case PSCI_AFFINITY_INFO: + args->a0 = psci_affinity_info(a1, a2); + break; + case PSCI_MIGRATE: + args->a0 = psci_migrate(a1); + break; + case PSCI_MIGRATE_INFO_TYPE: + args->a0 = psci_migrate_info_type(); + break; + case PSCI_MIGRATE_INFO_UP_CPU: + args->a0 = psci_migrate_info_up_cpu(); + break; + case PSCI_SYSTEM_OFF: + psci_system_off(); + while (1) + ; + break; + case PSCI_SYSTEM_RESET: + psci_system_off(); + while (1) + ; + break; + case PSCI_PSCI_FEATURES: + args->a0 = psci_features(a1); + break; + case PSCI_NODE_HW_STATE: + args->a0 = psci_node_hw_state(a1, a2); + break; + default: + args->a0 = OPTEE_SMC_RETURN_UNKNOWN_FUNCTION; + break; + } +} diff --git a/core/arch/arm/sm/sm.c b/core/arch/arm/sm/sm.c new file mode 100644 index 0000000..4a0c0f6 --- /dev/null +++ b/core/arch/arm/sm/sm.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016, Linaro Limited + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <arm.h> +#include <compiler.h> +#include <kernel/misc.h> +#include <platform_config.h> +#include <sm/optee_smc.h> +#include <sm/sm.h> +#include <sm/std_smc.h> +#include <string.h> +#include "sm_private.h" + +bool sm_from_nsec(struct sm_ctx *ctx) +{ + uint32_t *nsec_r0 = (uint32_t *)(&ctx->nsec.r0); + +#ifdef CFG_PSCI_ARM32 + if (OPTEE_SMC_OWNER_NUM(*nsec_r0) == OPTEE_SMC_OWNER_STANDARD) { + smc_std_handler((struct thread_smc_args *)nsec_r0); + return false; /* Return to non secure state */ + } +#endif + + sm_save_modes_regs(&ctx->nsec.mode_regs); + sm_restore_modes_regs(&ctx->sec.mode_regs); + + memcpy(&ctx->sec.r0, nsec_r0, sizeof(uint32_t) * 8); + if (OPTEE_SMC_IS_FAST_CALL(ctx->sec.r0)) + ctx->sec.mon_lr = (uint32_t)&thread_vector_table.fast_smc_entry; + else + ctx->sec.mon_lr = (uint32_t)&thread_vector_table.std_smc_entry; + return true; /* return into secure state */ +} diff --git a/core/arch/arm/sm/sm_a32.S b/core/arch/arm/sm/sm_a32.S new file mode 100644 index 0000000..9c6becd --- /dev/null +++ b/core/arch/arm/sm/sm_a32.S @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2016, Linaro Limited + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <asm.S> +#include <arm.h> +#include <arm32_macros.S> +#include <kernel/unwind.h> +#include <sm/optee_smc.h> +#include <sm/teesmc_opteed.h> +#include <sm/teesmc_opteed_macros.h> +#include <asm-defines.h> + + .section .text.sm_asm + +FUNC sm_save_modes_regs , : +UNWIND( .fnstart) +UNWIND( .cantunwind) + /* User mode registers has to be saved from system mode */ + cps #CPSR_MODE_SYS + stm r0!, {sp, lr} + + cps #CPSR_MODE_IRQ + mrs r2, spsr + stm r0!, {r2, sp, lr} + + cps #CPSR_MODE_FIQ + mrs r2, spsr + stm r0!, {r2, sp, lr} + + cps #CPSR_MODE_SVC + mrs r2, spsr + stm r0!, {r2, sp, lr} + + cps #CPSR_MODE_ABT + mrs r2, spsr + stm r0!, {r2, sp, lr} + + cps #CPSR_MODE_UND + mrs r2, spsr + stm r0!, {r2, sp, lr} + + cps #CPSR_MODE_MON + bx lr +UNWIND( .fnend) +END_FUNC sm_save_modes_regs + +/* Restores the mode specific registers */ +FUNC sm_restore_modes_regs , : +UNWIND( .fnstart) +UNWIND( .cantunwind) + /* User mode registers has to be saved from system mode */ + cps #CPSR_MODE_SYS + ldm r0!, {sp, lr} + + cps #CPSR_MODE_IRQ + ldm r0!, {r2, sp, lr} + msr spsr_fsxc, r2 + + cps #CPSR_MODE_FIQ + ldm r0!, {r2, sp, lr} + msr spsr_fsxc, r2 + + cps #CPSR_MODE_SVC + ldm r0!, {r2, sp, lr} + msr spsr_fsxc, r2 + + cps #CPSR_MODE_ABT + ldm r0!, {r2, sp, lr} + msr spsr_fsxc, r2 + + cps #CPSR_MODE_UND + ldm r0!, {r2, sp, lr} + msr spsr_fsxc, r2 + + cps #CPSR_MODE_MON + bx lr +UNWIND( .fnend) +END_FUNC sm_restore_modes_regs + +/* + * stack_tmp is used as stack, the top of the stack is reserved to hold + * struct sm_ctx, everything below is for normal stack usage. As several + * different CPU modes are using the same stack it's important that switch + * of CPU mode isn't done until one mode is done. This means FIQ, IRQ and + * Async abort has to be masked while using stack_tmp. + */ +LOCAL_FUNC sm_smc_entry , : +UNWIND( .fnstart) +UNWIND( .cantunwind) + srsdb sp!, #CPSR_MODE_MON + push {r0-r7} + + clrex /* Clear the exclusive monitor */ + + /* Find out if we're doing an secure or non-secure entry */ + read_scr r1 + tst r1, #SCR_NS + bne .smc_from_nsec + + /* + * As we're coming from secure world (NS bit cleared) the stack + * pointer points to sm_ctx.sec.r0 at this stage. After the + * instruction below the stack pointer points to sm_ctx. + */ + sub sp, sp, #(SM_CTX_SEC + SM_SEC_CTX_R0) + + /* Save secure context */ + add r0, sp, #SM_CTX_SEC + bl sm_save_modes_regs + + /* + * On FIQ exit we're restoring the non-secure context unchanged, on + * all other exits we're shifting r1-r4 from secure context into + * r0-r3 in non-secure context. + */ + add r8, sp, #(SM_CTX_SEC + SM_SEC_CTX_R0) + ldm r8, {r0-r4} + mov_imm r9, TEESMC_OPTEED_RETURN_FIQ_DONE + cmp r0, r9 + addne r8, sp, #(SM_CTX_NSEC + SM_NSEC_CTX_R0) + stmne r8, {r1-r4} + + /* Restore non-secure context */ + add r0, sp, #SM_CTX_NSEC + bl sm_restore_modes_regs + +.sm_ret_to_nsec: + /* + * Return to non-secure world + */ + add r0, sp, #(SM_CTX_NSEC + SM_NSEC_CTX_R8) + ldm r0, {r8-r12} + + /* Update SCR */ + read_scr r0 + orr r0, r0, #(SCR_NS | SCR_FIQ) /* Set NS and FIQ bit in SCR */ + write_scr r0 + + add sp, sp, #(SM_CTX_NSEC + SM_NSEC_CTX_R0) + b .sm_exit + +.smc_from_nsec: + /* + * As we're coming from non-secure world (NS bit set) the stack + * pointer points to sm_ctx.nsec.r0 at this stage. After the + * instruction below the stack pointer points to sm_ctx. + */ + sub sp, sp, #(SM_CTX_NSEC + SM_NSEC_CTX_R0) + + bic r1, r1, #(SCR_NS | SCR_FIQ) /* Clear NS and FIQ bit in SCR */ + write_scr r1 + + add r0, sp, #(SM_CTX_NSEC + SM_NSEC_CTX_R8) + stm r0, {r8-r12} + + mov r0, sp + bl sm_from_nsec + cmp r0, #0 + beq .sm_ret_to_nsec + + /* + * Continue into secure world + */ + add sp, sp, #(SM_CTX_SEC + SM_SEC_CTX_R0) + +.sm_exit: + pop {r0-r7} + rfefd sp! +UNWIND( .fnend) +END_FUNC sm_smc_entry + +/* + * FIQ handling + * + * Saves CPU context in the same way as sm_smc_entry() above. The CPU + * context will later be restored by sm_smc_entry() when handling a return + * from FIQ. + */ +LOCAL_FUNC sm_fiq_entry , : +UNWIND( .fnstart) +UNWIND( .cantunwind) + /* FIQ has a +4 offset for lr compared to preferred return address */ + sub lr, lr, #4 + /* sp points just past struct sm_sec_ctx */ + srsdb sp!, #CPSR_MODE_MON + push {r0-r7} + + clrex /* Clear the exclusive monitor */ + + /* + * As we're coming from non-secure world the stack pointer points + * to sm_ctx.nsec.r0 at this stage. After the instruction below the + * stack pointer points to sm_ctx. + */ + sub sp, sp, #(SM_CTX_NSEC + SM_NSEC_CTX_R0) + + /* Update SCR */ + read_scr r1 + bic r1, r1, #(SCR_NS | SCR_FIQ) /* Clear NS and FIQ bit in SCR */ + write_scr r1 + + /* Save non-secure context */ + add r0, sp, #SM_CTX_NSEC + bl sm_save_modes_regs + stm r0!, {r8-r12} + + /* Set FIQ entry */ + ldr r0, =(thread_vector_table + THREAD_VECTOR_TABLE_FIQ_ENTRY) + str r0, [sp, #(SM_CTX_SEC + SM_SEC_CTX_MON_LR)] + + /* Restore secure context */ + add r0, sp, #SM_CTX_SEC + bl sm_restore_modes_regs + + add sp, sp, #(SM_CTX_SEC + SM_SEC_CTX_MON_LR) + + rfefd sp! +UNWIND( .fnend) +END_FUNC sm_fiq_entry + + .align 5 +LOCAL_FUNC sm_vect_table , : +UNWIND( .fnstart) +UNWIND( .cantunwind) + b . /* Reset */ + b . /* Undefined instruction */ + b sm_smc_entry /* Secure monitor call */ + b . /* Prefetch abort */ + b . /* Data abort */ + b . /* Reserved */ + b . /* IRQ */ + b sm_fiq_entry /* FIQ */ +UNWIND( .fnend) +END_FUNC sm_vect_table + +/* void sm_init(vaddr_t stack_pointer); */ +FUNC sm_init , : +UNWIND( .fnstart) + /* Set monitor stack */ + mrs r1, cpsr + cps #CPSR_MODE_MON + /* Point just beyond sm_ctx.sec */ + sub sp, r0, #(SM_CTX_SIZE - SM_CTX_NSEC) + msr cpsr, r1 + + /* Set monitor vector (MVBAR) */ + ldr r0, =sm_vect_table + write_mvbar r0 + + bx lr +END_FUNC sm_init + + +/* struct sm_nsec_ctx *sm_get_nsec_ctx(void); */ +FUNC sm_get_nsec_ctx , : + mrs r1, cpsr + cps #CPSR_MODE_MON + mov r0, sp + msr cpsr, r1 + + /* + * As we're in secure mode mon_sp points just beyond sm_ctx.sec + * which is sm_ctx.nsec + */ + bx lr +END_FUNC sm_get_nsec_ctx diff --git a/core/arch/arm/sm/sm_private.h b/core/arch/arm/sm/sm_private.h new file mode 100644 index 0000000..0b41bec --- /dev/null +++ b/core/arch/arm/sm/sm_private.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, Linaro Limited + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SM_PRIVATE_H +#define SM_PRIVATE_H + +/* Returns true if returning to sec, false if returning to nsec */ +bool sm_from_nsec(struct sm_ctx *ctx); + +void sm_save_modes_regs(struct sm_mode_regs *regs); +void sm_restore_modes_regs(struct sm_mode_regs *regs); + +#endif /*SM_PRIVATE_H*/ + diff --git a/core/arch/arm/sm/std_smc.c b/core/arch/arm/sm/std_smc.c new file mode 100644 index 0000000..5e5bb81 --- /dev/null +++ b/core/arch/arm/sm/std_smc.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * All rights reserved. + * + * Peng Fan <peng.fan@nxp.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdint.h> +#include <sm/optee_smc.h> +#include <sm/psci.h> +#include <sm/sm.h> +#include <sm/std_smc.h> +#include <tee/uuid.h> +#include <trace.h> + +static const TEE_UUID uuid = { + 0x5f8b97df, 0x2d0d, 0x4ad2, + {0x98, 0xd2, 0x74, 0xf4, 0x38, 0x27, 0x98, 0xbb}, +}; + +void smc_std_handler(struct thread_smc_args *args) +{ + uint32_t smc_fid = args->a0; + + if (is_psci_fid(smc_fid)) { + tee_psci_handler(args); + return; + } + + switch (smc_fid) { + case ARM_STD_SVC_CALL_COUNT: + /* PSCI is the only STD service implemented */ + args->a0 = PSCI_NUM_CALLS; + break; + case ARM_STD_SVC_UID: + args->a0 = uuid.timeLow; + args->a1 = (uuid.timeHiAndVersion << 16) | uuid.timeMid; + args->a2 = (uuid.clockSeqAndNode[3] << 24) | + (uuid.clockSeqAndNode[2] << 16) | + (uuid.clockSeqAndNode[1] << 8) | + uuid.clockSeqAndNode[0]; + args->a3 = (uuid.clockSeqAndNode[7] << 24) | + (uuid.clockSeqAndNode[6] << 16) | + (uuid.clockSeqAndNode[5] << 8) | + uuid.clockSeqAndNode[4]; + break; + case ARM_STD_SVC_VERSION: + args->a0 = STD_SVC_VERSION_MAJOR; + args->a1 = STD_SVC_VERSION_MINOR; + break; + default: + args->a0 = OPTEE_SMC_RETURN_UNKNOWN_FUNCTION; + break; + } +} diff --git a/core/arch/arm/sm/sub.mk b/core/arch/arm/sm/sub.mk new file mode 100644 index 0000000..4e28e29 --- /dev/null +++ b/core/arch/arm/sm/sub.mk @@ -0,0 +1,3 @@ +srcs-y += sm_a32.S +srcs-y += sm.c +srcs-$(CFG_PSCI_ARM32) += std_smc.c psci.c |