From: liushiwei <liushiwei@eswincomputing.com>
To: opensbi@lists.infradead.org
Subject: [PATCH 1/1] Add RISC-V TEE support
Date: Wed, 11 Jan 2023 10:01:59 +0800 [thread overview]
Message-ID: <20230111020159.1234-1-liushiwei@eswincomputing.com> (raw)
RISC-V Trusted Executable Environment security software includes
linux, opensbi, and OP-TEE OS. linux is the non-secure domain,
and OP-TEE OS is the secure domain. At boot time, opensbi boots
OP-TEE OS and then starts linux. At runtime, opensbi acts as a
secure monitor, responsible for context saving and restoring
when switching between linux and OP-TEE OS.
TEE function is off by default, when using configuration is
added in the config and objects file, such as
platform/generic/configs/defconfig add CONFIG_SBI_ECALL_TEE = y,
In the platform/generic/objects.mk add CONFIG_TEE_LOAD_ADDR =
0x27c000000, CONFIG_TEE_LOAD_ADDR is the starting address
of the OP-TEE OS.
Signed-off-by: liushiwei <liushiwei@eswincomputing.com>
---
include/sbi/sbi_ecall_interface.h | 3 +
include/sbi_utils/tee/tee_context.h | 104 ++++++++++
include/sbi_utils/tee/tee_sm_dispatcher.h | 44 +++++
include/sbi_utils/tee/teeecall_opteed.h | 145 ++++++++++++++
lib/sbi/Kconfig | 4 +
lib/sbi/objects.mk | 3 +
lib/sbi/sbi_ecall_tee.c | 19 ++
lib/sbi/sbi_init.c | 5 +
lib/utils/tee/objects.mk | 16 ++
lib/utils/tee/tee_context.S | 189 ++++++++++++++++++
lib/utils/tee/tee_sm_dispatcher.c | 228 ++++++++++++++++++++++
11 files changed, 760 insertions(+)
create mode 100644 include/sbi_utils/tee/tee_context.h
create mode 100644 include/sbi_utils/tee/tee_sm_dispatcher.h
create mode 100644 include/sbi_utils/tee/teeecall_opteed.h
create mode 100644 lib/sbi/sbi_ecall_tee.c
create mode 100644 lib/utils/tee/objects.mk
create mode 100644 lib/utils/tee/tee_context.S
create mode 100644 lib/utils/tee/tee_sm_dispatcher.c
diff --git a/include/sbi/sbi_ecall_interface.h b/include/sbi/sbi_ecall_interface.h
index a3f2bf4..5ed5bd5 100644
--- a/include/sbi/sbi_ecall_interface.h
+++ b/include/sbi/sbi_ecall_interface.h
@@ -238,6 +238,9 @@ enum sbi_pmu_ctr_type {
#define SBI_EXT_VENDOR_END 0x09FFFFFF
#define SBI_EXT_FIRMWARE_START 0x0A000000
#define SBI_EXT_FIRMWARE_END 0x0AFFFFFF
+#define SBI_EXT_TEE_START 0x0A000000
+#define SBI_EXT_TEE_END 0x0AFFFFFF
+#define SBI_EXT_TEE 0xFFFFEEEE
/* SBI return error codes */
#define SBI_SUCCESS 0
diff --git a/include/sbi_utils/tee/tee_context.h b/include/sbi_utils/tee/tee_context.h
new file mode 100644
index 0000000..467ff00
--- /dev/null
+++ b/include/sbi_utils/tee/tee_context.h
@@ -0,0 +1,104 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2023 Beijing ESWIN Computing Technology Co., Ltd.
+ *
+ * Authors:
+ * Chen Chaokai <chenchaokai@eswincomputing.com>
+ * Liu Shiwei <liushiwei@eswincomputing.com>
+ */
+
+#ifndef __TEE_CONTEXT_H__
+#define __TEE_CONTEXT_H__
+
+#define TEE_SECURE_FLAG (0xFFFF0000)
+#define TEE_NON_SECURE_FLAG (0xFFFFFFFF)
+
+#define TEE_HART_COUNT (0x8)
+#define OPTEED_CORE_COUNT TEE_HART_COUNT
+
+#define ECALL_TEE_SHIFT (0x10)
+#define MCAUSE_INTR (1)
+
+/* The secure and non-secure contexts size are used to
+ * store the regisers respectively.
+ * The macros defined below are used to setup the spaces
+ * for secure and non-secure contexts.
+ * */
+
+#define SBI_SAVE_CONTEXT_sepc 35
+#define SBI_SAVE_CONTEXT_satp 36
+#define SBI_SAVE_CONTEXT_sstatus 37
+#define SBI_SAVE_CONTEXT_sie 38
+#define SBI_SAVE_CONTEXT_stvec 39
+#define SBI_SAVE_CONTEXT_sscratch 40
+#define SBI_SAVE_CONTEXT_scounteren 41
+#define SBI_SAVE_CONTEXT_scause 42
+#define SBI_SAVE_CONTEXT_stval 43
+#define SBI_SAVE_CONTEXT_sip 44
+#define SBI_SAVE_CONTEXT_last 45
+
+/** Get offset of member with name 'x' in sbi_save_context */
+#define SBI_SAVE_CONTEXT_OFFSET(x) ((SBI_SAVE_CONTEXT_##x) * __SIZEOF_POINTER__)
+/** Size (in bytes) of sbi_trap_regs */
+#define SBI_SAVE_CONTEXT_SIZE SBI_SAVE_CONTEXT_OFFSET(last)
+
+#ifndef __ASSEMBLER__
+#include <sbi/sbi_types.h>
+
+typedef uint32_t optee_vector_isn_t;
+
+typedef struct optee_vectors {
+ optee_vector_isn_t yield_smc_entry;
+ optee_vector_isn_t fast_smc_entry;
+ optee_vector_isn_t cpu_on_entry;
+ optee_vector_isn_t cpu_off_entry;
+ optee_vector_isn_t cpu_resume_entry;
+ optee_vector_isn_t cpu_suspend_entry;
+ optee_vector_isn_t fiq_entry;
+ optee_vector_isn_t system_off_entry;
+ optee_vector_isn_t system_reset_entry;
+} optee_vectors_t;
+
+struct sbi_save_context {
+ struct sbi_trap_regs regs;
+ unsigned long sepc;
+ unsigned long satp;
+ unsigned long sstatus;
+ unsigned long sie;
+ unsigned long stvec;
+ unsigned long sscratch;
+ unsigned long scounteren;
+ unsigned long scause;
+ unsigned long stval;
+ unsigned long sip;
+};
+
+/**
+ * Save opensbi context and enter into TEE OS
+ *
+ * @param cpu_ctx_addr Address of struct sbi_save_context to save context.
+ *
+ * @return Return 0 on success and negative value on failure
+ */
+int entry_teeos(unsigned long cpu_ctx_addr);
+
+/**
+ * Restore openSBI context and continue running openSBI
+ *
+ * @param cpu_ctx_addr Address of struct sbi_trap_regs to restore context.
+ * @param ret Return value coming from TEE OS.
+ *
+ */
+void teeos_entry_done(unsigned long cpu_ctx_addr);
+
+/**
+ * Load supervisor context and return to supervisor mode
+ *
+ * @param ctx_addr Address of struct sbi_trap_regs to restore context.
+ *
+ */
+void restore_to_supervisor(unsigned long ctx_addr);
+
+#endif /* __ASSEMBLER__ */
+#endif /* __TEE_CONTEXT_H__ */
diff --git a/include/sbi_utils/tee/tee_sm_dispatcher.h b/include/sbi_utils/tee/tee_sm_dispatcher.h
new file mode 100644
index 0000000..1c971a4
--- /dev/null
+++ b/include/sbi_utils/tee/tee_sm_dispatcher.h
@@ -0,0 +1,44 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2023 Beijing ESWIN Computing Technology Co., Ltd.
+ *
+ * Authors:
+ * Chen Chaokai <chenchaokai@eswincomputing.com>
+ * Liu Shiwei <liushiwei@eswincomputing.com>
+ */
+
+#ifndef __TEE_SM_DISPATCHER_H__
+#define __TEE_SM_DISPATCHER_H__
+
+#define TEE_ENTRY_ADDR TEE_LOAD_ADDR
+
+#ifndef __ASSEMBLER__
+#include <sbi/sbi_types.h>
+
+/**
+ * Initialize tee os
+ *
+ * @return Return 0 on success and negative value on failure
+ */
+void tee_os_init(void);
+
+/**
+ * TEE dispatcher handler which interact bewteen REE and TEE
+ *
+ * @param extid is SBI_EXT_TEE
+ * @param funcid Function id for this ecall trap.
+ * @param args Parameter passed from supervisor mode
+ * @param out_value Output value
+ * @param out_trap Trap detail
+ *
+ * @return Return 0 on success and negative value on failure
+ */
+
+int sbi_ecall_tee_handler(ulong extid, ulong funcid,
+ const struct sbi_trap_regs *regs,
+ ulong *out_val,
+ struct sbi_trap_info *out_trap);
+
+#endif /* __ASSEMBLER__ */
+#endif /* __TEE_SM_DISPATCHER_H__ */
diff --git a/include/sbi_utils/tee/teeecall_opteed.h b/include/sbi_utils/tee/teeecall_opteed.h
new file mode 100644
index 0000000..e953a36
--- /dev/null
+++ b/include/sbi_utils/tee/teeecall_opteed.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Copyright (c) 2014, Linaro Limited. All rights reserved. */
+
+#ifndef __TEEECALL_OPTEED_H__
+#define __TEEECALL_OPTEED_H__
+
+#define ECALL_TYPE_FAST (1)
+#define ECALL_TYPE_YEILD (0)
+
+#define FUNCID_TYPE_SHIFT (31)
+#define FUNCID_TYPE_MASK (0x1)
+#define ECALL_32 (0)
+#define FUNCID_CC_SHIFT (30)
+#define FUNCID_OEN_SHIFT (24)
+
+#define FUNCID_NUM_MASK (0xffff)
+
+#define GET_ECALL_TYPE(id) (((id) >> FUNCID_TYPE_SHIFT) & \
+ FUNCID_TYPE_MASK)
+
+
+#define TEEECALL_OPTEED_RV(func_num) \
+ ((ECALL_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+ ((ECALL_32) << FUNCID_CC_SHIFT) | \
+ (62 << FUNCID_OEN_SHIFT) | \
+ ((func_num) & FUNCID_NUM_MASK))
+
+
+/*
+ * This file specify SMC function IDs used when returning from TEE to the
+ * secure monitor.
+ *
+ * All SMC Function IDs indicates SMC32 Calling Convention but will carry
+ * full 64 bit values in the argument registers if invoked from Aarch64
+ * mode. This violates the SMC Calling Convention, but since this
+ * convention only coveres API towards Normwal World it's something that
+ * only concerns the OP-TEE Dispatcher in ARM Trusted Firmware and OP-TEE
+ * OS at Secure EL1.
+ */
+
+/*
+ * Issued when returning from initial entry.
+ *
+ * Register usage:
+ * r0/x0 SMC Function ID, TEEECALL_OPTEED_RETURN_ENTRY_DONE
+ * r1/x1 Pointer to entry vector
+ */
+#define TEEECALL_OPTEED_FUNCID_RETURN_ENTRY_DONE 0
+#define TEEECALL_OPTEED_RETURN_ENTRY_DONE \
+ TEEECALL_OPTEED_RV(TEEECALL_OPTEED_FUNCID_RETURN_ENTRY_DONE)
+
+
+
+/*
+ * Issued when returning from "cpu_on" vector
+ *
+ * Register usage:
+ * r0/x0 SMC Function ID, TEEECALL_OPTEED_RETURN_ON_DONE
+ * r1/x1 0 on success and anything else to indicate error condition
+ */
+#define TEEECALL_OPTEED_FUNCID_RETURN_ON_DONE 1
+#define TEEECALL_OPTEED_RETURN_ON_DONE \
+ TEEECALL_OPTEED_RV(TEEECALL_OPTEED_FUNCID_RETURN_ON_DONE)
+
+/*
+ * Issued when returning from "cpu_off" vector
+ *
+ * Register usage:
+ * r0/x0 SMC Function ID, TEEECALL_OPTEED_RETURN_OFF_DONE
+ * r1/x1 0 on success and anything else to indicate error condition
+ */
+#define TEEECALL_OPTEED_FUNCID_RETURN_OFF_DONE 2
+#define TEEECALL_OPTEED_RETURN_OFF_DONE \
+ TEEECALL_OPTEED_RV(TEEECALL_OPTEED_FUNCID_RETURN_OFF_DONE)
+
+/*
+ * Issued when returning from "cpu_suspend" vector
+ *
+ * Register usage:
+ * r0/x0 SMC Function ID, TEEECALL_OPTEED_RETURN_SUSPEND_DONE
+ * r1/x1 0 on success and anything else to indicate error condition
+ */
+#define TEEECALL_OPTEED_FUNCID_RETURN_SUSPEND_DONE 3
+#define TEEECALL_OPTEED_RETURN_SUSPEND_DONE \
+ TEEECALL_OPTEED_RV(TEEECALL_OPTEED_FUNCID_RETURN_SUSPEND_DONE)
+
+/*
+ * Issued when returning from "cpu_resume" vector
+ *
+ * Register usage:
+ * r0/x0 SMC Function ID, TEEECALL_OPTEED_RETURN_RESUME_DONE
+ * r1/x1 0 on success and anything else to indicate error condition
+ */
+#define TEEECALL_OPTEED_FUNCID_RETURN_RESUME_DONE 4
+#define TEEECALL_OPTEED_RETURN_RESUME_DONE \
+ TEEECALL_OPTEED_RV(TEEECALL_OPTEED_FUNCID_RETURN_RESUME_DONE)
+
+/*
+ * Issued when returning from "std_smc" or "fast_smc" vector
+ *
+ * Register usage:
+ * r0/x0 SMC Function ID, TEEECALL_OPTEED_RETURN_CALL_DONE
+ * r1-4/x1-4 Return value 0-3 which will passed to normal world in
+ * r0-3/x0-3
+ */
+#define TEEECALL_OPTEED_FUNCID_RETURN_CALL_DONE 5
+#define TEEECALL_OPTEED_RETURN_CALL_DONE \
+ TEEECALL_OPTEED_RV(TEEECALL_OPTEED_FUNCID_RETURN_CALL_DONE)
+
+/*
+ * Issued when returning from "fiq" vector
+ *
+ * Register usage:
+ * r0/x0 SMC Function ID, TEEECALL_OPTEED_RETURN_FIQ_DONE
+ */
+#define TEEECALL_OPTEED_FUNCID_RETURN_FIQ_DONE 6
+#define TEEECALL_OPTEED_RETURN_FIQ_DONE \
+ TEEECALL_OPTEED_RV(TEEECALL_OPTEED_FUNCID_RETURN_FIQ_DONE)
+
+/*
+ * Issued when returning from "system_off" vector
+ *
+ * Register usage:
+ * r0/x0 SMC Function ID, TEEECALL_OPTEED_RETURN_SYSTEM_OFF_DONE
+ */
+#define TEEECALL_OPTEED_FUNCID_RETURN_SYSTEM_OFF_DONE 7
+#define TEEECALL_OPTEED_RETURN_SYSTEM_OFF_DONE \
+ TEEECALL_OPTEED_RV(TEEECALL_OPTEED_FUNCID_RETURN_SYSTEM_OFF_DONE)
+
+/*
+ * Issued when returning from "system_reset" vector
+ *
+ * Register usage:
+ * r0/x0 SMC Function ID, TEEECALL_OPTEED_RETURN_SYSTEM_RESET_DONE
+ */
+#define TEEECALL_OPTEED_FUNCID_RETURN_SYSTEM_RESET_DONE 8
+#define TEEECALL_OPTEED_RETURN_SYSTEM_RESET_DONE \
+ TEEECALL_OPTEED_RV(TEEECALL_OPTEED_FUNCID_RETURN_SYSTEM_RESET_DONE)
+
+#endif /* __TEEECALL_OPTEED_H__ */
diff --git a/lib/sbi/Kconfig b/lib/sbi/Kconfig
index df74bba..7cfc8c3 100644
--- a/lib/sbi/Kconfig
+++ b/lib/sbi/Kconfig
@@ -34,4 +34,8 @@ config SBI_ECALL_VENDOR
bool "Platform-defined vendor extensions"
default y
+config SBI_ECALL_TEE
+ bool "trusted execution environment"
+ default n
+
endmenu
diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk
index c774ebb..ea79924 100644
--- a/lib/sbi/objects.mk
+++ b/lib/sbi/objects.mk
@@ -43,6 +43,9 @@ libsbi-objs-$(CONFIG_SBI_ECALL_LEGACY) += sbi_ecall_legacy.o
carray-sbi_ecall_exts-$(CONFIG_SBI_ECALL_VENDOR) += ecall_vendor
libsbi-objs-$(CONFIG_SBI_ECALL_VENDOR) += sbi_ecall_vendor.o
+carray-sbi_ecall_exts-$(CONFIG_SBI_ECALL_TEE) += ecall_tee
+libsbi-objs-$(CONFIG_SBI_ECALL_TEE) += sbi_ecall_tee.o
+
libsbi-objs-y += sbi_bitmap.o
libsbi-objs-y += sbi_bitops.o
libsbi-objs-y += sbi_console.o
diff --git a/lib/sbi/sbi_ecall_tee.c b/lib/sbi/sbi_ecall_tee.c
new file mode 100644
index 0000000..86deea3
--- /dev/null
+++ b/lib/sbi/sbi_ecall_tee.c
@@ -0,0 +1,19 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2023 Beijing ESWIN Computing Technology Co., Ltd.
+ *
+ * Authors:
+ * Chen Chaokai <chenchaokai@eswincomputing.com>
+ * Liu Shiwei <liushiwei@eswincomputing.com>
+ */
+
+#include <sbi/sbi_ecall.h>
+#include <sbi/sbi_ecall_interface.h>
+#include <sbi_utils/tee/tee_sm_dispatcher.h>
+
+struct sbi_ecall_extension ecall_tee = {
+ .extid_start = SBI_EXT_TEE,
+ .extid_end = SBI_EXT_TEE,
+ .handle = sbi_ecall_tee_handler,
+};
diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index 259a191..1158949 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -26,6 +26,7 @@
#include <sbi/sbi_timer.h>
#include <sbi/sbi_tlb.h>
#include <sbi/sbi_version.h>
+#include <sbi_utils/tee/tee_sm_dispatcher.h>
#define BANNER \
" ____ _____ ____ _____\n" \
@@ -350,6 +351,10 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
init_count = sbi_scratch_offset_ptr(scratch, init_count_offset);
(*init_count)++;
+#ifdef CONFIG_SBI_ECALL_TEE
+ tee_os_init();
+#endif
+
sbi_hsm_prepare_next_jump(scratch, hartid);
sbi_hart_switch_mode(hartid, scratch->next_arg1, scratch->next_addr,
scratch->next_mode, false);
diff --git a/lib/utils/tee/objects.mk b/lib/utils/tee/objects.mk
new file mode 100644
index 0000000..5bf81f7
--- /dev/null
+++ b/lib/utils/tee/objects.mk
@@ -0,0 +1,16 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright 2023 Beijing ESWIN Computing Technology Co., Ltd.
+#
+# Authors:
+# Chen Chaokai <chenchaokai@eswincomputing.com>
+# Liu Shiwei <liushiwei@eswincomputing.com>
+#
+
+ifdef CONFIG_TEE_LOAD_ADDR
+firmware-cflags-y += -DTEE_LOAD_ADDR=$(CONFIG_TEE_LOAD_ADDR)
+endif
+
+libsbiutils-objs-$(CONFIG_SBI_ECALL_TEE) += tee/tee_context.o
+libsbiutils-objs-$(CONFIG_SBI_ECALL_TEE) += tee/tee_sm_dispatcher.o
diff --git a/lib/utils/tee/tee_context.S b/lib/utils/tee/tee_context.S
new file mode 100644
index 0000000..90b1013
--- /dev/null
+++ b/lib/utils/tee/tee_context.S
@@ -0,0 +1,189 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2023 Beijing ESWIN Computing Technology Co., Ltd.
+ *
+ * Authors:
+ * Chen Chaokai <chenchaokai@eswincomputing.com>
+ * Liu Shiwei <liushiwei@eswincomputing.com>
+ */
+
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_trap.h>
+#include <sbi_utils/tee/tee_context.h>
+
+ .global entry_teeos
+ .type entry_teeos, @function
+entry_teeos:
+ /* Save t0 into scratch temporarily */
+ csrrw tp, CSR_MSCRATCH, tp
+ REG_S t0, SBI_SCRATCH_TMP0_OFFSET(tp)
+
+ li t0, 0
+ addi t0, sp, 0
+
+ /* Set new SP */
+ li sp, 0
+ addi sp, a0, 0
+
+ /* Save original SP and t0 */
+ REG_S t0, SBI_TRAP_REGS_OFFSET(sp)(sp)
+ REG_L t0, SBI_SCRATCH_TMP0_OFFSET(tp)
+ REG_S t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
+
+ csrrw tp, CSR_MSCRATCH, tp
+
+ /* Save all general registers except SP and T0*/
+ REG_S ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
+ REG_S a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
+ REG_S gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
+ REG_S tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
+ REG_S t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
+ REG_S t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
+ REG_S s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
+ REG_S s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
+ REG_S a1, SBI_TRAP_REGS_OFFSET(a1)(sp)
+ REG_S a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
+ REG_S a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
+ REG_S a4, SBI_TRAP_REGS_OFFSET(a4)(sp)
+ REG_S a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
+ REG_S a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
+ REG_S a7, SBI_TRAP_REGS_OFFSET(a7)(sp)
+ REG_S s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
+ REG_S s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
+ REG_S s4, SBI_TRAP_REGS_OFFSET(s4)(sp)
+ REG_S s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
+ REG_S s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
+ REG_S s7, SBI_TRAP_REGS_OFFSET(s7)(sp)
+ REG_S s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
+ REG_S s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
+ REG_S s10, SBI_TRAP_REGS_OFFSET(s10)(sp)
+ REG_S s11, SBI_TRAP_REGS_OFFSET(s11)(sp)
+ REG_S t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
+ REG_S t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
+ REG_S t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
+ REG_S t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
+ REG_L sp, SBI_TRAP_REGS_OFFSET(sp)(sp)
+
+ /* Enter supervisor mode */
+ call enter_teeos_start_point
+
+ .global teeos_entry_done
+ .type teeos_entry_done, @function
+teeos_entry_done:
+ li sp, 0
+ addi sp, a0, 0
+
+ /* Restore all general purpose registers except SP and T0*/
+ REG_L ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
+ REG_L gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
+ REG_L tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
+ REG_L t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
+ REG_L t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
+ REG_L s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
+ REG_L s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
+ REG_L a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
+ REG_L a1, SBI_TRAP_REGS_OFFSET(a1)(sp)
+ REG_L a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
+ REG_L a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
+ REG_L a4, SBI_TRAP_REGS_OFFSET(a4)(sp)
+ REG_L a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
+ REG_L a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
+ REG_L a7, SBI_TRAP_REGS_OFFSET(a7)(sp)
+ REG_L s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
+ REG_L s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
+ REG_L s4, SBI_TRAP_REGS_OFFSET(s4)(sp)
+ REG_L s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
+ REG_L s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
+ REG_L s7, SBI_TRAP_REGS_OFFSET(s7)(sp)
+ REG_L s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
+ REG_L s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
+ REG_L s10, SBI_TRAP_REGS_OFFSET(s10)(sp)
+ REG_L s11, SBI_TRAP_REGS_OFFSET(s11)(sp)
+ REG_L t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
+ REG_L t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
+ REG_L t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
+ REG_L t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
+
+ /* Restore T0 */
+ REG_L t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
+
+ /* Restore SP */
+ REG_L sp, SBI_TRAP_REGS_OFFSET(sp)(sp)
+ ret
+
+ .global restore_to_supervisor
+ .type restore_to_supervisor, @function
+restore_to_supervisor:
+ li sp, 0
+ add sp, a0, zero
+
+ /* Restore all general purpose registers except SP and T0*/
+ REG_L zero, SBI_TRAP_REGS_OFFSET(zero)(sp)
+ REG_L ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
+ REG_L gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
+ REG_L tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
+ REG_L t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
+ REG_L t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
+ REG_L s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
+ REG_L s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
+ REG_L a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
+ REG_L a1, SBI_TRAP_REGS_OFFSET(a1)(sp)
+ REG_L a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
+ REG_L a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
+ REG_L a4, SBI_TRAP_REGS_OFFSET(a4)(sp)
+ REG_L a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
+ REG_L a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
+ REG_L a7, SBI_TRAP_REGS_OFFSET(a7)(sp)
+ REG_L s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
+ REG_L s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
+ REG_L s4, SBI_TRAP_REGS_OFFSET(s4)(sp)
+ REG_L s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
+ REG_L s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
+ REG_L s7, SBI_TRAP_REGS_OFFSET(s7)(sp)
+ REG_L s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
+ REG_L s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
+ REG_L s10, SBI_TRAP_REGS_OFFSET(s10)(sp)
+ REG_L s11, SBI_TRAP_REGS_OFFSET(s11)(sp)
+ REG_L t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
+ REG_L t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
+ REG_L t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
+ REG_L t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
+
+ /* Restore Supervisor mode CSRs */
+ REG_L t0, SBI_SAVE_CONTEXT_OFFSET(sepc)(sp)
+ csrw CSR_SEPC, t0
+ REG_L t0, SBI_SAVE_CONTEXT_OFFSET(satp)(sp)
+ csrw CSR_SATP, t0
+ REG_L t0, SBI_SAVE_CONTEXT_OFFSET(sstatus)(sp)
+ csrw CSR_SSTATUS, t0
+ REG_L t0, SBI_SAVE_CONTEXT_OFFSET(sie)(sp)
+ csrw CSR_SIE, t0
+ REG_L t0, SBI_SAVE_CONTEXT_OFFSET(stvec)(sp)
+ csrw CSR_STVEC, t0
+ REG_L t0, SBI_SAVE_CONTEXT_OFFSET(sscratch)(sp)
+ csrw CSR_SSCRATCH, t0
+ REG_L t0, SBI_SAVE_CONTEXT_OFFSET(scounteren)(sp)
+ csrw CSR_SCOUNTEREN, t0
+ REG_L t0, SBI_SAVE_CONTEXT_OFFSET(scause)(sp)
+ csrw CSR_SCAUSE, t0
+ REG_L t0, SBI_SAVE_CONTEXT_OFFSET(stval)(sp)
+ csrw CSR_STVAL, t0
+ REG_L t0, SBI_SAVE_CONTEXT_OFFSET(sip)(sp)
+ csrw CSR_SIP, t0
+
+ /* Restore Machine mode CSRs */
+ REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
+ csrw CSR_MEPC, t0
+ REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
+ csrw CSR_MSTATUS, t0
+
+ /* Restore T0 */
+ REG_L t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
+
+ /* Restore SP */
+ REG_L sp, SBI_TRAP_REGS_OFFSET(sp)(sp)
+ mret
diff --git a/lib/utils/tee/tee_sm_dispatcher.c b/lib/utils/tee/tee_sm_dispatcher.c
new file mode 100644
index 0000000..74e55c5
--- /dev/null
+++ b/lib/utils/tee/tee_sm_dispatcher.c
@@ -0,0 +1,228 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2023 Beijing ESWIN Computing Technology Co., Ltd.
+ *
+ * Authors:
+ * Chen Chaokai <chenchaokai@eswincomputing.com>
+ * Liu Shiwei <liushiwei@eswincomputing.com>
+ */
+
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_error.h>
+#include <sbi/riscv_asm.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi_trap.h>
+#include <sbi/sbi_console.h>
+#include <sbi/sbi_hart.h>
+#include <sbi/sbi_string.h>
+#include <sbi/sbi_types.h>
+#include <sbi_utils/tee/tee_context.h>
+#include <sbi_utils/tee/teeecall_opteed.h>
+#include <sbi_utils/tee/tee_sm_dispatcher.h>
+
+optee_vectors_t *optee_vector_table;
+struct sbi_save_context nsec_cpu_context[OPTEED_CORE_COUNT];
+struct sbi_save_context sec_cpu_context[OPTEED_CORE_COUNT];
+struct sbi_trap_regs cpu_start_context[OPTEED_CORE_COUNT];
+ulong mscratch[OPTEED_CORE_COUNT];
+typedef ulong tee_tmp_trap_stack[1024];
+static tee_tmp_trap_stack tmp_stack[OPTEED_CORE_COUNT];
+
+static ulong get_save_context_addr(uint32_t direction)
+{
+ ulong addr = 0;
+ ulong hartid = current_hartid();
+ switch (direction) {
+ case TEE_SECURE_FLAG:
+ addr = (ulong)&sec_cpu_context[hartid];
+ break;
+ case TEE_NON_SECURE_FLAG:
+ addr = (ulong)&nsec_cpu_context[hartid];
+ break;
+ default:
+ sbi_printf("wrong state\n");
+ while(1)
+ wfi();
+ }
+
+ return addr;
+}
+
+static ulong save_context(const struct sbi_trap_regs *regs)
+{
+ ulong addr = 0;
+ struct sbi_save_context *context = NULL;
+
+ addr = get_save_context_addr(regs->a5);
+ context = (struct sbi_save_context *)addr;
+ if (context != NULL) {
+ sbi_memset(context, 0, sizeof(struct sbi_save_context));
+ sbi_memcpy(context, regs, sizeof(struct sbi_trap_regs));
+ } else {
+ return SBI_EINVAL;
+ }
+
+ context->sepc = csr_read(CSR_SEPC);
+ context->satp = csr_read(CSR_SATP);
+ context->sstatus = csr_read(CSR_SSTATUS);
+ context->sie = csr_read(CSR_SIE);
+ context->stvec = csr_read(CSR_STVEC);
+ context->sscratch = csr_read(CSR_SSCRATCH);
+ context->scounteren = csr_read(CSR_SCOUNTEREN);
+ context->scause = csr_read(CSR_SCAUSE);
+ context->stval = csr_read(CSR_STVAL);
+ context->sip = csr_read(CSR_SIP);
+
+ return SBI_OK;
+}
+
+static void restore_context(ulong ctx_addr)
+{
+ restore_to_supervisor(ctx_addr);
+}
+
+void enter_teeos_start_point(void)
+{
+ uint32_t hartid = current_hartid();
+ mscratch[hartid] = csr_read(CSR_MSCRATCH);
+ csr_write(CSR_MSCRATCH,&tmp_stack[hartid + 1]);
+ sbi_hart_switch_mode(hartid, 0, TEE_ENTRY_ADDR, PRV_S, false);
+}
+
+static void teeos_back(void)
+{
+ uint32_t hartid = current_hartid();
+ struct sbi_trap_regs *optee_ctx = &cpu_start_context[hartid];
+ csr_write(CSR_MSCRATCH,mscratch[hartid]);
+
+ teeos_entry_done((ulong)optee_ctx);
+
+ sbi_printf("Error, should never reach here\n");
+}
+
+static ulong prepare_tee_ctx(ulong funcid, ulong *args, ulong *ctx_addr)
+{
+ uint32_t hartid = current_hartid();
+ struct sbi_trap_regs *tee_regs = (struct sbi_trap_regs *)&sec_cpu_context[hartid];
+ tee_regs->mstatus |= MSTATUS_SUM;
+ struct sbi_save_context *context = (struct sbi_save_context *)tee_regs;
+ context->sstatus |= MSTATUS_SUM;
+ ulong func_type = GET_ECALL_TYPE(funcid);
+
+ if (func_type == ECALL_TYPE_FAST) {
+ tee_regs->mepc = (ulong)&optee_vector_table->fast_smc_entry;
+ tee_regs->a0 = funcid;
+ tee_regs->a1 = args[1];
+ tee_regs->a2 = args[2];
+ tee_regs->a3 = args[3];
+ tee_regs->a4 = args[4];
+ tee_regs->a5 = args[5];
+ } else if (func_type == ECALL_TYPE_YEILD) {
+ tee_regs->mepc = (ulong)&optee_vector_table->yield_smc_entry;
+ tee_regs->a0 = funcid;
+ tee_regs->a1 = args[1];
+ tee_regs->a2 = args[2];
+ tee_regs->a3 = args[3];
+ tee_regs->a4 = args[4];
+ tee_regs->a5 = args[0];
+ } else
+ return SBI_EFAIL;
+
+ *ctx_addr = (ulong)tee_regs;
+ return SBI_OK;
+}
+
+static ulong prepare_ree_ctx(ulong *args, ulong *ctx_addr)
+{
+ struct sbi_save_context *ns_regs = NULL;
+ uint32_t hartid = current_hartid();
+
+ ns_regs = &nsec_cpu_context[hartid];
+ ns_regs->regs.a0 = args[0];
+ ns_regs->regs.a1 = args[1];
+ ns_regs->regs.a2 = args[2];
+ ns_regs->regs.a3 = args[3];
+ ns_regs->regs.a4 = args[4];
+ ns_regs->regs.a5 = args[5];
+ ns_regs->regs.mepc += 4;
+ *ctx_addr = (ulong)ns_regs;
+
+ return SBI_OK;
+}
+
+void tee_os_init(void)
+{
+ uint32_t hartid = current_hartid();
+ struct sbi_trap_regs *optee_cpu_ctx = &cpu_start_context[hartid];
+
+ sbi_memset(optee_cpu_ctx, 0, sizeof(struct sbi_save_context));
+ entry_teeos((ulong )optee_cpu_ctx);
+}
+
+int sbi_ecall_tee_handler(ulong extid, ulong funcid,
+ const struct sbi_trap_regs *regs,
+ ulong *out_val,
+ struct sbi_trap_info *out_trap)
+{
+ ulong ret;
+ int tee_func_id = funcid;
+ ulong ctx_addr = 0;
+ ulong args[8] = {0};
+ ulong secure_state = 0;
+ args[0] = regs->a0;
+ args[1] = regs->a1;
+ args[2] = regs->a2;
+ args[3] = regs->a3;
+ args[4] = regs->a4;
+ args[5] = regs->a5;
+ args[6] = regs->a6;
+ args[7] = regs->a7;
+ secure_state = args[5];
+
+ ret = save_context(regs);
+ if (ret != SBI_OK) {
+ sbi_printf("save exception context failed\n");
+ return ret;
+ }
+
+ if (secure_state == TEE_NON_SECURE_FLAG) {
+ ret = prepare_tee_ctx(funcid, args, &ctx_addr);
+ if ( ret != SBI_OK) {
+ sbi_printf("Set optee context failed\n");
+ return ret;
+ }
+ restore_context(ctx_addr);
+ } else if (secure_state == TEE_SECURE_FLAG) {
+ switch (tee_func_id) {
+ case TEEECALL_OPTEED_RETURN_ENTRY_DONE:
+ /* Stash the OPTEE entry point information. */
+ optee_vector_table = (optee_vectors_t *)args[1];
+ if (!args[1] || (args[1] & 3)) {
+ sbi_printf("Get TEE vector table failed.\n");
+ while(1);
+ wfi();
+ }
+ teeos_back();
+ break;
+ case TEEECALL_OPTEED_RETURN_CALL_DONE:
+ ret = prepare_ree_ctx(args, &ctx_addr);
+ if (ret != SBI_OK) {
+ sbi_printf("Set ree context failed\n");
+ return ret;
+ }
+ restore_context(ctx_addr);
+ break;
+ default:
+ sbi_printf("Wrong TEE funcid, funcid = %lx\n", funcid);
+ return SBI_EILL;
+ }
+
+ } else {
+ sbi_printf("Wrong secure state!\n");
+ return SBI_EILL;
+ }
+
+ return SBI_OK;
+}
--
2.17.1
next reply other threads:[~2023-01-11 2:01 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-11 2:01 liushiwei [this message]
2023-01-11 12:02 ` [PATCH 1/1] Add RISC-V TEE support hchauhan
2023-01-11 12:27 ` 答复: " liushiwei
2023-01-11 12:34 ` Anup Patel
2023-01-12 7:06 ` 答复: " liushiwei
2023-01-13 3:30 ` liushiwei
2023-01-13 11:46 ` Conor Dooley
2023-01-11 15:38 ` Himanshu Chauhan
2023-01-12 7:08 ` 答复: " liushiwei
2023-01-13 11:59 ` Anup Patel
2023-01-16 13:09 ` 答复: " liushiwei
2023-01-21 13:36 ` Anup Patel
2023-01-24 19:12 ` Atish Patra
2023-01-11 12:43 ` liushiwei
-- strict thread matches above, loose matches on Subject: below --
2023-01-11 2:08 liushiwei
2023-01-16 13:08 liushiwei
2023-01-28 7:39 liushiwei
2023-01-28 8:33 liushiwei
2023-02-07 22:37 ` Atish Patra
2023-02-16 11:40 liushiwei
2023-02-21 20:22 ` Atish Patra
2023-02-23 11:23 liushiwei
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230111020159.1234-1-liushiwei@eswincomputing.com \
--to=liushiwei@eswincomputing.com \
--cc=opensbi@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.