diff options
author | sunny <sunny@allwinnertech.com> | 2014-11-07 14:23:34 +0800 |
---|---|---|
committer | sunny <sunny@allwinnertech.com> | 2015-01-16 19:25:33 -0800 |
commit | 056cd73a3901d0187d936e6f0e8d2917e96526df (patch) | |
tree | 94c5ec1cbb57e09926059f55831e18f4a5d04ff5 /core | |
parent | bedc2b9fafb3fe78e8176d5e0879ffd6eab52ea1 (diff) |
Add plat-sunxi
Initial version support for Allwinner A80 platform.
Allwinner A80 is big.little archtecture with 4*A7 + 4*A15,
Support Trustzone tech and secureboot inside hardware.
plat-sunxi support features:
1.Clone plat-sunxi from plat-vexpress;
2.Secure bootloader reserved 64MB secure DRAM for optee_os;
3.Support SMP secondary cpu secure stage bootup;
4.Add uart driver to core/driver/*;
5.Support GIC driver initialization.
The porting work test on Optimus board, with allwinner A80 chip.
Signed-off-by: sunny <sunny@allwinnertech.com>
Reviewed-by: Joakim Bech <joakim.bech@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Pascal Brand <pascal.brand@linaro.org>
Diffstat (limited to 'core')
23 files changed, 2012 insertions, 0 deletions
diff --git a/core/arch/arm32/include/arm32.h b/core/arch/arm32/include/arm32.h index 108c4fe..093ed79 100644 --- a/core/arch/arm32/include/arm32.h +++ b/core/arch/arm32/include/arm32.h @@ -86,6 +86,21 @@ #define SCTLR_AFE (1 << 29) #define SCTLR_TE (1 << 30) +#define ACTLR_SMP (1 << 6) +#define ACTLR_DODMBS (1 << 10) +#define ACTLR_L2RADIS (1 << 11) +#define ACTLR_L1RADIS (1 << 12) +#define ACTLR_L1PCTL (1 << 13) +#define ACTLR_DDVM (1 << 15) +#define ACTLR_DDI (1 << 28) + +#define NSACR_CP10 (1 << 10) +#define NSACR_CP11 (1 << 11) +#define NSACR_NSD32DIS (1 << 14) +#define NSACR_NSASEDIS (1 << 15) +#define NSACR_NS_L2ERR (1 << 17) +#define NSACR_NS_SMP (1 << 18) + #define DACR_DOMAIN(num, perm) ((perm) << ((num) * 2)) #define DACR_DOMAIN_PERM_NO_ACCESS 0x0 #define DACR_DOMAIN_PERM_CLIENT 0x1 @@ -276,6 +291,42 @@ static inline uint32_t read_spsr(void) return spsr; } +static inline uint32_t read_actlr(void) +{ + uint32_t actlr; + + asm volatile ("mrc p15, 0, %[actlr], c1, c0, 1" + : [actlr] "=r" (actlr) + ); + + return actlr; +} + +static inline void write_actlr(uint32_t actlr) +{ + asm volatile ("mcr p15, 0, %[actlr], c1, c0, 1" + : : [actlr] "r" (actlr) + ); +} + +static inline uint32_t read_nsacr(void) +{ + uint32_t nsacr; + + asm volatile ("mrc p15, 0, %[nsacr], c1, c1, 2" + : [nsacr] "=r" (nsacr) + ); + + return nsacr; +} + +static inline void write_nsacr(uint32_t nsacr) +{ + asm volatile ("mcr p15, 0, %[nsacr], c1, c1, 2" + : : [nsacr] "r" (nsacr) + ); +} + #endif #endif /*ARM32_H*/ diff --git a/core/arch/arm32/include/arm32_macros.S b/core/arch/arm32/include/arm32_macros.S index 62d94eb..20a5991 100644 --- a/core/arch/arm32/include/arm32_macros.S +++ b/core/arch/arm32/include/arm32_macros.S @@ -110,3 +110,12 @@ .macro write_pcr reg mcr p15, 0, \reg, c15, c0, 0 .endm + + .macro read_actlr reg + mrc p15, 0, \reg, c1, c0, 1 + .endm + + .macro read_nsacr reg + mrc p15, 0, \reg, c1, c1, 2 + .endm + diff --git a/core/arch/arm32/plat-sunxi/conf.mk b/core/arch/arm32/plat-sunxi/conf.mk new file mode 100644 index 0000000..7b94bab --- /dev/null +++ b/core/arch/arm32/plat-sunxi/conf.mk @@ -0,0 +1,41 @@ +include core/arch/$(ARCH)/plat-$(PLATFORM)/platform_flags.mk + +CROSS_PREFIX ?= arm-linux-gnueabihf +CROSS_COMPILE ?= $(CROSS_PREFIX)- +include mk/gcc.mk + +core-platform-cppflags = -I$(arch-dir)/include +core-platform-cppflags += -DNUM_THREADS=4 +core-platform-cppflags += -DWITH_STACK_CANARIES=1 +core-platform-subdirs += \ + $(addprefix $(arch-dir)/, kernel mm tee sta) $(platform-dir) +core-platform-subdirs += $(arch-dir)/sm +core-platform-cppflags += -DWITH_SEC_MON=1 + +CFG_PM_DEBUG ?= 0 +ifeq ($(CFG_PM_DEBUG),1) +core-platform-cppflags += \ + -DCFG_PM_DEBUG +endif + +libutil_with_isoc := y +WITH_SECURE_TIME_SOURCE_CNTPCT := y + +include mk/config.mk + +CFG_TEE_CORE_EMBED_INTERNAL_TESTS ?= 1 +core-platform-cppflags += \ + -DCFG_TEE_CORE_EMBED_INTERNAL_TESTS=$(CFG_TEE_CORE_EMBED_INTERNAL_TESTS) + +core-platform-cppflags += -DTEE_USE_DLMALLOC +core-platform-cppflags += -D_USE_SLAPORT_LIB + + +# Several CPU suppoorted +core-platform-cppflags += -DTEE_MULTI_CPU +# define flag to support booting from GDB +core-platform-cppflags += -DCONFIG_TEE_GDB_BOOT +core-platform-cppflags += -DCFG_NO_TA_HASH_SIGN +core-platform-cppflags += -DWITH_UART_DRV=1 +WITH_SUNXI_UART := y +WITH_GIC_DRV := y diff --git a/core/arch/arm32/plat-sunxi/console.c b/core/arch/arm32/plat-sunxi/console.c new file mode 100644 index 0000000..8b1f6e1 --- /dev/null +++ b/core/arch/arm32/plat-sunxi/console.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * 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 <drivers/sunxi_uart.h> +#include <console.h> + +void console_putc(int ch) +{ + sunxi_uart_putc(ch, CONSOLE_UART_BASE); +} + +void console_flush_tx_fifo(void) +{ + sunxi_uart_flush_tx_fifo(CONSOLE_UART_BASE); +} diff --git a/core/arch/arm32/plat-sunxi/core_bootcfg.c b/core/arch/arm32/plat-sunxi/core_bootcfg.c new file mode 100644 index 0000000..b79bb6e --- /dev/null +++ b/core/arch/arm32/plat-sunxi/core_bootcfg.c @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * 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 <mm/core_mmu.h> +#include <mm/core_memprot.h> +#include <util.h> +#include <kernel/tee_misc.h> +#include <trace.h> + +#ifndef CFG_DDR_TEETZ_RESERVED_START +#error "TEETZ reserved DDR start address undef: CFG_DDR_TEETZ_RESERVED_START" +#endif +#ifndef CFG_DDR_TEETZ_RESERVED_SIZE +#error "TEETZ reserved DDR siez undefined: CFG_DDR_TEETZ_RESERVED_SIZE" +#endif + +/* + * TEE/TZ RAM layout: + * + * +-----------------------------------------+ <- CFG_DDR_TEETZ_RESERVED_START + * | TEETZ private RAM | TEE_RAM | ^ + * | +--------------------+ | + * | | TA_RAM | | + * +-----------------------------------------+ | CFG_DDR_TEETZ_RESERVED_SIZE + * | | teecore alloc | | + * | TEE/TZ and NSec | PUB_RAM --------| | + * | shared memory | NSec alloc | | + * +-----------------------------------------+ v + * + * TEE_RAM : 1MByte + * PUB_RAM : 1MByte + * TA_RAM : all what is left (at least 2MByte !) + */ + +/* define the several memory area sizes */ +#if (CFG_DDR_TEETZ_RESERVED_SIZE < (4 * 1024 * 1024)) +#error "Invalid CFG_DDR_TEETZ_RESERVED_SIZE: at least 4MB expected" +#endif + +#define CFG_PUB_RAM_SIZE (1 * 1024 * 1024) +#define CFG_TEE_RAM_SIZE (1 * 1024 * 1024) +#define CFG_TA_RAM_SIZE (CFG_DDR_TEETZ_RESERVED_SIZE - \ + CFG_TEE_RAM_SIZE - CFG_PUB_RAM_SIZE) + +/* define the secure/unsecure memory areas */ +#define CFG_DDR_ARMTZ_ONLY_START (CFG_DDR_TEETZ_RESERVED_START) +#define CFG_DDR_ARMTZ_ONLY_SIZE (CFG_TEE_RAM_SIZE + CFG_TA_RAM_SIZE) + +#define CFG_DDR_ARM_ARMTZ_START \ + (CFG_DDR_ARMTZ_ONLY_START + CFG_DDR_ARMTZ_ONLY_SIZE) +#define CFG_DDR_ARM_ARMTZ_SIZE (CFG_PUB_RAM_SIZE) + +/* define the memory areas (TEE_RAM must start at reserved DDR start addr */ +#define CFG_TEE_RAM_START (CFG_DDR_ARMTZ_ONLY_START) +#define CFG_TA_RAM_START (CFG_TEE_RAM_START + CFG_TEE_RAM_SIZE) +#define CFG_PUB_RAM_START (CFG_TA_RAM_START + CFG_TA_RAM_SIZE) + + +/* + * define the platform memory Secure layout + */ +struct memaccess_area { + unsigned long paddr; + size_t size; +}; +#define MEMACCESS_AREA(a, s) { .paddr = a, .size = s } + +static struct memaccess_area ddr[] = { + MEMACCESS_AREA(CFG_DDR_START, CFG_DDR_SIZE), +}; + +static struct memaccess_area secure_only = +MEMACCESS_AREA(CFG_DDR_ARMTZ_ONLY_START, CFG_DDR_ARMTZ_ONLY_SIZE); + +static struct memaccess_area nsec_shared = +MEMACCESS_AREA(CFG_DDR_ARM_ARMTZ_START, CFG_DDR_ARM_ARMTZ_SIZE); + +/* pbuf_is_ddr - return true is buffer is inside the DDR */ +static bool pbuf_is_ddr(unsigned long paddr, size_t size) +{ + int i = sizeof(ddr) / sizeof(*ddr); + + while (i--) { + if (core_is_buffer_inside(paddr, size, + ddr[i].paddr, ddr[i].size)) + return true; + } + return false; +} + +/* + * pbuf_is_multipurpose - return true is buffer is inside unsafe DDR + * + * Unsafe DDR (or multipurpose DDR) is DDR that is under a firewalling + * reconfigured at run-time: there is no static information that can + * tell wether this RAM is tagged secured or not. + */ +static bool pbuf_is_multipurpose(unsigned long paddr, size_t size) +{ + if (core_is_buffer_intersect(paddr, size, + secure_only.paddr, secure_only.size)) + return false; + if (core_is_buffer_intersect(paddr, size, + nsec_shared.paddr, nsec_shared.size)) + return false; + + return pbuf_is_ddr(paddr, size); +} + +/* + * Wrapper for the platform specific pbuf_is() service. + */ +static bool pbuf_is(enum buf_is_attr attr, unsigned long paddr, size_t size) +{ + switch (attr) { + case CORE_MEM_SEC: + return core_is_buffer_inside(paddr, size, + secure_only.paddr, secure_only.size); + + case CORE_MEM_NON_SEC: + return core_is_buffer_inside(paddr, size, + nsec_shared.paddr, nsec_shared.size); + + case CORE_MEM_MULTPURPOSE: + return pbuf_is_multipurpose(paddr, size); + + case CORE_MEM_EXTRAM: + return pbuf_is_ddr(paddr, size); + + default: + EMSG("unpexted request: attr=%X", attr); + return false; + } +} + +static struct map_area bootcfg_memory[] = { + { /* teecore execution RAM */ + .type = MEM_AREA_TEE_RAM, + .pa = CFG_TEE_RAM_START, .size = CFG_TEE_RAM_SIZE, + .cached = true, .secure = true, .rw = true, .exec = true, + }, + + { /* teecore TA load/exec RAM - Secure, exec user only! */ + .type = MEM_AREA_TA_RAM, + .pa = CFG_TA_RAM_START, .size = CFG_TA_RAM_SIZE, + .cached = true, .secure = true, .rw = true, .exec = false, + }, + + { /* teecore public RAM - NonSecure, non-exec. */ + .type = MEM_AREA_NSEC_SHM, + .pa = CFG_PUB_RAM_START, .size = SECTION_SIZE, + .cached = true, .secure = false, .rw = true, .exec = false, + }, + + { /* AHB0 devices */ + .type = MEM_AREA_IO_NSEC, + .pa = 0x01400000 & ~SECTION_MASK, .size = 0x00900000, + .device = true, .secure = true, .rw = true, + }, + + { /* AHB1 devices */ + .type = MEM_AREA_IO_NSEC, + .pa = (0x00800000) & ~SECTION_MASK, .size = 0x00300000, + .device = true, .secure = true, .rw = true, + }, + { /* AHB2 devices */ + .type = MEM_AREA_IO_NSEC, + .pa = (0x03000000) & ~SECTION_MASK, .size = 0x01000000, + .device = true, .secure = true, .rw = true, + }, + { /* AHBS devices */ + .type = MEM_AREA_IO_NSEC, + .pa = (0x06000000) & ~SECTION_MASK, .size = 0x02200000, + .device = true, .secure = true, .rw = true, + }, + + {.type = MEM_AREA_NOTYPE} +}; + +/* + * bootcfg_get_pbuf_is_handler - return the platform specfic pbuf_is + */ +unsigned long bootcfg_get_pbuf_is_handler(void) +{ + return (unsigned long)pbuf_is; +} + +/* + * This routine is called while MMU and core memory management are not init. + */ +struct map_area *bootcfg_get_memory(void) +{ + struct map_area *map; + struct memaccess_area *a, *a2; + struct map_area *ret = bootcfg_memory; + + /* check defined memory access layout */ + a = (struct memaccess_area *)&secure_only; + a2 = (struct memaccess_area *)&nsec_shared; + if (core_is_buffer_intersect(a->paddr, a->size, a2->paddr, a2->size)) { + EMSG("invalid memory access configuration: sec/nsec"); + return NULL; + } + + /* check defined mapping (overlapping will be tested later) */ + map = bootcfg_memory; + while (map->type != MEM_AREA_NOTYPE) { + switch (map->type) { + case MEM_AREA_TEE_RAM: + a = (struct memaccess_area *)&secure_only; + if (!core_is_buffer_inside(map->pa, map->size, + a->paddr, a->size)) { + EMSG("TEE_RAM does not fit in secure_only"); + ret = NULL; + } + break; + case MEM_AREA_TA_RAM: + a = (struct memaccess_area *)&secure_only; + if (!core_is_buffer_inside(map->pa, map->size, + a->paddr, a->size)) { + EMSG("TA_RAM does not fit in secure_only"); + ret = NULL; + } + break; + case MEM_AREA_NSEC_SHM: + a = (struct memaccess_area *)&nsec_shared; + if (!core_is_buffer_inside(map->pa, map->size, + a->paddr, a->size)) { + EMSG("NSEC_RAM does not fit in nsec_shared"); + ret = NULL; + } + break; + default: + /* other mapped areas are not checked */ + break; + } + map++; + } + + return ret; +} + diff --git a/core/arch/arm32/plat-sunxi/core_chip.c b/core/arch/arm32/plat-sunxi/core_chip.c new file mode 100644 index 0000000..0a54f76 --- /dev/null +++ b/core/arch/arm32/plat-sunxi/core_chip.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * 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/tee_misc_unpg.h> + +uint32_t tee_get_cutid(void) +{ + return 0; +} diff --git a/core/arch/arm32/plat-sunxi/entry.S b/core/arch/arm32/plat-sunxi/entry.S new file mode 100644 index 0000000..882837c --- /dev/null +++ b/core/arch/arm32/plat-sunxi/entry.S @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * 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 <arm32.h> +#include <arm32_macros.S> +#include <sm/teesmc.h> +#include <sm/teesmc_opteed_macros.h> +#include <sm/teesmc_opteed.h> + +.section .text.boot +.align 5 +FUNC _start , : + b reset + b . /* Undef */ + b . /* Syscall */ + b . /* Prefetch abort */ + b . /* Data abort */ + b . /* Reserved */ + b . /* IRQ */ + b . /* FIQ */ +END_FUNC _start + +LOCAL_FUNC reset , : + read_sctlr r0 + orr r0, r0, #SCTLR_A + write_sctlr r0 + + ldr r0, =_start + write_vbar r0 + + mov r4, r1 + bl get_core_pos + lsl r0, #2 + ldr r1, =stack_tmp_top + ldr sp, [r1, r0] + + /* NSACR configuration */ + read_nsacr r1 + orr r1, r1, #NSACR_CP10 + orr r1, r1, #NSACR_CP11 + orr r1, r1, #NSACR_NS_SMP + write_nsacr r1 + + /* Enable SMP bit */ + read_actlr r0 + orr r0, r0, #ACTLR_SMP + write_actlr r0 + + bl core_init_mmu_tables + bl core_init_mmu_regs + bl cpu_mmu_enable + bl cpu_mmu_enable_icache + bl cpu_mmu_enable_dcache + + /* init BSS section */ + ldr r0, =__bss_start + ldr r2, =__bss_end + sub r2, r2, r0 + ldr r1, =0 + bl memset + + /* r4: the return address of normal world */ + mov r0, r4 + bl main_init + + mov r1, #0 + mov r2, #0 + mov r3, #0 + mov r0, #TEESMC_OPTEED_RETURN_ENTRY_DONE + smc #0 + b . /* SMC should never return */ +END_FUNC reset + diff --git a/core/arch/arm32/plat-sunxi/head.c b/core/arch/arm32/plat-sunxi/head.c new file mode 100644 index 0000000..838dbf4 --- /dev/null +++ b/core/arch/arm32/plat-sunxi/head.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * 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. + */ + +/** + * Header for optee, use for secure bootloader. + **/ + +#include <platform_config.h> + +/******************************************************************************/ +/* the control information stored in file head */ +/******************************************************************************/ +struct spare_boot_ctrl_head { + unsigned int jump_instruction; /* one intruction jumping to real code */ + unsigned char magic[8]; /* ="optee" */ + unsigned int check_sum; /* generated by PC */ + unsigned int align_size; /* align size in byte */ + unsigned int length; /* the size of all file */ + unsigned int optee_length; /* the size of optee */ + unsigned char version[8]; /* optee version */ + unsigned char platform[8]; /* platform information */ + int reserved[1]; /* stamp space, 16bytes align */ +}; + +const struct spare_boot_ctrl_head tee_spare_head + __attribute__ ((section(".text.head"))) = { + (0xEA000000 | (((sizeof(struct spare_boot_ctrl_head) + sizeof(int) - 1) / sizeof(int) - 2) & 0x00FFFFFF)), + "optee", + 0, + 0, + 0, + 0, + "2.0", + "optee", + {TZDRAM_BASE} +}; diff --git a/core/arch/arm32/plat-sunxi/kern.ld.S b/core/arch/arm32/plat-sunxi/kern.ld.S new file mode 100644 index 0000000..674b145 --- /dev/null +++ b/core/arch/arm32/plat-sunxi/kern.ld.S @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * 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. + */ + +/* + * Copyright (c) 2008-2010 Travis Geiselbrecht + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <platform_config.h> + +OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) +OUTPUT_ARCH(PLATFORM_LINKER_ARCH) + +ENTRY(_start) +SECTIONS +{ + . = TEE_RAM_START; + + /* text/read-only data */ + .text : { + __text_start = .; + KEEP(*(.text.head)) + KEEP(*(.text.boot.vectab1)) + KEEP(*(.text.boot.vectab2)) + KEEP(*(.text.boot)) + *(.text* .sram.text.glue_7* .gnu.linkonce.t.*) + __text_end = .; + } + + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) } + .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) } + .rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) } + .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) } + .rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } + .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0x9090 + .plt : { *(.plt) } + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } + __exidx_end = .; + + .rodata : ALIGN(4) { + __rodata_start = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + + __start_ta_head_section = . ; + *(ta_head_section) + __stop_ta_head_section = . ; + + . = ALIGN(4); + __rodata_end = .; + } + + + .data : ALIGN(4) { + /* writable data */ + __data_start_rom = .; + /* in one segment binaries, the rom data address is on top of the ram data address */ + __data_start = .; + *(.data .data.* .gnu.linkonce.d.*) + } + + .ctors : ALIGN(4) { + __ctor_list = .; + *(.ctors) + __ctor_end = .; + } + .dtors : ALIGN(4) { + __dtor_list = .; + *(.dtors) + __dtor_end = .; + } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + + __data_end = .; + + /* unintialized data (in same segment as writable data) */ + .bss : ALIGN(4) { + KEEP(*(.bss.prebss.*)) + . = ALIGN(4); + __bss_start = .; + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + __bss_end = .; + } + + /* + * Uninitialized data that shouldn't be zero initialized at + * runtime. + * + * L1 mmu table requires 16 KiB alignment + */ + .nozi : ALIGN(16 * 1024) { + __nozi_pad_end = .; + KEEP(*(.nozi .nozi.*)) + } + + teecore_heap_start = .; + . += 0x40000 /*256KiB*/; + teecore_heap_end = .; + + _end = .; + + . = TEE_RAM_START + TEE_RAM_SIZE; + _end_of_ram = .; + + /* Strip unnecessary stuff */ + /DISCARD/ : { *(.comment .note .eh_frame) } +} diff --git a/core/arch/arm32/plat-sunxi/link.mk b/core/arch/arm32/plat-sunxi/link.mk new file mode 100644 index 0000000..3ff1f05 --- /dev/null +++ b/core/arch/arm32/plat-sunxi/link.mk @@ -0,0 +1,54 @@ +link-out-dir = $(out-dir)/core + +link-script = $(platform-dir)/kern.ld.S +link-script-pp = $(link-out-dir)/kern.ld +link-script-dep = $(link-out-dir)/.kern.ld.d + +AWK = awk + +all: $(link-out-dir)/tee.elf $(link-out-dir)/tee.dmp $(link-out-dir)/tee.bin +all: $(link-out-dir)/tee.symb_sizes +cleanfiles += $(link-out-dir)/tee.elf $(link-out-dir)/tee.dmp $(link-out-dir)/tee.map +cleanfiles += $(link-out-dir)/tee.bin +cleanfiles += $(link-out-dir)/tee.symb_sizes +cleanfiles += $(link-script-pp) $(link-script-dep) + +link-ldflags = $(LDFLAGS) +link-ldflags += -T $(link-script-pp) -Map=$(link-out-dir)/tee.map +link-ldflags += --sort-section=alignment + +link-ldadd = $(LDADD) +link-ldadd += $(addprefix -L,$(libdirs)) +link-ldadd += $(addprefix -l,$(libnames)) +ldargs-tee.elf := $(link-ldflags) $(objs) $(link-ldadd) $(libgcc) + +link-script-cppflags := \ + $(filter-out $(CPPFLAGS_REMOVE) $(cppflags-remove), \ + $(nostdinc) $(CPPFLAGS) \ + $(addprefix -I,$(incdirs$(sm))) $(cppflags$(sm))) + + +-include $(link-script-dep) + +$(link-script-pp): $(link-script) + @echo ' CPP $@' + @mkdir -p $(dir $@) + $(q)$(CPP) -Wp,-P,-MT,$@,-MD,$(link-script-dep) \ + $(link-script-cppflags) $< > $@ + + +$(link-out-dir)/tee.elf: $(objs) $(libdeps) $(link-script-pp) + @echo ' LD $@' + $(q)$(LD) $(ldargs-tee.elf) -o $@ + +$(link-out-dir)/tee.dmp: $(link-out-dir)/tee.elf + @echo ' OBJDUMP $@' + $(q)$(OBJDUMP) -l -x -d $< > $@ + +$(link-out-dir)/tee.bin: $(link-out-dir)/tee.elf + @echo ' OBJCOPY $@' + $(q)$(OBJCOPY) -O binary $< $@ + +$(link-out-dir)/tee.symb_sizes: $(link-out-dir)/tee.elf + @echo ' GEN $@' + $(q)$(NM) --print-size --reverse-sort --size-sort $< > $@ diff --git a/core/arch/arm32/plat-sunxi/main.c b/core/arch/arm32/plat-sunxi/main.c new file mode 100644 index 0000000..5a4f783 --- /dev/null +++ b/core/arch/arm32/plat-sunxi/main.c @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * 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 <stdint.h> +#include <string.h> +#include <assert.h> + +#include <sm/sm.h> +#include <sm/sm_defs.h> +#include <sm/tee_mon.h> +#include <sm/teesmc.h> +#include <sm/teesmc_optee.h> + +#include <arm32.h> +#include <kernel/arch_debug.h> +#include <kernel/thread.h> +#include <kernel/time_source.h> +#include <kernel/panic.h> +#include <kernel/misc.h> +#include <mm/tee_pager.h> +#include <mm/tee_mmu.h> +#include <mm/core_mmu.h> +#include <mm/tee_mmu_defs.h> +#include <tee/entry.h> +#include <tee/arch_svc.h> +#include <platform.h> +#include <util.h> +#include <trace.h> +#include <malloc.h> + +#ifdef WITH_STACK_CANARIES +#define STACK_CANARY_SIZE (4 * sizeof(uint32_t)) +#define START_CANARY_VALUE 0xdededede +#define END_CANARY_VALUE 0xabababab +#define GET_START_CANARY(name, stack_num) name[stack_num][0] +#define GET_END_CANARY(name, stack_num) \ + name[stack_num][sizeof(name[stack_num]) / sizeof(uint32_t) - 1] +#else +#define STACK_CANARY_SIZE 0 +#endif + +#define STACK_ALIGNMENT 8 + +#define DECLARE_STACK(name, num_stacks, stack_size) \ + static uint32_t name[num_stacks][(stack_size + STACK_CANARY_SIZE) / \ + sizeof(uint32_t)] \ + __attribute__((section(".bss.prebss.stack"), \ + aligned(STACK_ALIGNMENT))) + +#define GET_STACK(stack) \ + ((vaddr_t)(stack) + sizeof(stack) - STACK_CANARY_SIZE / 2) + + +DECLARE_STACK(stack_tmp, CFG_TEE_CORE_NB_CORE, STACK_TMP_SIZE); +DECLARE_STACK(stack_abt, CFG_TEE_CORE_NB_CORE, STACK_ABT_SIZE); +DECLARE_STACK(stack_sm, CFG_TEE_CORE_NB_CORE, SM_STACK_SIZE); +DECLARE_STACK(stack_thread, NUM_THREADS, STACK_THREAD_SIZE); + +const vaddr_t stack_tmp_top[CFG_TEE_CORE_NB_CORE] = { + GET_STACK(stack_tmp[0]), +#if CFG_TEE_CORE_NB_CORE > 1 + GET_STACK(stack_tmp[1]), +#endif +#if CFG_TEE_CORE_NB_CORE > 2 + GET_STACK(stack_tmp[2]), +#endif +#if CFG_TEE_CORE_NB_CORE > 3 + GET_STACK(stack_tmp[3]), +#endif +#if CFG_TEE_CORE_NB_CORE > 4 + GET_STACK(stack_tmp[4]), +#endif +#if CFG_TEE_CORE_NB_CORE > 5 + GET_STACK(stack_tmp[5]), +#endif +#if CFG_TEE_CORE_NB_CORE > 6 + GET_STACK(stack_tmp[6]), +#endif +#if CFG_TEE_CORE_NB_CORE > 7 + GET_STACK(stack_tmp[7]), +#endif +#if CFG_TEE_CORE_NB_CORE > 8 +#error "Top of tmp stacks aren't defined for more than 8 CPUS" +#endif +}; + +/* teecore heap address/size is defined in scatter file */ +extern unsigned char teecore_heap_start; +extern unsigned char teecore_heap_end; + +/* Main MMU L1 table for teecore */ +static uint32_t main_mmu_l1_ttb[TEE_MMU_L1_NUM_ENTRIES] + __attribute__((section(".nozi.mmu.l1"), + aligned(TEE_MMU_L1_ALIGNMENT))); + +/* Main MMU L2 table for teecore */ +static uint32_t main_mmu_l2_ttb[TEE_MMU_L2_NUM_ENTRIES] + __attribute__((section(".nozi.mmu.l2"), + aligned(TEE_MMU_L2_ALIGNMENT))); + +/* MMU L1 table for TAs, one for each Core */ +static uint32_t main_mmu_ul1_ttb[NUM_THREADS][TEE_MMU_UL1_NUM_ENTRIES] + __attribute__((section(".nozi.mmu.ul1"), + aligned(TEE_MMU_UL1_ALIGNMENT))); + +static void main_fiq(void); +static void main_tee_entry(struct thread_smc_args *args); +static uint32_t main_default_pm_handler(uint32_t a0, uint32_t a1); + +static void init_canaries(void) +{ + size_t n; +#define INIT_CANARY(name) \ + for (n = 0; n < ARRAY_SIZE(name); n++) { \ + uint32_t *start_canary = &GET_START_CANARY(name, n); \ + uint32_t *end_canary = &GET_END_CANARY(name, n); \ + \ + *start_canary = START_CANARY_VALUE; \ + *end_canary = END_CANARY_VALUE; \ + } + + INIT_CANARY(stack_tmp); + INIT_CANARY(stack_abt); + INIT_CANARY(stack_sm); + INIT_CANARY(stack_thread); +} + +void check_canaries(void) +{ +#ifdef WITH_STACK_CANARIES + size_t n; + +#define ASSERT_STACK_CANARIES(name) \ + for (n = 0; n < ARRAY_SIZE(name); n++) { \ + assert(GET_START_CANARY(name, n) == START_CANARY_VALUE);\ + assert(GET_END_CANARY(name, n) == END_CANARY_VALUE); \ + } while (0) + + ASSERT_STACK_CANARIES(stack_tmp); + ASSERT_STACK_CANARIES(stack_abt); + ASSERT_STACK_CANARIES(stack_sm); + ASSERT_STACK_CANARIES(stack_thread); +#endif /*WITH_STACK_CANARIES*/ +} + +static const struct thread_handlers handlers = { + .std_smc = main_tee_entry, + .fast_smc = main_tee_entry, + .fiq = main_fiq, + .svc = tee_svc_handler, + .abort = tee_pager_abort_handler, + .cpu_on = main_default_pm_handler, + .cpu_off = main_default_pm_handler, + .cpu_suspend = main_default_pm_handler, + .cpu_resume = main_default_pm_handler, + .system_off = main_default_pm_handler, + .system_reset = main_default_pm_handler, +}; + +void main_init(uint32_t nsec_entry); /* called from assembly only */ +void main_init(uint32_t nsec_entry) +{ + struct sm_nsec_ctx *nsec_ctx; + 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 + * with the temporary stack. The thread subsystem also asserts that + * IRQ is blocked when using most if its functions. + */ + write_cpsr(read_cpsr() | CPSR_F | CPSR_I); + + if (pos == 0) { + size_t n; + + /* Initialize canries around the stacks */ + init_canaries(); + + /* Assign the thread stacks */ + for (n = 0; n < NUM_THREADS; n++) { + if (!thread_init_stack(n, GET_STACK(stack_thread[n]))) + panic(); + } + thread_init_handlers(&handlers); + + /* initialize platform */ + platform_init(); + } + + if (!thread_init_stack(THREAD_TMP_STACK, GET_STACK(stack_tmp[pos]))) + panic(); + if (!thread_init_stack(THREAD_ABT_STACK, GET_STACK(stack_abt[pos]))) + panic(); + + thread_init_per_cpu(); + + /* Initialize secure monitor */ + sm_init(GET_STACK(stack_sm[pos])); + nsec_ctx = sm_get_nsec_ctx(); + nsec_ctx->mon_lr = nsec_entry; + nsec_ctx->mon_spsr = CPSR_MODE_SVC | CPSR_I; + sm_set_entry_vector(thread_vector_table); + + if (pos == 0) { + unsigned long a, s; + /* core malloc pool init */ +#ifdef CFG_TEE_MALLOC_START + a = CFG_TEE_MALLOC_START; + s = CFG_TEE_MALLOC_SIZE; +#else + a = (unsigned long)&teecore_heap_start; + s = (unsigned long)&teecore_heap_end; + a = ((a + 1) & ~0x0FFFF) + 0x10000; /* 64kB aligned */ + s = s & ~0x0FFFF; /* 64kB aligned */ + s = s - a; +#endif + malloc_init((void *)a, s); + + teecore_init_ta_ram(); + + if (init_teecore() != TEE_SUCCESS) { + panic(); + } + } + + IMSG("optee initialize finished\n"); +} + +static void main_fiq(void) +{ + panic(); +} + +static uint32_t main_default_pm_handler(uint32_t a0, uint32_t a1) +{ + /* + * This function is not supported in this configuration, and + * should never be called. Panic to catch unintended calls. + */ + (void)&a0; + (void)&a1; + panic(); + return 1; +} + +static void main_tee_entry(struct thread_smc_args *args) +{ + /* TODO move to main_init() */ + if (init_teecore() != TEE_SUCCESS) + panic(); + + /* + * This function first catches platform specific SMC functions + * if none matches, the generic tee_entry is called. + */ + if (args->a0 == TEESMC32_OPTEE_FASTCALL_GET_SHM_CONFIG) { + args->a0 = TEESMC_RETURN_OK; + args->a1 = default_nsec_shm_paddr; + args->a2 = default_nsec_shm_size; + /* Should this be TEESMC cache attributes instead? */ + args->a3 = core_mmu_is_shm_cached(); + return; + } + + if (args->a0 == TEESMC32_OPTEE_FASTCALL_L2CC_MUTEX) { + switch (args->a1) { + case TEESMC_OPTEE_L2CC_MUTEX_GET_ADDR: + case TEESMC_OPTEE_L2CC_MUTEX_SET_ADDR: + case TEESMC_OPTEE_L2CC_MUTEX_ENABLE: + case TEESMC_OPTEE_L2CC_MUTEX_DISABLE: + /* A80 platform not support L2CC_MUTEX */ + args->a0 = TEESMC_RETURN_UNKNOWN_FUNCTION; + return; + default: + args->a0 = TEESMC_RETURN_EBADCMD; + return; + } + } + + /* SiP Service Call Count */ + if (args->a0 == TEESMC32_SIP_SUNXI_CALLS_COUNT) { + args->a0 = 1; + return; + } + + /* SiP Service Call UID */ + if (args->a0 == TEESMC32_SIP_SUNXI_CALLS_UID) { + args->a0 = TEESMC_SIP_SUNXI_UID_R0; + args->a1 = TEESMC_SIP_SUNXI_UID_R1; + args->a2 = TEESMC_SIP_SUNXI_UID_R2; + args->a3 = TEESMC_SIP_SUNXI_UID_R3; + return; + } + + /* SiP Service Calls */ + if (args->a0 == TEESMC32_OPTEE_FAST_CALL_SIP_SUNXI) { + platform_smc_handle(args); + return; + } + + tee_entry(args); +} + + +/* Override weak function in tee/entry.c */ +void tee_entry_get_api_call_count(struct thread_smc_args *args) +{ + args->a0 = tee_entry_generic_get_api_call_count() + 2; +} + +/* Override weak function in tee/entry.c */ +void tee_entry_get_api_uuid(struct thread_smc_args *args) +{ + args->a0 = TEESMC_OPTEE_UID_R0; + args->a1 = TEESMC_OPTEE_UID_R1; + args->a2 = TEESMC_OPTEE_UID_R2; + args->a3 = TEESMC_OPTEE_UID32_R3; +} + +/* Override weak function in tee/entry.c */ +void tee_entry_get_api_revision(struct thread_smc_args *args) +{ + args->a0 = TEESMC_OPTEE_REVISION_MAJOR; + args->a1 = TEESMC_OPTEE_REVISION_MINOR; +} + +/* Override weak function in tee/entry.c */ +void tee_entry_get_os_uuid(struct thread_smc_args *args) +{ + args->a0 = TEESMC_OS_OPTEE_UUID_R0; + args->a1 = TEESMC_OS_OPTEE_UUID_R1; + args->a2 = TEESMC_OS_OPTEE_UUID_R2; + args->a3 = TEESMC_OS_OPTEE_UUID_R3; +} + +/* Override weak function in tee/entry.c */ +void tee_entry_get_os_revision(struct thread_smc_args *args) +{ + args->a0 = TEESMC_OS_OPTEE_REVISION_MAJOR; + args->a1 = TEESMC_OS_OPTEE_REVISION_MINOR; +} + +paddr_t core_mmu_get_main_ttb_pa(void) +{ + /* Note that this depends on flat mapping of TEE Core */ + paddr_t pa = (paddr_t)core_mmu_get_main_ttb_va(); + + TEE_ASSERT(!(pa & ~TEE_MMU_TTB_L1_MASK)); + return pa; +} + +vaddr_t core_mmu_get_main_ttb_va(void) +{ + return (vaddr_t)main_mmu_l1_ttb; +} + +paddr_t core_mmu_get_ul1_ttb_pa(void) +{ + /* Note that this depends on flat mapping of TEE Core */ + paddr_t pa = (paddr_t)core_mmu_get_ul1_ttb_va(); + + TEE_ASSERT(!(pa & ~TEE_MMU_TTB_UL1_MASK)); + return pa; +} + +vaddr_t core_mmu_get_ul1_ttb_va(void) +{ + return (vaddr_t)main_mmu_ul1_ttb[thread_get_id()]; +} + +void *core_mmu_alloc_l2(struct map_area *map) +{ + /* Can't have this in .bss since it's not initialized yet */ + static size_t l2_offs __attribute__((section(".data"))); + size_t l2_va_space = ((sizeof(main_mmu_l2_ttb) - l2_offs) / + TEE_MMU_L2_SIZE) * SECTION_SIZE; + + if (l2_offs) + return NULL; + if (map->type != MEM_AREA_TEE_RAM) + return NULL; + if (map->size > l2_va_space) + return NULL; + l2_offs += ROUNDUP(map->size, SECTION_SIZE) / SECTION_SIZE; + return main_mmu_l2_ttb; +} diff --git a/core/arch/arm32/plat-sunxi/platform.c b/core/arch/arm32/plat-sunxi/platform.c new file mode 100644 index 0000000..576d9a5 --- /dev/null +++ b/core/arch/arm32/plat-sunxi/platform.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * 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 <sm/sm.h> +#include <sm/sm_defs.h> +#include <sm/tee_mon.h> +#include <sm/teesmc.h> +#include <sm/teesmc_optee.h> + +#include <arm32.h> +#include <kernel/thread.h> +#include <kernel/time_source.h> +#include <kernel/panic.h> +#include <kernel/misc.h> +#include <mm/tee_pager.h> +#include <mm/core_mmu.h> +#include <tee/entry.h> + +#include <drivers/gic.h> +#include <drivers/sunxi_uart.h> + +#include <trace.h> +#include <io.h> +#include <assert.h> +#include <util.h> +#include <platform.h> + +void sunxi_secondary_entry(void); + +uint32_t sunxi_secondary_ns_entry; + +static int platform_smp_init(void) +{ + write32((uint32_t)sunxi_secondary_entry, (PRCM_BASE + PRCM_CPU_SOFT_ENTRY_REG)); + + return 0; +} + +void platform_init(void) +{ + /* + * GIC configuration is initialized in Secure bootloader, + * Initialize GIC base address here for debugging. + */ + gic_init_base_addr(GIC_BASE + GICC_OFFSET, GIC_BASE + GICD_OFFSET); + + /* platform smp initialize */ + platform_smp_init(); + + /* enable non-secure access cci-400 registers */ + write32(0x1, CCI400_BASE + CCI400_SECURE_ACCESS_REG); + + /* Initialize uart with physical address */ + sunxi_uart_init(UART0_BASE); + + return ; +} + +/** + * handle platform special smc commands. + */ +uint32_t platform_smc_handle(struct thread_smc_args *smc_args) +{ + uint32_t ret = TEE_SUCCESS; + switch (smc_args->a1) { + case TEESMC_OPTEE_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)); + break; + default: + ret = TEESMC_RETURN_EBADCMD; + break; + } + smc_args->a0 = ret; + return ret; +} + diff --git a/core/arch/arm32/plat-sunxi/platform.h b/core/arch/arm32/plat-sunxi/platform.h new file mode 100644 index 0000000..962317f --- /dev/null +++ b/core/arch/arm32/plat-sunxi/platform.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * 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 PLATFORM_H +#define PLATFORM_H + +/* + * Function specified by SMC Calling convention. + * + * SiP Service Calls + * + * Call register usage: + * r0 SMC Function ID, TEESMC_OPTEE_FUNCID_SIP_SUNXI + * r1 TEESMC_OPTEE_SIP_SUNXI_SET_SMP_BOOTENTRY set smp bootup entry + */ +#define TEESMC_OPTEE_SIP_SUNXI_SET_SMP_BOOTENTRY (0xFFFF0000) + +#define TEESMC_OPTEE_FUNCID_SIP_SUNXI 0x8000 +#define TEESMC32_OPTEE_FAST_CALL_SIP_SUNXI \ + TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, TEESMC_OWNER_SIP, \ + TEESMC_OPTEE_FUNCID_SIP_SUNXI) + + +/* + * Function specified by SMC Calling convention. + * + * SiP Service Call Count + * + * This call returns a 32-bit count of the available + * Service Calls. A return value of zero means no + * services are available. + */ +#define TEESMC32_FUNCID_SIP_CALLS_COUNT 0xFF00 +#define TEESMC32_SIP_SUNXI_CALLS_COUNT \ + TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, \ + TEESMC_OWNER_SIP, \ + TEESMC32_FUNCID_CALLS_COUNT) + +/* + * Function specified by SMC Calling convention + * + * SiP Service Call UID + * + * Return the implementation of SiP Service Calls UID. + * + */ +#define TEESMC_SIP_SUNXI_UID_R0 0xa5d5c51b +#define TEESMC_SIP_SUNXI_UID_R1 0x8d6c0002 +#define TEESMC_SIP_SUNXI_UID_R2 0x6f8611e4 +#define TEESMC_SIP_SUNXI_UID_R3 0x12b7e560 +#define TEESMC32_FUNCID_SIP_SUNXI_CALLS_UID 0xFF01 +#define TEESMC32_SIP_SUNXI_CALLS_UID \ + TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, \ + TEESMC_OWNER_SIP, \ + TEESMC32_FUNCID_SIP_SUNXI_CALLS_UID) + +void platform_init(void); +uint32_t platform_smc_handle(struct thread_smc_args *smc_args); + +#endif /*PLATFORM_H*/ diff --git a/core/arch/arm32/plat-sunxi/platform_config.h b/core/arch/arm32/plat-sunxi/platform_config.h new file mode 100644 index 0000000..ae98a42 --- /dev/null +++ b/core/arch/arm32/plat-sunxi/platform_config.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * 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 PLATFORM_CONFIG_H +#define PLATFORM_CONFIG_H + +#define STACK_ALIGNMENT 8 + +#define PLATFORM_LINKER_FORMAT "elf32-littlearm" +#define PLATFORM_LINKER_ARCH arm + +#define GIC_BASE 0x01c40000 +#define GICC_OFFSET 0x2000 +#define GICD_OFFSET 0x1000 +#define UART0_BASE 0x07000000 +#define UART1_BASE 0x07000400 +#define UART2_BASE 0x07000800 +#define UART3_BASE 0x07000c00 +#define CCI400_BASE 0x01c90000 +#define SMC_BASE 0x01c0b000 +#define PRCM_BASE 0x08001400 + +/* CCI-400 register defines */ +#define CCI400_SECURE_ACCESS_REG (0x8) + +/* PRCM register defines */ +#define PRCM_CPU_SOFT_ENTRY_REG (0x164) + +/* console uart define */ +#define CONSOLE_UART_BASE UART0_BASE + +#define STACK_TMP_SIZE 1024 +#define STACK_ABT_SIZE 1024 +#define STACK_THREAD_SIZE 8192 + +#define DRAM0_BASE 0x20000000 +#define DRAM0_SIZE 0x80000000 + +/* Location of trusted dram on sunxi */ +#define TZDRAM_BASE 0x9C000000 +#define TZDRAM_SIZE 0x04000000 + +#define CFG_TEE_CORE_NB_CORE 8 + +#define DDR_PHYS_START DRAM0_BASE +#define DDR_SIZE DRAM0_SIZE + +#define CFG_DDR_START DDR_PHYS_START +#define CFG_DDR_SIZE DDR_SIZE + +#define CFG_DDR_TEETZ_RESERVED_START TZDRAM_BASE +#define CFG_DDR_TEETZ_RESERVED_SIZE TZDRAM_SIZE + +#define TEE_RAM_START (TZDRAM_BASE) +#define TEE_RAM_SIZE (1 * 1024 * 1024) + +#define CFG_SHMEM_START (DDR_PHYS_START + 0x1000000) +#define CFG_SHMEM_SIZE 0x100000 + +#endif /*PLATFORM_CONFIG_H*/ diff --git a/core/arch/arm32/plat-sunxi/platform_flags.mk b/core/arch/arm32/plat-sunxi/platform_flags.mk new file mode 100644 index 0000000..68945ee --- /dev/null +++ b/core/arch/arm32/plat-sunxi/platform_flags.mk @@ -0,0 +1,24 @@ +platform-cpuarch = cortex-a15 +platform-cflags = -mcpu=$(platform-cpuarch) -mthumb +platform-cflags += -pipe -mthumb-interwork -mlong-calls +platform-cflags += -fno-short-enums -mno-apcs-float -fno-common +platform-cflags += -mfloat-abi=soft +platform-cflags += -mno-unaligned-access +platform-aflags = -mcpu=$(platform-cpuarch) + +platform-cflags += -ffunction-sections -fdata-sections + +DEBUG ?= 1 +ifeq ($(DEBUG),1) +platform-cflags += -O0 +else +platform-cflags += -Os +endif + +platform-cflags += -g +platform-aflags += -g + +platform-cflags += -g3 +platform-aflags += -g3 + +user_ta-platform-cflags = -fpie diff --git a/core/arch/arm32/plat-sunxi/rng_support.c b/core/arch/arm32/plat-sunxi/rng_support.c new file mode 100644 index 0000000..434b104 --- /dev/null +++ b/core/arch/arm32/plat-sunxi/rng_support.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * 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 <stdlib.h> +#include <rng_support.h> +#include <trace.h> + +/* Bad software version */ +uint8_t hw_get_random_byte(void) +{ + static uint32_t lcg_state; + static uint32_t nb_soft = 9876543; +#define MAX_SOFT_RNG 1024 + static const uint32_t a = 1664525; + static const uint32_t c = 1013904223; + + nb_soft = (nb_soft + 1) % MAX_SOFT_RNG; + lcg_state = (a * lcg_state + c); + return (uint8_t) (lcg_state >> 24); +} diff --git a/core/arch/arm32/plat-sunxi/smp_boot.S b/core/arch/arm32/plat-sunxi/smp_boot.S new file mode 100644 index 0000000..4d04a04 --- /dev/null +++ b/core/arch/arm32/plat-sunxi/smp_boot.S @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <asm.S> +#include <arm32.h> +#include <arm32_macros.S> +#include <sm/teesmc.h> +#include <sm/teesmc_opteed_macros.h> +#include <sm/teesmc_opteed.h> + +FUNC smp_init_vector , : + b . /* Reset */ + b . /* Undef */ + b . /* Syscall */ + b . /* Prefetch abort */ + b . /* Data abort */ + b . /* Reserved */ + b . /* IRQ */ + b . /* FIQ */ +END_FUNC smp_init_vector + +FUNC sunxi_secondary_entry , : + /* secondary CPUs internal initialization */ + read_sctlr r0 + orr r0, r0, #SCTLR_A + write_sctlr r0 + + /* install smp initialization vector */ + ldr r0, =smp_init_vector + write_vbar r0 + + /* Setup tmp stack */ + bl get_core_pos + lsl r0, #2 + ldr r1, =stack_tmp_top + ldr sp, [r1, r0] + + /* NSACR configuration */ + read_nsacr r1 + orr r1, r1, #NSACR_CP10 + orr r1, r1, #NSACR_CP11 + orr r1, r1, #NSACR_NS_SMP + write_nsacr r1 + mcr p15, 0, r1, c1, c1, 2 + + /* Enable SMP bit */ + read_actlr r0 + orr r0, r0, #ACTLR_SMP + write_actlr r0 + + /* fixup some platform limits */ + bl sunxi_secondary_fixup + + /* initialize gic cpu interface */ + bl gic_cpu_init + + /* secure env initialization */ + bl core_init_mmu_regs + bl cpu_mmu_enable + bl cpu_mmu_enable_icache + bl cpu_mmu_enable_dcache + + /* Initialize thread handling and secure monitor */ + ldr r0, =sunxi_secondary_ns_entry + ldr r0, [r0] + bl main_init + + mov r0, #TEESMC_OPTEED_RETURN_ENTRY_DONE + smc #0 + b . /* SMC should not return */ + +END_FUNC sunxi_secondary_entry diff --git a/core/arch/arm32/plat-sunxi/smp_fixup.S b/core/arch/arm32/plat-sunxi/smp_fixup.S new file mode 100644 index 0000000..18701cc --- /dev/null +++ b/core/arch/arm32/plat-sunxi/smp_fixup.S @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * 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. + */ +#define SLAVE_SNOOPCTL_OFFSET 0 +#define SNOOPCTL_SNOOP_ENABLE (1 << 0) +#define SNOOPCTL_DVM_ENABLE (1 << 1) + +#define CCI_STATUS_OFFSET 0xc +#define STATUS_CHANGE_PENDING (1 << 0) + +#define CCI_SLAVE_OFFSET(n) (0x1000 + 0x1000 * (n)) + +#define SUNXI_CCI_PHYS_BASE 0x01c90000 +#define SUNXI_CCI_SLAVE_A7 3 +#define SUNXI_CCI_SLAVE_A15 4 +#define SUNXI_CCI_A15_OFFSET CCI_SLAVE_OFFSET(SUNXI_CCI_SLAVE_A15) +#define SUNXI_CCI_A7_OFFSET CCI_SLAVE_OFFSET(SUNXI_CCI_SLAVE_A7) + +#define SUNXI_CCU_PHYS_BASE (0x06000000) +#define SUNXI_CCU_C0_CFG_OFFSET (0x54) +#define SUNXI_CCU_C1_CFG_OFFSET (0x58) + +.globl sunxi_secondary_fixup +sunxi_secondary_fixup: + mrc p15, 0, r0, c0, c0, 5 /* MPIDR */ + ubfx r0, r0, #8, #4 /* cluster */ + + ldr r3, =SUNXI_CCU_PHYS_BASE + SUNXI_CCU_C0_CFG_OFFSET + cmp r0, #0 /* A7 cluster? */ + addne r3, r3, #SUNXI_CCU_C1_CFG_OFFSET - SUNXI_CCU_C0_CFG_OFFSET + ldr r1, [r3] + bic r1, r1, #(0x3<<8) /* a15 atb div */ + orr r1, r1, #(0x1<<8) /* div = 2 */ + bic r1, r1, #(0x7<<0) /* a15 atb div */ + orr r1, r1, #(0x2<<0) /* div = value + 1 */ + str r1, [r3] /* set atb div to 2, axi div to 3 */ + dsb /* Synchronise side-effects of axi config */ + ldr r1, [r3] + bic r1, r1, #(0x3<<8) /* a15 atb div */ + orr r1, r1, #(0x2<<8) /* div = 4 */ + bic r1, r1, #(0x7<<0) /* a15 atb div */ + orr r1, r1, #(0x3<<0) /* div = value + 1 */ + str r1, [r3] /* set atb div to 4, axi div to 4 */ + dsb /* Synchronise side-effects of axi config */ + + /* Enable CCI snoops. */ + ldr r3, =SUNXI_CCI_PHYS_BASE + SUNXI_CCI_A7_OFFSET + cmp r0, #0 /* A7 cluster? */ + addne r3, r3, #SUNXI_CCI_A15_OFFSET - SUNXI_CCI_A7_OFFSET + + @ r3 now points to the correct CCI slave register block + ldr r1, [r3, #SLAVE_SNOOPCTL_OFFSET] + orr r1, r1, #SNOOPCTL_SNOOP_ENABLE + orr r1, r1, #SNOOPCTL_DVM_ENABLE + str r1, [r3, #SLAVE_SNOOPCTL_OFFSET] /* enable CCI snoops */ + + /* Wait for snoop control change to complete */ + ldr r3, =SUNXI_CCI_PHYS_BASE +1: + ldr r1, [r3, #CCI_STATUS_OFFSET] + tst r1, #STATUS_CHANGE_PENDING + bne 1b + dsb /* Synchronise side-effects of enabling CCI */ + + cmp r0, #1 /* A15 cluster ? */ + bne 2f + + /* a80 platform-specific Cortex-A15 setup */ + mrc p15, 1, r1, c15, c0, 4 /* ACTLR2 */ + orr r1, r1, #(0x1<<31) /* Enable CPU regional clock gates */ + mcr p15, 1, r1, c15, c0, 4 + + mrc p15, 1, r1, c15, c0, 0 /* L2ACTLR */ + orr r1, r1, #(0x1<<26) /* Enables L2, GIC, and Timer regional clock gates */ + mcr p15, 1, r1, c15, c0, 0 + + mrc p15, 1, r1, c15, c0, 0 /* L2ACTLR */ + orr r1, r1, #(0x1<<3) /* Disables clean/evict from being pushed to external */ + mcr p15, 1, r1, c15, c0, 0 + + mrc p15, 1, r1, c9, c0, 2 + bic r1, r1, #(0x7<<0) /* L2 data ram latency */ + orr r1, r1, #(0x3<<0) + mcr p15, 1, r1, c9, c0, 2 + +2: + /* a80 platform-specific operations porcess done. */ + bx lr diff --git a/core/arch/arm32/plat-sunxi/sub.mk b/core/arch/arm32/plat-sunxi/sub.mk new file mode 100644 index 0000000..b36e4bd --- /dev/null +++ b/core/arch/arm32/plat-sunxi/sub.mk @@ -0,0 +1,15 @@ +global-incdirs-y += . +srcs-y += entry.S +srcs-y += main.c + +srcs-y += tee_common_otp.c +cflags-tee_common_otp.c-y += -Wno-unused-parameter + +srcs-y += core_bootcfg.c +srcs-y += core_chip.c +srcs-y += rng_support.c +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/arm32/plat-sunxi/tee_common_otp.c b/core/arch/arm32/plat-sunxi/tee_common_otp.c new file mode 100644 index 0000000..b281b8e --- /dev/null +++ b/core/arch/arm32/plat-sunxi/tee_common_otp.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014 Allwinner Technology Co., Ltd. + * 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 <stddef.h> +#include <string.h> +#include <trace.h> +#include <kernel/tee_common_otp.h> + +#define SHA256_HASH_SIZE 32 +uint8_t hw_key_digest[SHA256_HASH_SIZE]; + +/*---------------------------------------------------------------------------*/ +/* tee_otp_get_hw_unique_key */ +/*---------------------------------------------------------------------------*/ +/* + This function reads out a hw unique key. + + \param[in] hwkey data place holder for the key data read + \param[out] None. + \return None. + + */ +/*---------------------------------------------------------------------------*/ +void tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey) +{ + /* Copy the first part of the new hw key */ + memcpy(&hwkey->data[0], &hw_key_digest[0], + sizeof(struct tee_hw_unique_key)); +} + +int tee_otp_get_die_id(uint8_t *buffer, size_t len) +{ + size_t i; + + char pattern[4] = { 'B', 'E', 'E', 'F' }; + for (i = 0; i < len; i++) + buffer[i] = pattern[i % 4]; + + return 0; +} diff --git a/core/drivers/sub.mk b/core/drivers/sub.mk index 435b29c..c16f9d3 100644 --- a/core/drivers/sub.mk +++ b/core/drivers/sub.mk @@ -1,2 +1,3 @@ srcs-$(WITH_UART_DRV) += uart.c srcs-$(WITH_GIC_DRV) += gic.c +srcs-$(WITH_SUNXI_UART) += sunxi_uart.c diff --git a/core/drivers/sunxi_uart.c b/core/drivers/sunxi_uart.c new file mode 100644 index 0000000..6f45bd0 --- /dev/null +++ b/core/drivers/sunxi_uart.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014, Allwinner Technology Co., Ltd. + * 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 <drivers/sunxi_uart.h> +#include <console.h> +#include <io.h> +#include <assert.h> +#include <compiler.h> + +/* uart register defines */ +#define UART_REG_RBR (0x00) +#define UART_REG_THR (0x00) +#define UART_REG_DLL (0x00) +#define UART_REG_DLH (0x04) +#define UART_REG_IER (0x04) +#define UART_REG_IIR (0x08) +#define UART_REG_FCR (0x08) +#define UART_REG_LCR (0x0c) +#define UART_REG_MCR (0x10) +#define UART_REG_LSR (0x14) +#define UART_REG_MSR (0x18) +#define UART_REG_SCH (0x1c) +#define UART_REG_USR (0x7c) +#define UART_REG_TFL (0x80) +#define UART_REG_RFL (0x84) +#define UART_REG_HALT (0xa4) + +/* uart status register bits */ +#define UART_REG_USR_BUSY (0x1 << 0x0) +#define UART_REG_USR_TFNF (0x1 << 0x1) +#define UART_REG_USR_TFE (0x1 << 0x2) +#define UART_REG_USR_RFNE (0x1 << 0x3) +#define UART_REG_USR_RFF (0x1 << 0x4) + +void sunxi_uart_init(vaddr_t __unused base) +{ + /* do nothing, debug uart(uart0) share with normal world, + * everything for uart0 is ready now. + */ +} + +void sunxi_uart_flush_tx_fifo(vaddr_t base) +{ + while (read32(base + UART_REG_TFL)) { + /* waiting transmit fifo empty */ + ; + } +} + +bool sunxi_uart_have_rx_data(vaddr_t base) +{ + return read32(base + UART_REG_RFL); +} + +void sunxi_uart_putc(int ch, vaddr_t base) +{ + while (!(read32(base + UART_REG_USR) & UART_REG_USR_TFNF)) { + /* transmit fifo is full, waiting again. */ + ; + } + + /* write out charset to transmit fifo */ + write8(ch, base + UART_REG_THR); +} + +int sunxi_uart_getchar(vaddr_t base) +{ + while (!sunxi_uart_have_rx_data(base)) { + /* transmit fifo is empty, waiting again. */ + ; + } + return read32(base + UART_REG_RBR) & 0xff; +} + diff --git a/core/include/drivers/sunxi_uart.h b/core/include/drivers/sunxi_uart.h new file mode 100644 index 0000000..36091a7 --- /dev/null +++ b/core/include/drivers/sunxi_uart.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, 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 SUNXI_UART_H +#define SUNXI_UART_H + +#include <types_ext.h> + +void sunxi_uart_init(vaddr_t base); + +void sunxi_uart_putc(int ch, vaddr_t base); + +void sunxi_uart_flush_tx_fifo(vaddr_t base); + +bool sunxi_uart_have_rx_data(vaddr_t base); + +int sunxi_uart_getchar(vaddr_t base); + +#endif /*SUNXI_UART_H*/ + |