diff options
Diffstat (limited to 'core/arch/arm/plat-sunxi')
-rw-r--r-- | core/arch/arm/plat-sunxi/conf.mk | 17 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/console.c | 59 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/entry.S | 107 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/head.c | 60 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/kern.ld.S | 198 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/link.mk | 54 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/main.c | 177 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/platform.c | 125 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/platform.h | 85 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/platform_config.h | 152 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/rng_support.c | 43 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/smp_boot.S | 104 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/smp_fixup.S | 116 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/sub.mk | 9 |
14 files changed, 1306 insertions, 0 deletions
diff --git a/core/arch/arm/plat-sunxi/conf.mk b/core/arch/arm/plat-sunxi/conf.mk new file mode 100644 index 0000000..b2a9dc1 --- /dev/null +++ b/core/arch/arm/plat-sunxi/conf.mk @@ -0,0 +1,17 @@ +arm32-platform-cpuarch := cortex-a15 +arm32-platform-cflags += -mcpu=$(arm32-platform-cpuarch) +arm32-platform-aflags += -mcpu=$(arm32-platform-cpuarch) +core_arm32-platform-aflags += -mfpu=neon + +$(call force,CFG_ARM32_core,y) +$(call force,CFG_SECURE_TIME_SOURCE_CNTPCT,y) +$(call force,CFG_SUNXI_UART,y) +$(call force,CFG_PM_STUBS,y) +$(call force,CFG_GIC,y) + +ta-targets = ta_arm32 + +CFG_CRYPTO_SIZE_OPTIMIZATION ?= n +CFG_NUM_THREADS ?= 4 +CFG_WITH_STACK_CANARIES ?= y +CFG_WITH_STATS ?= y diff --git a/core/arch/arm/plat-sunxi/console.c b/core/arch/arm/plat-sunxi/console.c new file mode 100644 index 0000000..b985316 --- /dev/null +++ b/core/arch/arm/plat-sunxi/console.c @@ -0,0 +1,59 @@ +/* + * 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 <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; +} + + +void console_init(void) +{ + sunxi_uart_init(console_base()); +} + +void console_putc(int ch) +{ + sunxi_uart_putc(ch, console_base()); +} + +void console_flush(void) +{ + sunxi_uart_flush(console_base()); +} diff --git a/core/arch/arm/plat-sunxi/entry.S b/core/arch/arm/plat-sunxi/entry.S new file mode 100644 index 0000000..bff2b8b --- /dev/null +++ b/core/arch/arm/plat-sunxi/entry.S @@ -0,0 +1,107 @@ +/* + * 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 <arm.h> +#include <arm32_macros.S> +#include <sm/optee_smc.h> +#include <sm/teesmc_opteed_macros.h> +#include <sm/teesmc_opteed.h> +#include <kernel/unwind.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 , : +UNWIND( .fnstart) +UNWIND( .cantunwind) + read_sctlr r0 + orr r0, r0, #SCTLR_A + write_sctlr r0 + + ldr r0, =_start + write_vbar r0 + + mov r4, r1 + bl get_core_pos + add r0, r0, #1 + ldr r2, =stack_tmp_stride + ldr r1, [r2] + mul r2, r0, r1 + ldr r1, =stack_tmp + ldr sp, [r1, r2] + + /* 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_map + 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 */ +UNWIND( .fnend) +END_FUNC reset + diff --git a/core/arch/arm/plat-sunxi/head.c b/core/arch/arm/plat-sunxi/head.c new file mode 100644 index 0000000..838dbf4 --- /dev/null +++ b/core/arch/arm/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/arm/plat-sunxi/kern.ld.S b/core/arch/arm/plat-sunxi/kern.ld.S new file mode 100644 index 0000000..600ed09 --- /dev/null +++ b/core/arch/arm/plat-sunxi/kern.ld.S @@ -0,0 +1,198 @@ +/* + * 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(CFG_KERN_LINKER_FORMAT) +OUTPUT_ARCH(CFG_KERN_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 = .; + + . = ALIGN(4); + __initcall_start = .; + *(.initcall1) + *(.initcall2) + *(.initcall3) + *(.initcall4) + __initcall_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 = .; + + .ARM.extab : { + __extab_start = .; + *(.ARM.extab*) + __extab_end = .; + } + + .rodata : ALIGN(4) { + __rodata_start = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + + /* + * 8 to avoid unwanted padding between __start_ta_head_section + * and the first structure in ta_head_section, in 64-bit + * builds + */ + . = ALIGN(8); + __start_ta_head_section = . ; + KEEP(*(ta_head_section)) + __stop_ta_head_section = . ; + . = ALIGN(8); + __start_phys_mem_map_section = . ; + KEEP(*(phys_mem_map_section)) + __end_phys_mem_map_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/arm/plat-sunxi/link.mk b/core/arch/arm/plat-sunxi/link.mk new file mode 100644 index 0000000..2e289e6 --- /dev/null +++ b/core/arch/arm/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) $(libgcccore) + +link-script-cppflags := \ + $(filter-out $(CPPFLAGS_REMOVE) $(cppflags-remove), \ + $(nostdinccore) $(CPPFLAGS) \ + $(addprefix -I,$(incdirscore)) $(cppflagscore)) + + +-include $(link-script-dep) + +$(link-script-pp): $(link-script) $(conf-file) + @$(cmd-echo-silent) ' CPP $@' + @mkdir -p $(dir $@) + $(q)$(CPPcore) -Wp,-P,-MT,$@,-MD,$(link-script-dep) \ + $(link-script-cppflags) $< > $@ + + +$(link-out-dir)/tee.elf: $(objs) $(libdeps) $(link-script-pp) + @$(cmd-echo-silent) ' LD $@' + $(q)$(LDcore) $(ldargs-tee.elf) -o $@ + +$(link-out-dir)/tee.dmp: $(link-out-dir)/tee.elf + @$(cmd-echo-silent) ' OBJDUMP $@' + $(q)$(OBJDUMPcore) -l -x -d $< > $@ + +$(link-out-dir)/tee.bin: $(link-out-dir)/tee.elf + @$(cmd-echo-silent) ' OBJCOPY $@' + $(q)$(OBJCOPYcore) -O binary $< $@ + +$(link-out-dir)/tee.symb_sizes: $(link-out-dir)/tee.elf + @$(cmd-echo-silent) ' GEN $@' + $(q)$(NMcore) --print-size --reverse-sort --size-sort $< > $@ diff --git a/core/arch/arm/plat-sunxi/main.c b/core/arch/arm/plat-sunxi/main.c new file mode 100644 index 0000000..3954d9d --- /dev/null +++ b/core/arch/arm/plat-sunxi/main.c @@ -0,0 +1,177 @@ +/* + * 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/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 <kernel/panic.h> +#include <kernel/pm_stubs.h> +#include <kernel/misc.h> +#include <mm/tee_mmu.h> +#include <mm/core_mmu.h> +#include <tee/entry_std.h> +#include <tee/entry_fast.h> +#include <platform.h> +#include <util.h> +#include <trace.h> +#include <malloc.h> + +/* teecore heap address/size is defined in scatter file */ +extern unsigned char teecore_heap_start; +extern unsigned char teecore_heap_end; + +static void main_fiq(void); +static void main_tee_entry_std(struct thread_smc_args *args); +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, + .cpu_on = pm_panic, + .cpu_off = pm_panic, + .cpu_suspend = pm_panic, + .cpu_resume = pm_panic, + .system_off = pm_panic, + .system_reset = pm_panic, +}; + +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. + */ + thread_mask_exceptions(THREAD_EXCP_FIQ | THREAD_EXCP_IRQ); + + if (pos == 0) { + thread_init_primary(&handlers); + + /* initialize platform */ + platform_init(); + } + + thread_init_per_cpu(); + + /* Initialize secure monitor */ + nsec_ctx = sm_get_nsec_ctx(); + nsec_ctx->mon_lr = nsec_entry; + nsec_ctx->mon_spsr = CPSR_MODE_SVC | CPSR_I; + + 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_add_pool((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 void main_tee_entry_fast(struct thread_smc_args *args) +{ + /* TODO move to main_init() */ + if (init_teecore() != TEE_SUCCESS) + panic(); + + /* SiP Service Call Count */ + if (args->a0 == OPTEE_SMC_SIP_SUNXI_CALLS_COUNT) { + args->a0 = 1; + return; + } + + /* SiP Service Call UID */ + if (args->a0 == OPTEE_SMC_SIP_SUNXI_CALLS_UID) { + args->a0 = OPTEE_SMC_SIP_SUNXI_UID_R0; + args->a1 = OPTEE_SMC_SIP_SUNXI_UID_R1; + args->a2 = OPTEE_SMC_SIP_SUNXI_UID_R2; + args->a3 = OPTEE_SMC_SIP_SUNXI_UID_R3; + return; + } + + /* SiP Service Calls */ + if (args->a0 == OPTEE_SMC_OPTEE_FAST_CALL_SIP_SUNXI) { + platform_smc_handle(args); + return; + } + + tee_entry_fast(args); +} + + + +static void main_tee_entry_std(struct thread_smc_args *args) +{ + /* TODO move to main_init() */ + if (init_teecore() != TEE_SUCCESS) + panic(); + + tee_entry_std(args); +} + +/* main_tee_entry_fast() supports 3 platform-specific functions */ +void tee_entry_get_api_call_count(struct thread_smc_args *args) +{ + args->a0 = tee_entry_generic_get_api_call_count() + 3; +} diff --git a/core/arch/arm/plat-sunxi/platform.c b/core/arch/arm/plat-sunxi/platform.c new file mode 100644 index 0000000..e46541a --- /dev/null +++ b/core/arch/arm/plat-sunxi/platform.c @@ -0,0 +1,125 @@ +/* + * 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/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 <kernel/panic.h> +#include <kernel/misc.h> +#include <mm/tee_pager.h> +#include <mm/core_mmu.h> +#include <mm/core_memprot.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> +#include <console.h> + +void sunxi_secondary_entry(void); + +uint32_t sunxi_secondary_ns_entry; + +struct gic_data gic_data; + +static int platform_smp_init(void) +{ + vaddr_t base = (vaddr_t)phys_to_virt(PRCM_BASE, MEM_AREA_IO_SEC); + + assert(base); + write32((uint32_t)sunxi_secondary_entry, + base + PRCM_CPU_SOFT_ENTRY_REG); + + return 0; +} + +void platform_init(void) +{ + vaddr_t gicc_base; + vaddr_t gicd_base; + vaddr_t cci400_base; + + gicc_base = (vaddr_t)phys_to_virt(GIC_BASE + GICC_OFFSET, + MEM_AREA_IO_SEC); + gicd_base = (vaddr_t)phys_to_virt(GIC_BASE + GICD_OFFSET, + MEM_AREA_IO_SEC); + cci400_base = (vaddr_t)phys_to_virt(CCI400_BASE, MEM_AREA_IO_SEC); + if (!gicc_base || !gicd_base || !cci400_base) + panic(); + + /* + * GIC configuration is initialized in Secure bootloader, + * Initialize GIC base address here for debugging. + */ + gic_init_base_addr(&gic_data, gicc_base, gicd_base); + itr_init(&gic_data.chip); + + /* platform smp initialize */ + platform_smp_init(); + + /* enable non-secure access cci-400 registers */ + write32(0x1, cci400_base + CCI400_SECURE_ACCESS_REG); + + /* Initialize uart */ + console_init(); + + 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 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)); + break; + default: + ret = OPTEE_SMC_RETURN_EBADCMD; + break; + } + smc_args->a0 = ret; + return ret; +} + diff --git a/core/arch/arm/plat-sunxi/platform.h b/core/arch/arm/plat-sunxi/platform.h new file mode 100644 index 0000000..c6db14b --- /dev/null +++ b/core/arch/arm/plat-sunxi/platform.h @@ -0,0 +1,85 @@ +/* + * 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, OPTEE_SMC_FUNCID_SIP_SUNXI + * r1 OPTEE_SMC_SIP_SUNXI_SET_SMP_BOOTENTRY set smp bootup entry + */ +#define OPTEE_SMC_SIP_SUNXI_SET_SMP_BOOTENTRY (0xFFFF0000) + +#define OPTEE_SMC_FUNCID_SIP_SUNXI 0x8000 +#define OPTEE_SMC_OPTEE_FAST_CALL_SIP_SUNXI \ + OPTEE_SMC_CALL_VAL(OPTEE_SMC_32, OPTEE_SMC_FAST_CALL, \ + OPTEE_SMC_OWNER_SIP, \ + OPTEE_SMC_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 OPTEE_SMC_FUNCID_SIP_CALLS_COUNT 0xFF00 +#define OPTEE_SMC_SIP_SUNXI_CALLS_COUNT \ + OPTEE_SMC_CALL_VAL(OPTEE_SMC_32, OPTEE_SMC_FAST_CALL, \ + OPTEE_SMC_OWNER_SIP, \ + OPTEE_SMC_FUNCID_CALLS_COUNT) + +/* + * Function specified by SMC Calling convention + * + * SiP Service Call UID + * + * Return the implementation of SiP Service Calls UID. + * + */ +#define OPTEE_SMC_SIP_SUNXI_UID_R0 0xa5d5c51b +#define OPTEE_SMC_SIP_SUNXI_UID_R1 0x8d6c0002 +#define OPTEE_SMC_SIP_SUNXI_UID_R2 0x6f8611e4 +#define OPTEE_SMC_SIP_SUNXI_UID_R3 0x12b7e560 +#define OPTEE_SMC_FUNCID_SIP_SUNXI_CALLS_UID 0xFF01 +#define OPTEE_SMC_SIP_SUNXI_CALLS_UID \ + OPTEE_SMC_CALL_VAL(OPTEE_SMC_32, OPTEE_SMC_FAST_CALL, \ + OPTEE_SMC_OWNER_SIP, \ + OPTEE_SMC_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/arm/plat-sunxi/platform_config.h b/core/arch/arm/plat-sunxi/platform_config.h new file mode 100644 index 0000000..8060d9b --- /dev/null +++ b/core/arch/arm/plat-sunxi/platform_config.h @@ -0,0 +1,152 @@ +/* + * 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 + +#ifdef CFG_WITH_PAGER +#error "Pager not supported for platform sunxi" +#endif +#ifdef CFG_WITH_LPAE +#error "LPAE not supported for platform sunxi" +#endif + +#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 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) + +/* + * 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_TEE_RAM_PH_SIZE (1 * 1024 * 1024) +#define CFG_TEE_RAM_SIZE CFG_TEE_RAM_PH_SIZE +#define CFG_TA_RAM_SIZE (CFG_DDR_TEETZ_RESERVED_SIZE - \ + CFG_TEE_RAM_SIZE - CFG_SHMEM_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) + +/* Full GlobalPlatform test suite requires CFG_SHMEM_SIZE to be at least 2MB */ +#define CFG_SHMEM_START (DDR_PHYS_START + 0x1000000) +#define CFG_SHMEM_SIZE 0x100000 + +#define CFG_TEE_LOAD_ADDR TEE_RAM_START + +/* AHB0 devices */ +#define DEVICE0_PA_BASE ROUNDDOWN(0x01400000, CORE_MMU_DEVICE_SIZE) +#define DEVICE0_VA_BASE DEVICE0_PA_BASE +#define DEVICE0_SIZE ROUNDUP(0x00900000, CORE_MMU_DEVICE_SIZE) +#define DEVICE0_TYPE MEM_AREA_IO_SEC + +/* AHB1 devices */ +#define DEVICE1_PA_BASE ROUNDDOWN(0x00800000, CORE_MMU_DEVICE_SIZE) +#define DEVICE1_VA_BASE DEVICE1_PA_BASE +#define DEVICE1_SIZE ROUNDUP(0x00300000, CORE_MMU_DEVICE_SIZE) +#define DEVICE1_TYPE MEM_AREA_IO_SEC + +/* AHB2 devices */ +#define DEVICE2_PA_BASE ROUNDDOWN(0x03000000, CORE_MMU_DEVICE_SIZE) +#define DEVICE2_VA_BASE DEVICE2_PA_BASE +#define DEVICE2_SIZE ROUNDUP(0x01000000, CORE_MMU_DEVICE_SIZE) +#define DEVICE2_TYPE MEM_AREA_IO_SEC + +/* AHBS devices */ +#define DEVICE3_PA_BASE ROUNDDOWN(0x06000000, CORE_MMU_DEVICE_SIZE) +#define DEVICE3_VA_BASE DEVICE3_PA_BASE +#define DEVICE3_SIZE ROUNDUP(0x02200000, CORE_MMU_DEVICE_SIZE) +#define DEVICE3_TYPE MEM_AREA_IO_SEC + +#endif /*PLATFORM_CONFIG_H*/ diff --git a/core/arch/arm/plat-sunxi/rng_support.c b/core/arch/arm/plat-sunxi/rng_support.c new file mode 100644 index 0000000..434b104 --- /dev/null +++ b/core/arch/arm/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/arm/plat-sunxi/smp_boot.S b/core/arch/arm/plat-sunxi/smp_boot.S new file mode 100644 index 0000000..9e79842 --- /dev/null +++ b/core/arch/arm/plat-sunxi/smp_boot.S @@ -0,0 +1,104 @@ +/* + * 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 <arm.h> +#include <arm32_macros.S> +#include <sm/optee_smc.h> +#include <sm/teesmc_opteed_macros.h> +#include <sm/teesmc_opteed.h> +#include <kernel/unwind.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 , : +UNWIND( .fnstart) +UNWIND( .cantunwind) + /* 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 + add r0, r0, #1 + ldr r2, =stack_tmp_stride + ldr r1, [r2] + mul r2, r0, r1 + ldr r1, =stack_tmp + ldr sp, [r1, r2] + + /* 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 */ + ldr r0, =gic_data + 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 */ +UNWIND( .fnend) +END_FUNC sunxi_secondary_entry diff --git a/core/arch/arm/plat-sunxi/smp_fixup.S b/core/arch/arm/plat-sunxi/smp_fixup.S new file mode 100644 index 0000000..bf533b4 --- /dev/null +++ b/core/arch/arm/plat-sunxi/smp_fixup.S @@ -0,0 +1,116 @@ +/* + * 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 <kernel/unwind.h> + +#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) + +FUNC sunxi_secondary_fixup , : +UNWIND( .fnstart) + 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 +UNWIND( .fnend) +END_FUNC sunxi_secondary_fixup diff --git a/core/arch/arm/plat-sunxi/sub.mk b/core/arch/arm/plat-sunxi/sub.mk new file mode 100644 index 0000000..7c98a65 --- /dev/null +++ b/core/arch/arm/plat-sunxi/sub.mk @@ -0,0 +1,9 @@ +global-incdirs-y += . +srcs-y += entry.S +srcs-y += main.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 |