summaryrefslogtreecommitdiff
path: root/core/arch/arm/sm
diff options
context:
space:
mode:
Diffstat (limited to 'core/arch/arm/sm')
-rw-r--r--core/arch/arm/sm/psci.c166
-rw-r--r--core/arch/arm/sm/sm.c58
-rw-r--r--core/arch/arm/sm/sm_a32.S291
-rw-r--r--core/arch/arm/sm/sm_private.h38
-rw-r--r--core/arch/arm/sm/std_smc.c77
-rw-r--r--core/arch/arm/sm/sub.mk3
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