diff options
Diffstat (limited to 'core/arch/arm')
86 files changed, 1637 insertions, 1429 deletions
diff --git a/core/arch/arm/include/kernel/mutex.h b/core/arch/arm/include/kernel/mutex.h index 1698b35..893313e 100644 --- a/core/arch/arm/include/kernel/mutex.h +++ b/core/arch/arm/include/kernel/mutex.h @@ -36,6 +36,15 @@ enum mutex_value { MUTEX_VALUE_LOCKED, }; +/* + * Positive owner ids signifies actual threads, negative ids has special + * meanings according to the defines below. Note that only the first of the + * defines is allowed in struct mutex::owener_id. + */ +#define MUTEX_OWNER_ID_NONE -1 +#define MUTEX_OWNER_ID_CONDVAR_SLEEP -2 +#define MUTEX_OWNER_ID_MUTEX_UNLOCK -3 + struct mutex { enum mutex_value value; unsigned spin_lock; /* used when operating on this struct */ @@ -44,7 +53,7 @@ struct mutex { TAILQ_ENTRY(mutex) link; }; #define MUTEX_INITIALIZER \ - { .value = MUTEX_VALUE_UNLOCKED, .owner_id = -1, \ + { .value = MUTEX_VALUE_UNLOCKED, .owner_id = MUTEX_OWNER_ID_NONE, \ .wq = WAIT_QUEUE_INITIALIZER, } TAILQ_HEAD(mutex_head, mutex); diff --git a/core/arch/arm/include/kernel/pseudo_ta.h b/core/arch/arm/include/kernel/pseudo_ta.h index 98316bd..55d5e2b 100644 --- a/core/arch/arm/include/kernel/pseudo_ta.h +++ b/core/arch/arm/include/kernel/pseudo_ta.h @@ -38,7 +38,9 @@ TA_FLAG_MULTI_SESSION | \ TA_FLAG_INSTANCE_KEEP_ALIVE) -#define PTA_ALLOWED_FLAGS PTA_MANDATORY_FLAGS +#define PTA_ALLOWED_FLAGS (PTA_MANDATORY_FLAGS | \ + TA_FLAG_SECURE_DATA_PATH) + #define PTA_DEFAULT_FLAGS PTA_MANDATORY_FLAGS struct pseudo_ta_head { diff --git a/core/arch/arm/include/kernel/spinlock.h b/core/arch/arm/include/kernel/spinlock.h index c248673..a19b764 100644 --- a/core/arch/arm/include/kernel/spinlock.h +++ b/core/arch/arm/include/kernel/spinlock.h @@ -59,7 +59,7 @@ unsigned int __cpu_spin_trylock(unsigned int *lock); static inline void cpu_spin_lock(unsigned int *lock) { - assert(thread_irq_disabled()); + assert(thread_foreign_intr_disabled()); __cpu_spin_lock(lock); spinlock_count_incr(); } @@ -68,7 +68,7 @@ static inline bool cpu_spin_trylock(unsigned int *lock) { unsigned int rc; - assert(thread_irq_disabled()); + assert(thread_foreign_intr_disabled()); rc = __cpu_spin_trylock(lock); if (!rc) spinlock_count_incr(); @@ -77,7 +77,7 @@ static inline bool cpu_spin_trylock(unsigned int *lock) static inline void cpu_spin_unlock(unsigned int *lock) { - assert(thread_irq_disabled()); + assert(thread_foreign_intr_disabled()); __cpu_spin_unlock(lock); spinlock_count_decr(); } diff --git a/core/arch/arm/include/kernel/thread.h b/core/arch/arm/include/kernel/thread.h index 175ba77..831b5d6 100644 --- a/core/arch/arm/include/kernel/thread.h +++ b/core/arch/arm/include/kernel/thread.h @@ -30,6 +30,7 @@ #define KERNEL_THREAD_H #ifndef ASM +#include <arm.h> #include <types_ext.h> #include <compiler.h> #include <optee_msg.h> @@ -203,7 +204,7 @@ struct thread_svc_regs { #ifndef ASM typedef void (*thread_smc_handler_t)(struct thread_smc_args *args); -typedef void (*thread_fiq_handler_t)(void); +typedef void (*thread_nintr_handler_t)(void); typedef unsigned long (*thread_pm_handler_t)(unsigned long a0, unsigned long a1); struct thread_handlers { @@ -218,11 +219,12 @@ struct thread_handlers { * * fastcall handles fast calls which can't be preemted. This * handler is executed with a limited stack. This handler must not - * cause any aborts or reenenable FIQs which are temporarily masked - * while executing this handler. + * cause any aborts or reenenable native interrupts which are + * temporarily masked while executing this handler. * - * TODO investigate if we should execute fastcalls and FIQs on - * different stacks allowing FIQs to be enabled during a fastcall. + * TODO investigate if we should execute fastcalls and native interrupts + * on different stacks allowing native interrupts to be enabled during + * a fastcall. */ thread_smc_handler_t std_smc; thread_smc_handler_t fast_smc; @@ -231,12 +233,12 @@ struct thread_handlers { * fiq is called as a regular function and normal ARM Calling * Convention applies. * - * This handler handles FIQs which can't be preemted. This handler - * is executed with a limited stack. This handler must not cause - * any aborts or reenenable FIQs which are temporarily masked while - * executing this handler. + * This handler handles native interrupts which can't be preemted. This + * handler is executed with a limited stack. This handler must not cause + * any aborts or reenenable native interrupts which are temporarily + * masked while executing this handler. */ - thread_fiq_handler_t fiq; + thread_nintr_handler_t nintr; /* * Power management handlers triggered from ARM Trusted Firmware. @@ -285,28 +287,30 @@ int thread_get_id_may_fail(void); struct thread_specific_data *thread_get_tsd(void); /* - * Sets IRQ status for current thread, must only be called from an - * active thread context. + * Sets foreign interrupts status for current thread, must only be called + * from an active thread context. * - * enable == true -> enable IRQ - * enable == false -> disable IRQ + * enable == true -> enable foreign interrupts + * enable == false -> disable foreign interrupts */ -void thread_set_irq(bool enable); +void thread_set_foreign_intr(bool enable); /* - * Restores the IRQ status (in CPSR) for current thread, must only be called - * from an active thread context. + * Restores the foreign interrupts status (in CPSR) for current thread, must + * only be called from an active thread context. */ -void thread_restore_irq(void); +void thread_restore_foreign_intr(void); /* * Defines the bits for the exception mask used the the * thread_*_exceptions() functions below. + * These definitions are compatible with both ARM32 and ARM64. */ -#define THREAD_EXCP_FIQ (1 << 0) -#define THREAD_EXCP_IRQ (1 << 1) -#define THREAD_EXCP_ABT (1 << 2) -#define THREAD_EXCP_ALL (THREAD_EXCP_FIQ | THREAD_EXCP_IRQ | THREAD_EXCP_ABT) +#define THREAD_EXCP_FOREIGN_INTR (ARM32_CPSR_I >> ARM32_CPSR_F_SHIFT) +#define THREAD_EXCP_NATIVE_INTR (ARM32_CPSR_F >> ARM32_CPSR_F_SHIFT) +#define THREAD_EXCP_ALL (THREAD_EXCP_FOREIGN_INTR \ + | THREAD_EXCP_NATIVE_INTR \ + | (ARM32_CPSR_A >> ARM32_CPSR_F_SHIFT)) /* * thread_get_exceptions() - return current exception mask @@ -337,18 +341,18 @@ uint32_t thread_mask_exceptions(uint32_t exceptions); void thread_unmask_exceptions(uint32_t state); -static inline bool thread_irq_disabled(void) +static inline bool thread_foreign_intr_disabled(void) { - return !!(thread_get_exceptions() & THREAD_EXCP_IRQ); + return !!(thread_get_exceptions() & THREAD_EXCP_FOREIGN_INTR); } #ifdef CFG_WITH_VFP /* * thread_kernel_enable_vfp() - Temporarily enables usage of VFP * - * IRQ is masked while VFP is enabled. User space must not be entered before - * thread_kernel_disable_vfp() has been called to disable VFP and restore the - * IRQ status. + * Foreign interrupts are masked while VFP is enabled. User space must not be + * entered before thread_kernel_disable_vfp() has been called to disable VFP + * and restore the foreign interrupt status. * * This function may only be called from an active thread context and may * not be called again before thread_kernel_disable_vfp() has been called. @@ -364,7 +368,7 @@ uint32_t thread_kernel_enable_vfp(void); * thread_kernel_disable_vfp() - Disables usage of VFP * @state: state variable returned by thread_kernel_enable_vfp() * - * Disables usage of VFP and restores IRQ status after a call to + * Disables usage of VFP and restores foreign interrupt status after a call to * thread_kernel_enable_vfp(). * * This function may only be called after a call to @@ -484,13 +488,13 @@ bool thread_addr_is_in_stack(vaddr_t va); /* * Adds a mutex to the list of held mutexes for current thread - * Requires IRQs to be disabled. + * Requires foreign interrupts to be disabled. */ void thread_add_mutex(struct mutex *m); /* * Removes a mutex from the list of held mutexes for current thread - * Requires IRQs to be disabled. + * Requires foreign interrupts to be disabled. */ void thread_rem_mutex(struct mutex *m); diff --git a/core/arch/arm/include/kernel/thread_defs.h b/core/arch/arm/include/kernel/thread_defs.h index 0f54569..e081895 100644 --- a/core/arch/arm/include/kernel/thread_defs.h +++ b/core/arch/arm/include/kernel/thread_defs.h @@ -29,7 +29,7 @@ #define KERNEL_THREAD_DEFS_H #define THREAD_FLAGS_COPY_ARGS_ON_RETURN (1 << 0) -#define THREAD_FLAGS_IRQ_ENABLE (1 << 1) -#define THREAD_FLAGS_EXIT_ON_IRQ (1 << 2) +#define THREAD_FLAGS_FOREIGN_INTR_ENABLE (1 << 1) +#define THREAD_FLAGS_EXIT_ON_FOREIGN_INTR (1 << 2) #endif /*KERNEL_THREAD_DEFS_H*/ diff --git a/core/arch/arm/include/kernel/wait_queue.h b/core/arch/arm/include/kernel/wait_queue.h index eb8f881..bb53cb6 100644 --- a/core/arch/arm/include/kernel/wait_queue.h +++ b/core/arch/arm/include/kernel/wait_queue.h @@ -67,7 +67,8 @@ static inline void wq_wait_init(struct wait_queue *wq, /* Waits for the wait queue element to the awakened. */ void wq_wait_final(struct wait_queue *wq, struct wait_queue_elem *wqe, - const void *sync_obj, const char *fname, int lineno); + const void *sync_obj, int owner, const char *fname, + int lineno); /* Wakes up the first wait queue element in the wait queue, if there is one */ void wq_wake_one(struct wait_queue *wq, const void *sync_obj, diff --git a/core/arch/arm/include/mm/core_memprot.h b/core/arch/arm/include/mm/core_memprot.h index b7ccd21..99514fd 100644 --- a/core/arch/arm/include/mm/core_memprot.h +++ b/core/arch/arm/include/mm/core_memprot.h @@ -45,14 +45,14 @@ /* memory atttributes */ enum buf_is_attr { - CORE_MEM_SEC, + CORE_MEM_CACHED, + CORE_MEM_EXTRAM, + CORE_MEM_NSEC_SHM, CORE_MEM_NON_SEC, + CORE_MEM_SEC, CORE_MEM_TEE_RAM, CORE_MEM_TA_RAM, - CORE_MEM_NSEC_SHM, - CORE_MEM_EXTRAM, - CORE_MEM_INTRAM, - CORE_MEM_CACHED, + CORE_MEM_SDP_MEM, }; /* redirect legacy tee_vbuf_is() and tee_pbuf_is() to our routines */ @@ -95,6 +95,13 @@ bool core_vbuf_is(uint32_t flags, const void *vbuf, size_t len); void *phys_to_virt(paddr_t pa, enum teecore_memtypes m); /* + * Translate physical address to virtual address trying MEM_AREA_IO_SEC + * first then MEM_AREA_IO_NSEC if not found. + * Returns NULL on failure or a valid virtual address on success. + */ +void *phys_to_virt_io(paddr_t pa); + +/* * Translate virtual address to physical address * Returns 0 on failure or a valid physical address on success. */ diff --git a/core/arch/arm/include/mm/core_mmu.h b/core/arch/arm/include/mm/core_mmu.h index 03ad93d..70be5ab 100644 --- a/core/arch/arm/include/mm/core_mmu.h +++ b/core/arch/arm/include/mm/core_mmu.h @@ -100,6 +100,7 @@ enum teecore_memtypes { MEM_AREA_IO_SEC, MEM_AREA_RES_VASPACE, MEM_AREA_TA_VASPACE, + MEM_AREA_SDP_MEM, MEM_AREA_MAXTYPE }; @@ -115,6 +116,13 @@ struct core_mmu_phys_mem { __used __section("phys_mem_map_section") = \ { #addr, (type), (addr), (size) } +#define __register_sdp_mem2(pa, sz, id) \ + static const struct core_mmu_phys_mem __phys_sdp_mem_ ## id \ + __used __section("phys_sdp_mem_section") = \ + { .type = MEM_AREA_SDP_MEM, .addr = (pa), .size = (sz), } + +#define __register_sdp_mem1(pa, sz, id) __register_sdp_mem2(pa, sz, id) +#define register_sdp_mem(pa, sz) __register_sdp_mem1(pa, sz, __COUNTER__) /* Default NSec shared memory allocated from NSec world */ extern unsigned long default_nsec_shm_paddr; @@ -350,20 +358,6 @@ bool core_mmu_is_shm_cached(void); bool core_mmu_add_mapping(enum teecore_memtypes type, paddr_t addr, size_t len); -/* L1/L2 cache maintenance (op: refer to ???) */ -unsigned int cache_maintenance_l1(int op, void *va, size_t len); -#ifdef CFG_PL310 -unsigned int cache_maintenance_l2(int op, paddr_t pa, size_t len); -#else -static inline unsigned int cache_maintenance_l2(int op __unused, - paddr_t pa __unused, - size_t len __unused) -{ - /* Nothing to do about L2 Cache Maintenance when no PL310 */ - return TEE_SUCCESS; -} -#endif - /* various invalidate secure TLB */ enum teecore_tlb_op { TLBINV_UNIFIEDTLB, /* invalidate unified tlb */ @@ -375,25 +369,37 @@ enum teecore_tlb_op { int core_tlb_maintenance(int op, unsigned int a); /* Cache maintenance operation type */ -typedef enum { - DCACHE_CLEAN = 0x1, - DCACHE_AREA_CLEAN = 0x2, - DCACHE_INVALIDATE = 0x3, - DCACHE_AREA_INVALIDATE = 0x4, - ICACHE_INVALIDATE = 0x5, - ICACHE_AREA_INVALIDATE = 0x6, - WRITE_BUFFER_DRAIN = 0x7, - DCACHE_CLEAN_INV = 0x8, - DCACHE_AREA_CLEAN_INV = 0x9, - L2CACHE_INVALIDATE = 0xA, - L2CACHE_AREA_INVALIDATE = 0xB, - L2CACHE_CLEAN = 0xC, - L2CACHE_AREA_CLEAN = 0xD, - L2CACHE_CLEAN_INV = 0xE, - L2CACHE_AREA_CLEAN_INV = 0xF -} t_cache_operation_id; +enum cache_op { + DCACHE_CLEAN, + DCACHE_AREA_CLEAN, + DCACHE_INVALIDATE, + DCACHE_AREA_INVALIDATE, + ICACHE_INVALIDATE, + ICACHE_AREA_INVALIDATE, + DCACHE_CLEAN_INV, + DCACHE_AREA_CLEAN_INV, +}; + +/* L1/L2 cache maintenance */ +TEE_Result cache_op_inner(enum cache_op op, void *va, size_t len); +#ifdef CFG_PL310 +TEE_Result cache_op_outer(enum cache_op op, paddr_t pa, size_t len); +#else +static inline TEE_Result cache_op_outer(enum cache_op op __unused, + paddr_t pa __unused, + size_t len __unused) +{ + /* Nothing to do about L2 Cache Maintenance when no PL310 */ + return TEE_SUCCESS; +} +#endif /* Check cpu mmu enabled or not */ bool cpu_mmu_enabled(void); +#ifdef CFG_SECURE_DATA_PATH +/* Alloc and fill SDP memory objects table - table is NULL terminated */ +struct mobj **core_sdp_mem_create_mobjs(void); +#endif + #endif /* CORE_MMU_H */ diff --git a/core/arch/arm/include/mm/mobj.h b/core/arch/arm/include/mm/mobj.h index d5eeb69..1a76149 100644 --- a/core/arch/arm/include/mm/mobj.h +++ b/core/arch/arm/include/mm/mobj.h @@ -108,6 +108,11 @@ static inline bool mobj_is_secure(struct mobj *mobj) return mobj_matches(mobj, CORE_MEM_SEC); } +static inline bool mobj_is_sdp_mem(struct mobj *mobj) +{ + return mobj_matches(mobj, CORE_MEM_SDP_MEM); +} + struct mobj *mobj_mm_alloc(struct mobj *mobj_parent, size_t size, tee_mm_pool_t *pool); diff --git a/core/arch/arm/include/sm/optee_smc.h b/core/arch/arm/include/sm/optee_smc.h index b6fcd65..c369708 100644 --- a/core/arch/arm/include/sm/optee_smc.h +++ b/core/arch/arm/include/sm/optee_smc.h @@ -385,7 +385,7 @@ OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_BOOT_SECONDARY) /* - * Resume from RPC (for example after processing an IRQ) + * Resume from RPC (for example after processing a foreign interrupt) * * Call register usage: * a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC @@ -470,19 +470,19 @@ OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FREE) /* - * Deliver an IRQ in normal world. + * Deliver a foreign interrupt in normal world. * * "Call" register usage: - * a0 OPTEE_SMC_RETURN_RPC_IRQ + * a0 OPTEE_SMC_RETURN_RPC_FOREIGN_INTR * a1-7 Resume information, must be preserved * * "Return" register usage: * a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC. * a1-7 Preserved */ -#define OPTEE_SMC_RPC_FUNC_IRQ 4 -#define OPTEE_SMC_RETURN_RPC_IRQ \ - OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_IRQ) +#define OPTEE_SMC_RPC_FUNC_FOREIGN_INTR 4 +#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR \ + OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FOREIGN_INTR) /* * Do an RPC request. The supplied struct optee_msg_arg tells which diff --git a/core/arch/arm/include/sm/sm.h b/core/arch/arm/include/sm/sm.h index 6368359..3446506 100644 --- a/core/arch/arm/include/sm/sm.h +++ b/core/arch/arm/include/sm/sm.h @@ -29,6 +29,7 @@ #ifndef SM_SM_H #define SM_SM_H +#include <compiler.h> #include <types_ext.h> struct sm_mode_regs { @@ -120,4 +121,17 @@ void *sm_get_sp(void); */ void sm_init(vaddr_t stack_pointer); +#ifndef CFG_SM_PLATFORM_HANDLER +/* + * Returns false if we handled the monitor service and should now return + * back to the non-secure state + */ +static inline bool sm_platform_handler(__unused struct sm_ctx *ctx) +{ + return true; +} +#else +bool sm_platform_handler(struct sm_ctx *ctx); +#endif + #endif /*SM_SM_H*/ diff --git a/core/arch/arm/kernel/elf_common.h b/core/arch/arm/kernel/elf_common.h index dd8cd50..497a902 100644 --- a/core/arch/arm/kernel/elf_common.h +++ b/core/arch/arm/kernel/elf_common.h @@ -645,6 +645,7 @@ typedef struct { #define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ #define R_386_IRELATIVE 42 /* PLT entry resolved indirectly at runtime */ +#define R_AARCH64_ABS64 257 #define R_AARCH64_RELATIVE 1027 #define R_ARM_NONE 0 /* No relocation. */ diff --git a/core/arch/arm/kernel/elf_load.c b/core/arch/arm/kernel/elf_load.c index 420ba59..b1d6102 100644 --- a/core/arch/arm/kernel/elf_load.c +++ b/core/arch/arm/kernel/elf_load.c @@ -499,9 +499,13 @@ static TEE_Result e32_process_rel(struct elf_load_state *state, size_t rel_sidx, static TEE_Result e64_process_rel(struct elf_load_state *state, size_t rel_sidx, vaddr_t vabase) { + Elf64_Ehdr *ehdr = state->ehdr; Elf64_Shdr *shdr = state->shdr; Elf64_Rela *rela; Elf64_Rela *rela_end; + size_t sym_tab_idx; + Elf64_Sym *sym_tab = NULL; + size_t num_syms = 0; if (shdr[rel_sidx].sh_type != SHT_RELA) return TEE_ERROR_NOT_IMPLEMENTED; @@ -509,6 +513,27 @@ static TEE_Result e64_process_rel(struct elf_load_state *state, if (shdr[rel_sidx].sh_entsize != sizeof(Elf64_Rela)) return TEE_ERROR_BAD_FORMAT; + sym_tab_idx = shdr[rel_sidx].sh_link; + if (sym_tab_idx) { + if (sym_tab_idx >= ehdr->e_shnum) + return TEE_ERROR_BAD_FORMAT; + + if (shdr[sym_tab_idx].sh_entsize != sizeof(Elf64_Sym)) + return TEE_ERROR_BAD_FORMAT; + + /* Check the address is inside TA memory */ + if (shdr[sym_tab_idx].sh_addr > state->vasize || + (shdr[sym_tab_idx].sh_addr + + shdr[sym_tab_idx].sh_size) > state->vasize) + return TEE_ERROR_BAD_FORMAT; + + sym_tab = (Elf64_Sym *)(vabase + shdr[sym_tab_idx].sh_addr); + if (!ALIGNMENT_IS_OK(sym_tab, Elf64_Sym)) + return TEE_ERROR_BAD_FORMAT; + + num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf64_Sym); + } + /* Check the address is inside TA memory */ if (shdr[rel_sidx].sh_addr >= state->vasize) return TEE_ERROR_BAD_FORMAT; @@ -522,6 +547,7 @@ static TEE_Result e64_process_rel(struct elf_load_state *state, rela_end = rela + shdr[rel_sidx].sh_size / sizeof(Elf64_Rela); for (; rela < rela_end; rela++) { Elf64_Addr *where; + size_t sym_idx; /* Check the address is inside TA memory */ if (rela->r_offset >= state->vasize) @@ -532,6 +558,13 @@ static TEE_Result e64_process_rel(struct elf_load_state *state, return TEE_ERROR_BAD_FORMAT; switch (ELF64_R_TYPE(rela->r_info)) { + case R_AARCH64_ABS64: + sym_idx = ELF64_R_SYM(rela->r_info); + if (sym_idx > num_syms) + return TEE_ERROR_BAD_FORMAT; + *where = rela->r_addend + sym_tab[sym_idx].st_value + + vabase; + break; case R_AARCH64_RELATIVE: *where = rela->r_addend + vabase; break; diff --git a/core/arch/arm/kernel/generic_boot.c b/core/arch/arm/kernel/generic_boot.c index 8f13c36..0d78d40 100644 --- a/core/arch/arm/kernel/generic_boot.c +++ b/core/arch/arm/kernel/generic_boot.c @@ -93,12 +93,6 @@ __weak void plat_cpu_reset_late(void) KEEP_PAGER(plat_cpu_reset_late); /* May be overridden in plat-$(PLATFORM)/main.c */ -__weak void plat_cpu_reset_early(void) -{ -} -KEEP_PAGER(plat_cpu_reset_early); - -/* May be overridden in plat-$(PLATFORM)/main.c */ __weak void main_init_gic(void) { } @@ -289,9 +283,8 @@ static void init_runtime(unsigned long pageable_part) p = (uint8_t *)(((vaddr_t)__init_start + init_size) & ~SMALL_PAGE_MASK); - cache_maintenance_l1(DCACHE_AREA_CLEAN, p, SMALL_PAGE_SIZE); - cache_maintenance_l1(ICACHE_AREA_INVALIDATE, p, - SMALL_PAGE_SIZE); + cache_op_inner(DCACHE_AREA_CLEAN, p, SMALL_PAGE_SIZE); + cache_op_inner(ICACHE_AREA_INVALIDATE, p, SMALL_PAGE_SIZE); } /* @@ -607,7 +600,8 @@ static void init_primary_helper(unsigned long pageable_part, * Mask asynchronous exceptions before switch to the thread vector * as the thread handler requires those to be masked while * executing with the temporary stack. The thread subsystem also - * asserts that IRQ is blocked when using most if its functions. + * asserts that the foreign interrupts are blocked when using most of + * its functions. */ thread_set_exceptions(THREAD_EXCP_ALL); init_vfp_sec(); @@ -634,7 +628,8 @@ static void init_secondary_helper(unsigned long nsec_entry) * Mask asynchronous exceptions before switch to the thread vector * as the thread handler requires those to be masked while * executing with the temporary stack. The thread subsystem also - * asserts that IRQ is blocked when using most if its functions. + * asserts that the foreign interrupts are blocked when using most of + * its functions. */ thread_set_exceptions(THREAD_EXCP_ALL); diff --git a/core/arch/arm/kernel/generic_entry_a32.S b/core/arch/arm/kernel/generic_entry_a32.S index 27717d5..9c2ef41 100644 --- a/core/arch/arm/kernel/generic_entry_a32.S +++ b/core/arch/arm/kernel/generic_entry_a32.S @@ -25,16 +25,16 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <platform_config.h> - -#include <asm.S> #include <arm.h> #include <arm32_macros.S> +#include <asm.S> +#include <platform_config.h> +#include <keep.h> +#include <kernel/asan.h> +#include <kernel/unwind.h> #include <sm/optee_smc.h> #include <sm/teesmc_opteed_macros.h> #include <sm/teesmc_opteed.h> -#include <kernel/unwind.h> -#include <kernel/asan.h> .section .data .balign 4 @@ -87,6 +87,14 @@ END_FUNC __assert_flat_mapped_range .endm #endif /* CFG_PL310 */ +.weak plat_cpu_reset_early +FUNC plat_cpu_reset_early , : +UNWIND( .fnstart) + bx lr +UNWIND( .fnend) +END_FUNC plat_cpu_reset_early +KEEP_PAGER plat_cpu_reset_early + .section .text.boot FUNC _start , : b reset diff --git a/core/arch/arm/kernel/kern.ld.S b/core/arch/arm/kernel/kern.ld.S index 10dac6e..b761aea 100644 --- a/core/arch/arm/kernel/kern.ld.S +++ b/core/arch/arm/kernel/kern.ld.S @@ -107,6 +107,10 @@ SECTIONS __start_phys_mem_map_section = . ; KEEP(*(phys_mem_map_section)) __end_phys_mem_map_section = . ; + . = ALIGN(8); + __start_phys_sdp_mem_section = . ; + KEEP(*(phys_sdp_mem_section)) + __end_phys_sdp_mem_section = . ; #endif . = ALIGN(8); __rodata_end = .; @@ -254,6 +258,10 @@ SECTIONS KEEP(*(phys_mem_map_section)) __end_phys_mem_map_section = . ; . = ALIGN(8); + __start_phys_sdp_mem_section = . ; + KEEP(*(phys_sdp_mem_section)) + __end_phys_sdp_mem_section = . ; + . = ALIGN(8); __rodata_init_end = .; } __init_start = __text_init_start; diff --git a/core/arch/arm/kernel/mutex.c b/core/arch/arm/kernel/mutex.c index 0e1b836..a25ca12 100644 --- a/core/arch/arm/kernel/mutex.c +++ b/core/arch/arm/kernel/mutex.c @@ -45,6 +45,7 @@ static void __mutex_lock(struct mutex *m, const char *fname, int lineno) uint32_t old_itr_status; enum mutex_value old_value; struct wait_queue_elem wqe; + int owner = MUTEX_OWNER_ID_NONE; /* * If the mutex is locked we need to initialize the wqe @@ -61,6 +62,7 @@ static void __mutex_lock(struct mutex *m, const char *fname, int lineno) old_value = m->value; if (old_value == MUTEX_VALUE_LOCKED) { wq_wait_init(&m->wq, &wqe); + owner = m->owner_id; } else { m->value = MUTEX_VALUE_LOCKED; thread_add_mutex(m); @@ -74,7 +76,7 @@ static void __mutex_lock(struct mutex *m, const char *fname, int lineno) * Someone else is holding the lock, wait in normal * world for the lock to become available. */ - wq_wait_final(&m->wq, &wqe, m, fname, lineno); + wq_wait_final(&m->wq, &wqe, m, owner, fname, lineno); } else return; } @@ -260,7 +262,8 @@ static void __condvar_wait(struct condvar *cv, struct mutex *m, /* Wake eventual waiters */ wq_wake_one(&m->wq, m, fname, lineno); - wq_wait_final(&m->wq, &wqe, m, fname, lineno); + wq_wait_final(&m->wq, &wqe, + m, MUTEX_OWNER_ID_CONDVAR_SLEEP, fname, lineno); mutex_lock(m); } diff --git a/core/arch/arm/kernel/pseudo_ta.c b/core/arch/arm/kernel/pseudo_ta.c index 6352a28..78b2bfd 100644 --- a/core/arch/arm/kernel/pseudo_ta.c +++ b/core/arch/arm/kernel/pseudo_ta.c @@ -37,9 +37,41 @@ #include <trace.h> #include <types_ext.h> +#ifdef CFG_SECURE_DATA_PATH +static bool client_is_secure(struct tee_ta_session *s) +{ + /* rely on core entry to have constrained client IDs */ + if (s->clnt_id.login == TEE_LOGIN_TRUSTED_APP) + return true; + + return false; +} + +static bool validate_in_param(struct tee_ta_session *s, struct mobj *mobj) +{ + /* for secure clients, core entry always holds valid memref objects */ + if (client_is_secure(s)) + return true; + + /* all non-secure memory references are hanlded by pTAs */ + if (mobj_is_nonsec(mobj)) + return true; + + return false; +} +#else +static bool validate_in_param(struct tee_ta_session *s __unused, + struct mobj *mobj __unused) +{ + /* At this point, core has filled only valid accessible memref mobj */ + return true; +} +#endif + /* Maps static TA params */ -static TEE_Result copy_in_param(struct tee_ta_param *param, - TEE_Param tee_param[TEE_NUM_PARAMS]) +static TEE_Result copy_in_param(struct tee_ta_session *s __maybe_unused, + struct tee_ta_param *param, + TEE_Param tee_param[TEE_NUM_PARAMS]) { size_t n; void *va; @@ -55,6 +87,9 @@ static TEE_Result copy_in_param(struct tee_ta_param *param, case TEE_PARAM_TYPE_MEMREF_INPUT: case TEE_PARAM_TYPE_MEMREF_OUTPUT: case TEE_PARAM_TYPE_MEMREF_INOUT: + if (!validate_in_param(s, param->u[n].mem.mobj)) + return TEE_ERROR_BAD_PARAMETERS; + va = mobj_get_va(param->u[n].mem.mobj, param->u[n].mem.offs); if (!va) @@ -110,7 +145,7 @@ static TEE_Result pseudo_ta_enter_open_session(struct tee_ta_session *s, } if (stc->pseudo_ta->open_session_entry_point) { - res = copy_in_param(param, tee_param); + res = copy_in_param(s, param, tee_param); if (res != TEE_SUCCESS) { *eo = TEE_ORIGIN_TEE; goto out; @@ -136,7 +171,7 @@ static TEE_Result pseudo_ta_enter_invoke_cmd(struct tee_ta_session *s, TEE_Param tee_param[TEE_NUM_PARAMS]; tee_ta_push_current_session(s); - res = copy_in_param(param, tee_param); + res = copy_in_param(s, param, tee_param); if (res != TEE_SUCCESS) { *eo = TEE_ORIGIN_TEE; goto out; @@ -224,7 +259,7 @@ TEE_Result tee_ta_init_pseudo_ta_session(const TEE_UUID *uuid, struct tee_ta_ctx *ctx; const struct pseudo_ta_head *ta; - DMSG(" Lookup for Static TA %pUl", (void *)uuid); + DMSG(" Lookup for pseudo TA %pUl", (void *)uuid); ta = &__start_ta_head_section; while (true) { diff --git a/core/arch/arm/kernel/spin_lock_debug.c b/core/arch/arm/kernel/spin_lock_debug.c index 2a450a5..00a2a00 100644 --- a/core/arch/arm/kernel/spin_lock_debug.c +++ b/core/arch/arm/kernel/spin_lock_debug.c @@ -49,10 +49,11 @@ bool have_spinlock(void) { struct thread_core_local *l; - if (!thread_irq_disabled()) { + if (!thread_foreign_intr_disabled()) { /* * Normally we can't be holding a spinlock since doing so would - * imply IRQ are disabled (or the spinlock logic is flawed). + * imply foreign interrupts are disabled (or the spinlock + * logic is flawed). */ return false; } diff --git a/core/arch/arm/kernel/tee_time_arm_cntpct.c b/core/arch/arm/kernel/tee_time_arm_cntpct.c index 90e7f20..59d6ea4 100644 --- a/core/arch/arm/kernel/tee_time_arm_cntpct.c +++ b/core/arch/arm/kernel/tee_time_arm_cntpct.c @@ -93,7 +93,7 @@ void plat_prng_add_jitter_entropy(void) } } if (bytes) { - DMSG("%s: 0x%02X\n", __func__, + FMSG("%s: 0x%02X\n", __func__, (int)acc & ((1 << (bytes * 8)) - 1)); tee_prng_add_entropy((uint8_t *)&acc, bytes); } diff --git a/core/arch/arm/kernel/thread.c b/core/arch/arm/kernel/thread.c index c988b65..2aaa0e6 100644 --- a/core/arch/arm/kernel/thread.c +++ b/core/arch/arm/kernel/thread.c @@ -66,15 +66,11 @@ #endif #define STACK_THREAD_SIZE 8192 -#if TRACE_LEVEL > 0 #ifdef CFG_CORE_SANITIZE_KADDRESS #define STACK_ABT_SIZE 3072 #else #define STACK_ABT_SIZE 2048 #endif -#else -#define STACK_ABT_SIZE 1024 -#endif #endif /*ARM32*/ @@ -140,7 +136,7 @@ KEEP_PAGER(stack_tmp_offset); thread_smc_handler_t thread_std_smc_handler_ptr; static thread_smc_handler_t thread_fast_smc_handler_ptr; -thread_fiq_handler_t thread_fiq_handler_ptr; +thread_nintr_handler_t thread_nintr_handler_ptr; thread_pm_handler_t thread_cpu_on_handler_ptr; thread_pm_handler_t thread_cpu_off_handler_ptr; thread_pm_handler_t thread_cpu_suspend_handler_ptr; @@ -234,8 +230,8 @@ void thread_set_exceptions(uint32_t exceptions) { uint32_t cpsr = read_cpsr(); - /* IRQ must not be unmasked while holding a spinlock */ - if (!(exceptions & THREAD_EXCP_IRQ)) + /* Foreign interrupts must not be unmasked while holding a spinlock */ + if (!(exceptions & THREAD_EXCP_FOREIGN_INTR)) assert_have_no_spinlock(); cpsr &= ~(THREAD_EXCP_ALL << CPSR_F_SHIFT); @@ -256,8 +252,8 @@ void thread_set_exceptions(uint32_t exceptions) { uint32_t daif = read_daif(); - /* IRQ must not be unmasked while holding a spinlock */ - if (!(exceptions & THREAD_EXCP_IRQ)) + /* Foreign interrupts must not be unmasked while holding a spinlock */ + if (!(exceptions & THREAD_EXCP_FOREIGN_INTR)) assert_have_no_spinlock(); daif &= ~(THREAD_EXCP_ALL << DAIF_F_SHIFT); @@ -285,11 +281,11 @@ struct thread_core_local *thread_get_core_local(void) uint32_t cpu_id = get_core_pos(); /* - * IRQs must be disabled before playing with core_local since - * we otherwise may be rescheduled to a different core in the + * Foreign interrupts must be disabled before playing with core_local + * since we otherwise may be rescheduled to a different core in the * middle of this function. */ - assert(thread_get_exceptions() & THREAD_EXCP_IRQ); + assert(thread_get_exceptions() & THREAD_EXCP_FOREIGN_INTR); assert(cpu_id < CFG_TEE_CORE_NB_CORE); return &thread_core_local[cpu_id]; @@ -338,11 +334,12 @@ static void init_regs(struct thread_ctx *thread, thread->regs.pc = (uint32_t)thread_std_smc_entry; /* - * Stdcalls starts in SVC mode with masked IRQ, masked Asynchronous - * abort and unmasked FIQ. - */ + * Stdcalls starts in SVC mode with masked foreign interrupts, masked + * Asynchronous abort and unmasked native interrupts. + */ thread->regs.cpsr = read_cpsr() & ARM32_CPSR_E; - thread->regs.cpsr |= CPSR_MODE_SVC | CPSR_I | CPSR_A; + thread->regs.cpsr |= CPSR_MODE_SVC | CPSR_A | + (THREAD_EXCP_FOREIGN_INTR << ARM32_CPSR_F_SHIFT); /* Enable thumb mode if it's a thumb instruction */ if (thread->regs.pc & 1) thread->regs.cpsr |= CPSR_T; @@ -371,11 +368,11 @@ static void init_regs(struct thread_ctx *thread, thread->regs.pc = (uint64_t)thread_std_smc_entry; /* - * Stdcalls starts in SVC mode with masked IRQ, masked Asynchronous - * abort and unmasked FIQ. - */ + * Stdcalls starts in SVC mode with masked foreign interrupts, masked + * Asynchronous abort and unmasked native interrupts. + */ thread->regs.cpsr = SPSR_64(SPSR_64_MODE_EL1, SPSR_64_MODE_SP_EL0, - DAIFBIT_IRQ | DAIFBIT_ABT); + THREAD_EXCP_FOREIGN_INTR | DAIFBIT_ABT); /* Reinitialize stack pointer */ thread->regs.sp = thread->stack_va_end; @@ -556,7 +553,7 @@ static void thread_resume_from_rpc(struct thread_smc_args *args) core_mmu_set_user_map(&threads[n].user_map); /* - * Return from RPC to request service of an IRQ must not + * Return from RPC to request service of a foreign interrupt must not * get parameters from non-secure world. */ if (threads[n].flags & THREAD_FLAGS_COPY_ARGS_ON_RETURN) { @@ -769,8 +766,10 @@ bool thread_init_stack(uint32_t thread_id, vaddr_t sp) int thread_get_id_may_fail(void) { - /* thread_get_core_local() requires IRQs to be disabled */ - uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ); + /* + * thread_get_core_local() requires foreign interrupts to be disabled + */ + uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_FOREIGN_INTR); struct thread_core_local *l = thread_get_core_local(); int ct = l->curr_thread; @@ -790,7 +789,7 @@ static void init_handlers(const struct thread_handlers *handlers) { thread_std_smc_handler_ptr = handlers->std_smc; thread_fast_smc_handler_ptr = handlers->fast_smc; - thread_fiq_handler_ptr = handlers->fiq; + thread_nintr_handler_ptr = handlers->nintr; thread_cpu_on_handler_ptr = handlers->cpu_on; thread_cpu_off_handler_ptr = handlers->cpu_off; thread_cpu_suspend_handler_ptr = handlers->cpu_suspend; @@ -890,10 +889,10 @@ struct thread_ctx_regs *thread_get_ctx_regs(void) return &threads[l->curr_thread].regs; } -void thread_set_irq(bool enable) +void thread_set_foreign_intr(bool enable) { - /* thread_get_core_local() requires IRQs to be disabled */ - uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ); + /* thread_get_core_local() requires foreign interrupts to be disabled */ + uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_FOREIGN_INTR); struct thread_core_local *l; l = thread_get_core_local(); @@ -901,35 +900,37 @@ void thread_set_irq(bool enable) assert(l->curr_thread != -1); if (enable) { - threads[l->curr_thread].flags |= THREAD_FLAGS_IRQ_ENABLE; - thread_set_exceptions(exceptions & ~THREAD_EXCP_IRQ); + threads[l->curr_thread].flags |= + THREAD_FLAGS_FOREIGN_INTR_ENABLE; + thread_set_exceptions(exceptions & ~THREAD_EXCP_FOREIGN_INTR); } else { /* - * No need to disable IRQ here since it's already disabled - * above. + * No need to disable foreign interrupts here since they're + * already disabled above. */ - threads[l->curr_thread].flags &= ~THREAD_FLAGS_IRQ_ENABLE; + threads[l->curr_thread].flags &= + ~THREAD_FLAGS_FOREIGN_INTR_ENABLE; } } -void thread_restore_irq(void) +void thread_restore_foreign_intr(void) { - /* thread_get_core_local() requires IRQs to be disabled */ - uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ); + /* thread_get_core_local() requires foreign interrupts to be disabled */ + uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_FOREIGN_INTR); struct thread_core_local *l; l = thread_get_core_local(); assert(l->curr_thread != -1); - if (threads[l->curr_thread].flags & THREAD_FLAGS_IRQ_ENABLE) - thread_set_exceptions(exceptions & ~THREAD_EXCP_IRQ); + if (threads[l->curr_thread].flags & THREAD_FLAGS_FOREIGN_INTR_ENABLE) + thread_set_exceptions(exceptions & ~THREAD_EXCP_FOREIGN_INTR); } #ifdef CFG_WITH_VFP uint32_t thread_kernel_enable_vfp(void) { - uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ); + uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_FOREIGN_INTR); struct thread_ctx *thr = threads + thread_get_id(); struct thread_user_vfp_state *tuv = thr->vfp_state.uvfp; @@ -967,9 +968,9 @@ void thread_kernel_disable_vfp(uint32_t state) vfp_disable(); exceptions = thread_get_exceptions(); - assert(exceptions & THREAD_EXCP_IRQ); - exceptions &= ~THREAD_EXCP_IRQ; - exceptions |= state & THREAD_EXCP_IRQ; + assert(exceptions & THREAD_EXCP_FOREIGN_INTR); + exceptions &= ~THREAD_EXCP_FOREIGN_INTR; + exceptions |= state & THREAD_EXCP_FOREIGN_INTR; thread_set_exceptions(exceptions); } @@ -977,7 +978,7 @@ void thread_kernel_save_vfp(void) { struct thread_ctx *thr = threads + thread_get_id(); - assert(thread_get_exceptions() & THREAD_EXCP_IRQ); + assert(thread_get_exceptions() & THREAD_EXCP_FOREIGN_INTR); if (vfp_is_enabled()) { vfp_lazy_save_state_init(&thr->vfp_state.sec); thr->vfp_state.sec_lazy_saved = true; @@ -988,7 +989,7 @@ void thread_kernel_restore_vfp(void) { struct thread_ctx *thr = threads + thread_get_id(); - assert(thread_get_exceptions() & THREAD_EXCP_IRQ); + assert(thread_get_exceptions() & THREAD_EXCP_FOREIGN_INTR); assert(!vfp_is_enabled()); if (thr->vfp_state.sec_lazy_saved) { vfp_lazy_restore_state(&thr->vfp_state.sec, @@ -1003,7 +1004,7 @@ void thread_user_enable_vfp(struct thread_user_vfp_state *uvfp) struct thread_ctx *thr = threads + thread_get_id(); struct thread_user_vfp_state *tuv = thr->vfp_state.uvfp; - assert(thread_get_exceptions() & THREAD_EXCP_IRQ); + assert(thread_get_exceptions() & THREAD_EXCP_FOREIGN_INTR); assert(!vfp_is_enabled()); if (!thr->vfp_state.ns_saved) { @@ -1030,7 +1031,7 @@ void thread_user_save_vfp(void) struct thread_ctx *thr = threads + thread_get_id(); struct thread_user_vfp_state *tuv = thr->vfp_state.uvfp; - assert(thread_get_exceptions() & THREAD_EXCP_IRQ); + assert(thread_get_exceptions() & THREAD_EXCP_FOREIGN_INTR); if (!vfp_is_enabled()) return; @@ -1110,7 +1111,7 @@ void thread_add_mutex(struct mutex *m) int ct = l->curr_thread; assert(ct != -1 && threads[ct].state == THREAD_STATE_ACTIVE); - assert(m->owner_id == -1); + assert(m->owner_id == MUTEX_OWNER_ID_NONE); m->owner_id = ct; TAILQ_INSERT_TAIL(&threads[ct].mutexes, m, link); } @@ -1122,7 +1123,7 @@ void thread_rem_mutex(struct mutex *m) assert(ct != -1 && threads[ct].state == THREAD_STATE_ACTIVE); assert(m->owner_id == ct); - m->owner_id = -1; + m->owner_id = MUTEX_OWNER_ID_NONE; TAILQ_REMOVE(&threads[ct].mutexes, m, link); } @@ -1130,7 +1131,7 @@ bool thread_disable_prealloc_rpc_cache(uint64_t *cookie) { bool rv; size_t n; - uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ); + uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_FOREIGN_INTR); lock_global(); @@ -1163,7 +1164,7 @@ bool thread_enable_prealloc_rpc_cache(void) { bool rv; size_t n; - uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ); + uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_FOREIGN_INTR); lock_global(); @@ -1194,7 +1195,14 @@ static uint32_t rpc_cmd_nolock(uint32_t cmd, size_t num_params, assert(arg && carg && num_params <= THREAD_RPC_MAX_NUM_PARAMS); - plat_prng_add_jitter_entropy(); + + /* + * Break recursion in case plat_prng_add_jitter_entropy_norpc() + * sleeps on a mutex or unlocks a mutex with a sleeper (contended + * mutex). + */ + if (cmd != OPTEE_MSG_RPC_CMD_WAIT_QUEUE) + plat_prng_add_jitter_entropy_norpc(); memset(arg, 0, OPTEE_MSG_GET_ARG_SIZE(THREAD_RPC_MAX_NUM_PARAMS)); arg->cmd = cmd; diff --git a/core/arch/arm/kernel/thread_a32.S b/core/arch/arm/kernel/thread_a32.S index 6d3ac35..1a1c696 100644 --- a/core/arch/arm/kernel/thread_a32.S +++ b/core/arch/arm/kernel/thread_a32.S @@ -75,7 +75,7 @@ UNWIND( .fnstart) UNWIND( .cantunwind) /* Secure Monitor received a FIQ and passed control to us. */ bl thread_check_canaries - ldr lr, =thread_fiq_handler_ptr + ldr lr, =thread_nintr_handler_ptr ldr lr, [lr] blx lr mov r1, r0 @@ -392,7 +392,7 @@ UNWIND( .cantunwind) */ push {r0-r3, r8-r12, lr} bl thread_check_canaries - ldr lr, =thread_fiq_handler_ptr + ldr lr, =thread_nintr_handler_ptr ldr lr, [lr] blx lr pop {r0-r3, r8-r12, lr} @@ -416,7 +416,7 @@ UNWIND( .cantunwind) bl thread_save_state - mov r0, #THREAD_FLAGS_EXIT_ON_IRQ + mov r0, #THREAD_FLAGS_EXIT_ON_FOREIGN_INTR mrs r1, spsr pop {r12} pop {r2} @@ -432,7 +432,7 @@ UNWIND( .cantunwind) mov sp, r0 ldr r0, =TEESMC_OPTEED_RETURN_CALL_DONE - ldr r1, =OPTEE_SMC_RETURN_RPC_IRQ + ldr r1, =OPTEE_SMC_RETURN_RPC_FOREIGN_INTR mov r2, #0 mov r3, #0 /* r4 is already filled in above */ diff --git a/core/arch/arm/kernel/thread_a64.S b/core/arch/arm/kernel/thread_a64.S index abd482b..241868a 100644 --- a/core/arch/arm/kernel/thread_a64.S +++ b/core/arch/arm/kernel/thread_a64.S @@ -77,7 +77,7 @@ END_FUNC vector_fast_smc_entry LOCAL_FUNC vector_fiq_entry , : /* Secure Monitor received a FIQ and passed control to us. */ bl thread_check_canaries - adr x16, thread_fiq_handler_ptr + adr x16, thread_nintr_handler_ptr ldr x16, [x16] blr x16 ldr x0, =TEESMC_OPTEED_RETURN_FIQ_DONE @@ -487,9 +487,9 @@ LOCAL_FUNC el0_svc , : mov x0, sp /* - * Unmask FIQ, Serror, and debug exceptions since we have nothing - * left in sp_el1. Note that the SVC handler is excepted to - * re-enable IRQs by itself. + * Unmask native interrupts, Serror, and debug exceptions since we have + * nothing left in sp_el1. Note that the SVC handler is excepted to + * re-enable foreign interrupts by itself. */ msr daifclr, #(DAIFBIT_FIQ | DAIFBIT_ABT | DAIFBIT_DBG) @@ -713,7 +713,7 @@ LOCAL_FUNC elx_irq , : /* * Mark current thread as suspended */ - mov w0, #THREAD_FLAGS_EXIT_ON_IRQ + mov w0, #THREAD_FLAGS_EXIT_ON_FOREIGN_INTR mrs x1, spsr_el1 mrs x2, elr_el1 bl thread_state_suspend @@ -734,7 +734,7 @@ LOCAL_FUNC elx_irq , : */ ldr w0, =TEESMC_OPTEED_RETURN_CALL_DONE - ldr w1, =OPTEE_SMC_RETURN_RPC_IRQ + ldr w1, =OPTEE_SMC_RETURN_RPC_FOREIGN_INTR mov w2, #0 mov w3, #0 /* w4 is already filled in above */ @@ -787,7 +787,7 @@ LOCAL_FUNC elx_fiq , : stp x30, x2, [sp, #ELX_FIQ_REC_LR] bl thread_check_canaries - adr x16, thread_fiq_handler_ptr + adr x16, thread_nintr_handler_ptr ldr x16, [x16] blr x16 diff --git a/core/arch/arm/kernel/trace_ext.c b/core/arch/arm/kernel/trace_ext.c index 8b8454c..6cedba3 100644 --- a/core/arch/arm/kernel/trace_ext.c +++ b/core/arch/arm/kernel/trace_ext.c @@ -27,21 +27,40 @@ #include <stdbool.h> #include <trace.h> #include <console.h> +#include <kernel/spinlock.h> #include <kernel/thread.h> +#include <mm/core_mmu.h> const char trace_ext_prefix[] = "TEE-CORE"; int trace_level = TRACE_LEVEL; +static unsigned int puts_lock = SPINLOCK_UNLOCK; void trace_ext_puts(const char *str) { + uint32_t itr_status = thread_mask_exceptions(THREAD_EXCP_ALL); + bool mmu_enabled = cpu_mmu_enabled(); + bool was_contended = false; const char *p; + if (mmu_enabled && !cpu_spin_trylock(&puts_lock)) { + was_contended = true; + cpu_spin_lock(&puts_lock); + } + console_flush(); + if (was_contended) + console_putc('*'); + for (p = str; *p; p++) console_putc(*p); console_flush(); + + if (mmu_enabled) + cpu_spin_unlock(&puts_lock); + + thread_unmask_exceptions(itr_status); } int trace_ext_get_thread_id(void) diff --git a/core/arch/arm/kernel/user_ta.c b/core/arch/arm/kernel/user_ta.c index a63fb22..5c9aae8 100644 --- a/core/arch/arm/kernel/user_ta.c +++ b/core/arch/arm/kernel/user_ta.c @@ -194,8 +194,8 @@ static TEE_Result config_final_paging(struct user_ta_ctx *utc) size_t vasize = utc->mmu->ta_private_vmem_end - utc->mmu->ta_private_vmem_start; - cache_maintenance_l1(DCACHE_AREA_CLEAN, va, vasize); - cache_maintenance_l1(ICACHE_AREA_INVALIDATE, va, vasize); + cache_op_inner(DCACHE_AREA_CLEAN, va, vasize); + cache_op_inner(ICACHE_AREA_INVALIDATE, va, vasize); return TEE_SUCCESS; } #endif /*!CFG_PAGED_USER_TA*/ @@ -386,7 +386,7 @@ static TEE_Result ta_load(const TEE_UUID *uuid, const struct shdr *signed_ta, uint32_t man_flags = TA_FLAG_USER_MODE | TA_FLAG_EXEC_DDR; /* opt_flags: optional flags */ uint32_t opt_flags = man_flags | TA_FLAG_SINGLE_INSTANCE | - TA_FLAG_MULTI_SESSION | TA_FLAG_UNSAFE_NW_PARAMS | + TA_FLAG_MULTI_SESSION | TA_FLAG_SECURE_DATA_PATH | TA_FLAG_INSTANCE_KEEP_ALIVE | TA_FLAG_CACHE_MAINTENANCE; struct user_ta_ctx *utc = NULL; struct shdr *sec_shdr = NULL; @@ -748,8 +748,8 @@ static void user_ta_ctx_destroy(struct tee_ta_ctx *ctx) va = mobj_get_va(utc->mobj_code, 0); if (va) { memset(va, 0, utc->mobj_code->size); - cache_maintenance_l1(DCACHE_AREA_CLEAN, va, - utc->mobj_code->size); + cache_op_inner(DCACHE_AREA_CLEAN, va, + utc->mobj_code->size); } } @@ -757,8 +757,8 @@ static void user_ta_ctx_destroy(struct tee_ta_ctx *ctx) va = mobj_get_va(utc->mobj_stack, 0); if (va) { memset(va, 0, utc->mobj_stack->size); - cache_maintenance_l1(DCACHE_AREA_CLEAN, va, - utc->mobj_stack->size); + cache_op_inner(DCACHE_AREA_CLEAN, va, + utc->mobj_stack->size); } } } diff --git a/core/arch/arm/kernel/wait_queue.c b/core/arch/arm/kernel/wait_queue.c index a96e0fe..6fb4456 100644 --- a/core/arch/arm/kernel/wait_queue.c +++ b/core/arch/arm/kernel/wait_queue.c @@ -43,7 +43,8 @@ void wq_init(struct wait_queue *wq) } static void wq_rpc(uint32_t func, int id, const void *sync_obj __maybe_unused, - const char *fname, int lineno __maybe_unused) + int owner __maybe_unused, const char *fname, + int lineno __maybe_unused) { uint32_t ret; struct optee_msg_param params; @@ -51,10 +52,10 @@ static void wq_rpc(uint32_t func, int id, const void *sync_obj __maybe_unused, func == OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP ? "sleep" : "wake "; if (fname) - DMSG("%s thread %u %p %s:%d", cmd_str, id, - sync_obj, fname, lineno); + DMSG("%s thread %u %p %d %s:%d", cmd_str, id, + sync_obj, owner, fname, lineno); else - DMSG("%s thread %u %p", cmd_str, id, sync_obj); + DMSG("%s thread %u %p %d", cmd_str, id, sync_obj, owner); memset(¶ms, 0, sizeof(params)); params.attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; @@ -99,14 +100,15 @@ void wq_wait_init_condvar(struct wait_queue *wq, struct wait_queue_elem *wqe, } void wq_wait_final(struct wait_queue *wq, struct wait_queue_elem *wqe, - const void *sync_obj, const char *fname, int lineno) + const void *sync_obj, int owner, const char *fname, + int lineno) { uint32_t old_itr_status; unsigned done; do { wq_rpc(OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP, wqe->handle, - sync_obj, fname, lineno); + sync_obj, owner, fname, lineno); old_itr_status = thread_mask_exceptions(THREAD_EXCP_ALL); cpu_spin_lock(&wq_spin_lock); @@ -145,7 +147,7 @@ void wq_wake_one(struct wait_queue *wq, const void *sync_obj, if (do_wakeup) wq_rpc(OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP, handle, - sync_obj, fname, lineno); + sync_obj, MUTEX_OWNER_ID_MUTEX_UNLOCK, fname, lineno); } void wq_promote_condvar(struct wait_queue *wq, struct condvar *cv, diff --git a/core/arch/arm/mm/core_mmu.c b/core/arch/arm/mm/core_mmu.c index 62dda73..f85e496 100644 --- a/core/arch/arm/mm/core_mmu.c +++ b/core/arch/arm/mm/core_mmu.c @@ -101,6 +101,10 @@ static struct memaccess_area nsec_shared[] = { MEMACCESS_AREA(CFG_SHMEM_START, CFG_SHMEM_SIZE), }; +#ifdef CFG_TEE_SDP_MEM_BASE +register_sdp_mem(CFG_TEE_SDP_MEM_BASE, CFG_TEE_SDP_MEM_SIZE); +#endif + register_phys_mem(MEM_AREA_TEE_RAM, CFG_TEE_RAM_START, CFG_TEE_RAM_PH_SIZE); register_phys_mem(MEM_AREA_TA_RAM, CFG_TA_RAM_START, CFG_TA_RAM_SIZE); register_phys_mem(MEM_AREA_NSEC_SHM, CFG_SHMEM_START, CFG_SHMEM_SIZE); @@ -222,6 +226,107 @@ static struct tee_mmap_region *find_map_by_pa(unsigned long pa) return NULL; } +#ifdef CFG_SECURE_DATA_PATH +extern const struct core_mmu_phys_mem __start_phys_sdp_mem_section; +extern const struct core_mmu_phys_mem __end_phys_sdp_mem_section; + +static bool pbuf_is_sdp_mem(paddr_t pbuf, size_t len) +{ + const struct core_mmu_phys_mem *mem; + + for (mem = &__start_phys_sdp_mem_section; + mem < &__end_phys_sdp_mem_section; mem++) + if (core_is_buffer_inside(pbuf, len, mem->addr, mem->size)) + return true; + + return false; +} + +#define MSG_SDP_INSTERSECT(pa1, sz1, pa2, sz2) \ + EMSG("[%" PRIxPA " %" PRIxPA "] intersecs [%" PRIxPA " %" PRIxPA "]", \ + pa1, pa1 + sz1, pa2, pa2 + sz2) + +/* Check SDP memories comply with registered memories */ +static void verify_sdp_mem_areas(struct tee_mmap_region *mem_map, size_t len) +{ + const struct core_mmu_phys_mem *mem; + const struct core_mmu_phys_mem *mem2; + const struct core_mmu_phys_mem *start = &__start_phys_sdp_mem_section; + const struct core_mmu_phys_mem *end = &__end_phys_sdp_mem_section; + struct tee_mmap_region *mmap; + size_t n; + + if (start == end) { + IMSG("Secure data path enabled without any SDP memory area"); + return; + } + + for (mem = start; mem < end; mem++) + DMSG("SDP memory [%" PRIxPA " %" PRIxPA "]", + mem->addr, mem->addr + mem->size); + + /* Check SDP memories do not intersect each other */ + for (mem = start; mem < end - 1; mem++) { + for (mem2 = mem + 1; mem2 < end; mem2++) { + if (core_is_buffer_intersect(mem2->addr, mem2->size, + mem->addr, mem->size)) { + MSG_SDP_INSTERSECT(mem2->addr, mem2->size, + mem->addr, mem->size); + panic("SDP memory intersection"); + } + } + } + + /* + * Check SDP memories do not intersect any mapped memory. + * This is called before reserved VA space is loaded in mem_map. + */ + for (mem = start; mem < end; mem++) { + for (mmap = mem_map, n = 0; n < len; mmap++, n++) { + if (core_is_buffer_intersect(mem->addr, mem->size, + mmap->pa, mmap->size)) { + MSG_SDP_INSTERSECT(mem->addr, mem->size, + mmap->pa, mmap->size); + panic("SDP memory intersection"); + } + } + } +} + +struct mobj **core_sdp_mem_create_mobjs(void) +{ + const struct core_mmu_phys_mem *mem; + struct mobj **mobj_base; + struct mobj **mobj; + int cnt = &__end_phys_sdp_mem_section - &__start_phys_sdp_mem_section; + + /* SDP mobjs table must end with a NULL entry */ + mobj_base = calloc(cnt + 1, sizeof(struct mobj *)); + if (!mobj_base) + panic("Out of memory"); + + for (mem = &__start_phys_sdp_mem_section, mobj = mobj_base; + mem < &__end_phys_sdp_mem_section; mem++, mobj++) { + *mobj = mobj_phys_alloc(mem->addr, mem->size, + TEE_MATTR_CACHE_CACHED, + CORE_MEM_SDP_MEM); + if (!*mobj) + panic("can't create SDP physical memory object"); + } + return mobj_base; +} +#else /* CFG_SECURE_DATA_PATH */ +static bool pbuf_is_sdp_mem(paddr_t pbuf __unused, size_t len __unused) +{ + return false; +} + +static void verify_sdp_mem_areas(struct tee_mmap_region *mem_map __unused, + size_t len __unused) +{ +} +#endif /* CFG_SECURE_DATA_PATH */ + extern const struct core_mmu_phys_mem __start_phys_mem_map_section; extern const struct core_mmu_phys_mem __end_phys_mem_map_section; @@ -353,6 +458,8 @@ static void init_mem_map(struct tee_mmap_region *memory_map, size_t num_elems) add_phys_mem(memory_map, num_elems, &m, &last); } + verify_sdp_mem_areas(memory_map, num_elems); + add_va_space(memory_map, num_elems, MEM_AREA_RES_VASPACE, RES_VASPACE_SIZE, &last); @@ -382,7 +489,7 @@ static void init_mem_map(struct tee_mmap_region *memory_map, size_t num_elems) assert(map->type == MEM_AREA_TEE_RAM); map->va = map->pa; #ifdef CFG_WITH_PAGER - map->region_size = SMALL_PAGE_SIZE, + map->region_size = SMALL_PAGE_SIZE; #endif map->attr = core_mmu_type_to_attr(map->type); @@ -393,6 +500,7 @@ static void init_mem_map(struct tee_mmap_region *memory_map, size_t num_elems) while (map->type != MEM_AREA_NOTYPE) { map->attr = core_mmu_type_to_attr(map->type); va -= map->size; + va = ROUNDDOWN(va, map->region_size); map->va = va; map++; } @@ -413,6 +521,7 @@ static void init_mem_map(struct tee_mmap_region *memory_map, size_t num_elems) map++; while (map->type != MEM_AREA_NOTYPE) { map->attr = core_mmu_type_to_attr(map->type); + va = ROUNDUP(va, map->region_size); map->va = va; va += map->size; map++; @@ -541,6 +650,8 @@ bool core_pbuf_is(uint32_t attr, paddr_t pbuf, size_t len) return pbuf_inside_map_area(pbuf, len, map_ta_ram); case CORE_MEM_NSEC_SHM: return pbuf_inside_map_area(pbuf, len, map_nsec_shm); + case CORE_MEM_SDP_MEM: + return pbuf_is_sdp_mem(pbuf, len); case CORE_MEM_EXTRAM: return pbuf_is_inside(ddr, pbuf, len); case CORE_MEM_CACHED: @@ -648,7 +759,7 @@ int core_tlb_maintenance(int op, unsigned int a) return 0; } -unsigned int cache_maintenance_l1(int op, void *va, size_t len) +TEE_Result cache_op_inner(enum cache_op op, void *va, size_t len) { switch (op) { case DCACHE_CLEAN: @@ -672,10 +783,6 @@ unsigned int cache_maintenance_l1(int op, void *va, size_t len) if (len) arm_cl1_i_inv(va, (char *)va + len - 1); break; - case WRITE_BUFFER_DRAIN: - DMSG("unsupported operation 0x%X (WRITE_BUFFER_DRAIN)", - (unsigned int)op); - return -1; case DCACHE_CLEAN_INV: arm_cl1_d_cleaninvbysetway(); break; @@ -690,31 +797,31 @@ unsigned int cache_maintenance_l1(int op, void *va, size_t len) } #ifdef CFG_PL310 -unsigned int cache_maintenance_l2(int op, paddr_t pa, size_t len) +TEE_Result cache_op_outer(enum cache_op op, paddr_t pa, size_t len) { - unsigned int ret = TEE_SUCCESS; - uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ); + TEE_Result ret = TEE_SUCCESS; + uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_FOREIGN_INTR); tee_l2cc_mutex_lock(); switch (op) { - case L2CACHE_INVALIDATE: + case DCACHE_INVALIDATE: arm_cl2_invbyway(pl310_base()); break; - case L2CACHE_AREA_INVALIDATE: + case DCACHE_AREA_INVALIDATE: if (len) arm_cl2_invbypa(pl310_base(), pa, pa + len - 1); break; - case L2CACHE_CLEAN: + case DCACHE_CLEAN: arm_cl2_cleanbyway(pl310_base()); break; - case L2CACHE_AREA_CLEAN: + case DCACHE_AREA_CLEAN: if (len) arm_cl2_cleanbypa(pl310_base(), pa, pa + len - 1); break; - case L2CACHE_CLEAN_INV: + case DCACHE_CLEAN_INV: arm_cl2_cleaninvbyway(pl310_base()); break; - case L2CACHE_AREA_CLEAN_INV: + case DCACHE_AREA_CLEAN_INV: if (len) arm_cl2_cleaninvbypa(pl310_base(), pa, pa + len - 1); break; @@ -1163,6 +1270,21 @@ void *phys_to_virt(paddr_t pa, enum teecore_memtypes m) return va; } +void *phys_to_virt_io(paddr_t pa) +{ + struct tee_mmap_region *map; + void *va; + + map = find_map_by_type_and_pa(MEM_AREA_IO_SEC, pa); + if (!map) + map = find_map_by_type_and_pa(MEM_AREA_IO_NSEC, pa); + if (!map) + return NULL; + va = map_pa2va(map, pa); + check_va_matches_pa(pa, va); + return va; +} + bool cpu_mmu_enabled(void) { uint32_t sctlr; diff --git a/core/arch/arm/mm/core_mmu_lpae.c b/core/arch/arm/mm/core_mmu_lpae.c index eb96c70..7a5d74a 100644 --- a/core/arch/arm/mm/core_mmu_lpae.c +++ b/core/arch/arm/mm/core_mmu_lpae.c @@ -640,7 +640,7 @@ bool core_mmu_find_table(vaddr_t va, unsigned max_level, if (!tbl) return false; - va_base += n << level_size_shift; + va_base += (vaddr_t)n << level_size_shift; level++; num_entries = XLAT_TABLE_ENTRIES; } diff --git a/core/arch/arm/mm/mobj.c b/core/arch/arm/mm/mobj.c index 5458638..6daef50 100644 --- a/core/arch/arm/mm/mobj.c +++ b/core/arch/arm/mm/mobj.c @@ -114,12 +114,13 @@ static bool mobj_phys_matches(struct mobj *mobj, enum buf_is_attr attr) switch (attr) { case CORE_MEM_SEC: return a == CORE_MEM_SEC || a == CORE_MEM_TEE_RAM || - a == CORE_MEM_TA_RAM; + a == CORE_MEM_TA_RAM || a == CORE_MEM_SDP_MEM; case CORE_MEM_NON_SEC: return a == CORE_MEM_NSEC_SHM; case CORE_MEM_TEE_RAM: case CORE_MEM_TA_RAM: case CORE_MEM_NSEC_SHM: + case CORE_MEM_SDP_MEM: return attr == a; default: return false; @@ -151,6 +152,7 @@ struct mobj *mobj_phys_alloc(paddr_t pa, size_t size, uint32_t cattr, enum buf_is_attr battr) { struct mobj_phys *moph; + enum teecore_memtypes area_type; void *va; if ((pa & CORE_MMU_USER_PARAM_MASK) || @@ -159,8 +161,27 @@ struct mobj *mobj_phys_alloc(paddr_t pa, size_t size, uint32_t cattr, return NULL; } - va = phys_to_virt(pa, battr); - if (!va) + switch (battr) { + case CORE_MEM_TEE_RAM: + area_type = MEM_AREA_TEE_RAM; + break; + case CORE_MEM_TA_RAM: + area_type = MEM_AREA_TA_RAM; + break; + case CORE_MEM_NSEC_SHM: + area_type = MEM_AREA_NSEC_SHM; + break; + case CORE_MEM_SDP_MEM: + area_type = MEM_AREA_SDP_MEM; + break; + default: + DMSG("can't allocate with specified attribute"); + return NULL; + } + + /* Only SDP memory may not have a virtual address */ + va = phys_to_virt(pa, area_type); + if (!va && battr != CORE_MEM_SDP_MEM) return NULL; moph = calloc(1, sizeof(*moph)); diff --git a/core/arch/arm/mm/tee_pager.c b/core/arch/arm/mm/tee_pager.c index c7238fe..c75eee8 100644 --- a/core/arch/arm/mm/tee_pager.c +++ b/core/arch/arm/mm/tee_pager.c @@ -891,10 +891,10 @@ bool tee_pager_set_uta_area_attr(struct user_ta_ctx *utc, vaddr_t base, void *va = (void *)area_idx2va(pmem->area, pmem->pgidx); - cache_maintenance_l1(DCACHE_AREA_CLEAN, va, - SMALL_PAGE_SIZE); - cache_maintenance_l1(ICACHE_AREA_INVALIDATE, va, - SMALL_PAGE_SIZE); + cache_op_inner(DCACHE_AREA_CLEAN, va, + SMALL_PAGE_SIZE); + cache_op_inner(ICACHE_AREA_INVALIDATE, va, + SMALL_PAGE_SIZE); } } @@ -1269,10 +1269,9 @@ bool tee_pager_handle_fault(struct abort_info *ai) * Doing these operations to LoUIS (Level of * unification, Inner Shareable) would be enough */ - cache_maintenance_l1(DCACHE_AREA_CLEAN, - pmem->va_alias, SMALL_PAGE_SIZE); - - cache_maintenance_l1(ICACHE_INVALIDATE, NULL, 0); + cache_op_inner(DCACHE_AREA_CLEAN, pmem->va_alias, + SMALL_PAGE_SIZE); + cache_op_inner(ICACHE_INVALIDATE, NULL, 0); } pmem->area = area; diff --git a/core/arch/arm/plat-d02/main.c b/core/arch/arm/plat-d02/main.c index 95161d1..2cd339b 100644 --- a/core/arch/arm/plat-d02/main.c +++ b/core/arch/arm/plat-d02/main.c @@ -42,7 +42,7 @@ static void main_fiq(void); static const struct thread_handlers handlers = { .std_smc = tee_entry_std, .fast_smc = tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, .cpu_on = cpu_on_handler, .cpu_off = pm_do_nothing, .cpu_suspend = pm_do_nothing, @@ -51,6 +51,8 @@ static const struct thread_handlers handlers = { .system_reset = pm_do_nothing, }; +static struct hi16xx_uart_data console_data __early_bss; + register_phys_mem(MEM_AREA_IO_NSEC, CONSOLE_UART_BASE, HI16XX_UART_REG_SIZE); const struct thread_handlers *generic_boot_get_handlers(void) @@ -63,34 +65,9 @@ static void main_fiq(void) panic(); } -static vaddr_t console_base(void) -{ - static void *va; - - if (cpu_mmu_enabled()) { - if (!va) - va = phys_to_virt(CONSOLE_UART_BASE, MEM_AREA_IO_NSEC); - return (vaddr_t)va; - } - return CONSOLE_UART_BASE; -} - void console_init(void) { - hi16xx_uart_init(console_base(), CONSOLE_UART_CLK_IN_HZ, - CONSOLE_BAUDRATE); -} - -void console_putc(int ch) -{ - vaddr_t base = console_base(); - - if (ch == '\n') - hi16xx_uart_putc('\r', base); - hi16xx_uart_putc(ch, base); -} - -void console_flush(void) -{ - hi16xx_uart_flush(console_base()); + hi16xx_uart_init(&console_data, CONSOLE_UART_BASE, + CONSOLE_UART_CLK_IN_HZ, CONSOLE_BAUDRATE); + register_serial_console(&console_data.chip); } diff --git a/core/arch/arm/plat-hikey/main.c b/core/arch/arm/plat-hikey/main.c index 36789ce..8d72f38 100644 --- a/core/arch/arm/plat-hikey/main.c +++ b/core/arch/arm/plat-hikey/main.c @@ -49,7 +49,7 @@ static void main_fiq(void); static const struct thread_handlers handlers = { .std_smc = tee_entry_std, .fast_smc = tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, .cpu_on = cpu_on_handler, .cpu_off = pm_do_nothing, .cpu_suspend = pm_do_nothing, @@ -58,6 +58,8 @@ static const struct thread_handlers handlers = { .system_reset = pm_do_nothing, }; +static struct pl011_data console_data __early_bss; + register_phys_mem(MEM_AREA_IO_NSEC, CONSOLE_UART_BASE, PL011_REG_SIZE); register_phys_mem(MEM_AREA_IO_NSEC, PMUSSI_BASE, PMUSSI_REG_SIZE); #ifdef CFG_SPI @@ -78,35 +80,11 @@ static void main_fiq(void) panic(); } -static vaddr_t console_base(void) -{ - static void *va; - - if (cpu_mmu_enabled()) { - if (!va) - va = phys_to_virt(CONSOLE_UART_BASE, MEM_AREA_IO_NSEC); - return (vaddr_t)va; - } - return CONSOLE_UART_BASE; -} - void console_init(void) { - pl011_init(console_base(), CONSOLE_UART_CLK_IN_HZ, CONSOLE_BAUDRATE); -} - -void console_putc(int ch) -{ - vaddr_t base = console_base(); - - if (ch == '\n') - pl011_putc('\r', base); - pl011_putc(ch, base); -} - -void console_flush(void) -{ - pl011_flush(console_base()); + pl011_init(&console_data, CONSOLE_UART_BASE, CONSOLE_UART_CLK_IN_HZ, + CONSOLE_BAUDRATE); + register_serial_console(&console_data.chip); } vaddr_t nsec_periph_base(paddr_t pa) diff --git a/core/arch/arm/plat-imx/a9_plat_init.S b/core/arch/arm/plat-imx/a9_plat_init.S index 64d03f5..db13018 100644 --- a/core/arch/arm/plat-imx/a9_plat_init.S +++ b/core/arch/arm/plat-imx/a9_plat_init.S @@ -85,7 +85,7 @@ UNWIND( .fnstart) * - NSec cannot access PLE (PLE bit16=0) * - NSec can use SIMD/VFP (CP10/CP11) (bit15:14=2b00, bit11:10=2b11) * - * PCR = 0x00000001 + * PCR * - no change latency, enable clk gating */ movw r0, #0x4000 @@ -100,8 +100,8 @@ UNWIND( .fnstart) movt r0, #0x0002 write_nsacr r0 - movw r0, #0x0000 - movt r0, #0x0001 + read_pcr r0 + orr r0, r0, #0x1 write_pcr r0 mov pc, lr diff --git a/core/arch/arm/plat-imx/conf.mk b/core/arch/arm/plat-imx/conf.mk index 785736a..d780228 100644 --- a/core/arch/arm/plat-imx/conf.mk +++ b/core/arch/arm/plat-imx/conf.mk @@ -3,7 +3,7 @@ PLATFORM_FLAVOR ?= mx6ulevk ifeq ($(PLATFORM_FLAVOR),mx6ulevk) arm32-platform-cpuarch := cortex-a7 endif -ifeq ($(PLATFORM_FLAVOR),$(filter $(PLATFORM_FLAVOR),mx6qsabrelite mx6qsabresd)) +ifeq ($(PLATFORM_FLAVOR),$(filter $(PLATFORM_FLAVOR),mx6qsabrelite mx6qsabresd mx6dlsabresd)) arm32-platform-cpuarch := cortex-a9 endif arm32-platform-cflags += -mcpu=$(arm32-platform-cpuarch) @@ -19,7 +19,7 @@ $(call force,CFG_WITH_SOFTWARE_PRNG,y) ifeq ($(PLATFORM_FLAVOR),mx6ulevk) $(call force,CFG_SECURE_TIME_SOURCE_CNTPCT,y) endif -ifeq ($(PLATFORM_FLAVOR),$(filter $(PLATFORM_FLAVOR),mx6qsabrelite mx6qsabresd)) +ifeq ($(PLATFORM_FLAVOR),$(filter $(PLATFORM_FLAVOR),mx6qsabrelite mx6qsabresd mx6dlsabresd)) $(call force,CFG_PL310,y) $(call force,CFG_PL310_LOCKED,y) $(call force,CFG_SECURE_TIME_SOURCE_REE,y) diff --git a/core/arch/arm/plat-imx/main.c b/core/arch/arm/plat-imx/main.c index edfbc37..36750a2 100644 --- a/core/arch/arm/plat-imx/main.c +++ b/core/arch/arm/plat-imx/main.c @@ -45,7 +45,8 @@ #include <tee/entry_std.h> #if defined(PLATFORM_FLAVOR_mx6qsabrelite) || \ - defined(PLATFORM_FLAVOR_mx6qsabresd) + defined(PLATFORM_FLAVOR_mx6qsabresd) || \ + defined(PLATFORM_FLAVOR_mx6dlsabresd) #include <kernel/tz_ssvce_pl310.h> #endif @@ -55,7 +56,7 @@ static struct gic_data gic_data; static const struct thread_handlers handlers = { .std_smc = tee_entry_std, .fast_smc = tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, .cpu_on = pm_panic, .cpu_off = pm_panic, .cpu_suspend = pm_panic, @@ -64,11 +65,14 @@ static const struct thread_handlers handlers = { .system_reset = pm_panic, }; +static struct imx_uart_data console_data __early_bss; + register_phys_mem(MEM_AREA_IO_NSEC, CONSOLE_UART_BASE, CORE_MMU_DEVICE_SIZE); register_phys_mem(MEM_AREA_IO_SEC, GIC_BASE, CORE_MMU_DEVICE_SIZE); #if defined(PLATFORM_FLAVOR_mx6qsabrelite) || \ - defined(PLATFORM_FLAVOR_mx6qsabresd) + defined(PLATFORM_FLAVOR_mx6qsabresd) || \ + defined(PLATFORM_FLAVOR_mx6dlsabresd) register_phys_mem(MEM_AREA_IO_SEC, PL310_BASE, CORE_MMU_DEVICE_SIZE); register_phys_mem(MEM_AREA_IO_SEC, SRC_BASE, CORE_MMU_DEVICE_SIZE); #endif @@ -84,7 +88,8 @@ static void main_fiq(void) } #if defined(PLATFORM_FLAVOR_mx6qsabrelite) || \ - defined(PLATFORM_FLAVOR_mx6qsabresd) + defined(PLATFORM_FLAVOR_mx6qsabresd) || \ + defined(PLATFORM_FLAVOR_mx6dlsabresd) void plat_cpu_reset_late(void) { uintptr_t addr; @@ -126,41 +131,10 @@ void plat_cpu_reset_late(void) } #endif -static vaddr_t console_base(void) -{ - static void *va; - - if (cpu_mmu_enabled()) { - if (!va) - va = phys_to_virt(CONSOLE_UART_BASE, - MEM_AREA_IO_NSEC); - return (vaddr_t)va; - } - return CONSOLE_UART_BASE; -} - void console_init(void) { - vaddr_t base = console_base(); - - imx_uart_init(base); -} - -void console_putc(int ch) -{ - vaddr_t base = console_base(); - - /* If \n, also do \r */ - if (ch == '\n') - imx_uart_putc('\r', base); - imx_uart_putc(ch, base); -} - -void console_flush(void) -{ - vaddr_t base = console_base(); - - imx_uart_flush_tx_fifo(base); + imx_uart_init(&console_data, CONSOLE_UART_BASE); + register_serial_console(&console_data.chip); } void main_init_gic(void) @@ -182,7 +156,8 @@ void main_init_gic(void) } #if defined(PLATFORM_FLAVOR_mx6qsabrelite) || \ - defined(PLATFORM_FLAVOR_mx6qsabresd) + defined(PLATFORM_FLAVOR_mx6qsabresd) || \ + defined(PLATFORM_FLAVOR_mx6dlsabresd) vaddr_t pl310_base(void) { static void *va __early_bss; diff --git a/core/arch/arm/plat-imx/platform_config.h b/core/arch/arm/plat-imx/platform_config.h index 8e55ee8..b92322e 100644 --- a/core/arch/arm/plat-imx/platform_config.h +++ b/core/arch/arm/plat-imx/platform_config.h @@ -113,7 +113,8 @@ /* For i.MX6 Quad SABRE Lite and Smart Device board */ #elif defined(PLATFORM_FLAVOR_mx6qsabrelite) || \ - defined(PLATFORM_FLAVOR_mx6qsabresd) + defined(PLATFORM_FLAVOR_mx6qsabresd) || \ + defined(PLATFORM_FLAVOR_mx6dlsabresd) #define SCU_BASE 0x00A00000 #define PL310_BASE 0x00A02000 @@ -128,8 +129,16 @@ #define GICD_OFFSET 0x1000 #define GIC_CPU_BASE (GIC_BASE + GICC_OFFSET) #define GIC_DIST_BASE (GIC_BASE + GICD_OFFSET) + +#if defined(PLATFORM_FLAVOR_mx6qsabrelite) || \ + defined(PLATFORM_FLAVOR_mx6qsabresd) #define UART1_BASE 0x02020000 #define UART2_BASE 0x021E8000 +#else +#define UART1_BASE 0x02020000 +#define UART3_BASE 0x021EC000 +#define UART5_BASE 0x021F4000 +#endif /* Central Security Unit register values */ #define CSU_BASE 0x021C0000 @@ -146,12 +155,20 @@ #if defined(PLATFORM_FLAVOR_mx6qsabresd) #define CONSOLE_UART_BASE UART1_BASE #endif +#if defined(PLATFORM_FLAVOR_mx6dlsabresd) +#define CONSOLE_UART_BASE UART1_BASE +#endif #define DRAM0_BASE 0x10000000 #define DRAM0_SIZE 0x40000000 #define CFG_TEE_RAM_VA_SIZE (1024 * 1024) +#if defined(PLATFORM_FLAVOR_mx6qsabrelite) || \ + defined(PLATFORM_FLAVOR_mx6qsabresd) #define CFG_TEE_CORE_NB_CORE 4 +#else +#define CFG_TEE_CORE_NB_CORE 2 +#endif #define DDR_PHYS_START DRAM0_BASE #define DDR_SIZE DRAM0_SIZE @@ -200,7 +217,12 @@ * Full Line Zero (FLZ) disabled (bit0=0) */ #ifndef PL310_AUX_CTRL_INIT +#if defined(PLATFORM_FLAVOR_mx6qsabrelite) || \ + defined(PLATFORM_FLAVOR_mx6qsabresd) #define PL310_AUX_CTRL_INIT 0x3C470800 +#else +#define PL310_AUX_CTRL_INIT 0x3C440800 +#endif #endif /* @@ -384,7 +406,12 @@ * Cacheable accesses have high prio (bit10=0) * Full Line Zero (FLZ) disabled (bit0=0) */ +#if defined(PLATFORM_FLAVOR_mx6qsabrelite) || \ + defined(PLATFORM_FLAVOR_mx6qsabresd) #define PL310_AUX_CTRL_INIT 0x3C470800 +#else +#define PL310_AUX_CTRL_INIT 0x3C440800 +#endif /* * Prefetch Control Register diff --git a/core/arch/arm/plat-imx/psci.c b/core/arch/arm/plat-imx/psci.c index 065555b..12b60fb 100644 --- a/core/arch/arm/plat-imx/psci.c +++ b/core/arch/arm/plat-imx/psci.c @@ -43,7 +43,8 @@ static vaddr_t src_base(void) { - static void *va __data; /* in case it's used before .bss is cleared */ + /* in case it's used before .bss is cleared */ + static void *va __early_bss; if (cpu_mmu_enabled()) { if (!va) diff --git a/core/arch/arm/plat-imx/sub.mk b/core/arch/arm/plat-imx/sub.mk index d0a2f51..75a2fbc 100644 --- a/core/arch/arm/plat-imx/sub.mk +++ b/core/arch/arm/plat-imx/sub.mk @@ -6,4 +6,5 @@ srcs-$(CFG_PSCI_ARM32) += psci.c srcs-$(PLATFORM_FLAVOR_mx6qsabrelite) += a9_plat_init.S srcs-$(PLATFORM_FLAVOR_mx6qsabresd) += a9_plat_init.S +srcs-$(PLATFORM_FLAVOR_mx6dlsabresd) += a9_plat_init.S srcs-$(PLATFORM_FLAVOR_mx6ulevk) += imx6ul.c diff --git a/core/arch/arm/plat-ls/main.c b/core/arch/arm/plat-ls/main.c index 23ac0c6..7f8d523 100644 --- a/core/arch/arm/plat-ls/main.c +++ b/core/arch/arm/plat-ls/main.c @@ -48,7 +48,7 @@ static void main_fiq(void); static const struct thread_handlers handlers = { .std_smc = tee_entry_std, .fast_smc = tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, .cpu_on = pm_panic, .cpu_off = pm_panic, .cpu_suspend = pm_panic, @@ -58,6 +58,7 @@ static const struct thread_handlers handlers = { }; static struct gic_data gic_data; +static struct ns16550_data console_data __early_bss; register_phys_mem(MEM_AREA_IO_NSEC, CONSOLE_UART_BASE, CORE_MMU_DEVICE_SIZE); register_phys_mem(MEM_AREA_IO_SEC, GIC_BASE, CORE_MMU_DEVICE_SIZE); @@ -120,38 +121,10 @@ void plat_cpu_reset_late(void) } } -static vaddr_t console_base(void) -{ - static void *va __early_bss; - - if (cpu_mmu_enabled()) { - if (!va) - va = phys_to_virt(CONSOLE_UART_BASE, MEM_AREA_IO_NSEC); - return (vaddr_t)va; - } - return CONSOLE_UART_BASE; -} - void console_init(void) { - /* - * Do nothing, uart driver shared with normal world, - * everything for uart driver intialization is done in bootloader. - */ -} - -void console_putc(int ch) -{ - vaddr_t base = console_base(); - - if (ch == '\n') - ns16550_putc('\r', base); - ns16550_putc(ch, base); -} - -void console_flush(void) -{ - ns16550_flush(console_base()); + ns16550_init(&console_data, CONSOLE_UART_BASE); + register_serial_console(&console_data.chip); } void main_init_gic(void) diff --git a/core/arch/arm/plat-ls/plat_init.S b/core/arch/arm/plat-ls/plat_init.S index 81ba7d7..8813480 100644 --- a/core/arch/arm/plat-ls/plat_init.S +++ b/core/arch/arm/plat-ls/plat_init.S @@ -69,23 +69,20 @@ UNWIND( .fnstart) * * SCTLR = 0x00000000 * - * ACTRL = 0x00000041 - * - core always in full SMP (FW bit0=1) + * ACTRL = 0x00000040 + * - core NOT booted in full SMP (FW bit0=0) * - * NSACR = 0x00020C00 + * NSACR = 0x00000C00 * - NSec cannot change ACTRL.SMP (NS_SMP bit18=0) * - NSec can use SIMD/VFP (CP10/CP11) (bit15:14=2b00, bit11:10=2b11) */ - movw r0, #0x0000 - movt r0, #0x0000 + mov_imm r0, 0x00000000 write_sctlr r0 - movw r0, #0x0040 - movt r0, #0x0000 + mov_imm r0, 0x00000040 write_actlr r0 - movw r0, #0x0C00 - movt r0, #0x0000 + mov_imm r0, 0x00000C00 write_nsacr r0 mov pc, lr diff --git a/core/arch/arm/plat-mediatek/main.c b/core/arch/arm/plat-mediatek/main.c index 7780591..62180fc 100644 --- a/core/arch/arm/plat-mediatek/main.c +++ b/core/arch/arm/plat-mediatek/main.c @@ -41,7 +41,7 @@ static void main_fiq(void); static const struct thread_handlers handlers = { .std_smc = tee_entry_std, .fast_smc = tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, .cpu_on = cpu_on_handler, .cpu_off = pm_do_nothing, .cpu_suspend = pm_do_nothing, @@ -50,6 +50,8 @@ static const struct thread_handlers handlers = { .system_reset = pm_do_nothing, }; +static struct serial8250_uart_data console_data __early_bss; + const struct thread_handlers *generic_boot_get_handlers(void) { return &handlers; @@ -60,34 +62,9 @@ static void main_fiq(void) panic(); } -static vaddr_t console_base(void) -{ - static void *va; - - if (cpu_mmu_enabled()) { - if (!va) - va = phys_to_virt(CONSOLE_UART_BASE, MEM_AREA_IO_NSEC); - return (vaddr_t)va; - } - return CONSOLE_UART_BASE; -} - void console_init(void) { - serial8250_uart_init(console_base(), CONSOLE_UART_CLK_IN_HZ, - CONSOLE_BAUDRATE); -} - -void console_putc(int ch) -{ - vaddr_t base = console_base(); - - if (ch == '\n') - serial8250_uart_putc('\r', base); - serial8250_uart_putc(ch, base); -} - -void console_flush(void) -{ - serial8250_uart_flush_tx_fifo(console_base()); + serial8250_uart_init(&console_data, CONSOLE_UART_BASE, + CONSOLE_UART_CLK_IN_HZ, CONSOLE_BAUDRATE); + register_serial_console(&console_data.chip); } diff --git a/core/arch/arm/plat-rcar/main.c b/core/arch/arm/plat-rcar/main.c index 8f9482e..6a7e332 100644 --- a/core/arch/arm/plat-rcar/main.c +++ b/core/arch/arm/plat-rcar/main.c @@ -46,7 +46,7 @@ static void main_fiq(void); static const struct thread_handlers handlers = { .std_smc = tee_entry_std, .fast_smc = tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, .cpu_on = cpu_on_handler, .cpu_off = pm_do_nothing, .cpu_suspend = pm_do_nothing, @@ -55,6 +55,8 @@ static const struct thread_handlers handlers = { .system_reset = pm_do_nothing, }; +static struct scif_uart_data console_data __early_bss; + const struct thread_handlers *generic_boot_get_handlers(void) { return &handlers; @@ -65,31 +67,8 @@ static void main_fiq(void) panic(); } -static vaddr_t console_base(void) -{ - static void *va; - - if (cpu_mmu_enabled()) { - if (!va) - va = phys_to_virt(CONSOLE_UART_BASE, MEM_AREA_IO_SEC); - return (vaddr_t)va; - } - return CONSOLE_UART_BASE; -} - void console_init(void) { - scif_uart_init(console_base()); -} - -void console_putc(int ch) -{ - if (ch == '\n') - scif_uart_putc('\r', console_base()); - scif_uart_putc(ch, console_base()); -} - -void console_flush(void) -{ - scif_uart_flush(console_base()); + scif_uart_init(&console_data, CONSOLE_UART_BASE); + register_serial_console(&console_data.chip); } diff --git a/core/arch/arm/plat-rpi3/conf.mk b/core/arch/arm/plat-rpi3/conf.mk index 567680a..49fa817 100644 --- a/core/arch/arm/plat-rpi3/conf.mk +++ b/core/arch/arm/plat-rpi3/conf.mk @@ -25,7 +25,6 @@ CFG_CRYPTO_WITH_CE ?= n CFG_WITH_STACK_CANARIES ?= y CFG_TEE_CORE_EMBED_INTERNAL_TESTS ?= y -CFG_TEE_FS_KEY_MANAGER_TEST ?= y CFG_WITH_STACK_CANARIES ?= y CFG_WITH_STATS ?= y diff --git a/core/arch/arm/plat-rpi3/main.c b/core/arch/arm/plat-rpi3/main.c index 9270e19..8a714cb 100644 --- a/core/arch/arm/plat-rpi3/main.c +++ b/core/arch/arm/plat-rpi3/main.c @@ -45,7 +45,7 @@ static void main_fiq(void) static const struct thread_handlers handlers = { .std_smc = tee_entry_std, .fast_smc = tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, .cpu_on = cpu_on_handler, .cpu_off = pm_do_nothing, .cpu_suspend = pm_do_nothing, @@ -54,41 +54,16 @@ static const struct thread_handlers handlers = { .system_reset = pm_do_nothing, }; +static struct serial8250_uart_data console_data __early_bss; + const struct thread_handlers *generic_boot_get_handlers(void) { return &handlers; } -static vaddr_t console_base(void) -{ - static vaddr_t va; - - if (cpu_mmu_enabled()) { - if (!va) - va = (vaddr_t)phys_to_virt(CONSOLE_UART_BASE, - MEM_AREA_IO_NSEC); - return va; - } - - return CONSOLE_UART_BASE; -} - -void console_putc(int ch) -{ - vaddr_t base = console_base(); - - if (ch == '\n') - serial8250_uart_putc('\r', base); - serial8250_uart_putc(ch, base); -} - void console_init(void) { - serial8250_uart_init(console_base(), CONSOLE_UART_CLK_IN_HZ, - CONSOLE_BAUDRATE); -} - -void console_flush(void) -{ - serial8250_uart_flush_tx_fifo(console_base()); + serial8250_uart_init(&console_data, CONSOLE_UART_BASE, + CONSOLE_UART_CLK_IN_HZ, CONSOLE_BAUDRATE); + register_serial_console(&console_data.chip); } diff --git a/core/arch/arm/plat-sprd/console.c b/core/arch/arm/plat-sprd/console.c index 3263d69..ae56d95 100644 --- a/core/arch/arm/plat-sprd/console.c +++ b/core/arch/arm/plat-sprd/console.c @@ -29,30 +29,18 @@ #include <mm/core_memprot.h> #include <platform_config.h> -static vaddr_t console_base(void) -{ - static vaddr_t base; - - if (cpu_mmu_enabled()) - base = (vaddr_t)phys_to_virt(CONSOLE_UART_BASE, - MEM_AREA_IO_SEC); - else - base = CONSOLE_UART_BASE; - - return base; -} +static struct sprd_uart_data console_data __early_bss; -/* Do nothing in this function */ void console_init(void) { + sprd_uart_init(&console_data, CONSOLE_UART_BASE); + register_serial_console(&console_data.chip); } void console_putc(int ch) { - sprd_uart_putc(console_base(), (unsigned char)(ch & 0xff)); -} + struct serial_chip *cons = &console_data.chip; -void console_flush(void) -{ - sprd_uart_flush(console_base()); + cons->ops->putc(cons, ch & 0xff); } + diff --git a/core/arch/arm/plat-sprd/main.c b/core/arch/arm/plat-sprd/main.c index bf3a62d..ea2c984 100644 --- a/core/arch/arm/plat-sprd/main.c +++ b/core/arch/arm/plat-sprd/main.c @@ -40,7 +40,7 @@ static void main_fiq(void); static const struct thread_handlers handlers = { .std_smc = tee_entry_std, .fast_smc = tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, .cpu_on = cpu_on_handler, .cpu_off = pm_do_nothing, .cpu_suspend = pm_do_nothing, diff --git a/core/arch/arm/plat-stm/asc.S b/core/arch/arm/plat-stm/asc.S deleted file mode 100644 index 3f2b6aa..0000000 --- a/core/arch/arm/plat-stm/asc.S +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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 <platform_config.h> -#include <asm.S> -#include <kernel/unwind.h> - -#define ASC_BAUDRATE 0x00 -#define ASC_TXBUFFER 0x04 -#define ASC_RXBUFFER 0x08 -#define ASC_CONTROL 0x0c -#define ASC_INTENABLE 0x10 -#define ASC_STATUS 0x14 -#define ASC_GUARDTIME 0x18 -#define ASC_TIMEOUT 0x1c -#define ASC_TXRESET 0x20 -#define ASC_RXRESET 0x24 -#define ASC_RETRIES 0x28 - -.section .text.asc - - -/* - * void __asc_flush(vaddr_t base) - * - * Clobbers r0-r3 - */ -FUNC __asc_flush , : -UNWIND( .fnstart) - - ADD r3, r0, #ASC_STATUS - -flush_wait: - LDR r1, [r3] - ANDS r1, r1, #0x02 /* AND TX FIFO EMPTY flag */ - BEQ flush_wait /* ANDS should have set Z bit if zero */ - - LDR r0, =0 - BX lr -UNWIND( .fnend) -END_FUNC __asc_flush - -/* - * int __asc_xmit_char(char p, vaddr_t base) - Transmit a single character. - * - * R0 is the 1-byte character to be transmited - * R1 is the base address of the uart - * Clobbers r0-r3 - */ -FUNC __asc_xmit_char , : -UNWIND( .fnstart) - - ADD r2, r1, #ASC_TXBUFFER - ADD r3, r1, #ASC_STATUS - - /* Output byte */ - - /* Spin until TX FIFO ready */ -__asc_char_crwait: - LDR r1, [r3] - ANDS r1, r1, #0x04 /* AND TX FIFO HALF EMPTY flag */ - BEQ __asc_char_crwait /* ANDS should have set Z bit if zero */ - - MOVS r1, r0 - LDR r0, =0xFF - AND r1, r1, r0 - BEQ __asc_char_exit - CMP r1, #0xa /* r1 == \n (line feed) ? */ - BNE __asc_char_notlf - - /* Transmit character extra carriage return for each line feed */ - LDR r1, =0x0d - STR r1, [r2] - - LDR r1, =0x0a /* replace line feed */ - -__asc_char_notlf: - /* Transmit character */ - STR r1, [r2] - -__asc_char_exit: - LDR r0, =0 - BX lr -UNWIND( .fnend) -END_FUNC __asc_xmit_char diff --git a/core/arch/arm/plat-stm/asc.h b/core/arch/arm/plat-stm/asc.h deleted file mode 100644 index bbf574c..0000000 --- a/core/arch/arm/plat-stm/asc.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 ASC_H -#define ASC_H - -#include <types_ext.h> - -extern int __asc_xmit_char(const char p, vaddr_t base); -extern void __asc_flush(vaddr_t base); - -#endif diff --git a/core/arch/arm/plat-stm/conf.mk b/core/arch/arm/plat-stm/conf.mk index 4afe256..e34491f 100644 --- a/core/arch/arm/plat-stm/conf.mk +++ b/core/arch/arm/plat-stm/conf.mk @@ -22,6 +22,7 @@ CFG_TEE_CORE_EMBED_INTERNAL_TESTS ?= y CFG_WITH_STACK_CANARIES ?= y CFG_WITH_STATS ?= y CFG_WITH_SOFTWARE_PRNG ?= n +CFG_STIH_UART ?= y ifeq ($(PLATFORM_FLAVOR),b2260) CFG_PL310_LOCKED ?= y diff --git a/core/arch/arm/plat-stm/main.c b/core/arch/arm/plat-stm/main.c index e569e07..db92680 100644 --- a/core/arch/arm/plat-stm/main.c +++ b/core/arch/arm/plat-stm/main.c @@ -26,10 +26,9 @@ */ #include <arm32.h> -#include <asc.h> #include <console.h> #include <drivers/gic.h> -#include <drivers/pl011.h> +#include <drivers/stih_asc.h> #include <io.h> #include <kernel/generic_boot.h> #include <kernel/misc.h> @@ -50,6 +49,8 @@ register_phys_mem(MEM_AREA_IO_SEC, RNG_BASE, CORE_MMU_DEVICE_SIZE); register_phys_mem(MEM_AREA_IO_NSEC, UART_CONSOLE_BASE, CORE_MMU_DEVICE_SIZE); static struct gic_data gic_data; +static struct stih_asc_pd console_data __early_bss; + static void main_fiq(void); #if defined(PLATFORM_FLAVOR_b2260) @@ -75,7 +76,7 @@ static void stm_tee_entry_std(struct thread_smc_args *smc_args) static const struct thread_handlers handlers = { .std_smc = stm_tee_entry_std, .fast_smc = tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, .cpu_on = pm_panic, .cpu_off = pm_panic, .cpu_suspend = pm_panic, @@ -89,35 +90,30 @@ const struct thread_handlers *generic_boot_get_handlers(void) return &handlers; } -static vaddr_t console_base(void) -{ - static void *va __early_bss; - - if (cpu_mmu_enabled()) { - if (!va) - va = phys_to_virt(UART_CONSOLE_BASE, MEM_AREA_IO_NSEC); - return (vaddr_t)va; - } - return UART_CONSOLE_BASE; -} - void console_init(void) { + stih_asc_init(&console_data, UART_CONSOLE_BASE); } void console_putc(int ch) { + if (ns_resources_ready()) { + struct serial_chip *cons = &console_data.chip; + if (ch == '\n') - __asc_xmit_char('\r', console_base()); - __asc_xmit_char((char)ch, console_base()); + cons->ops->putc(cons, '\r'); + cons->ops->putc(cons, ch); } } void console_flush(void) { - if (ns_resources_ready()) - __asc_flush(console_base()); + if (ns_resources_ready()) { + struct serial_chip *cons = &console_data.chip; + + cons->ops->flush(cons); + } } vaddr_t pl310_base(void) diff --git a/core/arch/arm/plat-stm/platform_config.h b/core/arch/arm/plat-stm/platform_config.h index 407a412..a9afb90 100644 --- a/core/arch/arm/plat-stm/platform_config.h +++ b/core/arch/arm/plat-stm/platform_config.h @@ -242,13 +242,16 @@ * | external memory +------------------+ | * | | TA_RAM | | * +---------------------------------------+ | CFG_DDR_TEETZ_RESERVED_SIZE + * | Secure Data Path test memory (opt.) | | + * +---------------------------------------+ | * | Non secure | SHM | | * | shared memory | | | * +---------------------------------------+ v * * TEE_RAM : default 1MByte - * PUB_RAM : default 2MByte * TA_RAM : all what is left + * SDP_RAM : optional default SDP test memory 8MByte + * PUB_RAM : default 2MByte * * ---------------------------------------------------------------------------- * TEE RAM layout with CFG_WITH_PAGER=y: @@ -262,12 +265,15 @@ * | TEE private secure | TA_RAM | ^ * | external memory | | | * +---------------------------------------+ | CFG_DDR_TEETZ_RESERVED_SIZE + * | Secure Data Path test memory (opt.) | | + * +---------------------------------------+ | * | Non secure | SHM | | * | shared memory | | | * +---------------------------------------+ v * * TEE_RAM : default 256kByte * TA_RAM : all what is left in DDR TEE reserved area + * SDP_RAM : optional default SDP test memory 8MByte * PUB_RAM : default 2MByte */ @@ -282,13 +288,30 @@ CFG_SHMEM_SIZE) #endif +#if defined(CFG_SECURE_DATA_PATH) && !defined(CFG_TEE_SDP_MEM_BASE) +/* default locate SDP memory right before the shared memory in DDR */ +#define CFG_TEE_SDP_TEST_MEM_SIZE 0x00300000 + +#define CFG_TEE_SDP_MEM_SIZE CFG_TEE_SDP_TEST_MEM_SIZE +#define CFG_TEE_SDP_MEM_BASE (CFG_DDR_TEETZ_RESERVED_START + \ + CFG_DDR_TEETZ_RESERVED_SIZE - \ + CFG_SHMEM_SIZE - \ + CFG_TEE_SDP_MEM_SIZE) +#endif + +#ifndef CFG_TEE_SDP_TEST_MEM_SIZE +#define CFG_TEE_SDP_TEST_MEM_SIZE 0 +#endif + #if defined(CFG_WITH_PAGER) #define TZSRAM_BASE CFG_CORE_TZSRAM_EMUL_START #define TZSRAM_SIZE CFG_CORE_TZSRAM_EMUL_SIZE #define TZDRAM_BASE CFG_DDR_TEETZ_RESERVED_START -#define TZDRAM_SIZE (CFG_DDR_TEETZ_RESERVED_SIZE - CFG_SHMEM_SIZE) +#define TZDRAM_SIZE (CFG_DDR_TEETZ_RESERVED_SIZE - \ + CFG_SHMEM_SIZE - \ + CFG_TEE_SDP_TEST_MEM_SIZE) #define CFG_TEE_RAM_START TZSRAM_BASE #define CFG_TEE_RAM_PH_SIZE TZSRAM_SIZE @@ -299,7 +322,9 @@ #else /* CFG_WITH_PAGER */ #define TZDRAM_BASE CFG_DDR_TEETZ_RESERVED_START -#define TZDRAM_SIZE (CFG_DDR_TEETZ_RESERVED_SIZE - CFG_SHMEM_SIZE) +#define TZDRAM_SIZE (CFG_DDR_TEETZ_RESERVED_SIZE - \ + CFG_SHMEM_SIZE - \ + CFG_TEE_SDP_TEST_MEM_SIZE) #define CFG_TEE_RAM_START TZDRAM_BASE #ifndef CFG_TEE_RAM_PH_SIZE diff --git a/core/arch/arm/plat-stm/sub.mk b/core/arch/arm/plat-stm/sub.mk index d16bb72..4793bfb 100644 --- a/core/arch/arm/plat-stm/sub.mk +++ b/core/arch/arm/plat-stm/sub.mk @@ -1,6 +1,5 @@ global-incdirs-y += . srcs-y += rng_support.c -srcs-y += asc.S srcs-y += tz_a9init.S srcs-y += main.c diff --git a/core/arch/arm/plat-stm/tz_a9init.S b/core/arch/arm/plat-stm/tz_a9init.S index aee7dbe..2f78e04 100644 --- a/core/arch/arm/plat-stm/tz_a9init.S +++ b/core/arch/arm/plat-stm/tz_a9init.S @@ -78,20 +78,16 @@ END_FUNC arm_cl2_enable FUNC plat_cpu_reset_early , : UNWIND( .fnstart) - movw r0, #(CPU_SCTLR_INIT & 0xFFFF) - movt r0, #((CPU_SCTLR_INIT >> 16) & 0xFFFF) + mov_imm r0, CPU_SCTLR_INIT write_sctlr r0 - movw r0, #(CPU_ACTLR_INIT & 0xFFFF) - movt r0, #((CPU_ACTLR_INIT >> 16) & 0xFFFF) + mov_imm r0, CPU_ACTLR_INIT write_actlr r0 - movw r0, #(CPU_NSACR_INIT & 0xFFFF) - movt r0, #((CPU_NSACR_INIT >> 16) & 0xFFFF) + mov_imm r0, CPU_NSACR_INIT write_nsacr r0 - movw r0, #(CPU_PCR_INIT & 0xFFFF) - movt r0, #((CPU_PCR_INIT >> 16) & 0xFFFF) + mov_imm r0, CPU_PCR_INIT write_pcr r0 mov pc, lr diff --git a/core/arch/arm/plat-sunxi/main.c b/core/arch/arm/plat-sunxi/main.c index 3954d9d..5546c67 100644 --- a/core/arch/arm/plat-sunxi/main.c +++ b/core/arch/arm/plat-sunxi/main.c @@ -25,31 +25,30 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <platform_config.h> - -#include <stdint.h> -#include <string.h> -#include <assert.h> - -#include <sm/sm.h> -#include <sm/tee_mon.h> -#include <sm/optee_smc.h> -#include <optee_msg.h> - #include <arm.h> -#include <kernel/thread.h> -#include <kernel/time_source.h> +#include <assert.h> +#include <console.h> +#include <drivers/sunxi_uart.h> +#include <kernel/misc.h> #include <kernel/panic.h> #include <kernel/pm_stubs.h> -#include <kernel/misc.h> -#include <mm/tee_mmu.h> +#include <kernel/thread.h> +#include <kernel/time_source.h> +#include <malloc.h> #include <mm/core_mmu.h> -#include <tee/entry_std.h> -#include <tee/entry_fast.h> +#include <mm/tee_mmu.h> +#include <optee_msg.h> +#include <platform_config.h> #include <platform.h> -#include <util.h> +#include <sm/optee_smc.h> +#include <sm/sm.h> +#include <sm/tee_mon.h> +#include <stdint.h> +#include <string.h> +#include <tee/entry_fast.h> +#include <tee/entry_std.h> #include <trace.h> -#include <malloc.h> +#include <util.h> /* teecore heap address/size is defined in scatter file */ extern unsigned char teecore_heap_start; @@ -62,7 +61,7 @@ static void main_tee_entry_fast(struct thread_smc_args *args); static const struct thread_handlers handlers = { .std_smc = main_tee_entry_std, .fast_smc = main_tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, .cpu_on = pm_panic, .cpu_off = pm_panic, .cpu_suspend = pm_panic, @@ -78,12 +77,13 @@ void main_init(uint32_t nsec_entry) size_t pos = get_core_pos(); /* - * Mask IRQ and FIQ before switch to the thread vector as the - * thread handler requires IRQ and FIQ to be masked while executing + * Mask the interrupts before switch to the thread vector as the + * thread handler requires the interrupts to be masked while executing * with the temporary stack. The thread subsystem also asserts that - * IRQ is blocked when using most if its functions. + * foreign interrupts are blocked when using most if its functions. */ - thread_mask_exceptions(THREAD_EXCP_FIQ | THREAD_EXCP_IRQ); + thread_mask_exceptions( + THREAD_EXCP_NATIVE_INTR | THREAD_EXCP_FOREIGN_INTR); if (pos == 0) { thread_init_primary(&handlers); @@ -175,3 +175,11 @@ void tee_entry_get_api_call_count(struct thread_smc_args *args) { args->a0 = tee_entry_generic_get_api_call_count() + 3; } + +static struct sunxi_uart_data console_data __early_bss; + +void console_init(void) +{ + sunxi_uart_init(&console_data, CONSOLE_UART_BASE); + register_serial_console(&console_data.chip); +} diff --git a/core/arch/arm/plat-sunxi/platform.c b/core/arch/arm/plat-sunxi/platform.c index e46541a..34331be 100644 --- a/core/arch/arm/plat-sunxi/platform.c +++ b/core/arch/arm/plat-sunxi/platform.c @@ -109,11 +109,11 @@ uint32_t platform_smc_handle(struct thread_smc_args *smc_args) switch (smc_args->a1) { case OPTEE_SMC_SIP_SUNXI_SET_SMP_BOOTENTRY: sunxi_secondary_ns_entry = smc_args->a2; - + /* in order to sync with secondary up cpu */ - cache_maintenance_l1(DCACHE_AREA_CLEAN, - (void *)(&sunxi_secondary_ns_entry), - sizeof(uint32_t)); + cache_op_inner(DCACHE_AREA_CLEAN, + (void *)(&sunxi_secondary_ns_entry), + sizeof(uint32_t)); break; default: ret = OPTEE_SMC_RETURN_EBADCMD; diff --git a/core/arch/arm/plat-sunxi/sub.mk b/core/arch/arm/plat-sunxi/sub.mk index 7c98a65..f3fda2c 100644 --- a/core/arch/arm/plat-sunxi/sub.mk +++ b/core/arch/arm/plat-sunxi/sub.mk @@ -6,4 +6,3 @@ srcs-y += platform.c srcs-y += smp_boot.S srcs-y += smp_fixup.S srcs-y += head.c -srcs-y += console.c diff --git a/core/arch/arm/plat-ti/api_monitor_index.h b/core/arch/arm/plat-ti/api_monitor_index.h new file mode 100644 index 0000000..2f8e089 --- /dev/null +++ b/core/arch/arm/plat-ti/api_monitor_index.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015, Texas Instruments + * 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 API_MONITOR_INDEX_H +#define API_MONITOR_INDEX_H + +/* Number of APIs */ +#define NB_MAX_API_MONITOR 10 + +/* Base Index of APIs */ +#define API_MONITOR_BASE_INDEX 0x00000100 + +/* HyperVisor Start */ +#define API_MONITOR_HYP_STARTHYPERVISOR_INDEX (API_MONITOR_BASE_INDEX + 0x00000002) +/* Caches cleaning */ +#define API_MONITOR_CACHES_CLEAN_INDEX (API_MONITOR_BASE_INDEX + 0x00000003) +/* Write the L2 Cache Controller Auxiliary Control */ +#define API_MONITOR_L2ACTLR_SETREGISTER_INDEX (API_MONITOR_BASE_INDEX + 0x00000004) +/* Set the Data and Tag RAM Latency */ +#define API_MONITOR_L2CACHE_SETLATENCY_INDEX (API_MONITOR_BASE_INDEX + 0x00000005) +/* L2 Cache Prefetch Control Register */ +#define API_MONITOR_L2PFR_SETREGISTER_INDEX (API_MONITOR_BASE_INDEX + 0x00000006) +/* Set Auxiliary Control Register */ +#define API_MONITOR_ACTLR_SETREGISTER_INDEX (API_MONITOR_BASE_INDEX + 0x00000007) +/* AMBA IF mode */ +#define API_MONITOR_WUGEN_MPU_SETAMBAIF_INDEX (API_MONITOR_BASE_INDEX + 0x00000008) +/* Timer CNTFRQ register set */ +#define API_MONITOR_TIMER_SETCNTFRQ_INDEX (API_MONITOR_BASE_INDEX + 0x00000009) + +#endif /* API_MONITOR_INDEX_H */ diff --git a/core/arch/arm/plat-ti/conf.mk b/core/arch/arm/plat-ti/conf.mk index 64e499f..231a0b1 100644 --- a/core/arch/arm/plat-ti/conf.mk +++ b/core/arch/arm/plat-ti/conf.mk @@ -4,6 +4,7 @@ CFG_WITH_STACK_CANARIES ?= y CFG_WITH_STATS ?= y CFG_WITH_SOFTWARE_PRNG ?= n +$(call force,CFG_SM_PLATFORM_HANDLER,y) $(call force,CFG_8250_UART,y) $(call force,CFG_ARM32_core,y) $(call force,CFG_GENERIC_BOOT,y) diff --git a/core/arch/arm/plat-ti/console.c b/core/arch/arm/plat-ti/console.c deleted file mode 100644 index 48f0f65..0000000 --- a/core/arch/arm/plat-ti/console.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016, Linaro Limited - * 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 <console.h> -#include <drivers/serial8250_uart.h> -#include <mm/core_memprot.h> -#include <platform_config.h> - -register_phys_mem(MEM_AREA_IO_NSEC, - CONSOLE_UART_BASE, - SERIAL8250_UART_REG_SIZE); - -static vaddr_t console_base(void) -{ - static void *va __early_bss; - - if (cpu_mmu_enabled()) { - if (!va) - va = phys_to_virt(CONSOLE_UART_BASE, MEM_AREA_IO_NSEC); - return (vaddr_t)va; - } - return CONSOLE_UART_BASE; -} - -void console_init(void) -{ - serial8250_uart_init(console_base(), CONSOLE_UART_CLK_IN_HZ, - CONSOLE_BAUDRATE); -} - -void console_putc(int ch) -{ - vaddr_t base = console_base(); - - if (ch == '\n') - serial8250_uart_putc('\r', base); - serial8250_uart_putc(ch, base); -} - -void console_flush(void) -{ - serial8250_uart_flush_tx_fifo(console_base()); -} diff --git a/core/arch/arm/plat-ti/main.c b/core/arch/arm/plat-ti/main.c index c811862..be3bf3a 100644 --- a/core/arch/arm/plat-ti/main.c +++ b/core/arch/arm/plat-ti/main.c @@ -26,11 +26,12 @@ */ #include <platform_config.h> - +#include <console.h> #include <stdint.h> #include <string.h> #include <assert.h> #include <drivers/gic.h> +#include <drivers/serial8250_uart.h> #include <arm.h> #include <kernel/generic_boot.h> #include <kernel/panic.h> @@ -47,9 +48,12 @@ #include <sm/sm.h> static struct gic_data gic_data; +static struct serial8250_uart_data console_data __early_bss; register_phys_mem(MEM_AREA_IO_SEC, GICC_BASE, GICC_SIZE); register_phys_mem(MEM_AREA_IO_SEC, GICD_BASE, GICD_SIZE); +register_phys_mem(MEM_AREA_IO_NSEC, CONSOLE_UART_BASE, + SERIAL8250_UART_REG_SIZE); void main_init_gic(void) { @@ -79,7 +83,7 @@ static void main_fiq(void) static const struct thread_handlers handlers = { .std_smc = tee_entry_std, .fast_smc = tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, .cpu_on = pm_panic, .cpu_off = pm_panic, .cpu_suspend = pm_panic, @@ -126,8 +130,8 @@ void init_sec_mon(unsigned long nsec_entry) panic(); /* Invalidate cache to fetch data from external memory */ - cache_maintenance_l1(DCACHE_AREA_INVALIDATE, - plat_ctx, sizeof(*plat_ctx)); + cache_op_inner(DCACHE_AREA_INVALIDATE, + plat_ctx, sizeof(*plat_ctx)); /* Initialize secure monitor */ nsec_ctx = sm_get_nsec_ctx(); @@ -149,3 +153,10 @@ void init_sec_mon(unsigned long nsec_entry) nsec_ctx->mon_lr = plat_ctx->mon_lr; nsec_ctx->mon_spsr = plat_ctx->mon_spsr; } + +void console_init(void) +{ + serial8250_uart_init(&console_data, CONSOLE_UART_BASE, + CONSOLE_UART_CLK_IN_HZ, CONSOLE_BAUDRATE); + register_serial_console(&console_data.chip); +} diff --git a/core/arch/arm/plat-ti/platform_config.h b/core/arch/arm/plat-ti/platform_config.h index c1aaee9..48505a6 100644 --- a/core/arch/arm/plat-ti/platform_config.h +++ b/core/arch/arm/plat-ti/platform_config.h @@ -28,7 +28,7 @@ #ifndef PLATFORM_CONFIG_H #define PLATFORM_CONFIG_H -#if defined(PLATFORM_FLAVOR_dra7xx) +#if defined(PLATFORM_FLAVOR_dra7xx) || defined(PLATFORM_FLAVOR_am57xx) #define DRAM0_BASE 0xbe000000 #define DRAM0_SIZE 0x02000000 @@ -43,10 +43,14 @@ #define CFG_TEE_CORE_NB_CORE 2 +#define UART1_BASE 0x4806A000 +#define UART2_BASE 0x4806C000 +#define UART3_BASE 0x48020000 + /* UART1 */ -#define CONSOLE_UART_BASE 0x4806A000 +#define CONSOLE_UART_BASE UART1_BASE +#define CONSOLE_BAUDRATE 115200 #define CONSOLE_UART_CLK_IN_HZ 48000000 -#define UART_BAUDRATE 115200 #define GIC_BASE 0x48210000 #define GICC_OFFSET 0x2000 @@ -65,6 +69,14 @@ #error "Unknown platform flavor" #endif +#if defined(PLATFORM_FLAVOR_am57xx) + +/* UART3 */ +#undef CONSOLE_UART_BASE +#define CONSOLE_UART_BASE UART3_BASE + +#endif + /* Make stacks aligned to data cache line length */ #define STACK_ALIGNMENT 64 @@ -99,11 +111,4 @@ #define DEVICE2_SIZE CORE_MMU_DEVICE_SIZE #define DEVICE2_TYPE MEM_AREA_IO_SEC -#ifndef UART_BAUDRATE -#define UART_BAUDRATE 115200 -#endif -#ifndef CONSOLE_BAUDRATE -#define CONSOLE_BAUDRATE UART_BAUDRATE -#endif - #endif /*PLATFORM_CONFIG_H*/ diff --git a/core/arch/arm/plat-sunxi/console.c b/core/arch/arm/plat-ti/sm_platform_handler.c index b985316..23bb48d 100644 --- a/core/arch/arm/plat-sunxi/console.c +++ b/core/arch/arm/plat-ti/sm_platform_handler.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * Copyright (c) 2017, Texas Instruments * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -18,42 +18,40 @@ * 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 + * 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 <platform_config.h> -#include <drivers/sunxi_uart.h> -#include <mm/core_memprot.h> -#include <console.h> - -static vaddr_t console_base(void) -{ - static void *va; - - if (cpu_mmu_enabled()) { - if (!va) - va = phys_to_virt(CONSOLE_UART_BASE, MEM_AREA_IO_SEC); - return (vaddr_t)va; - } - return CONSOLE_UART_BASE; -} +#include <arm32.h> +#include <sm/sm.h> +#include "api_monitor_index.h" +#define API_HAL_RET_VALUE_OK 0x00000000 +#define API_HAL_RET_VALUE_SERVICE_UNKNWON 0xFFFFFFFF -void console_init(void) +bool sm_platform_handler(struct sm_ctx *ctx) { - sunxi_uart_init(console_base()); -} + if (ctx->nsec.r12 == 0x200) + return true; -void console_putc(int ch) -{ - sunxi_uart_putc(ch, console_base()); -} + switch (ctx->nsec.r12) { + case API_MONITOR_ACTLR_SETREGISTER_INDEX: + write_actlr(ctx->nsec.r0); + isb(); + ctx->nsec.r0 = API_HAL_RET_VALUE_OK; + break; + case API_MONITOR_TIMER_SETCNTFRQ_INDEX: + write_cntfrq(ctx->nsec.r0); + isb(); + ctx->nsec.r0 = API_HAL_RET_VALUE_OK; + break; + default: + ctx->nsec.r0 = API_HAL_RET_VALUE_SERVICE_UNKNWON; + break; + } -void console_flush(void) -{ - sunxi_uart_flush(console_base()); + return false; } diff --git a/core/arch/arm/plat-ti/sub.mk b/core/arch/arm/plat-ti/sub.mk index 3a8214b..9e195b7 100644 --- a/core/arch/arm/plat-ti/sub.mk +++ b/core/arch/arm/plat-ti/sub.mk @@ -1,3 +1,3 @@ global-incdirs-y += . srcs-y += main.c -srcs-y += console.c +srcs-y += sm_platform_handler.c diff --git a/core/arch/arm/plat-vexpress/conf.mk b/core/arch/arm/plat-vexpress/conf.mk index 5d7d8c1..5ba0840 100644 --- a/core/arch/arm/plat-vexpress/conf.mk +++ b/core/arch/arm/plat-vexpress/conf.mk @@ -46,7 +46,6 @@ else $(call force,CFG_ARM32_core,y) endif -CFG_TEE_FS_KEY_MANAGER_TEST ?= y CFG_WITH_STACK_CANARIES ?= y CFG_WITH_STATS ?= y diff --git a/core/arch/arm/plat-vexpress/main.c b/core/arch/arm/plat-vexpress/main.c index 85ed9ee..44eef24 100644 --- a/core/arch/arm/plat-vexpress/main.c +++ b/core/arch/arm/plat-vexpress/main.c @@ -55,7 +55,7 @@ static void main_fiq(void); static const struct thread_handlers handlers = { .std_smc = tee_entry_std, .fast_smc = tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, #if defined(CFG_WITH_ARM_TRUSTED_FW) .cpu_on = cpu_on_handler, .cpu_off = pm_do_nothing, @@ -74,6 +74,7 @@ static const struct thread_handlers handlers = { }; static struct gic_data gic_data; +static struct pl011_data console_data __early_bss; register_phys_mem(MEM_AREA_IO_SEC, CONSOLE_UART_BASE, PL011_REG_SIZE); @@ -116,44 +117,20 @@ static void main_fiq(void) gic_it_handle(&gic_data); } -static vaddr_t console_base(void) -{ - static void *va; - - if (cpu_mmu_enabled()) { - if (!va) - va = phys_to_virt(CONSOLE_UART_BASE, MEM_AREA_IO_SEC); - return (vaddr_t)va; - } - return CONSOLE_UART_BASE; -} - void console_init(void) { - pl011_init(console_base(), CONSOLE_UART_CLK_IN_HZ, CONSOLE_BAUDRATE); -} - -void console_putc(int ch) -{ - vaddr_t base = console_base(); - - if (ch == '\n') - pl011_putc('\r', base); - pl011_putc(ch, base); -} - -void console_flush(void) -{ - pl011_flush(console_base()); + pl011_init(&console_data, CONSOLE_UART_BASE, CONSOLE_UART_CLK_IN_HZ, + CONSOLE_BAUDRATE); + register_serial_console(&console_data.chip); } #ifdef IT_CONSOLE_UART static enum itr_return console_itr_cb(struct itr_handler *h __unused) { - paddr_t uart_base = console_base(); + struct serial_chip *cons = &console_data.chip; - while (pl011_have_rx_data(uart_base)) { - int ch __maybe_unused = pl011_getchar(uart_base); + while (cons->ops->have_rx_data(cons)) { + int ch __maybe_unused = cons->ops->getchar(cons); DMSG("cpu %zu: got 0x%x", get_core_pos(), ch); } diff --git a/core/arch/arm/plat-vexpress/platform_config.h b/core/arch/arm/plat-vexpress/platform_config.h index bd006ca..45d9993 100644 --- a/core/arch/arm/plat-vexpress/platform_config.h +++ b/core/arch/arm/plat-vexpress/platform_config.h @@ -39,6 +39,13 @@ #endif #endif /*ARM64*/ +/* SDP enable but no pool defined: reserve 4MB for SDP tests */ +#if defined(CFG_SECURE_DATA_PATH) && !defined(CFG_TEE_SDP_MEM_BASE) +#define CFG_TEE_SDP_MEM_TEST_SIZE 0x00400000 +#else +#define CFG_TEE_SDP_MEM_TEST_SIZE 0 +#endif + #if defined(PLATFORM_FLAVOR_fvp) #define GIC_BASE 0x2c000000 @@ -187,23 +194,25 @@ #define DRAM0_TEERES_BASE (DRAM0_BASE + DRAM0_SIZE) #define DRAM0_TEERES_SIZE CFG_SHMEM_SIZE +#define SECRAM_BASE 0x0e000000 +#define SECRAM_SIZE 0x01000000 + #ifdef CFG_WITH_PAGER /* Emulated SRAM */ -#define TZSRAM_BASE 0x0e000000 +#define TZSRAM_BASE SECRAM_BASE #define TZSRAM_SIZE CFG_CORE_TZSRAM_EMUL_SIZE #define TZDRAM_BASE (TZSRAM_BASE + TZSRAM_SIZE) -#define TZDRAM_SIZE (0x01000000 - TZSRAM_SIZE) +#define TZDRAM_SIZE (SECRAM_SIZE - TZSRAM_SIZE) #else /* CFG_WITH_PAGER */ -#define TZDRAM_BASE 0x0e000000 -#define TZDRAM_SIZE 0x01000000 +#define TZDRAM_BASE SECRAM_BASE +#define TZDRAM_SIZE SECRAM_SIZE #endif /* CFG_WITH_PAGER */ - #define CFG_TEE_CORE_NB_CORE 2 #define CFG_SHMEM_START (DRAM0_TEERES_BASE + \ @@ -226,8 +235,12 @@ #define DRAM0_TEERES_BASE (DRAM0_BASE + DRAM0_SIZE) #define DRAM0_TEERES_SIZE CFG_SHMEM_SIZE -#define TZDRAM_BASE 0x0e100000 -#define TZDRAM_SIZE 0x00f00000 +#define SECRAM_BASE 0x0e000000 +#define SECRAM_SIZE 0x01000000 + +/* First 1MByte of the secure RAM is reserved to ARM-TF runtime services */ +#define TZDRAM_BASE (SECRAM_BASE + 0x00100000) +#define TZDRAM_SIZE (SECRAM_SIZE - 0x00100000) #define CFG_TEE_CORE_NB_CORE 2 @@ -254,28 +267,42 @@ * | TZSRAM | TEE_RAM | * +--------+---------+ * | TZDRAM | TA_RAM | + * | +---------+ + * | | SDP RAM | (SDP test pool, optional) * +--------+---------+ */ #define CFG_TEE_RAM_PH_SIZE TZSRAM_SIZE #define CFG_TEE_RAM_START TZSRAM_BASE #define CFG_TA_RAM_START ROUNDUP(TZDRAM_BASE, CORE_MMU_DEVICE_SIZE) -#define CFG_TA_RAM_SIZE ROUNDDOWN(TZDRAM_SIZE, CORE_MMU_DEVICE_SIZE) + #else /* * Assumes that either TZSRAM isn't large enough or TZSRAM doesn't exist, * everything is in TZDRAM. * +------------------+ * | | TEE_RAM | - * + TZDRAM +---------+ + * | TZDRAM +---------+ * | | TA_RAM | + * | +---------+ + * | | SDP RAM | (test pool, optional) * +--------+---------+ */ #define CFG_TEE_RAM_PH_SIZE CFG_TEE_RAM_VA_SIZE #define CFG_TEE_RAM_START TZDRAM_BASE -#define CFG_TA_RAM_START ROUNDUP((TZDRAM_BASE + CFG_TEE_RAM_VA_SIZE), \ +#define CFG_TA_RAM_START ROUNDUP(TZDRAM_BASE + CFG_TEE_RAM_VA_SIZE, \ CORE_MMU_DEVICE_SIZE) -#define CFG_TA_RAM_SIZE ROUNDDOWN((TZDRAM_SIZE - CFG_TEE_RAM_VA_SIZE), \ +#endif + +#define CFG_TA_RAM_SIZE ROUNDDOWN(TZDRAM_SIZE - \ + (CFG_TA_RAM_START - TZDRAM_BASE) - \ + CFG_TEE_SDP_MEM_TEST_SIZE, \ CORE_MMU_DEVICE_SIZE) + +/* Secure data path test memory pool: located at end of TA RAM */ +#if CFG_TEE_SDP_MEM_TEST_SIZE +#define CFG_TEE_SDP_MEM_SIZE CFG_TEE_SDP_MEM_TEST_SIZE +#define CFG_TEE_SDP_MEM_BASE (TZDRAM_BASE + TZDRAM_SIZE - \ + CFG_TEE_SDP_MEM_SIZE) #endif #ifdef GIC_BASE diff --git a/core/arch/arm/plat-zynq7k/main.c b/core/arch/arm/plat-zynq7k/main.c index 74bc1ce..2991b94 100644 --- a/core/arch/arm/plat-zynq7k/main.c +++ b/core/arch/arm/plat-zynq7k/main.c @@ -51,7 +51,7 @@ static void platform_tee_entry_fast(struct thread_smc_args *args); static const struct thread_handlers handlers = { .std_smc = tee_entry_std, .fast_smc = platform_tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, .cpu_on = pm_panic, .cpu_off = pm_panic, .cpu_suspend = pm_panic, @@ -61,6 +61,7 @@ static const struct thread_handlers handlers = { }; static struct gic_data gic_data; +static struct cdns_uart_data console_data __early_bss; register_phys_mem(MEM_AREA_IO_NSEC, CONSOLE_UART_BASE, CORE_MMU_DEVICE_SIZE); register_phys_mem(MEM_AREA_IO_SEC, GIC_BASE, CORE_MMU_DEVICE_SIZE); @@ -117,33 +118,10 @@ void plat_cpu_reset_late(void) } } -static vaddr_t console_base(void) -{ - static void *va __early_bss; - - if (cpu_mmu_enabled()) { - if (!va) - va = phys_to_virt(CONSOLE_UART_BASE, - MEM_AREA_IO_NSEC); - return (vaddr_t)va; - } - return CONSOLE_UART_BASE; -} - void console_init(void) { -} - -void console_putc(int ch) -{ - if (ch == '\n') - cdns_uart_putc('\r', console_base()); - cdns_uart_putc(ch, console_base()); -} - -void console_flush(void) -{ - cdns_uart_flush(console_base()); + cdns_uart_init(&console_data, CONSOLE_UART_BASE, 0, 0); + register_serial_console(&console_data.chip); } vaddr_t pl310_base(void) diff --git a/core/arch/arm/plat-zynq7k/plat_init.S b/core/arch/arm/plat-zynq7k/plat_init.S index 6d99a30..8d06c53 100644 --- a/core/arch/arm/plat-zynq7k/plat_init.S +++ b/core/arch/arm/plat-zynq7k/plat_init.S @@ -90,20 +90,16 @@ UNWIND( .fnstart) * PCR = 0x00000001 * - no change latency, enable clk gating */ - movw r0, #0x4000 - movt r0, #0x0000 + mov_imm r0, 0x00004000 write_sctlr r0 - movw r0, #0x0041 - movt r0, #0x0000 + mov_imm r0, 0x00000041 write_actlr r0 - movw r0, #0x0FFF - movt r0, #0x0002 + mov_imm r0, 0x00020C00 write_nsacr r0 - movw r0, #0x0000 - movt r0, #0x0001 + mov_imm r0, 0x00000001 write_pcr r0 mov pc, lr diff --git a/core/arch/arm/plat-zynqmp/conf.mk b/core/arch/arm/plat-zynqmp/conf.mk index 67570bc..5aea3a8 100644 --- a/core/arch/arm/plat-zynqmp/conf.mk +++ b/core/arch/arm/plat-zynqmp/conf.mk @@ -23,7 +23,6 @@ else $(call force,CFG_ARM32_core,y) endif -CFG_TEE_FS_KEY_MANAGER_TEST ?= y CFG_WITH_STACK_CANARIES ?= y CFG_WITH_STATS ?= y CFG_CRYPTO_WITH_CE ?= y diff --git a/core/arch/arm/plat-zynqmp/main.c b/core/arch/arm/plat-zynqmp/main.c index 31b8475..a00d1ae 100644 --- a/core/arch/arm/plat-zynqmp/main.c +++ b/core/arch/arm/plat-zynqmp/main.c @@ -46,11 +46,12 @@ static void main_fiq(void); static struct gic_data gic_data; +static struct cdns_uart_data console_data __early_bss; static const struct thread_handlers handlers = { .std_smc = tee_entry_std, .fast_smc = tee_entry_fast, - .fiq = main_fiq, + .nintr = main_fiq, #if defined(CFG_WITH_ARM_TRUSTED_FW) .cpu_on = cpu_on_handler, .cpu_off = pm_do_nothing, @@ -90,33 +91,9 @@ static void main_fiq(void) gic_it_handle(&gic_data); } -static vaddr_t console_base(void) -{ - static void *va; - - if (cpu_mmu_enabled()) { - if (!va) - va = phys_to_virt(CONSOLE_UART_BASE, MEM_AREA_IO_SEC); - return (vaddr_t)va; - } - - return CONSOLE_UART_BASE; -} - void console_init(void) { - cdns_uart_init(console_base(), CONSOLE_UART_CLK_IN_HZ, - CONSOLE_BAUDRATE); -} - -void console_putc(int ch) -{ - if (ch == '\n') - cdns_uart_putc('\r', console_base()); - cdns_uart_putc(ch, console_base()); -} - -void console_flush(void) -{ - cdns_uart_flush(console_base()); + cdns_uart_init(&console_data, CONSOLE_UART_BASE, + CONSOLE_UART_CLK_IN_HZ, CONSOLE_BAUDRATE); + register_serial_console(&console_data.chip); } diff --git a/core/arch/arm/pta/core_fs_htree_tests.c b/core/arch/arm/pta/core_fs_htree_tests.c new file mode 100644 index 0000000..23be98c --- /dev/null +++ b/core/arch/arm/pta/core_fs_htree_tests.c @@ -0,0 +1,456 @@ +/* + * Copyright (c) 2017, Linaro Limited + * 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 <assert.h> +#include <string.h> +#include <tee/fs_htree.h> +#include <tee/tee_fs_rpc.h> +#include <trace.h> +#include <types_ext.h> +#include <util.h> + +#include "core_self_tests.h" + +/* + * The smallest blocks size that can hold two struct + * tee_fs_htree_node_image or two struct tee_fs_htree_image. + */ +#define TEST_BLOCK_SIZE 144 + +struct test_aux { + uint8_t *data; + size_t data_len; + size_t data_alloced; + uint8_t *block; +}; + +static TEE_Result test_get_offs_size(enum tee_fs_htree_type type, size_t idx, + uint8_t vers, size_t *offs, size_t *size) +{ + const size_t node_size = sizeof(struct tee_fs_htree_node_image); + const size_t block_nodes = TEST_BLOCK_SIZE / (node_size * 2); + size_t pbn; + size_t bidx; + + COMPILE_TIME_ASSERT(TEST_BLOCK_SIZE > + sizeof(struct tee_fs_htree_node_image) * 2); + COMPILE_TIME_ASSERT(TEST_BLOCK_SIZE > + sizeof(struct tee_fs_htree_image) * 2); + + assert(vers == 0 || vers == 1); + + /* + * File layout + * + * phys block 0: + * tee_fs_htree_image vers 0 @ offs = 0 + * tee_fs_htree_image vers 1 @ offs = sizeof(tee_fs_htree_image) + * + * phys block 1: + * tee_fs_htree_node_image 0 vers 0 @ offs = 0 + * tee_fs_htree_node_image 0 vers 1 @ offs = node_size + * + * phys block 2: + * data block 0 vers 0 + * + * phys block 3: + * tee_fs_htree_node_image 1 vers 0 @ offs = 0 + * tee_fs_htree_node_image 1 vers 1 @ offs = node_size + * + * phys block 4: + * data block 0 vers 1 + * + * ... + */ + + switch (type) { + case TEE_FS_HTREE_TYPE_HEAD: + *offs = sizeof(struct tee_fs_htree_image) * vers; + *size = sizeof(struct tee_fs_htree_image); + return TEE_SUCCESS; + case TEE_FS_HTREE_TYPE_NODE: + pbn = 1 + ((idx / block_nodes) * block_nodes * 2); + *offs = pbn * TEST_BLOCK_SIZE + + 2 * node_size * (idx % block_nodes) + + node_size * vers; + *size = node_size; + return TEE_SUCCESS; + case TEE_FS_HTREE_TYPE_BLOCK: + bidx = 2 * idx + vers; + pbn = 2 + bidx + bidx / (block_nodes * 2 - 1); + *offs = pbn * TEST_BLOCK_SIZE; + *size = TEST_BLOCK_SIZE; + return TEE_SUCCESS; + default: + return TEE_ERROR_GENERIC; + } +} + +static TEE_Result test_read_init(void *aux, struct tee_fs_rpc_operation *op, + enum tee_fs_htree_type type, size_t idx, + uint8_t vers, void **data) +{ + TEE_Result res; + struct test_aux *a = aux; + size_t offs; + size_t sz; + + res = test_get_offs_size(type, idx, vers, &offs, &sz); + if (res == TEE_SUCCESS) { + memset(op, 0, sizeof(*op)); + op->params[0].u.value.a = (vaddr_t)aux; + op->params[0].u.value.b = offs; + op->params[0].u.value.c = sz; + *data = a->block; + } + + return res; +} + +static void *uint_to_ptr(uintptr_t p) +{ + return (void *)p; +} + +static TEE_Result test_read_final(struct tee_fs_rpc_operation *op, + size_t *bytes) +{ + struct test_aux *a = uint_to_ptr(op->params[0].u.value.a); + size_t offs = op->params[0].u.value.b; + size_t sz = op->params[0].u.value.c; + + if (offs + sz <= a->data_len) + *bytes = sz; + else if (offs <= a->data_len) + *bytes = a->data_len - offs; + else + *bytes = 0; + + memcpy(a->block, a->data + offs, *bytes); + return TEE_SUCCESS; +} + +static TEE_Result test_write_init(void *aux, struct tee_fs_rpc_operation *op, + enum tee_fs_htree_type type, size_t idx, + uint8_t vers, void **data) +{ + return test_read_init(aux, op, type, idx, vers, data); +} + +static TEE_Result test_write_final(struct tee_fs_rpc_operation *op) +{ + struct test_aux *a = uint_to_ptr(op->params[0].u.value.a); + size_t offs = op->params[0].u.value.b; + size_t sz = op->params[0].u.value.c; + size_t end = offs + sz; + + if (end > a->data_alloced) { + EMSG("out of bounds"); + return TEE_ERROR_GENERIC; + } + + memcpy(a->data + offs, a->block, sz); + if (end > a->data_len) + a->data_len = end; + return TEE_SUCCESS; + +} + +static const struct tee_fs_htree_storage test_htree_ops = { + .block_size = TEST_BLOCK_SIZE, + .rpc_read_init = test_read_init, + .rpc_read_final = test_read_final, + .rpc_write_init = test_write_init, + .rpc_write_final = test_write_final, +}; + +#define CHECK_RES(res, cleanup) \ + do { \ + TEE_Result _res = (res); \ + \ + if (_res != TEE_SUCCESS) { \ + EMSG("error: res = %#" PRIx32, _res); \ + { cleanup; } \ + } \ + } while (0) + +static uint32_t val_from_bn_n_salt(size_t bn, size_t n, uint8_t salt) +{ + assert(bn < UINT16_MAX); + assert(n < UINT8_MAX); + return SHIFT_U32(n, 16) | SHIFT_U32(bn, 8) | salt; +} + +static TEE_Result write_block(struct tee_fs_htree **ht, size_t bn, uint8_t salt) +{ + uint32_t b[TEST_BLOCK_SIZE / sizeof(uint32_t)]; + size_t n; + + for (n = 0; n < ARRAY_SIZE(b); n++) + b[n] = val_from_bn_n_salt(bn, n, salt); + + return tee_fs_htree_write_block(ht, bn, b); +} + +static TEE_Result read_block(struct tee_fs_htree **ht, size_t bn, uint8_t salt) +{ + TEE_Result res; + uint32_t b[TEST_BLOCK_SIZE / sizeof(uint32_t)]; + size_t n; + + res = tee_fs_htree_read_block(ht, bn, b); + if (res != TEE_SUCCESS) + return res; + + for (n = 0; n < ARRAY_SIZE(b); n++) { + if (b[n] != val_from_bn_n_salt(bn, n, salt)) { + DMSG("Unpected b[%zu] %#" PRIx32 + "(expected %#" PRIx32 ")", + n, b[n], val_from_bn_n_salt(bn, n, salt)); + return TEE_ERROR_SECURITY; + } + } + + return TEE_SUCCESS; +} + +static TEE_Result do_range(TEE_Result (*fn)(struct tee_fs_htree **ht, + size_t bn, uint8_t salt), + struct tee_fs_htree **ht, size_t begin, + size_t num_blocks, size_t salt) +{ + TEE_Result res = TEE_SUCCESS; + size_t n; + + for (n = 0; n < num_blocks; n++) { + res = fn(ht, n + begin, salt); + CHECK_RES(res, goto out); + } + +out: + return res; +} + +static TEE_Result do_range_backwards(TEE_Result (*fn)(struct tee_fs_htree **ht, + size_t bn, uint8_t salt), + struct tee_fs_htree **ht, size_t begin, + size_t num_blocks, size_t salt) +{ + TEE_Result res = TEE_SUCCESS; + size_t n; + + for (n = 0; n < num_blocks; n++) { + res = fn(ht, num_blocks - 1 - n + begin, salt); + CHECK_RES(res, goto out); + } + +out: + return res; +} + +static TEE_Result htree_test_rewrite(struct test_aux *aux, size_t num_blocks, + size_t w_unsync_begin, size_t w_unsync_num) +{ + TEE_Result res; + struct tee_fs_htree *ht = NULL; + size_t salt = 23; + + assert((w_unsync_begin + w_unsync_num) <= num_blocks); + + aux->data_len = 0; + memset(aux->data, 0xce, aux->data_alloced); + + res = tee_fs_htree_open(true, &test_htree_ops, aux, &ht); + CHECK_RES(res, goto out); + + /* + * Intialize all blocks and verify that they read back as + * expected. + */ + res = do_range(write_block, &ht, 0, num_blocks, salt); + CHECK_RES(res, goto out); + + res = do_range(read_block, &ht, 0, num_blocks, salt); + CHECK_RES(res, goto out); + + /* + * Write all blocks again, but starting from the end using a new + * salt, then verify that that read back as expected. + */ + salt++; + res = do_range_backwards(write_block, &ht, 0, num_blocks, salt); + CHECK_RES(res, goto out); + + res = do_range(read_block, &ht, 0, num_blocks, salt); + CHECK_RES(res, goto out); + + /* + * Use a new salt to write all blocks once more and verify that + * they read back as expected. + */ + salt++; + res = do_range(write_block, &ht, 0, num_blocks, salt); + CHECK_RES(res, goto out); + + res = do_range(read_block, &ht, 0, num_blocks, salt); + CHECK_RES(res, goto out); + + /* + * Sync the changes of the nodes to memory, verify that all + * blocks are read back as expected. + */ + res = tee_fs_htree_sync_to_storage(&ht); + CHECK_RES(res, goto out); + + res = do_range(read_block, &ht, 0, num_blocks, salt); + CHECK_RES(res, goto out); + + /* + * Close and reopen the hash-tree + */ + tee_fs_htree_close(&ht); + res = tee_fs_htree_open(false, &test_htree_ops, aux, &ht); + CHECK_RES(res, goto out); + + /* + * Verify that all blocks are read as expected. + */ + res = do_range(read_block, &ht, 0, num_blocks, salt); + CHECK_RES(res, goto out); + + /* + * Rewrite a few blocks and verify that all blocks are read as + * expected. + */ + res = do_range_backwards(write_block, &ht, w_unsync_begin, w_unsync_num, + salt + 1); + CHECK_RES(res, goto out); + + res = do_range(read_block, &ht, 0, w_unsync_begin, salt); + CHECK_RES(res, goto out); + res = do_range(read_block, &ht, w_unsync_begin, w_unsync_num, salt + 1); + CHECK_RES(res, goto out); + res = do_range(read_block, &ht, w_unsync_begin + w_unsync_num, + num_blocks - (w_unsync_begin + w_unsync_num), salt); + CHECK_RES(res, goto out); + + /* + * Rewrite the blocks from above again with another salt and + * verify that they are read back as expected. + */ + res = do_range(write_block, &ht, w_unsync_begin, w_unsync_num, + salt + 2); + CHECK_RES(res, goto out); + + res = do_range(read_block, &ht, 0, w_unsync_begin, salt); + CHECK_RES(res, goto out); + res = do_range(read_block, &ht, w_unsync_begin, w_unsync_num, salt + 2); + CHECK_RES(res, goto out); + res = do_range(read_block, &ht, w_unsync_begin + w_unsync_num, + num_blocks - (w_unsync_begin + w_unsync_num), salt); + CHECK_RES(res, goto out); + + /* + * Skip tee_fs_htree_sync_to_storage() and call + * tee_fs_htree_close() directly to undo the changes since last + * call to tee_fs_htree_sync_to_storage(). Reopen the hash-tree + * and verify that recent changes indeed was discarded. + */ + tee_fs_htree_close(&ht); + res = tee_fs_htree_open(false, &test_htree_ops, aux, &ht); + CHECK_RES(res, goto out); + + res = do_range(read_block, &ht, 0, num_blocks, salt); + CHECK_RES(res, goto out); + + /* + * Close, reopen and verify that all blocks are read as expected + * again. + */ + tee_fs_htree_close(&ht); + res = tee_fs_htree_open(false, &test_htree_ops, aux, &ht); + CHECK_RES(res, goto out); + + res = do_range(read_block, &ht, 0, num_blocks, salt); + CHECK_RES(res, goto out); + +out: + tee_fs_htree_close(&ht); + return res; +} + +TEE_Result core_fs_htree_tests(uint32_t nParamTypes, + TEE_Param pParams[TEE_NUM_PARAMS] __unused) +{ + TEE_Result res; + struct test_aux aux; + size_t num_blocks = 10; + size_t offs; + size_t sz; + size_t n; + size_t m; + size_t o; + + if (nParamTypes) + return TEE_ERROR_BAD_PARAMETERS; + + res = test_get_offs_size(TEE_FS_HTREE_TYPE_BLOCK, num_blocks, 1, + &offs, &sz); + CHECK_RES(res, return res); + + aux.data_alloced = offs + sz; + aux.data = malloc(aux.data_alloced); + aux.block = malloc(TEST_BLOCK_SIZE); + if (!aux.data || !aux.block) { + res = TEE_ERROR_OUT_OF_MEMORY; + goto out; + } + + /* + * n is the number of block we're going to initialize/use. + * m is the offset from where we'll rewrite blocks and expect + * the changes to be visible until tee_fs_htree_close() is called + * without a call to tee_fs_htree_sync_to_storage() before. + * o is the number of blocks we're rewriting starting at m. + */ + for (n = 0; n < num_blocks; n += 3) { + for (m = 0; m < n; m += 3) { + for (o = 0; o < (n - m); o++) { + res = htree_test_rewrite(&aux, n, m, o); + CHECK_RES(res, goto out); + o += 2; + } + } + } + + +out: + free(aux.data); + free(aux.block); + return res; +} + diff --git a/core/arch/arm/pta/core_self_tests.h b/core/arch/arm/pta/core_self_tests.h index ed98669..b775430 100644 --- a/core/arch/arm/pta/core_self_tests.h +++ b/core/arch/arm/pta/core_self_tests.h @@ -34,4 +34,7 @@ TEE_Result core_self_tests(uint32_t nParamTypes, TEE_Param pParams[TEE_NUM_PARAMS]); +TEE_Result core_fs_htree_tests(uint32_t nParamTypes, + TEE_Param pParams[TEE_NUM_PARAMS]); + #endif /*CORE_SELF_TESTS_H*/ diff --git a/core/arch/arm/pta/interrupt_tests.c b/core/arch/arm/pta/interrupt_tests.c index bc307a8..2b9ea00 100644 --- a/core/arch/arm/pta/interrupt_tests.c +++ b/core/arch/arm/pta/interrupt_tests.c @@ -174,7 +174,7 @@ static TEE_Result test_ppi(void) itr_add(&ppi_handler); itr_enable(TEST_PPI_ID); - exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ); + exceptions = thread_mask_exceptions(THREAD_EXCP_FOREIGN_INTR); expect_ppi_value[get_core_pos()]++; itr_raise_pi(TEST_PPI_ID); thread_unmask_exceptions(exceptions); diff --git a/core/arch/arm/pta/pta_self_tests.c b/core/arch/arm/pta/pta_invoke_tests.c index 6472356..33691b0 100644 --- a/core/arch/arm/pta/pta_self_tests.c +++ b/core/arch/arm/pta/pta_invoke_tests.c @@ -24,23 +24,21 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + #include <compiler.h> -#include <types_ext.h> #include <kernel/pseudo_ta.h> -#include <trace.h> -#include <tee_api_types.h> +#include <mm/core_memprot.h> +#include <pta_invoke_tests.h> +#include <string.h> +#include <tee/cache.h> #include <tee_api_defines.h> -#include "core_self_tests.h" - -#define TA_NAME "sta_self_tests.ta" +#include <tee_api_types.h> +#include <trace.h> +#include <types_ext.h> -#define STA_SELF_TEST_UUID \ - { 0xd96a5b40, 0xc3e5, 0x21e3, \ - { 0x87, 0x94, 0x10, 0x02, 0xa5, 0xd5, 0xc6, 0x1b } } +#include "core_self_tests.h" -#define CMD_TRACE 0 -#define CMD_PARAMS 1 -#define CMD_SELF_TESTS 2 +#define TA_NAME "invoke_tests.pta" static TEE_Result test_trace(uint32_t param_types __unused, TEE_Param params[TEE_NUM_PARAMS] __unused) @@ -196,6 +194,116 @@ static TEE_Result test_entry_params(uint32_t type, TEE_Param p[TEE_NUM_PARAMS]) } /* + * Test access to Secure Data Path memory from pseudo TAs + */ + +static TEE_Result test_inject_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS]) +{ + char *src = p[0].memref.buffer; + char *dst = p[1].memref.buffer; + size_t sz = p[0].memref.size; + uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, + TEE_PARAM_TYPE_MEMREF_OUTPUT, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE); + + if (exp_pt != type) { + DMSG("bad parameter types"); + return TEE_ERROR_BAD_PARAMETERS; + } + + if (p[1].memref.size < sz) { + p[1].memref.size = sz; + return TEE_ERROR_SHORT_BUFFER; + } + + + if (!core_vbuf_is(CORE_MEM_NSEC_SHM, src, sz) || + !core_vbuf_is(CORE_MEM_SDP_MEM, dst, sz)) { + DMSG("bad memref secure attribute"); + return TEE_ERROR_BAD_PARAMETERS; + } + + if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS) + return TEE_ERROR_GENERIC; + + memcpy(dst, src, sz); + + if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} + +static TEE_Result test_transform_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS]) +{ + char *buf = p[0].memref.buffer; + size_t sz = p[0].memref.size; + uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE); + + if (exp_pt != type) { + DMSG("bad parameter types"); + return TEE_ERROR_BAD_PARAMETERS; + } + + if (!core_vbuf_is(CORE_MEM_SDP_MEM, buf, sz)) { + DMSG("bad memref secure attribute"); + return TEE_ERROR_BAD_PARAMETERS; + } + + if (cache_operation(TEE_CACHEFLUSH, buf, sz) != TEE_SUCCESS) + return TEE_ERROR_GENERIC; + + for (; sz; sz--, buf++) + *buf = ~(*buf) + 1; + + if (cache_operation(TEE_CACHEFLUSH, buf, sz) != TEE_SUCCESS) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} + +static TEE_Result test_dump_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS]) +{ + char *src = p[0].memref.buffer; + char *dst = p[1].memref.buffer; + size_t sz = p[0].memref.size; + uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, + TEE_PARAM_TYPE_MEMREF_OUTPUT, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE); + + if (exp_pt != type) { + DMSG("bad parameter types"); + return TEE_ERROR_BAD_PARAMETERS; + } + + if (p[1].memref.size < sz) { + p[1].memref.size = sz; + return TEE_ERROR_SHORT_BUFFER; + } + + if (!core_vbuf_is(CORE_MEM_SDP_MEM, src, sz) || + !core_vbuf_is(CORE_MEM_NSEC_SHM, dst, sz)) { + DMSG("bad memref secure attribute"); + return TEE_ERROR_BAD_PARAMETERS; + } + + if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS) + return TEE_ERROR_GENERIC; + + memcpy(dst, src, sz); + + if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} + +/* * Trusted Application Entry Points */ @@ -230,20 +338,30 @@ static TEE_Result invoke_command(void *pSessionContext __unused, DMSG("command entry point for pseudo ta \"%s\"", TA_NAME); switch (nCommandID) { - case CMD_TRACE: + case PTA_INVOKE_TESTS_CMD_TRACE: return test_trace(nParamTypes, pParams); - case CMD_PARAMS: + case PTA_INVOKE_TESTS_CMD_PARAMS: return test_entry_params(nParamTypes, pParams); - case CMD_SELF_TESTS: + case PTA_INVOKE_TESTS_CMD_COPY_NSEC_TO_SEC: + return test_inject_sdp(nParamTypes, pParams); + case PTA_INVOKE_TESTS_CMD_READ_MODIFY_SEC: + return test_transform_sdp(nParamTypes, pParams); + case PTA_INVOKE_TESTS_CMD_COPY_SEC_TO_NSEC: + return test_dump_sdp(nParamTypes, pParams); + case PTA_INVOKE_TESTS_CMD_SELF_TESTS: return core_self_tests(nParamTypes, pParams); +#if defined(CFG_WITH_USER_TA) + case PTA_INVOKE_TESTS_CMD_FS_HTREE: + return core_fs_htree_tests(nParamTypes, pParams); +#endif default: break; } return TEE_ERROR_BAD_PARAMETERS; } -pseudo_ta_register(.uuid = STA_SELF_TEST_UUID, .name = TA_NAME, - .flags = PTA_DEFAULT_FLAGS, +pseudo_ta_register(.uuid = PTA_INVOKE_TESTS_UUID, .name = TA_NAME, + .flags = PTA_DEFAULT_FLAGS | TA_FLAG_SECURE_DATA_PATH, .create_entry_point = create_ta, .destroy_entry_point = destroy_ta, .open_session_entry_point = open_session, diff --git a/core/arch/arm/pta/sub.mk b/core/arch/arm/pta/sub.mk index 3d961d4..4333e86 100644 --- a/core/arch/arm/pta/sub.mk +++ b/core/arch/arm/pta/sub.mk @@ -1,6 +1,9 @@ -srcs-$(CFG_TEE_CORE_EMBED_INTERNAL_TESTS) += pta_self_tests.c +srcs-$(CFG_TEE_CORE_EMBED_INTERNAL_TESTS) += pta_invoke_tests.c srcs-$(CFG_TEE_CORE_EMBED_INTERNAL_TESTS) += core_self_tests.c srcs-$(CFG_TEE_CORE_EMBED_INTERNAL_TESTS) += interrupt_tests.c +ifeq ($(CFG_WITH_USER_TA),y) +srcs-$(CFG_TEE_CORE_EMBED_INTERNAL_TESTS) += core_fs_htree_tests.c +endif srcs-$(CFG_WITH_STATS) += stats.c srcs-$(CFG_TA_GPROF_SUPPORT) += gprof.c @@ -8,7 +11,3 @@ ifeq ($(CFG_SE_API),y) srcs-$(CFG_SE_API_SELF_TEST) += se_api_self_tests.c cppflags-se_api_self_tests.c-y += -Icore/tee/se endif - -ifeq ($(CFG_WITH_USER_TA),y) -srcs-$(CFG_TEE_FS_KEY_MANAGER_TEST) += tee_fs_key_manager_tests.c -endif diff --git a/core/arch/arm/pta/tee_fs_key_manager_tests.c b/core/arch/arm/pta/tee_fs_key_manager_tests.c deleted file mode 100644 index f9dc714..0000000 --- a/core/arch/arm/pta/tee_fs_key_manager_tests.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (c) 2015, Linaro Limited - * 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 <kernel/pseudo_ta.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <tee/tee_fs_key_manager.h> -#include <trace.h> - -#define TA_NAME "tee_fs_key_manager_tests.ta" - -#define CMD_SELF_TESTS 0 - -#define ENC_FS_KEY_MANAGER_TEST_UUID \ - { 0x17E5E280, 0xD12E, 0x11E4, \ - { 0xA4, 0x1A, 0x00, 0x02, 0xA5, 0xD5, 0xC5, 0x1B } } - -#define DUMP_BUF_MAX 256 - -static uint8_t test_data[] = { - 0x00, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96, - 0x00, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92, - 0x00, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6, - 0x00, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x00 -}; - -static char *print_buf(char *buf, size_t *remain_size, const char *fmt, ...) - __attribute__((__format__(__printf__, 3, 4))); - -static char *print_buf(char *buf, size_t *remain_size, const char *fmt, ...) -{ - va_list ap; - size_t len; - - va_start(ap, fmt); - len = vsnprintf(buf, *remain_size, fmt, ap); - buf += len; - *remain_size -= len; - va_end(ap); - return buf; -} - -static void dump_hex(char *buf, size_t *remain_size, uint8_t *input_buf, - size_t input_size) -{ - size_t i; - - for (i = 0; i < input_size; i++) - buf = print_buf(buf, remain_size, "%02X ", input_buf[i]); -} - -static void print_hex(uint8_t *input_buf, size_t input_size) -{ - char buf[DUMP_BUF_MAX]; - size_t remain = sizeof(buf); - - dump_hex(buf, &remain, input_buf, input_size); - DMSG("%s", buf); -} - -/* - * Trusted Application Entry Points - */ - -static TEE_Result test_file_decrypt_with_invalid_content(void) -{ - TEE_Result res = TEE_SUCCESS; - size_t header_size; - size_t encrypt_data_out_size; - uint8_t *encrypt_data_out = NULL; - size_t decrypt_data_out_size; - uint8_t *decrypt_data_out = NULL; - uint8_t tmp_byte; - uint8_t encrypted_fek[TEE_FS_KM_FEK_SIZE]; - - DMSG("Start"); - - /* data encryption */ - header_size = tee_fs_get_header_size(META_FILE); - - encrypt_data_out_size = header_size + sizeof(test_data); - encrypt_data_out = malloc(encrypt_data_out_size); - if (!encrypt_data_out) { - EMSG("malloc for encrypt data buffer failed"); - res = TEE_ERROR_OUT_OF_MEMORY; - goto exit; - } - - res = tee_fs_encrypt_file(META_FILE, - test_data, sizeof(test_data), - encrypt_data_out, &encrypt_data_out_size, - encrypted_fek); - if (res != TEE_SUCCESS) { - EMSG("file encryption failed"); - goto exit; - } - - /* data decryption */ - decrypt_data_out_size = sizeof(test_data); - decrypt_data_out = malloc(decrypt_data_out_size); - if (!decrypt_data_out) { - EMSG("malloc for decrypt data buffer failed"); - res = TEE_ERROR_OUT_OF_MEMORY; - goto exit; - } - - /* case1: data decryption with modified encrypted_key */ - tmp_byte = *(encrypt_data_out + 4); - *(encrypt_data_out + 4) = ~tmp_byte; - - DMSG("case1: decryption with modified encrypted FEK"); - - res = tee_fs_decrypt_file(META_FILE, - encrypt_data_out, encrypt_data_out_size, - decrypt_data_out, &decrypt_data_out_size, - encrypted_fek); - if (res == TEE_ERROR_MAC_INVALID) { - DMSG("case1: passed, return code=%x", res); - } else { - EMSG("case1: failed, return code=%x", res); - res = TEE_ERROR_GENERIC; - goto exit; - } - - *(encrypt_data_out + 4) = tmp_byte; - - /* case2: data decryption with modified iv */ - tmp_byte = *(encrypt_data_out + 20); - *(encrypt_data_out + 20) = ~tmp_byte; - - DMSG("case2: decryption with modified IV"); - - res = tee_fs_decrypt_file(META_FILE, - encrypt_data_out, encrypt_data_out_size, - decrypt_data_out, &decrypt_data_out_size, - encrypted_fek); - if (res == TEE_ERROR_MAC_INVALID) { - DMSG("case2: passed, return code=%x", res); - } else { - EMSG("case2: failed, return code=%x", res); - res = TEE_ERROR_GENERIC; - goto exit; - } - - *(encrypt_data_out + 20) = tmp_byte; - - /* case3: data decryption with modified cipher text */ - tmp_byte = *(encrypt_data_out + encrypt_data_out_size - 5); - *(encrypt_data_out + encrypt_data_out_size - 5) = ~tmp_byte; - - DMSG("case3: decryption with modified cipher text"); - - res = tee_fs_decrypt_file(META_FILE, - encrypt_data_out, encrypt_data_out_size, - decrypt_data_out, &decrypt_data_out_size, - encrypted_fek); - if (res == TEE_ERROR_MAC_INVALID) { - DMSG("case3: passed, return code=%x", res); - } else { - EMSG("case3: failed, return code=%x", res); - res = TEE_ERROR_GENERIC; - goto exit; - } - - *(encrypt_data_out + encrypt_data_out_size - 5) = tmp_byte; - - /* case4: data decryption with shorter cipher text length */ - DMSG("case4: decryption with shorter cipher text length"); - - res = tee_fs_decrypt_file(META_FILE, - encrypt_data_out, encrypt_data_out_size - 1, - decrypt_data_out, &decrypt_data_out_size, - encrypted_fek); - if (res == TEE_ERROR_MAC_INVALID) { - DMSG("case4: passed, return code=%x", res); - } else { - EMSG("case4: failed, return code=%x", res); - res = TEE_ERROR_GENERIC; - goto exit; - } - - /* case5: data decryption with shorter plain text buffer */ - decrypt_data_out_size = sizeof(test_data) - 1; - - DMSG("case5: decryption with shorter plain text buffer"); - - res = tee_fs_decrypt_file(META_FILE, - encrypt_data_out, encrypt_data_out_size, - decrypt_data_out, &decrypt_data_out_size, - encrypted_fek); - if (res == TEE_ERROR_SHORT_BUFFER) { - DMSG("case5: passed, return code=%x", res); - } else { - EMSG("case5: failed, return code=%x", res); - res = TEE_ERROR_GENERIC; - goto exit; - } - - decrypt_data_out_size = encrypt_data_out_size; - - /* data decryption with correct encrypted data */ - DMSG("good path test - decryption with correct data"); - - res = tee_fs_decrypt_file(META_FILE, - encrypt_data_out, encrypt_data_out_size, - decrypt_data_out, &decrypt_data_out_size, - encrypted_fek); - if (res != TEE_SUCCESS) { - EMSG("failed to decrypted data, return code=%x", res); - goto exit; - } - - /* data comparison */ - if (memcmp(test_data, decrypt_data_out, sizeof(test_data)) != 0) { - EMSG("decrypted data doest not correct"); - res = TEE_ERROR_GENERIC; - } else { - DMSG("good path test - passed"); - } - -exit: - if (encrypt_data_out != NULL) - free(encrypt_data_out); - - if (decrypt_data_out != NULL) - free(decrypt_data_out); - - DMSG("Finish"); - - return res; -} - -static TEE_Result test_file_decrypt_success(void) -{ - TEE_Result res = TEE_SUCCESS; - size_t header_size; - size_t encrypt_data_out_size; - uint8_t *encrypt_data_out = NULL; - size_t decrypt_data_out_size; - uint8_t *decrypt_data_out = NULL; - uint8_t encrypted_fek[TEE_FS_KM_FEK_SIZE]; - - DMSG("Start"); - - res = tee_fs_generate_fek(encrypted_fek, TEE_FS_KM_FEK_SIZE); - if (res != TEE_SUCCESS) - goto exit; - - /* data encryption */ - header_size = tee_fs_get_header_size(META_FILE); - - encrypt_data_out_size = header_size + sizeof(test_data); - encrypt_data_out = malloc(encrypt_data_out_size); - if (!encrypt_data_out) { - EMSG("malloc for encrypt data buffer failed"); - res = TEE_ERROR_OUT_OF_MEMORY; - goto exit; - } - - res = tee_fs_encrypt_file(META_FILE, - test_data, sizeof(test_data), - encrypt_data_out, &encrypt_data_out_size, - encrypted_fek); - if (res != TEE_SUCCESS) { - EMSG("file encryption failed"); - goto exit; - } - - - /* data decryption */ - decrypt_data_out_size = sizeof(test_data); - decrypt_data_out = malloc(decrypt_data_out_size); - if (!decrypt_data_out) { - EMSG("malloc for decrypt data buffer failed"); - res = TEE_ERROR_OUT_OF_MEMORY; - goto exit; - } - - res = tee_fs_decrypt_file(META_FILE, - encrypt_data_out, encrypt_data_out_size, - decrypt_data_out, &decrypt_data_out_size, - encrypted_fek); - if (res != TEE_SUCCESS) - goto exit; - - /* data comparison */ - if (memcmp(test_data, decrypt_data_out, sizeof(test_data)) != 0) { - EMSG("Data compare failed"); - res = TEE_ERROR_GENERIC; - } - -exit: - /* dump data for debug */ - if (res != TEE_SUCCESS) - DMSG("return code = %x", res); - else { - DMSG("Test Data (%zu bytes)", sizeof(test_data)); - print_hex(test_data, sizeof(test_data)); - DMSG("Encrypted Data (%zu bytes)", encrypt_data_out_size); - print_hex(encrypt_data_out, encrypt_data_out_size); - DMSG("Decrypted Data (%zu bytes)", decrypt_data_out_size); - print_hex(decrypt_data_out, decrypt_data_out_size); - } - - if (encrypt_data_out != NULL) - free(encrypt_data_out); - - if (decrypt_data_out != NULL) - free(decrypt_data_out); - - DMSG("Finish"); - - return res; -} - -static TEE_Result self_tests( - uint32_t nParamTypes __unused, - TEE_Param pParams[TEE_NUM_PARAMS] __unused) -{ - TEE_Result res; - - res = test_file_decrypt_success(); - if (res != TEE_SUCCESS) - return res; - - res = test_file_decrypt_with_invalid_content(); - if (res != TEE_SUCCESS) - return res; - - return TEE_SUCCESS; -} - -static TEE_Result invoke_command(void *pSessionContext __unused, - uint32_t nCommandID, uint32_t nParamTypes, - TEE_Param pParams[TEE_NUM_PARAMS]) -{ - DMSG("command entry point for static ta \"%s\"", TA_NAME); - - switch (nCommandID) { - case CMD_SELF_TESTS: - return self_tests(nParamTypes, pParams); - default: - break; - } - return TEE_ERROR_BAD_PARAMETERS; -} - -pseudo_ta_register(.uuid = ENC_FS_KEY_MANAGER_TEST_UUID, .name = TA_NAME, - .flags = PTA_DEFAULT_FLAGS, - .invoke_command_entry_point = invoke_command); diff --git a/core/arch/arm/sm/psci.c b/core/arch/arm/sm/psci.c index b2bd645..32a897c 100644 --- a/core/arch/arm/sm/psci.c +++ b/core/arch/arm/sm/psci.c @@ -149,7 +149,7 @@ void tee_psci_handler(struct thread_smc_args *args) ; break; case PSCI_SYSTEM_RESET: - psci_system_off(); + psci_system_reset(); while (1) ; break; diff --git a/core/arch/arm/sm/sm.c b/core/arch/arm/sm/sm.c index 4a0c0f6..f3fa4af 100644 --- a/core/arch/arm/sm/sm.c +++ b/core/arch/arm/sm/sm.c @@ -39,6 +39,9 @@ bool sm_from_nsec(struct sm_ctx *ctx) { uint32_t *nsec_r0 = (uint32_t *)(&ctx->nsec.r0); + if (!sm_platform_handler(ctx)) + return false; + #ifdef CFG_PSCI_ARM32 if (OPTEE_SMC_OWNER_NUM(*nsec_r0) == OPTEE_SMC_OWNER_STANDARD) { smc_std_handler((struct thread_smc_args *)nsec_r0); diff --git a/core/arch/arm/tee/arch_svc.c b/core/arch/arm/tee/arch_svc.c index 8a89ce9..f6767d7 100644 --- a/core/arch/arm/tee/arch_svc.c +++ b/core/arch/arm/tee/arch_svc.c @@ -35,12 +35,12 @@ #include <tee/tee_svc_cryp.h> #include <tee/tee_svc_storage.h> #include <tee/se/svc.h> +#include <tee/svc_cache.h> #include <tee_syscall_numbers.h> #include <trace.h> #include <util.h> #include "arch_svc_private.h" -#include "svc_cache.h" #if (TRACE_LEVEL == TRACE_FLOW) && defined(CFG_TEE_CORE_TA_TRACE) #define TRACE_SYSCALLS @@ -201,8 +201,8 @@ void tee_svc_handler(struct thread_svc_regs *regs) /* TA has just entered kernel mode */ tee_ta_update_session_utime_suspend(); - /* Restore IRQ which are disabled on exception entry */ - thread_restore_irq(); + /* Restore foreign interrupts which are disabled on exception entry */ + thread_restore_foreign_intr(); get_scn_max_args(regs, &scn, &max_args); diff --git a/core/arch/arm/tee/cache.c b/core/arch/arm/tee/cache.c new file mode 100644 index 0000000..ff4bab3 --- /dev/null +++ b/core/arch/arm/tee/cache.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, STMicroelectronics International N.V. + * Copyright (c) 2015, Linaro Limited + * 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 <mm/core_memprot.h> +#include <mm/core_mmu.h> +#include <tee/cache.h> + +/* + * tee_uta_cache_operation - dynamic cache clean/inval request from a TA. + * It follows ARM recommendation: + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0246d/Beicdhde.html + * Note that this implementation assumes dsb operations are part of + * cache_op_inner(), and outer cache sync are part of cache_op_outer(). + */ +TEE_Result cache_operation(enum utee_cache_operation op, void *va, size_t len) +{ + TEE_Result res; + paddr_t pa; + + pa = virt_to_phys(va); + if (!pa) + return TEE_ERROR_ACCESS_DENIED; + + switch (op) { + case TEE_CACHEFLUSH: +#ifdef CFG_PL310 /* prevent initial L1 clean in case there is no outer L2 */ + /* Clean L1, Flush L2, Flush L1 */ + res = cache_op_inner(DCACHE_AREA_CLEAN, va, len); + if (res != TEE_SUCCESS) + return res; + res = cache_op_outer(DCACHE_AREA_CLEAN_INV, pa, len); + if (res != TEE_SUCCESS) + return res; +#endif + return cache_op_inner(DCACHE_AREA_CLEAN_INV, va, len); + + case TEE_CACHECLEAN: + /* Clean L1, Clean L2 */ + res = cache_op_inner(DCACHE_AREA_CLEAN, va, len); + if (res != TEE_SUCCESS) + return res; + return cache_op_outer(DCACHE_AREA_CLEAN, pa, len); + + case TEE_CACHEINVALIDATE: + /* Inval L2, Inval L1 */ + res = cache_op_outer(DCACHE_AREA_INVALIDATE, pa, len); + if (res != TEE_SUCCESS) + return res; + return cache_op_inner(DCACHE_AREA_INVALIDATE, va, len); + + default: + return TEE_ERROR_NOT_SUPPORTED; + } +} diff --git a/core/arch/arm/tee/entry_fast.c b/core/arch/arm/tee/entry_fast.c index 0e80dc8..da7cd31 100644 --- a/core/arch/arm/tee/entry_fast.c +++ b/core/arch/arm/tee/entry_fast.c @@ -82,17 +82,21 @@ static void tee_entry_fastcall_l2cc_mutex(struct thread_smc_args *args) static void tee_entry_exchange_capabilities(struct thread_smc_args *args) { - if (args->a1) { - /* - * Either unknown capability or - * OPTEE_SMC_NSEC_CAP_UNIPROCESSOR, in either case we can't - * deal with it. - * - * The memory mapping of shared memory is defined as normal - * shared memory for SMP systems and normal memory for UP - * systems. Currently we map all memory as shared in secure - * world. - */ + /* + * Currently we ignore OPTEE_SMC_NSEC_CAP_UNIPROCESSOR. + * + * The memory mapping of shared memory is defined as normal + * shared memory for SMP systems and normal memory for UP + * systems. Currently we map all memory as shared in secure + * world. + * + * When translation tables are created with shared bit cleared for + * uniprocessor systems we'll need to check + * OPTEE_SMC_NSEC_CAP_UNIPROCESSOR. + */ + + if (args->a1 & ~OPTEE_SMC_NSEC_CAP_UNIPROCESSOR) { + /* Unknown capability. */ args->a0 = OPTEE_SMC_RETURN_ENOTAVAIL; return; } diff --git a/core/arch/arm/tee/entry_std.c b/core/arch/arm/tee/entry_std.c index 29c3b74..233d731 100644 --- a/core/arch/arm/tee/entry_std.c +++ b/core/arch/arm/tee/entry_std.c @@ -51,28 +51,45 @@ static struct tee_ta_session_head tee_open_sessions = TAILQ_HEAD_INITIALIZER(tee_open_sessions); static struct mobj *shm_mobj; +#ifdef CFG_SECURE_DATA_PATH +static struct mobj **sdp_mem_mobjs; +#endif -static TEE_Result set_mem_param(const struct optee_msg_param *param, - struct param_mem *mem) +static bool param_mem_from_mobj(struct param_mem *mem, struct mobj *mobj, + const paddr_t pa, const size_t sz) { paddr_t b; - size_t sz; - size_t tsz; - if (mobj_get_pa(shm_mobj, 0, 0, &b) != TEE_SUCCESS) - panic("Failed to be PA of shared memory MOBJ"); + if (mobj_get_pa(mobj, 0, 0, &b) != TEE_SUCCESS) + panic("mobj_get_pa failed"); - sz = shm_mobj->size; - tsz = param->u.tmem.size; - if (param->u.tmem.buf_ptr && !tsz) - tsz++; - if (!core_is_buffer_inside(param->u.tmem.buf_ptr, tsz, b, sz)) - return TEE_ERROR_BAD_PARAMETERS; + if (!core_is_buffer_inside(pa, MAX(sz, 1UL), b, mobj->size)) + return false; - mem->mobj = shm_mobj; - mem->offs = param->u.tmem.buf_ptr - b; - mem->size = param->u.tmem.size; - return TEE_SUCCESS; + mem->mobj = mobj; + mem->offs = pa - b; + mem->size = sz; + return true; +} + +/* fill 'struct param_mem' structure if buffer matches a valid memory object */ +static TEE_Result assign_mobj_to_param_mem(const paddr_t pa, const size_t sz, + struct param_mem *mem) +{ + struct mobj __maybe_unused **mobj; + + /* belongs to nonsecure shared memory ? */ + if (param_mem_from_mobj(mem, shm_mobj, pa, sz)) + return TEE_SUCCESS; + +#ifdef CFG_SECURE_DATA_PATH + /* belongs to SDP memories ? */ + for (mobj = sdp_mem_mobjs; *mobj; mobj++) + if (param_mem_from_mobj(mem, *mobj, pa, sz)) + return TEE_SUCCESS; +#endif + + return TEE_ERROR_BAD_PARAMETERS; } static TEE_Result copy_in_params(const struct optee_msg_param *params, @@ -115,7 +132,9 @@ static TEE_Result copy_in_params(const struct optee_msg_param *params, case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: pt[n] = TEE_PARAM_TYPE_MEMREF_INPUT + attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT; - res = set_mem_param(params + n, &ta_param->u[n].mem); + res = assign_mobj_to_param_mem(params[n].u.tmem.buf_ptr, + params[n].u.tmem.size, + &ta_param->u[n].mem); if (res != TEE_SUCCESS) return res; break; @@ -346,7 +365,8 @@ void tee_entry_std(struct thread_smc_args *smc_args) return; } - thread_set_irq(true); /* Enable IRQ for STD calls */ + /* Enable foreign interrupts for STD calls */ + thread_set_foreign_intr(true); switch (arg->cmd) { case OPTEE_MSG_CMD_OPEN_SESSION: entry_open_session(smc_args, arg, num_params); @@ -380,6 +400,12 @@ static TEE_Result default_mobj_init(void) if (!mobj_sec_ddr) panic("Failed to register secure ta ram"); +#ifdef CFG_SECURE_DATA_PATH + sdp_mem_mobjs = core_sdp_mem_create_mobjs(); + if (!sdp_mem_mobjs) + panic("Failed to register SDP memory"); +#endif + return TEE_SUCCESS; } diff --git a/core/arch/arm/tee/pta_socket.c b/core/arch/arm/tee/pta_socket.c index d696773..de27c55 100644 --- a/core/arch/arm/tee/pta_socket.c +++ b/core/arch/arm/tee/pta_socket.c @@ -38,7 +38,7 @@ static uint32_t get_instance_id(struct tee_ta_session *sess) return sess->ctx->ops->get_instance_id(sess->ctx); } -static TEE_Result socket_open(struct tee_ta_session *sess, uint32_t param_types, +static TEE_Result socket_open(uint32_t instance_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { TEE_Result res; @@ -65,7 +65,7 @@ static TEE_Result socket_open(struct tee_ta_session *sess, uint32_t param_types, msg_params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; msg_params[0].u.value.a = OPTEE_MRC_SOCKET_OPEN; - msg_params[0].u.value.b = get_instance_id(sess); + msg_params[0].u.value.b = instance_id; msg_params[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; msg_params[1].u.value.a = params[0].value.b; /* server port number */ @@ -90,8 +90,7 @@ static TEE_Result socket_open(struct tee_ta_session *sess, uint32_t param_types, return res; } -static TEE_Result socket_close(struct tee_ta_session *sess, - uint32_t param_types, +static TEE_Result socket_close(uint32_t instance_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { struct optee_msg_param msg_params[1]; @@ -110,13 +109,13 @@ static TEE_Result socket_close(struct tee_ta_session *sess, msg_params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; msg_params[0].u.value.a = OPTEE_MRC_SOCKET_CLOSE; - msg_params[0].u.value.b = get_instance_id(sess); + msg_params[0].u.value.b = instance_id; msg_params[0].u.value.c = params[0].value.a; return thread_rpc_cmd(OPTEE_MSG_RPC_CMD_SOCKET, 1, msg_params); } -static TEE_Result socket_send(struct tee_ta_session *sess, uint32_t param_types, +static TEE_Result socket_send(uint32_t instance_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { TEE_Result res; @@ -143,7 +142,7 @@ static TEE_Result socket_send(struct tee_ta_session *sess, uint32_t param_types, msg_params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; msg_params[0].u.value.a = OPTEE_MRC_SOCKET_SEND; - msg_params[0].u.value.b = get_instance_id(sess); + msg_params[0].u.value.b = instance_id; msg_params[0].u.value.c = params[0].value.a; /* handle */ /* buffer */ @@ -162,7 +161,7 @@ static TEE_Result socket_send(struct tee_ta_session *sess, uint32_t param_types, return res; } -static TEE_Result socket_recv(struct tee_ta_session *sess, uint32_t param_types, +static TEE_Result socket_recv(uint32_t instance_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { TEE_Result res; @@ -189,7 +188,7 @@ static TEE_Result socket_recv(struct tee_ta_session *sess, uint32_t param_types, msg_params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; msg_params[0].u.value.a = OPTEE_MRC_SOCKET_RECV; - msg_params[0].u.value.b = get_instance_id(sess); + msg_params[0].u.value.b = instance_id; msg_params[0].u.value.c = params[0].value.a; /* handle */ /* buffer */ @@ -209,8 +208,7 @@ static TEE_Result socket_recv(struct tee_ta_session *sess, uint32_t param_types, return res; } -static TEE_Result socket_ioctl(struct tee_ta_session *sess, - uint32_t param_types, +static TEE_Result socket_ioctl(uint32_t instance_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { TEE_Result res; @@ -237,7 +235,7 @@ static TEE_Result socket_ioctl(struct tee_ta_session *sess, msg_params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; msg_params[0].u.value.a = OPTEE_MRC_SOCKET_IOCTL; - msg_params[0].u.value.b = get_instance_id(sess); + msg_params[0].u.value.b = instance_id; msg_params[0].u.value.c = params[0].value.a; /* handle */ /* buffer */ @@ -257,7 +255,7 @@ static TEE_Result socket_ioctl(struct tee_ta_session *sess, return res; } -typedef TEE_Result (*ta_func)(struct tee_ta_session *sess, uint32_t param_types, +typedef TEE_Result (*ta_func)(uint32_t instance_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]); static const ta_func ta_funcs[] = { @@ -274,7 +272,7 @@ static const ta_func ta_funcs[] = { static TEE_Result pta_socket_open_session(uint32_t param_types __unused, TEE_Param pParams[TEE_NUM_PARAMS] __unused, - void **sess_ctx __unused) + void **sess_ctx) { struct tee_ta_session *s; @@ -283,7 +281,7 @@ static TEE_Result pta_socket_open_session(uint32_t param_types __unused, if (!s) return TEE_ERROR_ACCESS_DENIED; - *sess_ctx = s; + *sess_ctx = (void *)(vaddr_t)get_instance_id(s); return TEE_SUCCESS; } @@ -297,7 +295,7 @@ static void pta_socket_close_session(void *sess_ctx) msg_params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; msg_params[0].u.value.a = OPTEE_MRC_SOCKET_CLOSE_ALL; - msg_params[0].u.value.b = get_instance_id(sess_ctx); + msg_params[0].u.value.b = (vaddr_t)sess_ctx; res = thread_rpc_cmd(OPTEE_MSG_RPC_CMD_SOCKET, 1, msg_params); if (res != TEE_SUCCESS) @@ -308,7 +306,7 @@ static TEE_Result pta_socket_invoke_command(void *sess_ctx, uint32_t cmd_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { if (cmd_id < ARRAY_SIZE(ta_funcs) && ta_funcs[cmd_id]) - return ta_funcs[cmd_id](sess_ctx, param_types, params); + return ta_funcs[cmd_id]((vaddr_t)sess_ctx, param_types, params); return TEE_ERROR_NOT_IMPLEMENTED; } diff --git a/core/arch/arm/tee/sub.mk b/core/arch/arm/tee/sub.mk index 0ee9f64..d95c38c 100644 --- a/core/arch/arm/tee/sub.mk +++ b/core/arch/arm/tee/sub.mk @@ -10,3 +10,4 @@ endif srcs-y += entry_std.c srcs-y += entry_fast.c srcs-y += init.c +srcs-y += cache.c diff --git a/core/arch/arm/tee/svc_cache.c b/core/arch/arm/tee/svc_cache.c index 88b89a9..49ee3cf 100644 --- a/core/arch/arm/tee/svc_cache.c +++ b/core/arch/arm/tee/svc_cache.c @@ -25,32 +25,27 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ -#include <types_ext.h> -#include <utee_types.h> + #include <kernel/tee_ta_manager.h> #include <mm/tee_mmu.h> -#include <mm/core_memprot.h> - -#include "svc_cache.h" +#include <tee/cache.h> +#include <tee/svc_cache.h> -/* - * tee_uta_cache_operation - dynamic cache clean/inval request from a TA - * It follows ARM recommendation: - * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0246d/Beicdhde.html - * Note that this implementation assumes dsb operations are part of - * cache_maintenance_l1(), and L2 cache sync are part of - * cache_maintenance_l2() - */ -static TEE_Result cache_operation(struct tee_ta_session *sess, - enum utee_cache_operation op, void *va, size_t len) +TEE_Result syscall_cache_operation(void *va, size_t len, unsigned long op) { - TEE_Result ret; - paddr_t pa = 0; - struct user_ta_ctx *utc = to_user_ta_ctx(sess->ctx); + TEE_Result res; + struct tee_ta_session *sess; + struct user_ta_ctx *utc; + + res = tee_ta_get_current_session(&sess); + if (res != TEE_SUCCESS) + return res; if ((sess->ctx->flags & TA_FLAG_CACHE_MAINTENANCE) == 0) return TEE_ERROR_NOT_SUPPORTED; + utc = to_user_ta_ctx(sess->ctx); + /* * TAs are allowed to operate cache maintenance on TA memref parameters * only, not on the TA private memory. @@ -58,57 +53,11 @@ static TEE_Result cache_operation(struct tee_ta_session *sess, if (tee_mmu_is_vbuf_intersect_ta_private(utc, va, len)) return TEE_ERROR_ACCESS_DENIED; - ret = tee_mmu_check_access_rights(utc, TEE_MEMORY_ACCESS_READ | + res = tee_mmu_check_access_rights(utc, TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_ANY_OWNER, (uaddr_t)va, len); - if (ret != TEE_SUCCESS) - return TEE_ERROR_ACCESS_DENIED; - - pa = virt_to_phys(va); - if (!pa) - return TEE_ERROR_ACCESS_DENIED; - - switch (op) { - case TEE_CACHEFLUSH: - /* Clean L1, Flush L2, Flush L1 */ - ret = cache_maintenance_l1(DCACHE_AREA_CLEAN, va, len); - if (ret != TEE_SUCCESS) - return ret; - ret = cache_maintenance_l2(L2CACHE_AREA_CLEAN_INV, pa, len); - if (ret != TEE_SUCCESS) - return ret; - return cache_maintenance_l1(DCACHE_AREA_CLEAN_INV, va, len); - - case TEE_CACHECLEAN: - /* Clean L1, Clean L2 */ - ret = cache_maintenance_l1(DCACHE_AREA_CLEAN, va, len); - if (ret != TEE_SUCCESS) - return ret; - return cache_maintenance_l2(L2CACHE_AREA_CLEAN, pa, len); - - case TEE_CACHEINVALIDATE: - /* Inval L2, Inval L1 */ - ret = cache_maintenance_l2(L2CACHE_AREA_INVALIDATE, pa, len); - if (ret != TEE_SUCCESS) - return ret; - return cache_maintenance_l1(DCACHE_AREA_INVALIDATE, va, len); - - default: - return TEE_ERROR_NOT_SUPPORTED; - } -} - -TEE_Result syscall_cache_operation(void *va, size_t len, unsigned long op) -{ - TEE_Result res; - struct tee_ta_session *s = NULL; - - res = tee_ta_get_current_session(&s); if (res != TEE_SUCCESS) - return res; - - if ((s->ctx->flags & TA_FLAG_CACHE_MAINTENANCE) == 0) - return TEE_ERROR_NOT_SUPPORTED; + return TEE_ERROR_ACCESS_DENIED; - return cache_operation(s, op, va, len); + return cache_operation(op, va, len); } diff --git a/core/arch/arm/tee/svc_cache.h b/core/arch/arm/tee/svc_cache.h deleted file mode 100644 index d5d4972..0000000 --- a/core/arch/arm/tee/svc_cache.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2015, Linaro Limited - * 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 SVC_CACHE_H -#define SVC_CACHE_H - -#include <types_ext.h> -#include <tee_api_types.h> - -#ifdef CFG_CACHE_API -TEE_Result syscall_cache_operation(void *va, size_t len, unsigned long op); -#else -#define syscall_cache_operation syscall_not_supported -#endif - -#endif /*SVC_CACHE_H*/ |