diff options
257 files changed, 56568 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4220018 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +# Ignore miscellaneous files +cscope.* +*.swp +*.patch +.project +.cproject + +# Ignore build directory +build/ + +# Ignore build products from tools +tools/**/*.o +tools/fip_create/fip_create diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e74f386 --- /dev/null +++ b/Makefile @@ -0,0 +1,41 @@ +include $(buildsrc)/config.mk +include $(buildtree)/include/autoconf.mk +include $(buildtree)/.config + +ARMCC_$(CONFIG_ENABLE_ARMCC_DEBUGROM)=$(shell echo __CC_ARM | armcc -E - | tail -n 1) +ifneq ($(ARMCC_y),) +targetComplier=arm +else +targetComplier=gcc +endif + +MAKEFLAGS += --no-print-directory + +.PHONY: all clean realclean distclean + +all: + $(Q)$(MAKE) -f Makefile.$(targetComplier) + +#ifndef CONFIG_M3 +# $(MAKE) -f Makefile.ddr_init +#endif + +ifdef CONFIG_AML_EXT_PGM + $(MAKE) -f Makefile.ft +endif + +ifdef CONFIG_AML_SECU_BOOT_V2 + $(MAKE) -f Makefile.usb +endif +ifeq ($(CONFIG_CMD_RUNARC),y) + $(MAKE) -f Makefile.rbt +endif + +ifeq ($(CONFIG_AML_SUSPEND),y) +ifneq ($(CONFIG_MESON_TRUSTZONE),y) + $(MAKE) -f Makefile.krbt +endif +endif + +realclean distclean: + $(Q)$(MAKE) -f Makefile.$(targetComplier) distclean
\ No newline at end of file diff --git a/Makefile.gcc b/Makefile.gcc new file mode 100644 index 0000000..3890a6a --- /dev/null +++ b/Makefile.gcc @@ -0,0 +1,409 @@ +# +# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 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. +# +# Neither the name of ARM nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific +# prior written permission. +# +# 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. +# + +# +# Default values for build configurations +# + +# Build verbosity +V := 0 +# Debug build +BUILD_TYPE := ${BL2_BUILD_TYPE} +# Build architecture +ARCH := aarch64 +# Build platform +#DEFAULT_PLAT := gx +PLAT := ${SOC} +export PLAT +# SPD choice +SPD := none +# Base commit to perform code check on +BASE_COMMIT := origin/master +# NS timer register save and restore +NS_TIMER_SWITCH := 0 +# By default, Bl1 acts as the reset handler, not BL31 +RESET_TO_BL31 := 0 + +# Checkpatch ignores +CHECK_IGNORE = --ignore COMPLEX_MACRO + +CHECKPATCH_ARGS = --no-tree --no-signoff ${CHECK_IGNORE} +CHECKCODE_ARGS = --no-patch --no-tree --no-signoff ${CHECK_IGNORE} + +ifeq (${V},0) + Q=@ + CHECKCODE_ARGS += --no-summary --terse +else + Q= +endif +export Q + +BL_COMMON_SOURCES := common/bl_common.c \ + common/debug.c \ + lib/aarch64/cache_helpers.S \ + lib/aarch64/misc_helpers.S \ + lib/aarch64/tlb_helpers.S \ + lib/aarch64/xlat_helpers.c \ + lib/stdlib/std.c \ + lib/io_storage.c \ + plat/common/aarch64/platform_helpers.S + +BUILD_BASE := ./ +BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${BUILD_TYPE} + +# Convenience function for adding build definitions +# $(eval $(call add_define,FOO)) will have: +# -DFOO if $(FOO) is empty; -DFOO=$(FOO) otherwise +define add_define +DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),) +endef + +# Convenience function for verifying option has a boolean value +# $(eval $(call assert_boolean,FOO)) will assert FOO is 0 or 1 +define assert_boolean +$(and $(patsubst 0,,$(value $(1))),$(patsubst 1,,$(value $(1))),$(error $(1) must be boolean)) +endef + +ifeq (${PLAT},) + $(error "Error: Unknown platform. Please use PLAT=<platform name> to specify the platform.") +endif + +all: msg_start + +msg_start: + @echo "Building ${PLAT}" + +include plat/${PLAT}/platform.mk +ifdef BL2_SOURCES +NEED_BL2 := yes +include bl2/bl2.mk +endif + +# Include SPD Makefile if one has been specified +ifneq (${SPD},none) + # We expect to locate an spd.mk under the specified SPD directory + SPD_MAKE := $(shell m="services/spd/${SPD}/${SPD}.mk"; [ -f "$$m" ] && echo "$$m") + + ifeq (${SPD_MAKE},) + $(error Error: No services/spd/${SPD}/${SPD}.mk located) + endif + $(info Including ${SPD_MAKE}) + include ${SPD_MAKE} + + # If there's BL32 companion for the chosen SPD, and the SPD wants to build the + # BL2 from source, we expect that the SPD's Makefile would set NEED_BL32 + # variable to "yes" +endif + +.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool fip +.SUFFIXES: + +INCLUDES += -Iinclude/bl2 \ + -Iinclude/bl31 \ + -Iinclude/common \ + -Iinclude/drivers \ + -Iinclude/drivers/arm \ + -Iinclude/drivers/serial \ + -Iinclude/lib \ + -Iinclude/lib/aarch64 \ + -Iinclude/plat/common \ + -Iinclude/stdlib \ + -Iinclude/stdlib/sys \ + ${PLAT_INCLUDES} \ + ${SPD_INCLUDES} + +# Process DEBUG flag +$(eval $(call assert_boolean,DEBUG)) +$(eval $(call add_define,DEBUG)) +ifeq (${DEBUG},0) + $(eval $(call add_define,NDEBUG)) +else +CFLAGS += -g +ASFLAGS += -g -Wa,--gdwarf-2 +endif + +# Process NS_TIMER_SWITCH flag +$(eval $(call assert_boolean,NS_TIMER_SWITCH)) +$(eval $(call add_define,NS_TIMER_SWITCH)) + +# Process RESET_TO_BL31 flag +$(eval $(call assert_boolean,RESET_TO_BL31)) +$(eval $(call add_define,RESET_TO_BL31)) + +ASFLAGS += -nostdinc -ffreestanding -Wa,--fatal-warnings \ + -mgeneral-regs-only -D__ASSEMBLY__ \ + ${DEFINES} ${INCLUDES} +CFLAGS += -nostdinc -pedantic -ffreestanding -Wall \ + -Werror -mgeneral-regs-only -std=c99 -c -Os \ + ${DEFINES} ${INCLUDES} +CFLAGS += -ffunction-sections -fdata-sections +CFLAGS += ${FIRMWARE_CPPFLAGS} + +LDFLAGS += --fatal-warnings -O1 +LDFLAGS += --gc-sections + + +CC := ${CROSS_COMPILE}gcc +CPP := ${CROSS_COMPILE}cpp +AS := ${CROSS_COMPILE}gcc +AR := ${CROSS_COMPILE}ar +LD := ${CROSS_COMPILE}ld +OC := ${CROSS_COMPILE}objcopy +OD := ${CROSS_COMPILE}objdump +NM := ${CROSS_COMPILE}nm +PP := ${CROSS_COMPILE}gcc -E ${CFLAGS} + +# Variables for use with Firmware Image Package +FIPTOOLPATH ?= tools/fip_create +FIPTOOL ?= ${FIPTOOLPATH}/fip_create +fiptool: ${FIPTOOL} +fip: ${BUILD_PLAT}/fip.bin + +locate-checkpatch: +ifndef CHECKPATCH + $(error "Please set CHECKPATCH to point to the Linux checkpatch.pl file, eg: CHECKPATCH=../linux/script/checkpatch.pl") +else +ifeq (,$(wildcard ${CHECKPATCH})) + $(error "The file CHECKPATCH points to cannot be found, use eg: CHECKPATCH=../linux/script/checkpatch.pl") +endif +endif + +clean: + @echo " CLEAN" + ${Q}rm -rf ${BUILD_PLAT} + ${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean + +realclean distclean: + @echo " REALCLEAN" + ${Q}rm -rf ${BUILD_BASE} + ${Q}rm -f ${CURDIR}/cscope.* + ${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean + +checkcodebase: locate-checkpatch + @echo " CHECKING STYLE" + @if test -d .git ; then \ + git ls-files | while read GIT_FILE ; do ${CHECKPATCH} ${CHECKCODE_ARGS} -f $$GIT_FILE ; done ; \ + else \ + find . -type f -not -iwholename "*.git*" -not -iwholename "*build*" -exec ${CHECKPATCH} ${CHECKCODE_ARGS} -f {} \; ; \ + fi + +checkpatch: locate-checkpatch + @echo " CHECKING STYLE" + @git format-patch --stdout ${BASE_COMMIT} | ${CHECKPATCH} ${CHECKPATCH_ARGS} - || true + +${FIPTOOL}: + ${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} + @echo + @echo "Built $@ successfully" + @echo + +define match_goals +$(strip $(foreach goal,$(1),$(filter $(goal),$(MAKECMDGOALS)))) +endef + +# List of rules that involve building things +BUILD_TARGETS := all bl1 bl2 bl31 bl32 fip + +# Does the list of goals specified on the command line include a build target? +ifneq ($(call match_goals,${BUILD_TARGETS}),) +IS_ANYTHING_TO_BUILD := 1 +endif + +define MAKE_C + +$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2)))) +$(eval PREREQUISITES := $(patsubst %.o,%.d,$(OBJ))) + +$(OBJ) : $(2) + @echo " CC $$<" + $$(Q)$$(CC) $$(CFLAGS) -c $$< -o $$@ + + +$(PREREQUISITES) : $(2) + @echo " DEPS $$@" + @mkdir -p $(1) + $$(Q)$$(CC) $$(CFLAGS) -M -MT $(OBJ) -MF $$@ $$< + +ifdef IS_ANYTHING_TO_BUILD +-include $(PREREQUISITES) +endif + +endef + + +define MAKE_S + +$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2)))) +$(eval PREREQUISITES := $(patsubst %.o,%.d,$(OBJ))) + +$(OBJ) : $(2) + @echo " AS $$<" + $$(Q)$$(AS) $$(ASFLAGS) -c $$< -o $$@ + +$(PREREQUISITES) : $(2) + @echo " DEPS $$@" + @mkdir -p $(1) + $$(Q)$$(AS) $$(ASFLAGS) -M -MT $(OBJ) -MF $$@ $$< + +ifdef IS_ANYTHING_TO_BUILD +-include $(PREREQUISITES) +endif + +endef + + +define MAKE_LD + +$(eval PREREQUISITES := $(1).d) + +$(1) : $(2) + @echo " PP $$<" + $$(Q)$$(AS) $$(ASFLAGS) -P -E -o $$@ $$< + +$(PREREQUISITES) : $(2) + @echo " DEPS $$@" + @mkdir -p $$(dir $$@) + $$(Q)$$(AS) $$(ASFLAGS) -M -MT $(1) -MF $$@ $$< + +ifdef IS_ANYTHING_TO_BUILD +-include $(PREREQUISITES) +endif + +endef + + +define MAKE_OBJS + $(eval C_OBJS := $(filter %.c,$(2))) + $(eval REMAIN := $(filter-out %.c,$(2))) + $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C,$(1),$(obj)))) + + $(eval S_OBJS := $(filter %.S,$(REMAIN))) + $(eval REMAIN := $(filter-out %.S,$(REMAIN))) + $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S,$(1),$(obj)))) + + $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN))) +endef + + +# NOTE: The line continuation '\' is required in the next define otherwise we +# end up with a line-feed characer at the end of the last c filename. +# Also bare this issue in mind if extending the list of supported filetypes. +define SOURCES_TO_OBJS + $(notdir $(patsubst %.c,%.o,$(filter %.c,$(1)))) \ + $(notdir $(patsubst %.S,%.o,$(filter %.S,$(1)))) +endef + +define MAKE_BL + $(eval BUILD_DIR := ${BUILD_PLAT}/bl$(1)) + $(eval SOURCES := $(BL$(1)_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES)) + $(eval OBJS := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES)))) + $(eval LINKERFILE := $(BUILD_DIR)/bl$(1).ld) + $(eval MAPFILE := $(BUILD_DIR)/bl$(1).map) + $(eval ELF := $(BUILD_DIR)/bl$(1).elf) + $(eval DUMP := $(BUILD_DIR)/bl$(1).dump) + $(eval BIN := $(BUILD_PLAT)/bl$(1).bin) + + $(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES))) + $(eval $(call MAKE_LD,$(LINKERFILE),$(BL$(1)_LINKERFILE))) + +$(BUILD_DIR) : + $$(Q)mkdir -p "$$@" + +$(ELF) : $(OBJS) $(LINKERFILE) + @echo " LD $$@" + @echo 'const char build_message[] = "Built : "__TIME__", "__DATE__;' | \ + $$(CC) $$(CFLAGS) -xc - -o $(BUILD_DIR)/build_message.o + $$(Q)$$(LD) -o $$@ $$(LDFLAGS) -Map=$(MAPFILE) --script $(LINKERFILE) \ + $(BUILD_DIR)/build_message.o $(OBJS) + +$(DUMP) : $(ELF) + @echo " OD $$@" + $${Q}$${OD} -dxS $$< > $$@ + +$(BIN) : $(ELF) + @echo " BIN $$@" + $$(Q)$$(OC) -O binary $$< $$@ + @echo + @echo "Built $$@ successfully" + @echo + +.PHONY : bl$(1) +bl$(1) : $(BUILD_DIR) $(DUMP) $(BIN) + +all : bl$(1) + +$(eval FIP_DEPS += $(if $2,$(BIN),)) +$(eval FIP_ARGS += $(if $2,--bl$(1) $(BIN),)) + +endef + +ifeq (${NEED_BL2},yes) +$(eval $(call MAKE_BL,2,in_fip)) +endif + +${BUILD_PLAT}/fip.bin: ${FIP_DEPS} ${BL33} ${FIPTOOL} + $(if ${BL33},,$(error "To build a FIP, please set BL33 to point to the Normal World binary, eg: BL33=../uefi/FVP_AARCH64_EFI.fd")) + ${Q}${FIPTOOL} --dump \ + ${FIP_ARGS} \ + --bl33 ${BL33} \ + $@ + @echo + @echo "Built $@ successfully" + @echo + + +cscope: + @echo " CSCOPE" + ${Q}find ${CURDIR} -name "*.[chsS]" > cscope.files + ${Q}cscope -b -q -k + +help: + @echo "usage: ${MAKE} PLAT=<${HELP_PLATFORMS}> <all|bl1|bl2|bl31|distclean|clean|checkcodebase|checkpatch>" + @echo "" + @echo "PLAT is used to specify which platform you wish to build." + @echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}" + @echo "" + @echo "Supported Targets:" + @echo " all Build the BL1, BL2 and BL31 binaries" + @echo " bl1 Build the BL1 binary" + @echo " bl2 Build the BL2 binary" + @echo " bl31 Build the BL31 binary" + @echo " checkcodebase Check the coding style of the entire source tree" + @echo " checkpatch Check the coding style on changes in the current" + @echo " branch against BASE_COMMIT (default origin/master)" + @echo " clean Clean the build for the selected platform" + @echo " cscope Generate cscope index" + @echo " distclean Remove all build artifacts for all platforms" + @echo " fiptool Build the Firmware Image Package(FIP) creation tool" + @echo "" + @echo "note: most build targets require PLAT to be set to a specific platform." + @echo "" + @echo "example: build all targets for the FVP platform:" + @echo " CROSS_COMPILE=aarch64-none-elf- make PLAT=fvp all" diff --git a/acknowledgements.md b/acknowledgements.md new file mode 100644 index 0000000..a428f2f --- /dev/null +++ b/acknowledgements.md @@ -0,0 +1,9 @@ +Contributor Acknowledgements +============================ + +Companies +--------- +Linaro Limited + +Individuals +----------- diff --git a/bl2/aarch64/bl2_arch_setup.c b/bl2/aarch64/bl2_arch_setup.c new file mode 100644 index 0000000..f4ce661 --- /dev/null +++ b/bl2/aarch64/bl2_arch_setup.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <arch_helpers.h> +#include <pll.h> +#include <stdio.h> +#include <saradc.h> + +/******************************************************************************* + * Place holder function to perform any S-EL1 specific architectural setup. At + * the moment there is nothing to do. + ******************************************************************************/ +extern void platform_power_init(int mode); +void bl2_arch_setup(void) +{ + /* Give access to FP/SIMD registers */ + write_cpacr(CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE)); + + /* get board id */ + saradc_ch1_get(); + + /* init power for each domain */ + platform_power_init(0); + + /* Init plls */ +#ifndef CONFIG_PXP_EMULATOR + pll_init(); +#endif + +} diff --git a/bl2/aarch64/bl2_entrypoint.S b/bl2/aarch64/bl2_entrypoint.S new file mode 100644 index 0000000..5adc71b --- /dev/null +++ b/bl2/aarch64/bl2_entrypoint.S @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> +#include <bl_common.h> +#include <platform_def.h> + + .globl bl2_entrypoint + +func bl2_entrypoint + /*--------------------------------------------- + * Store the extents of the tzram available to + * BL2 for future use. Use the opcode param to + * allow implement other functions if needed. + * --------------------------------------------- + */ + mov x20, x0 + mov x21, x1 + + /* --------------------------------------------- + * This is BL2 which is expected to be executed + * only by the primary cpu (at least for now). + * So, make sure no secondary has lost its way. + * --------------------------------------------- + */ + mrs x0, mpidr_el1 + bl platform_is_primary_cpu + cbz x0, _panic + + /* --------------------------------------------- + * Set the exception vector to something sane. + * --------------------------------------------- + */ + adr x0, early_exceptions + msr vbar_el1, x0 + + /* --------------------------------------------- + * Enable the instruction cache. + * --------------------------------------------- + */ + mrs x0, sctlr_el1 + orr x0, x0, #SCTLR_I_BIT + msr sctlr_el1, x0 + isb + + /* --------------------------------------------- + * Check the opcodes out of paranoia. + * --------------------------------------------- + */ + // mov x0, #RUN_IMAGE + // cmp x0, x20 + // b.ne _panic + + + + /* --------------------------------------------- + * Zero out NOBITS sections. There are 2 of them: + * - the .bss section; + * - the coherent memory section. + * --------------------------------------------- + */ + ldr x0, =__BSS_START__ + ldr x1, =__BSS_SIZE__ + bl zeromem16 + + ldr x0, =__COHERENT_RAM_START__ + ldr x1, =__COHERENT_RAM_UNALIGNED_SIZE__ + bl zeromem16 + + /* -------------------------------------------- + * Give ourselves a small coherent stack to + * ease the pain of initializing the MMU + * -------------------------------------------- + */ + mrs x0, mpidr_el1 + bl platform_set_coherent_stack + + /* --------------------------------------------- + * Perform early platform setup & platform + * specific early arch. setup e.g. mmu setup + * --------------------------------------------- + */ + mov x0, x21 + bl bl2_early_platform_setup + bl bl2_plat_arch_setup + + /* --------------------------------------------- + * Give ourselves a stack allocated in Normal + * -IS-WBWA memory + * --------------------------------------------- + */ + mrs x0, mpidr_el1 + bl platform_set_stack + + /* --------------------------------------------- + * Jump to main function. + * --------------------------------------------- + */ + bl bl2_main +_panic: + b _panic diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S new file mode 100644 index 0000000..62685cd --- /dev/null +++ b/bl2/bl2.ld.S @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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_def.h> + +OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) +OUTPUT_ARCH(PLATFORM_LINKER_ARCH) +ENTRY(bl2_entrypoint) + +MEMORY { + RAM (rwx): ORIGIN = TZRAM_BASE, LENGTH = TZRAM_SIZE +} + + +SECTIONS +{ + . = BL2_BASE; + ASSERT(. == ALIGN(4096), + "BL2_BASE address is not aligned on a page boundary.") + + ro . : { + __RO_START__ = .; + *bl2_entrypoint.o(.text*) + *(.text*) + *(.rodata*) + *(.vectors) + __RO_END_UNALIGNED__ = .; + /* + * Memory page(s) mapped to this section will be marked as + * read-only, executable. No RW data from the next section must + * creep in. Ensure the rest of the current memory page is unused. + */ + . = NEXT(BL2_ALIGN); + __RO_END__ = .; + } >RAM + + .data . : { + __DATA_START__ = .; + *(.data*) + __DATA_END__ = .; + } >RAM + + stacks (NOLOAD) : { + __STACKS_START__ = .; + *(tzfw_normal_stacks) + __STACKS_END__ = .; + } >RAM + + /* + * The .bss section gets initialised to 0 at runtime. + * Its base address must be 16-byte aligned. + */ + .bss : ALIGN(16) { + __BSS_START__ = .; + *(SORT_BY_ALIGNMENT(.bss*)) + *(COMMON) + __BSS_END__ = .; + } >RAM + + /* + * The xlat_table section is for full, aligned page tables (4K). + * Removing them from .bss avoids forcing 4K alignment on + * the .bss section and eliminates the unecessary zero init + */ + //xlat_table (NOLOAD) : { + // *(xlat_table) + //} >RAM + + /* + * The base address of the coherent memory section must be page-aligned (4K) + * to guarantee that the coherent data are stored on their own pages and + * are not mixed with normal data. This is required to set up the correct + * memory attributes for the coherent data page tables. + */ + coherent_ram (NOLOAD) : ALIGN(BL2_ALIGN) { + __COHERENT_RAM_START__ = .; + *(tzfw_coherent_mem) + __COHERENT_RAM_END_UNALIGNED__ = .; + /* + * Memory page(s) mapped to this section will be marked + * as device memory. No other unexpected data must creep in. + * Ensure the rest of the current memory page is unused. + */ + . = NEXT(BL2_ALIGN); + __COHERENT_RAM_END__ = .; + } >RAM + + __BL2_END__ = .; + + __BSS_SIZE__ = SIZEOF(.bss); + __COHERENT_RAM_UNALIGNED_SIZE__ = + __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__; + + ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.") +} diff --git a/bl2/bl2.mk b/bl2/bl2.mk new file mode 100644 index 0000000..cfde24b --- /dev/null +++ b/bl2/bl2.mk @@ -0,0 +1,40 @@ +# +# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 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. +# +# Neither the name of ARM nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific +# prior written permission. +# +# 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. +# + +BL2_SOURCES += bl2/bl2_main.c \ + bl2/usb_bl2_cmd.c \ + bl2/aarch64/bl2_entrypoint.S \ + bl2/aarch64/bl2_arch_setup.c \ + common/aarch64/early_exceptions.S \ + common/fip.c \ + lib/locks/exclusive/spinlock.S \ + common/memtest.c + +BL2_LINKERFILE := bl2/bl2.ld.S diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c new file mode 100644 index 0000000..11b95ba --- /dev/null +++ b/bl2/bl2_main.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <fip.h> +#include <debug.h> +#include <platform.h> +#include <platform_def.h> +#include <stdio.h> +#include "bl2_private.h" +#include <serial.h> +#include <plat_init.h> +#include <common.h> +#include <asm/arch/secure_apb.h> +extern unsigned int ddr_init(void); +void print_version(void); +extern int bl2_usb_handler(void); + +/******************************************************************************* + * The only thing to do in BL2 is to load further images and pass control to + * BL31. The memory occupied by BL2 will be reclaimed by BL3_x stages. BL2 runs + * entirely in S-EL1. Since arm standard c libraries are not PIC, printf et al + * are not available. We rely on assertions to signal error conditions + ******************************************************************************/ +void bl2_main(void) +{ + pinmux_init(); + + print_version(); + + /* Perform remaining generic architectural setup in S-El1 */ + bl2_arch_setup(); + + bl2_usb_handler(); + + ddr_init(); + + /* Perform platform setup in BL1 */ + bl2_platform_setup(); + + /* Load images */ + bl2_load_image(); + + serial_puts("NEVER BE HERE\n"); + while (1); +} + +void print_version(void) +{ + serial_puts("serial_puts_test\n"); + serial_puts("\n\nBL2 "); + serial_puts(build_message); + serial_puts(".\n"); + serial_puts(CONFIG_SYS_CONFIG_NAME); + serial_puts("@"); + serial_puts(PLAIN_VERSION); + serial_puts("\n\n"); +} diff --git a/bl2/bl2_private.h b/bl2/bl2_private.h new file mode 100644 index 0000000..022d1e9 --- /dev/null +++ b/bl2/bl2_private.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __BL2_PRIVATE_H__ +#define __BL2_PRIVATE_H__ + +/****************************************** + * Function prototypes + *****************************************/ +void bl2_arch_setup(void); + +#endif /* __BL2_PRIVATE_H__ */ diff --git a/bl2/bl30.h b/bl2/bl30.h new file mode 100644 index 0000000..8aaeb02 --- /dev/null +++ b/bl2/bl30.h @@ -0,0 +1,2361 @@ +const unsigned bl30_data[]={ + 0x20008000 , 0x20000179 , 0x200001a7 , 0x200001a7, + 0x200001a7 , 0x20000225 , 0x200001a7 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x20000a91, + 0x200001a7 , 0x00000000 , 0x200001a7 , 0x200001a7, + 0x200001a7 , 0x200001a7 , 0x200001a7 , 0x20000cad, + 0x200001a7 , 0x200001a7 , 0x20001407 , 0x20001417, + 0x20001427 , 0x20001437 , 0x20001447 , 0x20000e69, + 0x20000e79 , 0x20000e89 , 0x20000e99 , 0x20000ea9, + 0x20000eb9 , 0x20000ec9 , 0x200001a7 , 0x200001a7, + 0x200001a7 , 0x200001a7 , 0x200001a7 , 0x20001457, + 0x200001a7 , 0x200017ed , 0x200001a7 , 0x200001a7, + 0x200001a7 , 0x20001791 , 0x200017a1 , 0x200001a7, + 0x200001a7 , 0x200001a7 , 0x200001a7 , 0x200001a7, + 0x200001a7 , 0x20001d69 , 0x200001a7 , 0x200001a7, + 0x20001467 , 0x20000cc1 , 0x200001a7 , 0x200001a7, + 0x200001a7 , 0x200001a7 , 0x200001a7 , 0x200001a7, + 0x200001a7 , 0x200001a7 , 0x200001a7 , 0x200001a7, + 0x200001a7 , 0x200001a7 , 0x200001a7 , 0x200001a7, + 0x200001a7 , 0x200001a7 , 0x200001a7 , 0x200001a7, + 0x200001a7 , 0x200001a7 , 0x200001a7 , 0x200001a7, + 0x200001a7 , 0x200001a7 , 0x200001a7 , 0x200001a7, + 0xce112233 , 0x7263636d , 0x656b736f , 0x31765f79, + 0x322e312e , 0x2d373034 , 0x62383762 , 0x2d366232, + 0x00726964 , 0xce445566 , 0x0000f04f , 0x8814f380, + 0x8f6ff3bf , 0x4a10490f , 0xf04f6011 , 0x49070000, + 0x42914a07 , 0xf841bfb8 , 0xdbfa0b04 , 0x4685480b, + 0xf860f004 , 0xf000e7fe , 0xbf00b82b , 0x20007c00, + 0x20009300 , 0x20009300 , 0x2000935c , 0x20007b6c, + 0x00004770 , 0x20000000 , 0xe000ed08 , 0x20008000, + 0x681a4b05 , 0x021af042 , 0x3310601a , 0xf442681a, + 0x601a22e0 , 0xbf004770 , 0xe000ed14 , 0x000ff000, + 0xd0032801 , 0xbf142809 , 0x20012000 , 0x00004770, + 0xc01cf8df , 0x46004805 , 0x8109f3ef , 0x8205f3ef, + 0xe880466b , 0x46e54ffe , 0xb930f000 , 0x2000bf90, + 0x2000bf88 , 0x681b4b02 , 0xf7ffb90b , 0x4770bfe9, + 0x20008000 , 0x60184b01 , 0xbf004770 , 0x20008000, + 0x4b14b570 , 0x28094616 , 0x0230f100 , 0x460d4604, + 0xdd03705a , 0xeb004b10 , 0x18d30240 , 0x785a7819, + 0x789b480e , 0xf8f6f004 , 0x480db12d , 0x1026f855, + 0xf8f0f004 , 0x480be002 , 0xf912f004 , 0x4a0b4b0a, + 0x0003f004 , 0xbf0c2803 , 0x46184610 , 0x4070e8bd, + 0xb906f004 , 0x20009300 , 0x20005faa , 0x20006070, + 0x20006176 , 0x20006078 , 0x20006ef5 , 0x2000775e, + 0x6803b510 , 0xb1134604 , 0xf0044803 , 0x6823f8f1, + 0x60233301 , 0xbf00bd10 , 0x20006124 , 0x45f7e92d, + 0x1d064604 , 0xf7ff6b00 , 0x78a5ff89 , 0xf0154b59, + 0x49590501 , 0xf104bf18 , 0x46070534 , 0xbf082800, + 0x68724619 , 0xf04fb915 , 0xe00033ff , 0x485369eb, + 0xf004b2d2 , 0xf04ff8a7 , 0x46400800 , 0x46294642, + 0x0801f108 , 0xff94f7ff , 0x0f04f1b8 , 0x4640d1f5, + 0x32fff108 , 0xf1084631 , 0xf7ff0801 , 0xf1b8ff89, + 0xd1f40f0a , 0x46314640 , 0xf7ff2209 , 0x4631ff81, + 0x200b4642 , 0xff7cf7ff , 0x200c4629 , 0xf7ff2204, + 0x4631ff77 , 0x2f00200d , 0x2202bf14 , 0xf7ff2200, + 0x4629ff6f , 0x2205200e , 0xff6af7ff , 0x200f4629, + 0xf7ff2206 , 0x2500ff65 , 0xa054f8d4 , 0xf8d46e66, + 0x95018068 , 0x40ab2301 , 0x0f0aea13 , 0x4b30d009, + 0x7025f853 , 0xa801b12f , 0xff8af7ff , 0xf0044638, + 0x3501f87f , 0xd1ed2d20 , 0xda052e00 , 0xf7ffa801, + 0x4828ff7f , 0xf874f004 , 0x4f80f016 , 0xa801d005, + 0xff76f7ff , 0xf0044824 , 0xf016f86b , 0xd0050f02, + 0xf7ffa801 , 0x4821ff6d , 0xf862f004 , 0x23012500, + 0xea1340ab , 0xd0070f08 , 0xf7ffa801 , 0x4b1cff61, + 0x0025f853 , 0xf854f004 , 0x2d053501 , 0x6d63d1ef, + 0x4f00f413 , 0x4817d003 , 0xf0046da1 , 0x6d63f823, + 0x0f80f013 , 0x4814d003 , 0xf0046de1 , 0x6d61f81b, + 0xf0044812 , 0x6e21f817 , 0xf0044811 , 0x6e61f813, + 0xf0044810 , 0x4810f80f , 0xf0046ea1 , 0xe8bdf80b, + 0xbf0085fe , 0x20006081 , 0x20006089 , 0x20006091, + 0x20005fdc , 0x200060c0 , 0x200060cc , 0x200060de, + 0x2000605c , 0x200060f5 , 0x20006101 , 0x2000610d, + 0x2000611a , 0x20006127 , 0x20006133 , 0x4c39b570, + 0x6b204b39 , 0x23746723 , 0x3b7266e3 , 0x3b017063, + 0x3b017023 , 0x70e370a3 , 0xfea8f7ff , 0x68e3b108, + 0x6863e000 , 0x0203f013 , 0xf1b3d114 , 0xd3115f00, + 0x428b492e , 0x492ed80e , 0x4022f853 , 0x0c82ea4f, + 0x44613201 , 0x48272a08 , 0xd1f4604c , 0xf0437883, + 0x70830301 , 0x4c234b27 , 0x4620681b , 0x4b266563, + 0x65a3681b , 0x681b4b25 , 0x4b2565e3 , 0x6623681b, + 0x681b4b24 , 0x4b246663 , 0x66a3681b , 0xfee6f7ff, + 0xf0034822 , 0x78a3ffa7 , 0x0f01f013 , 0x6b20d022, + 0xf7ff6866 , 0xb938fe6b , 0xf4036d23 , 0x2b007300, + 0x2320bf0c , 0x18f62324 , 0x4b192400 , 0x429d1d35, + 0xf014d813 , 0xd1030f03 , 0x46314816 , 0xff8af003, + 0xf8554815 , 0x34011c04 , 0xff84f003 , 0xd0042c10, + 0xe7ea462e , 0xf0034811 , 0xe8bdff7d , 0xf0034070, + 0xbf00bfb1 , 0x2000bf8c , 0x21636e50 , 0x2000bfe0, + 0x2000bfbc , 0xe000ed28 , 0xe000ed38 , 0xe000ed34, + 0xe000ed24 , 0xe000ed2c , 0xe000ed30 , 0x2000613e, + 0x2000c000 , 0x2000616e , 0x20006175 , 0x2000617b, + 0x8309f3ef , 0xe923680a , 0xe8b20ff0 , 0x60030ff0, + 0x8809f382 , 0x0214f101 , 0xf0126812 , 0xbf0c0f01, + 0x22032202 , 0x8314f3ef , 0x0304f003 , 0x0302ea43, + 0x8814f383 , 0x4a0d4770 , 0x0302f04f , 0x0244f102, + 0x0100f04f , 0x8809f382 , 0x0201f04f , 0x8f6ff3bf, + 0x8814f383 , 0xf04f4603 , 0xf3bf0000 , 0x601a8f6f, + 0xf84af000 , 0x0001f04f , 0x00004770 , 0x200088a8, + 0x3f00e850 , 0x0301ea23 , 0x3200e840 , 0x0f00f092, + 0x4770d1f6 , 0x3f00e850 , 0x0301ea43 , 0x3200e840, + 0x0f00f092 , 0x4770d1f6 , 0xe7fdbf30 , 0x22184b02, + 0x3000fb02 , 0xbf004770 , 0x20008008 , 0x4770b672, + 0x4770b662 , 0x8005f3ef , 0x50c0ea4f , 0x00004770, + 0x68184b04 , 0x1ac04b04 , 0x10c04b04 , 0xb2c04358, + 0xbf004770 , 0x20009304 , 0x20008008 , 0xaaaaaaab, + 0xf7ffb508 , 0x3004ffdb , 0x0000bd08 , 0x6f984b01, + 0xbf004770 , 0x20008008 , 0x4770df00 , 0x46032800, + 0xf100bfb8 , 0x115a031f , 0x18d34b09 , 0x4b09009a, + 0x0303ea00 , 0xda052b00 , 0xea6f3b01 , 0xea6f63c3, + 0x330163d3 , 0xfa112101 , 0x6013f303 , 0xbf004770, + 0x38003840 , 0x8000001f , 0x60184b01 , 0xbf004770, + 0xe000ef00 , 0x4a33b538 , 0xf1a22100 , 0x4d320380, + 0x186c2001 , 0xc008f8b4 , 0xea4f6158 , 0x586d0c9c, + 0x0010f1ac , 0x0080eb02 , 0x60186864 , 0x6205611a, + 0x63844d2a , 0x7480f04f , 0x63c46345 , 0xe0024610, + 0xf8404c27 , 0x681c4c04 , 0x30044686 , 0xd3f745a6, + 0x3318310c , 0xd002293c , 0x028ceb02 , 0x4b21e7d7, + 0xf5034c21 , 0xf8c3620a , 0x4a1d28b0 , 0x28a0f8c3, + 0x1ae44b1e , 0x10644b1e , 0x32fff04f , 0xf8c3601a, + 0x4a1c2100 , 0x42933304 , 0xf7ffd1f6 , 0x4b17ff71, + 0xe01a2100 , 0x2c02f813 , 0x0c07f04f , 0x0003f002, + 0x300500c0 , 0xfc00fa0c , 0x02fcf002 , 0x4260f102, + 0x4264f502 , 0x31016815 , 0x0c0cea25 , 0x5c01f813, + 0xf000fa15 , 0x0000ea4c , 0x33026010 , 0xdbe142a1, + 0xbf00bd38 , 0x20008088 , 0x20006324 , 0x20000945, + 0xdeadd00d , 0x20008008 , 0x20005c74 , 0x20005c24, + 0xe000e180 , 0xe000e194 , 0x23014803 , 0xf5006783, + 0x3004600e , 0xbef7f7ff , 0x20008008 , 0x43f0e92d, + 0x2000b087 , 0xf001491c , 0x4d1cff67 , 0x24004e1c, + 0x40a22201 , 0x89314b1b , 0x68a8685b , 0xf855421a, + 0xbf14cc08 , 0x23202352 , 0xeb022200 , 0x1a8f0e00, + 0xd20645e6 , 0x8002f850 , 0xe054f8df , 0x45f03204, + 0x4a11d0f3 , 0xf8529105 , 0x20002024 , 0xf8559200, + 0x490e2c04 , 0x46229201 , 0xe8f53401 , 0x97048906, + 0x8902e9cd , 0xf001360c , 0xf001ff23 , 0x2c05ff1f, + 0xb007d1ce , 0x83f0e8bd , 0x200063b4 , 0x20008010, + 0x20006324 , 0x20009304 , 0x20006360 , 0x200063eb, + 0xdeadd00d , 0xf7ffb508 , 0x2000ffb1 , 0x0000bd08, + 0x41f3e92d , 0x4d234b22 , 0x4b23681e , 0x10ed1b75, + 0x4604435d , 0xb2ed460f , 0xfed4f7ff , 0x481fb130, + 0x4a20491f , 0x73a6f44f , 0xfe10f003 , 0xdd122c00, + 0xf0044668 , 0xe9ddfcc3 , 0x19000100 , 0x71e4eb41, + 0xf004462a , 0xb130fd77 , 0x49154817 , 0xf44f4a15, + 0xf00373a9 , 0xf106fdfb , 0xe0040804 , 0x20014639, + 0xfed2f7ff , 0x26004637 , 0x0600f04f , 0x2f00e858, + 0x6300e848 , 0x0f00f093 , 0x4616d1f8 , 0xd0ed2a00, + 0xdd022c00 , 0xf0044628 , 0x4630fe2b , 0x81fce8bd, + 0x20009304 , 0x20008008 , 0xaaaaaaab , 0x2000640f, + 0x20006374 , 0x20006427 , 0x2000643c , 0xf7ff2100, + 0x0000bfa7 , 0xf7ffb508 , 0x4b07fe8b , 0xeb034602, + 0x49060380 , 0x6bdb2016 , 0xff1af001 , 0x30fff04f, + 0xffecf7ff , 0xbf00e7fa , 0x20006324 , 0x2000644e, + 0x4605b570 , 0xfe74f7ff , 0x40842401 , 0xd1062cff, + 0x49114810 , 0xf2404a11 , 0xf00313d5 , 0x1d2efda7, + 0x46214630 , 0xfe46f7ff , 0xe8552302 , 0xf0922f00, + 0xbf080f00 , 0x3200e845 , 0xd1032a02 , 0xf7ff2000, + 0xe7f1ffc5 , 0xd1ef2a00 , 0x46214630 , 0x4070e8bd, + 0xbe26f7ff , 0x20006463 , 0x20006380 , 0x20006427, + 0x41f0e92d , 0x460e4604 , 0xf7ff4615 , 0x4607fe2f, + 0x4814b930 , 0x4a154914 , 0x1361f240 , 0xfd76f003, + 0x46311d38 , 0xfe16f7ff , 0xfe2cf7ff , 0x2501b158, + 0xfa15480f , 0xf7fff104 , 0x4b0efe0d , 0xf8c32000, + 0xe8bd58e4 , 0xb13581f0 , 0x30fff04f , 0xe8bd4621, + 0xf7ff41f0 , 0x4621bf35 , 0xfe36f7ff , 0xe8bd4628, + 0xbf0081f0 , 0x20006479 , 0x2000638c , 0x20006427, + 0x20009308 , 0x20008008 , 0x4b10b570 , 0x681e2400, + 0x681a1d03 , 0x46146004 , 0xfab4e00f , 0xf1c5f584, + 0xb2ed051f , 0xf04f4628 , 0x22004180 , 0xffb0f7ff, + 0xfa132301 , 0xea24f505 , 0x2c000405 , 0x1d30d1ed, + 0x4180f04f , 0x4070e8bd , 0xbdc2f7ff , 0x20009304, + 0x4606b570 , 0xb671460d , 0x8f6ff3bf , 0x681c4b24, + 0x681a6923 , 0x429a4b23 , 0x4b23d00d , 0x1ae34a23, + 0x435310db , 0x48234a22 , 0x0383eb02 , 0xf0036bd9, + 0xf003fcc9 , 0xb176fcff , 0xb9636863 , 0x491b4a1a, + 0x10d21aa2 , 0x2101434a , 0xf202fa11 , 0x68594b14, + 0x0202ea21 , 0x2301605a , 0xf505fa13 , 0x685a4b10, + 0x605d4315 , 0x4814b92d , 0x4a154914 , 0xf00323f2, + 0x4d0bfced , 0xfab06868 , 0xf1c0f080 , 0xb2c0001f, + 0xfd94f7ff , 0x22004b08 , 0x460142a0 , 0x28e4f8c3, + 0x6028d005 , 0xe8bd4620 , 0xf7ff4070 , 0xbd70bd39, + 0x20009304 , 0xdeadd00d , 0x20008008 , 0xaaaaaaab, + 0x20006324 , 0x20006482 , 0x200064a0 , 0x2000639c, + 0x20006427 , 0xf8d34b06 , 0xb13b38e4 , 0x000ff000, + 0xd0032801 , 0x46012000 , 0xbf92f7ff , 0xbf004770, + 0x20008008 , 0xf3efb510 , 0xf0008309 , 0x2c01040f, + 0x461abf14 , 0x6991460a , 0x6952480a , 0xfc62f003, + 0xd1032c01 , 0xf0034808 , 0xe005fc83 , 0xfd60f7ff, + 0x48064601 , 0xfc56f003 , 0xfb84f004 , 0x4010e8bd, + 0xbe1cf7ff , 0x200064e5 , 0x20006510 , 0x2000651b, + 0x681b4b02 , 0x0f08f013 , 0x4770d0fa , 0x40002804, + 0x681a4b04 , 0x0f20f012 , 0x681ad0fa , 0x0210f042, + 0x4770601a , 0x40002804 , 0x681a4b05 , 0x0210f022, + 0x4b03601a , 0xf013681b , 0xd0fa0f20 , 0xbf004770, + 0x40002804 , 0x4a14b538 , 0x25194b14 , 0x8814881b, + 0xf5f5fbb1 , 0xea44b2a4 , 0xf6494403 , 0xfb034340, + 0x19454000 , 0xffd4f7ff , 0x0c2a4b0d , 0x4a0d801a, + 0x8015b2ad , 0x682b4d0c , 0x0302f023 , 0x682b602b, + 0x0302f043 , 0xf7ff602b , 0x682bffcf , 0xf0234620, + 0x602b0308 , 0xbf00bd38 , 0x4000281c , 0x40002818, + 0x40002820 , 0x40002824 , 0x40002804 , 0xf7ffb508, + 0xf7ffffa7 , 0x4b09ffad , 0xf022681a , 0x601a0202, + 0xffb2f7ff , 0xf44f4b06 , 0x601a3200 , 0x88184b05, + 0x881b3304 , 0xea43b29b , 0xbd084000 , 0x40002804, + 0x40010414 , 0x40002818 , 0xbfe0f7ff , 0xb5014670, + 0xfffaf7ff , 0x4001e8bd , 0xbf4cf7ff , 0xbfd6f7ff, + 0xb5014670 , 0xfffaf7ff , 0x4001e8bd , 0xbf42f7ff, + 0x4603b508 , 0xb111b900 , 0xf7ff4618 , 0xb672ff93, + 0x681a4b08 , 0x7280f442 , 0x3b04601a , 0xf042681a, + 0x601a020e , 0x681a4b04 , 0x0204f042 , 0xbf30601a, + 0xbf00e7fe , 0x40007004 , 0xe000ed10 , 0x47704800, + 0x02dc6c00 , 0x4b24b510 , 0xf012681a , 0xd1080f02, + 0xf042681a , 0x601a0201 , 0x681b4b1f , 0x0f02f013, + 0x4b1ed0fa , 0x02d0f44f , 0x3b04601a , 0xf042681a, + 0x601a7280 , 0x681b4b18 , 0x7f00f013 , 0x4a18d0fa, + 0x601a4b16 , 0x681b4b15 , 0x030cf003 , 0xd1f92b08, + 0xff2ef7ff , 0xff34f7ff , 0x23004a12 , 0x32046013, + 0xf7ff8013 , 0x4b10ff39 , 0x681a2003 , 0x3200f442, + 0x3308601a , 0xf442681a , 0x601a3200 , 0x681a4b0b, + 0x0203f022 , 0x0201f042 , 0xf7ff601a , 0x2029fc7f, + 0x4010e8bd , 0xbc7af7ff , 0x40021000 , 0x40021004, + 0x00680002 , 0x40002808 , 0x40010400 , 0x40007000, + 0x43432314 , 0x18184801 , 0xbf004770 , 0x40020008, + 0x6804b510 , 0x0f01f014 , 0x6804d003 , 0x0401f024, + 0x60826004 , 0xf44f60c3 , 0x60415340 , 0x9b026003, + 0x5340f443 , 0xbd106003 , 0x8f4ff3bf , 0xf0436803, + 0x60030301 , 0x00004770 , 0x4613b513 , 0x46047802, + 0x43422014 , 0xf04068a0 , 0x90000090 , 0x18104802, + 0xf7ff6862 , 0xbd1cffd5 , 0x40020008 , 0x681a4b06, + 0x0201f042 , 0x2300601a , 0xf04f4a04 , 0x54d131ff, + 0x2b073301 , 0x4770d1f8 , 0x40021014 , 0x200088f0, + 0x0080210f , 0xf000fa11 , 0x685a4b02 , 0x0202ea40, + 0x4770605a , 0x40020000 , 0xb5014670 , 0xf89af000, + 0x4001e8bd , 0xbe6ef7ff , 0xb5014670 , 0xf882f000, + 0x4001e8bd , 0xbe66f7ff , 0xb5014670 , 0xf86af000, + 0x4001e8bd , 0xbe5ef7ff , 0xb5014670 , 0xf852f000, + 0x4001e8bd , 0xbe56f7ff , 0xb5014670 , 0xf83af000, + 0x4001e8bd , 0xbe4ef7ff , 0xb5014670 , 0xf822f000, + 0x4001e8bd , 0xbe46f7ff , 0xb5014670 , 0xf80af000, + 0x4001e8bd , 0xbe3ef7ff , 0x5100f04f , 0xf7ff2200, + 0x0000bd77 , 0x2006b510 , 0xffb2f7ff , 0x79984b04, + 0xd00328ff , 0x4010e8bd , 0xbfeef7ff , 0xbf00bd10, + 0x200088f0 , 0x2005b510 , 0xffa2f7ff , 0x79584b04, + 0xd00328ff , 0x4010e8bd , 0xbfdef7ff , 0xbf00bd10, + 0x200088f0 , 0x2004b510 , 0xff92f7ff , 0x79184b04, + 0xd00328ff , 0x4010e8bd , 0xbfcef7ff , 0xbf00bd10, + 0x200088f0 , 0x2003b510 , 0xff82f7ff , 0x78d84b04, + 0xd00328ff , 0x4010e8bd , 0xbfbef7ff , 0xbf00bd10, + 0x200088f0 , 0x2002b510 , 0xff72f7ff , 0x78984b04, + 0xd00328ff , 0x4010e8bd , 0xbfaef7ff , 0xbf00bd10, + 0x200088f0 , 0x2001b510 , 0xff62f7ff , 0x78584b04, + 0xd00328ff , 0x4010e8bd , 0xbf9ef7ff , 0xbf00bd10, + 0x200088f0 , 0x2000b510 , 0xff52f7ff , 0x78184b04, + 0xd00328ff , 0x4010e8bd , 0xbf8ef7ff , 0xbf00bd10, + 0x200088f0 , 0x22804b01 , 0x4770601a , 0x40022010, + 0x5000f100 , 0x6000f5a0 , 0x47707800 , 0x4604b510, + 0xf7ff2001 , 0x4b12f927 , 0xf013681b , 0xd0040f80, + 0x4a114b10 , 0x4a11601a , 0xf414601a , 0xd0097f00, + 0x681b4b0b , 0x7f00f413 , 0x4b0dd104 , 0x601a4a0a, + 0x601a4a0a , 0xf7ff2000 , 0x4b05f90d , 0x0480f044, + 0xf483681b , 0x421c7300 , 0x2000bf0c , 0xbd102001, + 0x40022010 , 0x40022004 , 0x45670123 , 0xcdef89ab, + 0x40022008 , 0xf44fb510 , 0xe0023496 , 0xf004200a, + 0x4b06f997 , 0xf0106818 , 0xd0020001 , 0xd2f53c01, + 0x2c00e001 , 0x2004dc00 , 0xbf00bd10 , 0x4002200c, + 0x41f3e92d , 0x460f4606 , 0xffe4f7ff , 0x28004604, + 0xf106d164 , 0xf5a55500 , 0x782b6500 , 0xd05d42bb, + 0xf64f882a , 0x429a73ff , 0x4680d03c , 0x0048ea4f, + 0xff96f7ff , 0x0008f80d , 0x0801f108 , 0x0f08f1b8, + 0xab02d1f4 , 0x76d6eb06 , 0x0666eb03 , 0x33fff04f, + 0x3c08f806 , 0xffbef7ff , 0x28004680 , 0xf44fd141, + 0xf7ff7000 , 0x4680ff83 , 0xd13a2800 , 0x681a4b1e, + 0x0220f042 , 0x681a601a , 0x0240f042 , 0xf7ff601a, + 0x4680ffa9 , 0xd12c2800 , 0xff64f7ff , 0x00704646, + 0x1006f81d , 0xffb4f7ff , 0x28004680 , 0x3601d121, + 0xd1f42e08 , 0xd0192fff , 0x7000f44f , 0xff5ef7ff, + 0xb9984604 , 0x681a4b0c , 0x0210f042 , 0x43fa601a, + 0x2702ea47 , 0x802fb2bf , 0xf022681a , 0x601a0210, + 0xff80f7ff , 0xb9084604 , 0xff3cf7ff , 0xe8bd4620, + 0x464481fc , 0xbf00e7fa , 0x40022010 , 0xb088b570, + 0x46062500 , 0x46202408 , 0xff32f7ff , 0xab043402, + 0x0005f84d , 0x35045158 , 0xd1f42c10 , 0x2b0f2300, + 0x2102bfcc , 0x085a2101 , 0xf00242b1 , 0xf003020c, + 0xa8080107 , 0x1812d808 , 0xfa102001 , 0xf852f101, + 0xea200c20 , 0xe0070101 , 0x20011812 , 0xf101fa10, + 0x0c20f852 , 0x0101ea40 , 0x2b203301 , 0x1c20f842, + 0x2508d1dd , 0xab042400 , 0x1004f85d , 0x428b591b, + 0x4628d003 , 0xf7ffb2c9 , 0x3404ff4b , 0x2c103502, + 0x2000d1f1 , 0xbd70b008 , 0x4604b5f8 , 0x460d2000, + 0xf7ff4616 , 0x4607fef3 , 0xd1392800 , 0x22344b21, + 0x3304601a , 0xf042681a , 0x601a0201 , 0xf000e02c, + 0x2300fe81 , 0x3301e000 , 0x68124a1a , 0x0f01f012, + 0xf5b3d002 , 0xd1f63f96 , 0x785119f2 , 0xf1045df2, + 0xeb026300 , 0x53da2201 , 0xe0002300 , 0x4a113301, + 0xf0126812 , 0xd0020f01 , 0x3f96f5b3 , 0x4b0dd1f6, + 0xf012681a , 0xd0010f01 , 0xe00a2404 , 0x3702681b, + 0x0f14f013 , 0x3d02d104 , 0xdcd02d00 , 0xe0002400, + 0x4b052401 , 0xf022681a , 0x601a0201 , 0xfea2f7ff, + 0xbdf84620 , 0x4002200c , 0x40022010 , 0x4604b5f7, + 0x460d2000 , 0xfea2f7ff , 0x2401b108 , 0x4b2be053, + 0x601a2234 , 0x681a3304 , 0x0202f042 , 0xe040601a, + 0xf44f4620 , 0xf0016180 , 0x2800faae , 0x4b24d135, + 0x6200f104 , 0x3b04601a , 0xf042681a , 0x601a0240, + 0xfe20f000 , 0xf0034668 , 0xe9ddffb9 , 0xf44f6700, + 0x2300527a , 0xeb4718b6 , 0xe0030703 , 0x7096f44f, + 0xf8a0f004 , 0x681b4b15 , 0x0f01f013 , 0x4668d008, + 0xffa4f003 , 0x2300e9dd , 0xeb7342b2 , 0xd3ed0107, + 0x681a4b0e , 0x0f01f012 , 0x2404d001 , 0x681be00c, + 0x0f14f013 , 0x2401d001 , 0xf5a5e006 , 0xf5046580, + 0x2d006480 , 0x2400dcbc , 0x681a4b06 , 0x0202f022, + 0xf7ff601a , 0x4620fe3f , 0xbf00bdfe , 0x4002200c, + 0x40022014 , 0x40022010 , 0x681b4b07 , 0x2001b10b, + 0x22014770 , 0xf000fa12 , 0x681b4b04 , 0xbf144218, + 0x20012000 , 0xbf004770 , 0x200088f8 , 0x40022020, + 0x68184b03 , 0xbf142800 , 0x20002004 , 0xbf004770, + 0x200088f8 , 0x47702007 , 0xf0830843 , 0xf0000301, + 0xf003000c , 0x28080301 , 0xf043bf08 , 0x46180304, + 0x00004770 , 0x4b06b507 , 0x681a2101 , 0xf843ab02, + 0xf2452d04 , 0x22047050 , 0xfd1cf003 , 0xbf00bd0e, + 0x200088f8 , 0xb908b508 , 0xbd083005 , 0xf7fe2001, + 0x4b06ff29 , 0x32fff04f , 0x2000601a , 0xff22f7fe, + 0x22014b03 , 0x2000601a , 0xbf00bd08 , 0x40022004, + 0x200088f8 , 0x46704770 , 0xf000b501 , 0xe8bdf8d7, + 0xf7ff4001 , 0x4670bb9f , 0xf000b501 , 0xe8bdf8cf, + 0xf7ff4001 , 0x4670bb97 , 0xf000b501 , 0xe8bdf8c7, + 0xf7ff4001 , 0x4670bb8f , 0xf000b501 , 0xe8bdf8bf, + 0xf7ff4001 , 0x4670bb87 , 0xf000b501 , 0xe8bdf8b7, + 0xf7ff4001 , 0x4670bb7f , 0xf000b501 , 0xe8bdf8af, + 0xf7ff4001 , 0x4670bb77 , 0xf000b501 , 0xe8bdf8a7, + 0xf7ff4001 , 0xb510bb6f , 0xf7ff2006 , 0x2007f90f, + 0xf90cf7ff , 0xf7ff2008 , 0x2009f909 , 0xf906f7ff, + 0xf7ff200a , 0x2017f903 , 0xf900f7ff , 0xe8bd2028, + 0xf7ff4010 , 0x0000b8fb , 0xf011b570 , 0x460d0fff, + 0xd0024614 , 0x4601468c , 0x1d01e002 , 0x2c15ea4f, + 0xfc0cfb0c , 0xfc0cfb0c , 0x0c4cea4c , 0x028cea4f, + 0xea42680b , 0xea23060c , 0xf0140306 , 0xd0070620, + 0x3c11f00c , 0x0f01f014 , 0x030cea43 , 0xe013d017, + 0x0f08f014 , 0xf014d113 , 0xd0040f02 , 0x3288f002, + 0x61054313 , 0xf014e00b , 0xd0050f04 , 0x3288f002, + 0x042a4313 , 0xe0026102 , 0x3244f002 , 0x600b4313, + 0xf014b14e , 0xd0010f80 , 0xe0046105 , 0x0f40f014, + 0x042bd001 , 0xf4146103 , 0xd0055fc0 , 0x490b480a, + 0x235d4a0b , 0xffcaf002 , 0x7f80f414 , 0x4b09d004, + 0xea45681a , 0x601a0202 , 0x7f00f414 , 0x4b06d003, + 0x4315681a , 0xbd70601d , 0x20006544 , 0x2000652c, + 0x20006572 , 0x40010408 , 0x4001040c , 0x22144b06, + 0x3300fb02 , 0x689b685a , 0xb2928912 , 0xbf0c421a, + 0x20012000 , 0xbf004770 , 0x200065fc , 0x22144b06, + 0x3300fb02 , 0x689b685a , 0xbf0c2900 , 0x21002110, + 0x6113408b , 0xbf004770 , 0x200065fc , 0x4b0db507, + 0xb292681a , 0x601a9201 , 0xa801e00f , 0xfb1ef004, + 0xf8534b09 , 0xb1422020 , 0xb1336913 , 0x1a124807, + 0x10924807 , 0xb2c04350 , 0x9b014798 , 0xd1ec2b00, + 0xbf00bd0e , 0x40010414 , 0x200088fc , 0x200065fc, + 0xcccccccd , 0x2314b573 , 0x4e1e4343 , 0x68a518f4, + 0xd0352d00 , 0x2a006922 , 0xfab5d032 , 0x4a1af585, + 0x051ff1c5 , 0x2025f852 , 0x42a2b142 , 0x9500d006, + 0x49162007 , 0x58f36812 , 0xf8aaf001 , 0xf0254b12, + 0xf8430203 , 0x4b124025 , 0x0503f005 , 0x686218d3, + 0xf10200ad , 0x210f4240 , 0x3284f5a2 , 0x0a9240a9, + 0xf505fa12 , 0xea206818 , 0xea410101 , 0x601d0505, + 0x68a24b08 , 0x20006819 , 0x0202ea41 , 0xe000601a, + 0xbd7c2005 , 0x200065fc , 0x200088fc , 0x2000658b, + 0x40010008 , 0x40010400 , 0x0c024b1c , 0x4b1c6018, + 0xb29b881b , 0xd915429a , 0xb2914b1a , 0x491a8019, + 0xf023880b , 0x041b0302 , 0x800b0c1b , 0xf64f4b17, + 0x801971fd , 0x80194b16 , 0x88194b16 , 0xf041b289, + 0x80190102 , 0x881b4b0e , 0x429ab29b , 0x4b12d115, + 0xb2804a10 , 0x88138018 , 0x0302f023 , 0x0c1b041b, + 0x4b0a8013 , 0x72fdf64f , 0x4b09801a , 0x3b04801a, + 0xb292881a , 0x0202f042 , 0x4770801a , 0x2000893c, + 0x40000424 , 0x40000434 , 0x4000080c , 0x40000410, + 0x40000810 , 0x4000040c , 0x40000834 , 0x68184b01, + 0xbf004770 , 0x2000893c , 0xf64f4b05 , 0x881972fd, + 0x0101ea02 , 0x4b038019 , 0x400a8819 , 0x4770801a, + 0x4000080c , 0x4000040c , 0x49064a05 , 0x88098813, + 0xb2898812 , 0xb298429a , 0xea41d1f6 , 0x47704000, + 0x40000424 , 0x40000824 , 0x0c024b03 , 0x4b03801a, + 0x8018b280 , 0xbf004770 , 0x40000424 , 0x40000824, + 0xb5014670 , 0xf8ccf000 , 0x4001e8bd , 0xb9daf7ff, + 0xb5014670 , 0xf8c4f000 , 0x4001e8bd , 0xb9d2f7ff, + 0xbf0c2801 , 0x6200f44f , 0x38022200 , 0xd9012805, + 0xe0024b08 , 0x40822201 , 0xb14a4b07 , 0x6819b121, + 0x0202ea41 , 0x4770601a , 0xea216819 , 0x601a0202, + 0xbf004770 , 0x40021018 , 0x4002101c , 0x46694670, + 0xf000b501 , 0xe8bdf895 , 0xf7ff4001 , 0x0000b9ab, + 0x6ada4b01 , 0x4770625a , 0x40012c00 , 0x4b07b508, + 0x0200f04f , 0xf7ff801a , 0x4b05fa79 , 0xfb904a05, + 0x3b01f3f3 , 0x8013b29b , 0xbf00bd08 , 0x40000428, + 0x000f4240 , 0x40000828 , 0x2001b510 , 0xf7ff4601, + 0x4b09ffb7 , 0x609a2237 , 0x625a3a27 , 0x3a1062da, + 0x615a629a , 0x60da3201 , 0x32942019 , 0xe8bd601a, + 0xf7fe4010 , 0xbf00bf1b , 0x40012c00 , 0x2101b5f8, + 0x20034604 , 0xff9cf7ff , 0x21014e1d , 0x4d1d2004, + 0xff96f7ff , 0x80332304 , 0x4b1b802b , 0x801f2700, + 0xf04f4b1a , 0x801a0220 , 0xf04f4b19 , 0x801a0237, + 0x4a194b18 , 0xf64f801f , 0x801373ff , 0x80134a17, + 0xffacf7ff , 0x23014a16 , 0x4a168013 , 0x80134620, + 0x80134a15 , 0x801f4b15 , 0xb29b8833 , 0x0301f043, + 0x882b8033 , 0xf043b29b , 0x802b0301 , 0xff4cf7ff, + 0xf7fe201d , 0x201efedb , 0xfed8f7fe , 0xbdf8201e, + 0x40000400 , 0x40000800 , 0x40000404 , 0x40000804, + 0x40000408 , 0x40000808 , 0x4000042c , 0x4000082c, + 0x40000414 , 0x40000814 , 0x4000040c , 0x4000080c, + 0x22004b02 , 0xf7ff611a , 0xbf00b925 , 0x40012c00, + 0x49054b04 , 0x22008818 , 0x0001f000 , 0x801a800a, + 0xbdaef003 , 0x40000410 , 0x40000810 , 0x4b17b538, + 0x24002512 , 0x116cf8d3 , 0x42914a15 , 0xf110d11e, + 0xd1040f02 , 0x2170f8d3 , 0x4402ea44 , 0xf1b0e016, + 0xd1033fff , 0x2170f8d3 , 0xe00f4314 , 0x0212f1a5, + 0xd10b4282 , 0x30fff04f , 0xffe0f7ff , 0x22144b07, + 0x3505fb02 , 0xea4468ab , 0xe0034403 , 0x33143501, + 0xd1d72d1f , 0x4b03b10c , 0xbd38601c , 0x200065fc, + 0x40011000 , 0x40011010 , 0x2300b530 , 0x4618490c, + 0x461a469c , 0x684d680c , 0xbf1c4564 , 0xb29b8923, + 0xd005422b , 0x0c01f04f , 0xfc02fa0c , 0x000cea40, + 0x31143201 , 0x46a42a08 , 0xf080d1ec , 0xbd3000ff, + 0x20006600 , 0xb1584b0a , 0x681a490a , 0xea426808, + 0x600b0300 , 0x68194b08 , 0x0202ea41 , 0x4770601a, + 0x681b4a05 , 0xea216811 , 0x60130303 , 0xbf004770, + 0x20008940 , 0x40010414 , 0x40010400 , 0x681a4b07, + 0xf1034b07 , 0x689801a0 , 0x43023314 , 0xd1fa428b, + 0x20004b02 , 0xf7ff601a , 0xbf00bfd5 , 0x20008940, + 0x200065fc , 0x2000b510 , 0xfdd4f7ff , 0xf7ff2001, + 0x2002fdd1 , 0xfdcef7ff , 0xf7ff2003 , 0x2004fdcb, + 0xfdc8f7ff , 0xf7ff2005 , 0x2006fdc5 , 0xfdc2f7ff, + 0xe8bd2007 , 0xf7ff4010 , 0x2004bdbd , 0x5100f04f, + 0xf7fe2200 , 0x0000bf9d , 0xd9012829 , 0x47702000, + 0x4b054a04 , 0xbf98280a , 0xf8334613 , 0xb2800020, + 0xbf004770 , 0x40006c04 , 0x40006c40 , 0xd9012829, + 0x47702005 , 0x4b054a04 , 0xbf98280a , 0xf8234613, + 0x20001020 , 0xbf004770 , 0x40006c04 , 0x40006c40, + 0x47704800 , 0x200065ab , 0x47704800 , 0x2000775f, + 0x2502b570 , 0xf1004604 , 0x46280610 , 0xffccf7ff, + 0x0a007020 , 0x34027060 , 0x42b43501 , 0xd1f4b2ed, + 0xbd702000 , 0x2502b570 , 0xf1004604 , 0x78610610, + 0x3b02f814 , 0xea434628 , 0xf7ff2101 , 0x4603ffc7, + 0x3501b918 , 0xb2ed42b4 , 0x4618d1f1 , 0xb508bd70, + 0xf7ff2001 , 0xb200ffa9 , 0xbd080fc0 , 0xf7ffb508, + 0x4b03fff6 , 0x28004a03 , 0x4610bf14 , 0xbd084618, + 0x200065af , 0x200065b9 , 0x4604b538 , 0xf7ff2001, + 0x4605ff93 , 0xfd6af7fe , 0x0002f014 , 0xf002d003, + 0xf440fed9 , 0xf0145000 , 0xbf180f04 , 0x5080f440, + 0x0401f014 , 0xf440bf18 , 0xf4056000 , 0xea404500, + 0xb2890105 , 0xf7ff2001 , 0xb154ff89 , 0xf2454b07, + 0x601a5255 , 0x21014a06 , 0xf64c6011 , 0x601a42cc, + 0x4a04e7fe , 0x601a4b04 , 0xbf00e7fe , 0x40003000, + 0x40003008 , 0x05fa0004 , 0xe000ed0c , 0x41f0e92d, + 0x681a4b39 , 0x5280f042 , 0x681a601a , 0x6200f042, + 0x4b36601a , 0xf442681a , 0x601a7280 , 0x681a4b34, + 0x0201f042 , 0x4b32601a , 0xf013681b , 0xd0fa0f02, + 0x4a314b30 , 0xea016819 , 0xf5b20202 , 0xd00b4f02, + 0xf442681a , 0x601a3280 , 0xf422681a , 0xf42232c0, + 0xf4427240 , 0x601a4202 , 0xf7ff2001 , 0x4b24ff2d, + 0x681d4a26 , 0x681a6817 , 0xf0424606 , 0x601a7280, + 0xf4204b1e , 0x681a4400 , 0xf0422001 , 0x601a0208, + 0x4100f406 , 0xff2af7ff , 0x4fc0f015 , 0xf416d004, + 0xbf086f00 , 0x0410f044 , 0x5f80f015 , 0xf044bf18, + 0xf0150420 , 0xbf186f00 , 0x0408f044 , 0x6f80f015, + 0xf044bf18 , 0xf0170402 , 0xbf180f02 , 0x0440f044, + 0xf015b924 , 0xbf0c4f7e , 0x24012400 , 0x0350f004, + 0xd1032b50 , 0x46012000 , 0xf80af7ff , 0xe8bd4620, + 0xf00241f0 , 0xbf00be3d , 0x4002101c , 0x40007000, + 0x40021024 , 0x40021020 , 0x00018300 , 0x40007004, + 0x4605b570 , 0xf000460c , 0x4628fcd9 , 0xe8bd4621, + 0xf7fe4070 , 0x0000bfed , 0x68184b01 , 0xbf004770, + 0x20008944 , 0x881b4b02 , 0x0f80f013 , 0x4770d0fa, + 0x40013800 , 0x88184b02 , 0x0080f000 , 0xbf004770, + 0x40013800 , 0x88184b02 , 0x0040f000 , 0xbf004770, + 0x40013800 , 0x88184b02 , 0x0020f000 , 0xbf004770, + 0x40013800 , 0x4604b510 , 0xffe4f7ff , 0xd0fb2800, + 0x801c4b01 , 0xbf00bd10 , 0x40013804 , 0x88184b01, + 0x4770b280 , 0x40013804 , 0xb5014670 , 0xf842f000, + 0x4001e8bd , 0xbeeef7fe , 0xf7feb508 , 0xf44fffc7, + 0xf5005316 , 0xfb925296 , 0x4b02f2f3 , 0x801ab292, + 0xbf00bd08 , 0x40013808 , 0x4b12b508 , 0x681a201d, + 0xf4422101 , 0x601a4280 , 0xf9e8f001 , 0xf2424b0e, + 0x4a0e010c , 0xf04f8019 , 0x80110100 , 0x88113204, + 0xf041b289 , 0x80110180 , 0xb292881a , 0x0220f042, + 0xf7ff801a , 0x2025ffd1 , 0xfc60f7fe , 0x22014b04, + 0xbd08601a , 0x40021018 , 0x4001380c , 0x40013810, + 0x20008944 , 0x4b09b510 , 0xf013881b , 0xd0060f40, + 0x88134a07 , 0x0340f023 , 0x0c1b041b , 0xf0038013, + 0xe8bdfc95 , 0xf0034010 , 0xbf00bcc5 , 0x40013800, + 0x4001380c , 0x4602b510 , 0xf7fe480b , 0x4a0bffed, + 0x88132003 , 0x0340f023 , 0x0c1b041b , 0x4b088013, + 0xb292881a , 0x0240f042 , 0xf7fe801a , 0xe8bdffb9, + 0xf7fe4010 , 0xbf00bfd1 , 0x200065f0 , 0x40013800, + 0x4001380c , 0x88134a0a , 0x0340f023 , 0x0c1b041b, + 0x4b088013 , 0x605a2201 , 0x4b071892 , 0x0f00e853, + 0x0002ea20 , 0x0100e843 , 0x0f00f091 , 0x4770d1f6, + 0x4001380c , 0x20008944 , 0x20009020 , 0x4b0eb510, + 0xf012881a , 0xd1160040 , 0x4a0c2102 , 0x4f00e852, + 0x0401ea44 , 0x4c00e842 , 0x0f00f09c , 0x4908d1f6, + 0x881a6048 , 0xb2922025 , 0x0240f042 , 0xe8bd801a, + 0xf7fe4010 , 0xbd10bc01 , 0x4001380c , 0x20009020, + 0x20008944 , 0x4b09b508 , 0x5255f245 , 0x4a08601a, + 0x60112106 , 0x71aef44f , 0x60113204 , 0x42ccf64c, + 0xf7ff601a , 0x2000fc99 , 0xbf00bd08 , 0x40003000, + 0x40003004 , 0xf64a4b02 , 0x601a22aa , 0xbc70f7ff, + 0x40003000 , 0x2400b510 , 0x681a4b0f , 0x18a24b0f, + 0x0303ea02 , 0xda052b00 , 0xea6f3b01 , 0xea6f7343, + 0x33017353 , 0x434b2150 , 0x18994a07 , 0xb1297909, + 0x20003204 , 0x18d24906 , 0xfba2f000 , 0x2c083401, + 0x2000d1e2 , 0xbf00bd10 , 0x2000894c , 0x80000007, + 0x20007789 , 0x4c06b510 , 0x2284f8d4 , 0x2000b132, + 0xf0004904 , 0x2300fb8d , 0x3284f8c4 , 0xbf00bd10, + 0x2000894c , 0x20006a7c , 0x4c08b510 , 0x2284f8d4, + 0x3288f8d4 , 0xd008429a , 0x49052000 , 0xfb8cf000, + 0x3284f8d4 , 0xf8c43301 , 0xbd103284 , 0x2000894c, + 0x20006a82 , 0x41f0e92d , 0xf0034680 , 0x2500fc35, + 0x4c0b4606 , 0x6827e00d , 0x46394640 , 0xf0034632, + 0xb928fc70 , 0x4604b10d , 0x5dbbe007 , 0x4625b12b, + 0x4b043410 , 0xd3ee429c , 0x4620462c , 0x81f0e8bd, + 0x20005c74 , 0x20005e14 , 0x41f0e92d , 0x460e2802, + 0x684cd143 , 0x4620493d , 0xfc3bf003 , 0xb9d04605, + 0x4e3c4c3b , 0x1b36493c , 0xfb4ef000 , 0xe00a1136, + 0xf854493a , 0xf8542c10 , 0x20003c04 , 0xfb30f000, + 0xfb2cf000 , 0x34103501 , 0xdbf142b5 , 0x49342000, + 0xfb3af000 , 0x4620e01e , 0xffb4f7ff , 0xb9304604, + 0x68724930 , 0xfb1cf000 , 0xe8bd2001 , 0x688381f0, + 0x20004d2d , 0x492d6822 , 0xbf084283 , 0xf000462b, + 0x68e2fb0f , 0x4610b912 , 0x81f0e8bd , 0x49282000, + 0xfb06f000 , 0xe8bd2000 , 0x200081f0 , 0xf000491e, + 0x4b1bfb13 , 0x24004a1b , 0x0802ebc3 , 0x1828ea4f, + 0x0704f108 , 0xfb972305 , 0xe019f7f3 , 0x491d2000, + 0xfb02f000 , 0x26004625 , 0xda0a4545 , 0x012a4b10, + 0x49192000 , 0x360158d2 , 0xfae2f000 , 0x2e0519ed, + 0x4916d1f2 , 0xf0002000 , 0xf000faef , 0x3401fad7, + 0xdbe342bc , 0x49122000 , 0xfae6f000 , 0x49082000, + 0xfae2f000 , 0xe8bd2000 , 0xbf0081f0 , 0x20006a87, + 0x20005c74 , 0x20005e14 , 0x20006a8c , 0x20006a9d, + 0x20006aa8 , 0x20006ac1 , 0x2000775f , 0x20006ae7, + 0x20007789 , 0x20006ef4 , 0x20006af5 , 0x2000775e, + 0x20006afb , 0x22504904 , 0x1d0b6808 , 0x3000fb02, + 0x7123f501 , 0xbcf2f003 , 0x2000894c , 0xbac6f003, + 0x4604b538 , 0xe003460d , 0xf7ff4620 , 0x3d01fff7, + 0xd1f92d00 , 0x0000bd38 , 0x4c16b510 , 0x1d212250, + 0x1100fb02 , 0x7023f504 , 0xfcd8f003 , 0xfef2f7ff, + 0x7123f504 , 0xf0002000 , 0xf504fa97 , 0xf0037023, + 0xf8d4fb4b , 0x46031288 , 0xf8c44281 , 0xdd0b0284, + 0x20201ac9 , 0xffd4f7ff , 0x1288f8d4 , 0x3284f8d4, + 0x1ac92008 , 0xffccf7ff , 0xf8d34b02 , 0xf8c32284, + 0xbd102288 , 0x2000894c , 0xf04f2003 , 0x22005100, + 0xbbf6f7fe , 0xb08bb5f0 , 0x24004b9c , 0x428cf883, + 0x499b4620 , 0xfa54f000 , 0x499a4620 , 0xfa64f000, + 0xf9e8f003 , 0x3ffff1b0 , 0xf0004604 , 0x280d8226, + 0x4b92d105 , 0xf8c32201 , 0x1ec422dc , 0x280ae013, + 0x4b8ed107 , 0x22dcf8d3 , 0x2200b11a , 0x22dcf8c3, + 0x4b8ae7e6 , 0x2c1b2200 , 0x22dcf8c3 , 0x3201d103, + 0x22e0f883 , 0x4b85e7dc , 0x32e0f893 , 0xd03b2b00, + 0x2b053b01 , 0xe8dfd829 , 0x2803f003 , 0x1d25210b, + 0xd1012c5b , 0xe0292203 , 0xd11e2c4f , 0xe0252206, + 0xd1012c31 , 0xe0212204 , 0xd1012c33 , 0xe01d2205, + 0xd0052c41 , 0xd0032c42 , 0xd0012c43 , 0xd10c2c44, + 0xe1e734bf , 0xd1082c46 , 0xe1e334be , 0xd1042c7e, + 0xe1df3487 , 0xf0002c7e , 0x462081db , 0xfad9f003, + 0x2c7eb908 , 0x2200d101 , 0x2202e000 , 0xf04f4b67, + 0xf88334ff , 0xe18722e0 , 0xf0002c0e , 0xdc1b816c, + 0xf0002c06 , 0xdc098123 , 0xf0002c02 , 0x2c0580ff, + 0x810cf000 , 0xf0402c01 , 0xe0f48177 , 0xd0722c0a, + 0x2c08dc03 , 0x8170f040 , 0x2c0be035 , 0x8111f000, + 0xf0402c0c , 0xe1298169 , 0x7f81f5b4 , 0x8106f000, + 0x2c7fdc10 , 0xdc03d027 , 0xf0402c10 , 0xe130815d, + 0x7f80f5b4 , 0x812df000 , 0x1301f240 , 0xf040429c, + 0xe1388153 , 0x7f82f5b4 , 0x80e0f000 , 0x80cef2c0, + 0x1305f240 , 0xf000429c , 0xf5b480c6 , 0xf0407f83, + 0x4b428143 , 0x2284f8d3 , 0x3288f8d3 , 0xf43f429a, + 0xf7ffaf4f , 0x4c3dfe19 , 0x3284f8d4 , 0xf43f2b00, + 0x2008af47 , 0xfef2f7ff , 0x1284f8d4 , 0x3288f8d4, + 0xd0114299 , 0x7523f504 , 0x20001869 , 0xf99cf000, + 0x3284f8d4 , 0x2288f8d4 , 0x32011e58 , 0x18e91828, + 0xf0031ad2 , 0xe003fb96 , 0x2300190c , 0x328bf884, + 0x20204c2a , 0xfed2f7ff , 0x1288f8d4 , 0x3284f8d4, + 0x1ac93101 , 0xf7ff2008 , 0xf8d4fecb , 0x3b013288, + 0x3288f8c4 , 0x4620e08c , 0xf7ff4c20 , 0xf8d4febf, + 0xb1933288 , 0xfeaef7ff , 0x4b1f6822 , 0xea023201, + 0x2b000303 , 0x3b01da05 , 0x7343ea6f , 0x7353ea6f, + 0x4a163301 , 0xf8c26013 , 0x250032e4 , 0x462e4c17, + 0x46387827 , 0xfa18f003 , 0xb927b900 , 0x2300b176, + 0x35017023 , 0x2f23e00a , 0x2e00d00c , 0x811ff040, + 0xdc092d09 , 0xf843466b , 0xe1184025 , 0x2600b117, + 0xe7e53401 , 0xd03d2d00 , 0xf7ff9800 , 0x4604fdbb, + 0x4907b980 , 0xf0009a00 , 0xe033f923 , 0x2000894c, + 0x20006b13 , 0x20006b91 , 0x80000007 , 0x20008bd8, + 0x20006ac1 , 0x46696843 , 0x47984628 , 0xb3084602, + 0xd8052809 , 0x20004b7b , 0xf853497b , 0xe0102022, + 0x030bf1a0 , 0xd8032b08 , 0x49782000 , 0xe0083a0a, + 0xd1042814 , 0x49762000 , 0xf90ef000 , 0x4975e003, + 0xf0002000 , 0x68a3f8f5 , 0x2000b123 , 0x68224972, + 0xf8eef000 , 0x20004b71 , 0x0288f8c3 , 0x0284f8c3, + 0x028cf883 , 0xf7ffe691 , 0xe691fd4d , 0xf8d44c6b, + 0x2b003284 , 0xae8cf43f , 0x49692000 , 0xf8ecf000, + 0x3284f8d4 , 0xf8c43b01 , 0xe6813284 , 0xf8d44c63, + 0xf8d43284 , 0x42932288 , 0xae7af43f , 0x20001ad2, + 0xf0004960 , 0xf8d4f8c5 , 0xe7ec3288 , 0xfd3cf7ff, + 0x4c5ae66e , 0x3284f8d4 , 0x1288f8d4 , 0xf43f428b, + 0x1ac9ae67 , 0xf7ff2020 , 0xf8d4fe13 , 0xf8d43284, + 0x20081288 , 0xf7ff1ac9 , 0xf8d4fe0b , 0xf8c43284, + 0x191c3288 , 0xf8842300 , 0xe651328c , 0x20004c4b, + 0xf000494d , 0xf504f8b1 , 0x20007123 , 0xf8acf000, + 0x1288f8d4 , 0x3284f8d4 , 0x1ac92008 , 0xfdf0f7ff, + 0x4b42e63e , 0x22e4f8d3 , 0x429a681b , 0xf7ffd101, + 0x4b3efdd9 , 0x22e4f8d3 , 0x2a003a01 , 0x22e4f8c3, + 0x2207da14 , 0x4b39e010 , 0x22e4f8d3 , 0x429a681b, + 0xf7ffd101 , 0x4b35fdc7 , 0x22e4f8d3 , 0x2a073201, + 0x22e4f8c3 , 0x2200dd02 , 0x22e4f8c3 , 0xf8d34b2f, + 0xf7ff02e4 , 0xe613fdd1 , 0xf0034620 , 0x2800f94e, + 0xae0ef43f , 0xf8d54d29 , 0x2b4e3288 , 0xae08f63f, + 0xf7ff4620 , 0xf8d5fdb3 , 0xf8d51284 , 0x42993288, + 0xf505d018 , 0x18717623 , 0xf0002000 , 0xf8d5f85d, + 0xf8d53284 , 0x1c582288 , 0x18f13201 , 0x18301ad2, + 0xfa57f003 , 0x1288f8d5 , 0x3284f8d5 , 0x1ac92008, + 0xfd96f7ff , 0xf8d34b15 , 0x18d12284 , 0xf8c33201, + 0xf8d32284 , 0xf8812288 , 0x3201428c , 0x2288f8c3, + 0x220018d3 , 0x228cf883 , 0xf7fee5d2 , 0xe5cff96f, + 0x7483f44f , 0x22004b09 , 0x22e0f883 , 0x2601e62c, + 0xbf00e6e6 , 0x20006a44 , 0x20007789 , 0x20006b3c, + 0x20006b52 , 0x20006b6a , 0x20006ae7 , 0x2000894c, + 0x20006b85 , 0x20006b8a , 0x20006b90 , 0xb8b2f003, + 0xb503b40e , 0x681b4b07 , 0xf000fa33 , 0x0001f010, + 0xa904d004 , 0x91019803 , 0xf82cf003 , 0x400ce8bd, + 0x4770b003 , 0x2000930c , 0x681b4b05 , 0xf000fa33, + 0x0001f010 , 0x4770d100 , 0xf0024608 , 0xbf00bfed, + 0x2000930c , 0x2802b51f , 0x684cd123 , 0x46204922, + 0xf8cff003 , 0xb9184603 , 0x68114a20 , 0xe0386051, + 0x491f4620 , 0xf8c5f003 , 0xb9184603 , 0x68514a1b, + 0xe02e6011 , 0xa9034620 , 0xf0032200 , 0x9b03f8f5, + 0xb10b781b , 0xe024230b , 0xf0404a14 , 0x60100001, + 0x2000e01f , 0xf7ff4913 , 0x2400ffc7 , 0x46224b0f, + 0x2000681b , 0xf00340e3 , 0x2b000301 , 0x232abf14, + 0x93002320 , 0x490d4b0c , 0x3024f853 , 0x23019301, + 0x340140a3 , 0xff9cf7ff , 0xff98f7ff , 0xd1e52c1e, + 0x46182300 , 0xbd10b004 , 0x20006cc0 , 0x2000930c, + 0x20006cc5 , 0x20006ccd , 0x20006c40 , 0x20006ce4, + 0xb533b40e , 0x46054b0f , 0x40c4681c , 0x0401f014, + 0x4620d101 , 0x490ce012 , 0xff7af7ff , 0x4604a906, + 0x91019805 , 0xffaef002 , 0x28004908 , 0x4604bf18, + 0xf7ff4628 , 0x2800ff81 , 0x4620bf08 , 0x403ce8bd, + 0x4770b003 , 0x2000930c , 0x20006cf4 , 0x2000744a, + 0x6000f100 , 0xb5384770 , 0x461d1e04 , 0x2900db10, + 0x190bdb0e , 0x3f00f5b3 , 0x3a01dc0a , 0x420a4321, + 0xb115d106 , 0xffecf7ff , 0xf5c46028 , 0xbd383000, + 0x30fff04f , 0xb513bd38 , 0xeb0d2204 , 0x460c0302, + 0xffe1f7ff , 0xdb0d2800 , 0xe00708a4 , 0x681a9b01, + 0x3ffff1b2 , 0x3304d106 , 0x93013c01 , 0xd1f52c00, + 0xe0002001 , 0xbd1c2000 , 0x21026903 , 0x71197099, + 0x22001849 , 0x310c7259 , 0x705a701a , 0x715a70da, + 0x71da719a , 0x729a721a , 0x731a72da , 0x739a7359, + 0x798273da , 0x82c1b90a , 0x8a81e022 , 0xf0213908, + 0xf0010201 , 0x741901fe , 0x74590a11 , 0x74990c11, + 0x74d90e11 , 0x8a81b962 , 0xf0213908 , 0xf0010201, + 0x741901fe , 0x74590a11 , 0x0e120c11 , 0x74da7499, + 0x751a2200 , 0x759a755a , 0xf04f75da , 0x82c30318, + 0x47702000 , 0x69036882 , 0xc001f892 , 0xea417811, + 0xf892210c , 0x78d2c002 , 0x410cea41 , 0x6102ea41, + 0xd00f2901 , 0x2902d303 , 0x2003d014 , 0x22004770, + 0x010ff06f , 0x705a701a , 0x70da709a , 0x7159711a, + 0xe010719a , 0x701a2200 , 0x7099705a , 0x711a70da, + 0xe007715a , 0x701a2200 , 0x709a705a , 0x711a70da, + 0x2101715a , 0x71da7199 , 0x0308f04f , 0x200082c3, + 0xb5374770 , 0x46056884 , 0x78627823 , 0xea437961, + 0x78a32202 , 0xea4278e0 , 0x79234203 , 0x6000ea42, + 0x2301ea43 , 0x220179a1 , 0x4301ea43 , 0xea4379e1, + 0xab016101 , 0xff3ff7ff , 0xda012800 , 0xe0182002, + 0x79627923 , 0x2202ea43 , 0xea4279a3 , 0x79e34203, + 0x6203ea42 , 0x429a8aab , 0x200bd901 , 0x6928e009, + 0xf0039901 , 0x7923f84d , 0x20007962 , 0x2302ea43, + 0xbd3e82eb , 0x4604b510 , 0x4070f44f , 0xff18f7ff, + 0x46012204 , 0xf0034620 , 0x7823f83b , 0xd0062b02, + 0x21004620 , 0xf0032204 , 0x2302f862 , 0xbd107023, + 0xb085b5f0 , 0x20212300 , 0x93029301 , 0xfdcef7fe, + 0xbf0c2800 , 0x24002408 , 0xf7ffa803 , 0xf89dffdb, + 0xf013300d , 0xbf180f02 , 0x0401f044 , 0x46282500, + 0xfcaaf7fe , 0xbf8c2d0f , 0x27012700 , 0xbf142f00, + 0x26042602 , 0xb13000bf , 0x18ffab04 , 0x3c0cf857, + 0xb14b4334 , 0xab04e006 , 0x230118ff , 0xf8474226, + 0xd0013c0c , 0x0420f044 , 0x2d203501 , 0xf004d1df, + 0x2b040306 , 0xf044bf08 , 0xf7fe0420 , 0x4320fc99, + 0xbdf0b005 , 0x2280b510 , 0x493d2000 , 0xfe20f7ff, + 0x20002280 , 0xf7ff493b , 0x2202fe1b , 0x20004613, + 0xf7ff4939 , 0x2301fe15 , 0x49382000 , 0x6280f44f, + 0xfe0ef7ff , 0xf44f4936 , 0x20005280 , 0xfe08f7ff, + 0xff9ef7ff , 0x46044933 , 0xf7ff2000 , 0xf014fe01, + 0xd0030f08 , 0x49302000 , 0xfe0ef7ff , 0x0f01f014, + 0x2000d003 , 0xf7ff492d , 0xf014fe07 , 0xd0030f40, + 0x492b2000 , 0xfe00f7ff , 0x0f02f014 , 0x2000d003, + 0xf7ff4928 , 0xf014fdf9 , 0xd0030f04 , 0x49262000, + 0xfdf2f7ff , 0x0f10f014 , 0x2000d003 , 0xf7ff4923, + 0xf014fdeb , 0xd0030f20 , 0x49212000 , 0xfde4f7ff, + 0x20004920 , 0xfde0f7ff , 0x491f2000 , 0xfddcf7ff, + 0xf0142400 , 0xd101001f , 0xe003491c , 0x0007f014, + 0x491bd102 , 0xfdd0f7ff , 0xf7fe4620 , 0x4b19fc15, + 0x34014919 , 0xbf082800 , 0x20004619 , 0xfdc4f7ff, + 0xd1e62c20 , 0x490f2000 , 0xfdbef7ff , 0xbd102000, + 0x20006e1c , 0x20006e2d , 0x20006e3e , 0x20006e5b, + 0x20006e78 , 0x20006e88 , 0x20006e91 , 0x20006ea3, + 0x20006eaf , 0x20006ebc , 0x20006ec4 , 0x20006ecd, + 0x20006ed4 , 0x2000775e , 0x20006ee2 , 0x20006ef1, + 0x20006ef5 , 0x20006ef7 , 0x20006ef9 , 0x2300b570, + 0x6280f44f , 0x460c4605 , 0xfe1df7ff , 0xda012800, + 0xbd702005 , 0x46214628 , 0x4070e8bd , 0xbb66f7fe, + 0x6884b510 , 0xff04f7ff , 0x0f04f010 , 0x7823d131, + 0x79617862 , 0x2202ea43 , 0x78e078a3 , 0x4203ea42, + 0xea427923 , 0xea436000 , 0x79a12301 , 0x4301ea43, + 0xea4379e1 , 0xf0016101 , 0xb9d0fef1 , 0x78627823, + 0xea437961 , 0x78a32202 , 0xea4278e0 , 0x79234203, + 0x6000ea42 , 0x2301ea43 , 0xea4379a1 , 0x79e14301, + 0x6101ea43 , 0xffbaf7ff , 0xbf142800 , 0x20002002, + 0x2004bd10 , 0xb573bd10 , 0x2800ac01 , 0x2602bf14, + 0x46052600 , 0xf7ff4620 , 0xf89dfead , 0x42b33005, + 0x200fd021 , 0xfb80f7fe , 0x2307b108 , 0x4668e01f, + 0x6005f88d , 0xfe9ef7ff , 0x46214668 , 0x466e2204, + 0xfeccf002 , 0xf44fb178 , 0xf44f4070 , 0xf7fe5180, + 0x4603fb05 , 0xf44fb958 , 0x21044070 , 0xf7fe4622, + 0x4603faab , 0x4628b918 , 0xfa60f7fe , 0x46182300, + 0xe92dbd7c , 0xf01041f0 , 0xbf0e0501 , 0xf001462f, + 0x25010701 , 0x0840f010 , 0x460e4604 , 0xf011d00a, + 0xd1070f40 , 0xfe84f7ff , 0x0001f000 , 0xbf182800, + 0xe0002701 , 0x4638b11d , 0xffadf7ff , 0xf7ff4605, + 0x43c0fe77 , 0x0f09f010 , 0xf1b8d123 , 0xd0080f00, + 0x0f40f016 , 0x2002d005 , 0xff9df7ff , 0xbf182800, + 0xf0144605 , 0xd0080f02 , 0x0f02f016 , 0x2000d005, + 0xfb60f7fe , 0xbf182800 , 0xf0144605 , 0xd0080f04, + 0x0f04f016 , 0x2001d005 , 0xfb54f7fe , 0xbf182800, + 0x46284605 , 0x81f0e8bd , 0x6882b538 , 0x78514605, + 0x69047813 , 0x2301ea43 , 0x78d07891 , 0x4301ea43, + 0x6000ea53 , 0x7951d00b , 0xea437913 , 0x79912301, + 0x4301ea43 , 0xea4379d1 , 0xf7ff6101 , 0xf7ffff9a, + 0x0a03fe2f , 0x70637020 , 0x0e000c03 , 0x70e070a3, + 0xfb08f7fe , 0x0038f040 , 0x71630a03 , 0x78620c03, + 0x782371a3 , 0xea437120 , 0x0e002302 , 0x71e078a2, + 0xea4378e0 , 0xea434302 , 0xf7fe6000 , 0x0a03faf5, + 0x0c037263 , 0x72a37220 , 0xf04f0e00 , 0x72e0030c, + 0x200082eb , 0x0000bd38 , 0x2801b510 , 0x2014dc01, + 0x684cbd10 , 0x46204915 , 0xfd5bf002 , 0x3001b908, + 0x4913e00d , 0xf0024620 , 0x4601fd54 , 0x3001b908, + 0x4620e018 , 0xf002490f , 0xb918fd4c , 0xf04f3004, + 0xe00f31ff , 0x490c4620 , 0xfd43f002 , 0x3040b908, + 0x490ae7f5 , 0xf0024620 , 0x4601fd3c , 0x200bb108, + 0x2040bd10 , 0x4010e8bd , 0xbf3bf7ff , 0x20006efb, + 0x20006f02 , 0x20006ec9 , 0x20006f0c , 0x20006f0a, + 0x2300b570 , 0x22024614 , 0x460d4606 , 0xfccbf7ff, + 0xda012800 , 0xbd702005 , 0x46294630 , 0xe8bd4622, + 0xf7fe4070 , 0xb538b9c1 , 0x68844605 , 0xfdb0f7ff, + 0x0f04f010 , 0x7923d13a , 0xea437961 , 0x79a32101, + 0x4103ea41 , 0xea4179e3 , 0x89ab6103 , 0x0208f101, + 0xd901429a , 0xbd382003 , 0x78237862 , 0xea4378e0, + 0x78a22302 , 0x4302ea43 , 0x6000ea43 , 0xfd96f001, + 0x7823b9e0 , 0x79617862 , 0x2202ea43 , 0x78e078a3, + 0x4203ea42 , 0xea427923 , 0xea436000 , 0x79a12301, + 0x0208f104 , 0x4301ea43 , 0xea4379e1 , 0xf7ff6101, + 0x2800ffaf , 0x2002bf14 , 0xbd382000 , 0xbd382004, + 0xb1e1b510 , 0x46022800 , 0xbfb84b1d , 0x10d21dc2, + 0x4b1c5c99 , 0x0303ea00 , 0xda052b00 , 0xea6f3b01, + 0xea6f7343 , 0x33017353 , 0xf003fa51 , 0x0f01f010, + 0x2001d124 , 0xf303fa10 , 0x0101ea43 , 0x2800e01b, + 0x4b0f4602 , 0x1dc2bfb8 , 0x5c9910d2 , 0xea004b0d, + 0x2b000303 , 0x3b01da05 , 0x7343ea6f , 0x7353ea6f, + 0xfa513301 , 0xf010f003 , 0xd0070f01 , 0xfa102001, + 0xea21f303 , 0x4c020103 , 0xbd1054a1 , 0xbd102000, + 0x20008c34 , 0x80000007 , 0x4606b570 , 0x7803b178, + 0x2500b16b , 0x4b07462c , 0x58e94630 , 0xfc81f002, + 0xb2e0b908 , 0x3401bd70 , 0x2c253514 , 0x2025d1f3, + 0xbf00bd70 , 0x200065fc , 0x6885b538 , 0xffc2f001, + 0xb1084604 , 0xbd382004 , 0xf7ff4628 , 0x2825ffdd, + 0x4b09d00f , 0xfb012114 , 0x689a3300 , 0x68dbb14a, + 0x0f20f013 , 0xf895d005 , 0xf7fe1020 , 0x4620fadf, + 0x2002bd38 , 0xbf00bd38 , 0x200065fc , 0x41f0e92d, + 0x79ae4605 , 0x692c6880 , 0xf7ffb966 , 0x2825ffbd, + 0xf7fed046 , 0xf04ffabb , 0x70200301 , 0x463082eb, + 0x81f0e8bd , 0x2b017803 , 0xd304d010 , 0xd0102b02, + 0xe8bd2003 , 0x300181f0 , 0xffa6f7ff , 0xd02f2825, + 0xfaa4f7fe , 0x0301f04f , 0xe0257020 , 0x70222225, + 0x7847e022 , 0xd8232f24 , 0x437b2314 , 0xf8524a12, + 0x18d68003 , 0xf0024640 , 0x4641fbef , 0x1c601c42, + 0xfce6f002 , 0xf7fe4638 , 0x7020fa89 , 0xf8847b33, + 0x7b733024 , 0x3025f884 , 0xf8847bb3 , 0x7bf33026, + 0x3027f884 , 0x0328f04f , 0x200082eb , 0x81f0e8bd, + 0xe8bd2002 , 0xbf0081f0 , 0x200065fc , 0x2802b537, + 0xdc01460d , 0xe0202014 , 0xf7ff6848 , 0x2825ff65, + 0xd0194604 , 0x22144b0d , 0x3300fb02 , 0xb19a689a, + 0xf01368db , 0xd00f0f20 , 0xa90168a8 , 0xf0022200, + 0x9b01fc1b , 0x781d4601 , 0x200cb10d , 0x4620e005, + 0xfa5cf7fe , 0xe0004628 , 0xbd3e200b , 0x200065fc, + 0x2802b573 , 0x6848d11b , 0xff3ef7ff , 0x46042825, + 0xf7fed035 , 0x4605fa3b , 0x46204629 , 0xfef0f7ff, + 0x43542214 , 0x28004a17 , 0x232abf14 , 0x58a22320, + 0x92002000 , 0x462a4914 , 0xfabaf7ff , 0x4d11e01b, + 0x68ab2400 , 0xb2e0b1a3 , 0xfa20f7fe , 0x46314606, + 0xf7ff4620 , 0x682afed5 , 0xbf142800 , 0x2320232a, + 0x49099200 , 0x20004632 , 0xfaa2f7ff , 0xfa9ef7ff, + 0x2c253401 , 0x2000d101 , 0x3514e002 , 0x200be7e1, + 0xbf00bd7c , 0x200065fc , 0x20006f70 , 0x41f0e92d, + 0x46804b1a , 0x681e460f , 0x25004c19 , 0xf814e02a, + 0x45433c03 , 0xf834d124 , 0xb17f2c02 , 0x5f00f412, + 0xf854d105 , 0xf8540c0c , 0xf7fe1c08 , 0xf854f97d, + 0xf8540c0c , 0xf9141c08 , 0xe00f2c04 , 0x5f00f412, + 0xf854d106 , 0xf8540c0c , 0x22101c08 , 0xf96cf7fe, + 0x0c0cf854 , 0x1c08f854 , 0x32fff04f , 0xf912f7fe, + 0x340c3501 , 0xdbd242b5 , 0x81f0e8bd , 0x200068e0, + 0x200068ec , 0x45f8e92d , 0x21004b15 , 0x7030f853, + 0x03c0eb03 , 0x8004f8d3 , 0xebc7460e , 0xea4f0a08, + 0xe0150aea , 0x42a2685a , 0x428ada01 , 0x4622dc00, + 0x46143308 , 0xd3f54543 , 0xe006463d , 0x42a3686b, + 0x682bd102 , 0x47983601 , 0x45453508 , 0xd3f54621, + 0xda034556 , 0xf242463b , 0xe7eb7410 , 0x85f8e8bd, + 0x20006fb0 , 0xf7ff2000 , 0x0000bfcd , 0x00000000, + 0x4ff7e92d , 0x22014b4c , 0x4f4c601a , 0x1aff4b4c, + 0x4e4c10bf , 0xf0014668 , 0x46b2ffe9 , 0x9d019c00, + 0x0800f04f , 0xe9dae014 , 0xea522300 , 0xd00b0103, + 0xeb7342a2 , 0xd2070c05 , 0x22002300 , 0x2300e9ca, + 0xf8534b3f , 0x47983028 , 0x0801f108 , 0x0a08f10a, + 0xdbe845b8 , 0x80f4f8df , 0xe9d1a133 , 0xe9d80100, + 0x1aa22300 , 0x0303eb65 , 0xeb714290 , 0xd2040c03, + 0xf7ff200d , 0xe9c8ff8f , 0xf8df4500 , 0xa12c80d0, + 0x0100e9d1 , 0x2302e9d8 , 0xeb651aa2 , 0x42900303, + 0x0c03eb71 , 0x200ed204 , 0xff7cf7ff , 0x4502e9c8, + 0xf0014668 , 0x4c28ffa3 , 0x25004928 , 0x0100e9d1, + 0x18249a00 , 0xeb459b01 , 0x42a20501 , 0x0c05eb73, + 0x2000d301 , 0xf500e004 , 0xf50020f4 , 0x1a807090, + 0x21004c19 , 0xe01a64a1 , 0x4500e9d6 , 0x0c05ea54, + 0x4294d013 , 0x0c03eb75 , 0x2000d201 , 0x46a2e00d, + 0x468046ab , 0x79e8ea4f , 0x0a02ebba , 0x0b03eb6b, + 0xeb7b45c2 , 0xbf380c09 , 0x31011aa0 , 0x42b93608, + 0x2800da02 , 0xe77cdce0 , 0xf77f2800 , 0xf7fdaf7a, + 0xe776fadd , 0x8000f3af , 0x0007a11f , 0x00000000, + 0x000f423f , 0x00000000 , 0x20008c40 , 0x20005fc8, + 0x20005fc8 , 0x20008c48 , 0x0007a120 , 0x20009318, + 0x18184b01 , 0xbf004770 , 0x20008c90 , 0x6803b508, + 0xbd084798 , 0xe0034b05 , 0x4290685a , 0x330cd004, + 0x42934a03 , 0x2300d3f8 , 0x47704618 , 0x20005e14, + 0x20005f88 , 0x23006902 , 0x70112102 , 0x70937053, + 0xf04f70d3 , 0x82c20204 , 0x47704618 , 0x69026883, + 0xc001f893 , 0xea417819 , 0xf893210c , 0x78dbc002, + 0x410cea41 , 0x6103ea41 , 0x18cb4b06 , 0x70130a19, + 0x0c197051 , 0x70d30e1b , 0x0304f04f , 0x82c37091, + 0x47702000 , 0x01020304 , 0x6883b570 , 0x781a6904, + 0xf893785d , 0xea42c005 , 0x789a2505 , 0x4502ea45, + 0xea4578da , 0x791a6502 , 0x2c0cea42 , 0x79db799a, + 0x4c02ea4c , 0x6c03ea4c , 0x0c9cea4f , 0x0f20f1bc, + 0x2002d901 , 0x2300bd70 , 0x195ae00b , 0x0183eb04, + 0xf8040a16 , 0x704e2023 , 0x0e120c16 , 0x70ca708e, + 0x45633301 , 0xf04fd1f1 , 0x82c30380 , 0xbd702000, + 0x6883b538 , 0x69044605 , 0xf7ff7818 , 0xb908ff8b, + 0xbd383003 , 0x70227a02 , 0x70627a42 , 0x70a27a82, + 0x20007ac3 , 0xf04f70e3 , 0x82eb0304 , 0x0000bd38, + 0x68832200 , 0x785882c2 , 0xea417819 , 0x78982100, + 0xea4178db , 0xea414100 , 0x4b026103 , 0xf8c34610, + 0x47701100 , 0x20008c90 , 0x2801b538 , 0xdd10460d, + 0x4b0e2400 , 0xf8536868 , 0xf0021024 , 0xb920f9c2, + 0x2c044b0b , 0xd104701c , 0x3401e00e , 0xd1f02c04, + 0x4b07e00a , 0x781a2000 , 0x49064b04 , 0x2022f853, + 0xf8b6f7ff , 0xbd382000 , 0xbd38200b , 0x20007028, + 0x20009328 , 0x20007054 , 0x6884b5f8 , 0x79236906, + 0x46057967 , 0x2707ea43 , 0x210079a3 , 0x4703ea47, + 0x222079e3 , 0x6703ea47 , 0xbf282f20 , 0x46302720, + 0xfa8df002 , 0x4630463a , 0x0108f104 , 0xfa58f002, + 0x79237962 , 0x2302ea43 , 0x786282eb , 0x78e07823, + 0x2302ea43 , 0xea4378a2 , 0xea434302 , 0xbdf86000, + 0x6883b538 , 0x785d4604 , 0x182b7818 , 0xdd012bff, + 0xbd382003 , 0xfefcf7ff , 0x4601462a , 0xf0026920, + 0x82e5fa37 , 0xbd382000 , 0x43f0e92d , 0x4b35b085, + 0x781b4604 , 0xd03c2b00 , 0xd1252b01 , 0xf001a802, + 0x4931fe35 , 0xf8d188a0 , 0x9a025108 , 0x9b0342a8, + 0xe9f1d113 , 0xf24c6744 , 0x1b96384f , 0x0707eb63, + 0x0900f04f , 0xeb7945b0 , 0xd3060c07 , 0x2300e9c1, + 0x49262008 , 0xf858f7ff , 0x4923e01b , 0x7588f501, + 0x2300e9c5 , 0x0108f8c1 , 0x781b4b1e , 0xd90b2b02, + 0xb14989a1 , 0x68a19100 , 0x910188a2 , 0x200879a3, + 0xf7ff491b , 0xe004f8a5 , 0x491a2008 , 0xf7ff88a2, + 0x88a0f89f , 0xfeb6f7ff , 0x2501b908 , 0x79a2e00b, + 0xfa316881 , 0xf012f202 , 0xd0180f01 , 0x46206803, + 0x46054798 , 0x2008b120 , 0x462a490f , 0xf888f7ff, + 0x781b4b08 , 0xd9062b02 , 0xb1228ae2 , 0x490b2008, + 0xf7ff6923 , 0xb2e8f87d , 0xe8bdb005 , 0x250683f0, + 0xbf00e7e9 , 0x20009328 , 0x20008c90 , 0x20007073, + 0x20007075 , 0x20007087 , 0x20007091 , 0x2000709b, + 0x2020b538 , 0xfe74f7ff , 0x70032345 , 0xf7ff2020, + 0x2343fe6f , 0x20227043 , 0xfe6af7ff , 0x70042401, + 0xf7ff2026 , 0x7004fe65 , 0x5000f44f , 0xf89ef000, + 0xf832f000 , 0x4602490c , 0xf7ff2008 , 0xf04ff849, + 0xf7fd30ff , 0xf010f91b , 0xd0f80f01 , 0xf8d54d07, + 0x2c004118 , 0x4620d0f3 , 0xff56f7ff , 0xf8d57620, + 0xf7ff0118 , 0xe7eafe4b , 0x200070f3 , 0x20008c90, + 0x3f00e850 , 0x0301ea23 , 0x3200e840 , 0x0f00f092, + 0x4770d1f6 , 0x3f00e850 , 0x0301ea43 , 0x3200e840, + 0x0f00f092 , 0x4770d1f6 , 0x68184b01 , 0xbf004770, + 0x20008dc8 , 0x69034a07 , 0x70197911 , 0x70597951, + 0x70997991 , 0x70da79d2 , 0x0304f04f , 0x200082c3, + 0xbf004770 , 0x20008dc8 , 0x4b08b510 , 0x685b4604, + 0xd0044218 , 0x49062006 , 0xf7fe4622 , 0x4805fff9, + 0xe8bd4621 , 0xf7ff4010 , 0xbf00bfc3 , 0x20008dc8, + 0x20007170 , 0x20008dcc , 0x6883b508 , 0x781a7859, + 0xea4278d8 , 0x78992201 , 0x4201ea42 , 0x6000ea42, + 0xffdaf7ff , 0xbd082000 , 0x4b0ab538 , 0x681b4604, + 0xd0044218 , 0x49082006 , 0xf7fe4622 , 0x4d05ffd1, + 0x46284621 , 0xff9cf7ff , 0xf7ff2034 , 0x682bfdd9, + 0xbd386003 , 0x20008dc8 , 0x20007185 , 0x6883b508, + 0x781a7859 , 0xea4278d8 , 0x78992201 , 0x4201ea42, + 0x6000ea42 , 0xffd8f7ff , 0xbd082000 , 0x4b10b538, + 0x681a4604 , 0x0202ea00 , 0xd1044282 , 0xea00685b, + 0x42830303 , 0x2006d004 , 0x4622490a , 0xffa0f7fe, + 0x46214d07 , 0xf7ff4628 , 0x1d28ff75 , 0xf7ff4621, + 0x2034ff71 , 0xfda4f7ff , 0x6003682b , 0xbf00bd38, + 0x20008dc8 , 0x20007198 , 0x2803b537 , 0xd127460c, + 0x22006888 , 0xf002a901 , 0x9b01f83f , 0x781b4605, + 0x200cb10b , 0x6864e028 , 0x46204914 , 0xfff9f001, + 0x4628b918 , 0xffc2f7ff , 0x4620e012 , 0xf0014910, + 0xb918fff0 , 0xf7ff4628 , 0xe009ff8f , 0x490d4620, + 0xffe7f001 , 0x200bb108 , 0x4628e00e , 0xff5cf7ff, + 0x490a4c09 , 0x20006822 , 0xfee2f7fe , 0x49082000, + 0xf7fe6862 , 0x2000fedd , 0xbf00bd3e , 0x20006d5e, + 0x200071a9 , 0x200071af , 0x20008dc8 , 0x200071b6, + 0x200071c9 , 0x21086903 , 0x70192200 , 0x705a3105, + 0x70da709a , 0x715a7119 , 0x71da719a , 0xf04f721a, + 0x82c30309 , 0x47704610 , 0x4d1cb570 , 0x46066904, + 0x22074629 , 0xf0024620 , 0x782bf87b , 0x786b7023, + 0x78ab7063 , 0x78eb70a3 , 0x792b70e3 , 0x796b7123, + 0x79ab7163 , 0xf0007523 , 0x7803f931 , 0x784373a3, + 0x788373e3 , 0x78c37423 , 0x79037463 , 0x794374a3, + 0x798374e3 , 0x79c371a3 , 0x7a0371e3 , 0x7a437323, + 0x7b037363 , 0x7b437223 , 0x7b837263 , 0x7bc372a3, + 0x72e32000 , 0x0315f04f , 0xbd7082f3 , 0x2000932c, + 0x0101f1d0 , 0x2100bf38 , 0xf7fd2023 , 0x0000bdf7, + 0x4d0ab538 , 0x490a200a , 0xfeeaf7fe , 0x602b2300, + 0x60ab606b , 0x040cf105 , 0x462035dc , 0x220d2100, + 0xf002340d , 0x42acf85c , 0xbd38d1f7 , 0x20008dd0, + 0x2000722a , 0x4b1bb570 , 0x79184606 , 0x0001f010, + 0x4c19d02e , 0x68a3799a , 0xd3054293 , 0x4917200a, + 0xfec6f7fe , 0xbd702003 , 0x00dcf104 , 0xffb0f7fc, + 0xf1046860 , 0x220d050c , 0xfb024631 , 0xf0025000, + 0x6863f807 , 0x33012601 , 0x030ff003 , 0x34086063, + 0x3f00e854 , 0xe8444433 , 0xf0923200 , 0xd1f70f00, + 0x00d0f105 , 0xf800f7fd , 0xf7ff4630 , 0x2000ffa9, + 0xbf00bd70 , 0x2000932c , 0x20008dd0 , 0x20007241, + 0x4c18b538 , 0x68a24605 , 0xf1046900 , 0xb94a030c, + 0x320d6821 , 0xf001310f , 0xfb02010f , 0xf0013101, + 0xe015ffd7 , 0x220d6821 , 0x3101fb02 , 0xffd0f001, + 0x33016823 , 0x030ff003 , 0x3b08f844 , 0xe8542301, + 0xeba11f00 , 0xe8440103 , 0xf0921200 , 0xd1f60f00, + 0x68984b04 , 0xf7ffb908 , 0xf04fff73 , 0x82eb030d, + 0xbd382000 , 0x20008dd0 , 0x6885b570 , 0x786e782b, + 0xea437969 , 0x78ab2606 , 0x4603ea46 , 0xea4678eb, + 0x4b306603 , 0x4016681a , 0x4011795a , 0x0f80f016, + 0x7d2ad004 , 0xbfa82a10 , 0x719a2210 , 0x791c4b29, + 0xea24792b , 0x40190401 , 0xf000430c , 0xf016f857, + 0xd0040f01 , 0x79ea79ab , 0x2302ea43 , 0xf01680c3, + 0xd00a0f02 , 0x7a2b7a6a , 0x2302ea43 , 0xea437aaa, + 0x7aea4302 , 0x6302ea43 , 0xf01660c3 , 0xd0070f08, + 0x7b6a7b2b , 0x2302ea43 , 0xbfb82bc8 , 0x810323c8, + 0x0f10f016 , 0x7babd004 , 0xea437bea , 0x80032302, + 0x0f20f016 , 0x7c2bd004 , 0xea437c6a , 0x80432302, + 0x0f40f016 , 0x7cabd004 , 0xea437cea , 0x80832302, + 0x0f01f014 , 0x4b07d009 , 0xf012791a , 0xd1040201, + 0xf04f2004 , 0xf7fc5100 , 0x4b02ff1b , 0x711c2000, + 0xbf00bd70 , 0x2000932c , 0x68184b03 , 0x0001f1d0, + 0x2000bf38 , 0xbf004770 , 0x20008eb4 , 0x47704800, + 0x20009334 , 0x460ab570 , 0x490c4605 , 0xf7fe200b, + 0x2400fd67 , 0xb1225d2a , 0x4909200b , 0xfd60f7fe, + 0x200be003 , 0xf7fe4907 , 0x3401fd6f , 0xd1f12c0d, + 0x200b4905 , 0x4070e8bd , 0xbd66f7fe , 0x20007274, + 0x2000727f , 0x20007285 , 0x2000744a , 0x00000000, + 0x4606b573 , 0xf0014668 , 0x9c00fb19 , 0xe0039d01, + 0x88d84b0d , 0xfc06f001 , 0x695b4b0c , 0xd10e42b3, + 0xf0014668 , 0xe9ddfb0b , 0xa1052300 , 0x0100e9d1, + 0xeb631b12 , 0x42900305 , 0x0c03eb71 , 0xbd7cd2e8, + 0x0001869f , 0x00000000 , 0x20009334 , 0x20008eb4, + 0x2801b510 , 0x6848dd06 , 0xf0014912 , 0xb908fe99, + 0xbd10300b , 0x49114c10 , 0xf7ff1d20 , 0xf104ffa3, + 0x490f001c , 0xff9ef7ff , 0x002cf104 , 0xf7ff490d, + 0x6822ff99 , 0x490c2000 , 0xfd02f7fe , 0x4b0b69a4, + 0x20004a0b , 0x4284490b , 0x461abf08 , 0xfcf8f7fe, + 0xbd102000 , 0x20008ecc , 0x20008eb4 , 0x20007289, + 0x20007294 , 0x2000729f , 0x200072aa , 0x20007738, + 0x200079bb , 0x200072ce , 0xf7fdb508 , 0x4a05f817, + 0x737af44f , 0xf3f3fb90 , 0xf3f3fb92 , 0x63d34a02, + 0xbf00bd08 , 0x00f42400 , 0x20008eb4 , 0x2500b5f8, + 0x462c4607 , 0xff50f7ff , 0x4e0eb1a0 , 0xf7fd4620, + 0x8830fe1d , 0xfb34f001 , 0xfe4ef7fd , 0x19364b0a, + 0xb2c05d1b , 0x7c334318 , 0x40184305 , 0x34015538, + 0xd1e72c0d , 0x30fff04f , 0xfe08f7fd , 0xbf181e28, + 0xbdf82001 , 0x20009334 , 0x20008ef4 , 0xf04f2004, + 0x22005100 , 0xbe3cf7fc , 0xf04fb570 , 0xfa0c0c01, + 0x4614fc00 , 0xbf183a00 , 0xfa122201 , 0x4b12f000, + 0xf89118c9 , 0xea055040 , 0x4286060c , 0xea85d01b, + 0x695d0c0c , 0x0040f103 , 0xc040f881 , 0xf7ff490b, + 0xf7ffff19 , 0x4628ffdb , 0xff3af7ff , 0xb10c4b08, + 0xe0008858 , 0xf0018898 , 0x4b03fb45 , 0xe8bd6958, + 0xf7ff4070 , 0xbd70bf2d , 0x20008eb4 , 0x20007318, + 0x20009334 , 0x45f7e92d , 0x46822801 , 0xd11b4688, + 0x49322000 , 0xfc78f7fe , 0x4b312400 , 0xb17b5d1b, + 0x4b2f2500 , 0x412b5d1b , 0x0f01f013 , 0x2000d005, + 0x4622492c , 0xf7fe462b , 0x3501fc53 , 0xd1f02d08, + 0x2c0d3401 , 0xe045d1e9 , 0x2b011ec3 , 0xaf01d842, + 0x22006848 , 0xf0014639 , 0x9b01fd77 , 0x781a4604, + 0xd1312a00 , 0xdb2f2800 , 0xdc2d280c , 0x0008f8d8, + 0xf0014639 , 0x9b01fd69 , 0x781e4605 , 0x2800bb36, + 0x2807db24 , 0xf1badc22 , 0xd10a0f03 , 0x22014621, + 0xff82f7ff , 0x46214628 , 0xf7ff4632 , 0x4630ff7d, + 0x4632e019 , 0x000cf8d8 , 0xf0014639 , 0x9b01fd4d, + 0x781b4602 , 0x2800b963 , 0x2801db0a , 0x4628dc08, + 0xf7ff4621 , 0xe005ff69 , 0xe004200b , 0xe002200c, + 0xe000200d , 0xe8bd2000 , 0xbf0085fe , 0x20007323, + 0x20008ef4 , 0x20007334 , 0x6885b538 , 0xf842f001, + 0xb1084604 , 0xbd382004 , 0x290c7829 , 0x7868d807, + 0xd8042807 , 0xf7ff78aa , 0x4620ff47 , 0x2003bd38, + 0x0000bd38 , 0xb085b5f0 , 0xf7fd4c31 , 0x1d25fda7, + 0x30fff04f , 0xfd32f7fd , 0xf7ff4628 , 0xe895ff07, + 0xf104000f , 0xe8ac0c1c , 0x46620007 , 0xf0007013, + 0x2800fd27 , 0xf000d13d , 0xf010fd15 , 0xd1030f02, + 0xf01379a3 , 0xd0340f04 , 0x462c2500 , 0x46684b21, + 0x195b5d5f , 0x2100785e , 0xf001220d , 0xb11efdb0, + 0x5ddb4b1d , 0xd0184233 , 0x19dfab04 , 0x3c10f817, + 0x0606ea43 , 0x6c10f807 , 0x3002f89d , 0x0304f043, + 0x3002f88d , 0x4a142300 , 0x1003f81d , 0x438a5cd2, + 0x3301d103 , 0xd1f62b0d , 0x3401e004 , 0x2c033502, + 0xe006d1d4 , 0x200b4622 , 0xf7fe490c , 0xb2e4fc09, + 0x24ffe000 , 0x2c014b0a , 0x4020f883 , 0xf44fd106, + 0xb0054080 , 0x40f0e8bd , 0xbc48f7ff , 0xbdf0b005, + 0x20008eb4 , 0x2000725c , 0x20008eb8 , 0x2000733c, + 0x20009334 , 0x4ff0e92d , 0x489fb085 , 0xf7ff499f, + 0xf7fdfe01 , 0xf7fffd47 , 0x499dfe87 , 0xf7fe200b, + 0xf7fffbdf , 0xb118fde9 , 0x0001f06f , 0xfcb6f7fd, + 0xf7fd2001 , 0xf7fdfd07 , 0xb110fce7 , 0xfddcf7ff, + 0xf04fb918 , 0xf7fc30ff , 0xf7fffca1 , 0x2800fdd5, + 0x4990d0f1 , 0xf7fe200b , 0x2000fbc3 , 0xfcf2f7fd, + 0x30fff04f , 0xfc9af7fd , 0x4668e107 , 0xf916f001, + 0x2300e9dd , 0xe9cd4668 , 0xf0012302 , 0x4b86f90f, + 0x6d1a9f00 , 0x2a1f3201 , 0xdd01651a , 0x651a2200, + 0x6d034881 , 0x0383eb00 , 0x30d4655f , 0xfe56f7ff, + 0x46062300 , 0x5cc8497d , 0x1c5ab178 , 0xe00a1859, + 0xcf01f811 , 0x0c0cea00 , 0x3efff10c , 0x0f0cea1e, + 0x80b2f040 , 0x2a0c3201 , 0x3301ddf2 , 0xd1e92b0d, + 0xf8934b71 , 0x2300e050 , 0xf1a04870 , 0x5cc102b8, + 0xc003f812 , 0x0c0cea91 , 0x3010d016 , 0x00c3eb00, + 0xfa4c2200 , 0xf018f802 , 0xbf180f01 , 0xe000f880, + 0x30013201 , 0xd1f42a08 , 0x5cd04a65 , 0x0c00ea4c, + 0xc003f802 , 0x54d13a10 , 0x2b0d3301 , 0x2000d1dc, + 0x4a5f4603 , 0x8003f812 , 0x0f00f1b8 , 0xf102d03e, + 0xeb0c0cb8 , 0x21000cc3 , 0x408a2201 , 0xe158f8df, + 0x0f08ea12 , 0x0ad4f10e , 0x9003f81a , 0xf89cd029, + 0xea12a000 , 0xeb0e0909 , 0xf8de0e8a , 0xf8dfa054, + 0xebcae150 , 0xbf140a07 , 0xe002f8be , 0xe004f8be, + 0xd31645f2 , 0xe128f8df , 0xfa82fa5f , 0xb003f81e, + 0x0b0aea2b , 0xb003f80e , 0x0e28f1ae , 0xb003f81e, + 0x020bea02 , 0xd004454a , 0x0a0bea8a , 0xa003f80e, + 0x31012001 , 0xf10c2908 , 0xd1c50c01 , 0x2b0d3301, + 0x2800d1b7 , 0x4838d034 , 0xb11b6983 , 0x49393004, + 0xfd28f7ff , 0x7a1a4b34 , 0xd1262a01 , 0x2b017b9b, + 0x2b40d001 , 0x2300d121 , 0x492b461a , 0xb1015c89, + 0x32013301 , 0xd1f82a0d , 0xd1162b03 , 0x79da4b2a, + 0xd1062a80 , 0x200b492c , 0xfaf2f7fe , 0xfc00f7ff, + 0x7a9be01d , 0xd1082b02 , 0x4928200b , 0xfae8f7fe, + 0x46012000 , 0xfd8cf7fd , 0x481be011 , 0xfc0af7ff, + 0x695a4b1d , 0x615a3201 , 0x4b21b14e , 0xe9dd68d9, + 0x18522302 , 0x0300f143 , 0x461d4614 , 0x4620e007, + 0xaa024629 , 0xf8adf001 , 0xf47f2800 , 0x4e18aee6, + 0x8008f8dd , 0x466888f7 , 0xf820f001 , 0xeb089b00, + 0x1ac00007 , 0x42988933 , 0x4618bfb8 , 0x6bdb4b0a, + 0xbf384298 , 0xf0014618 , 0xf7fff905 , 0x2800fcbd, + 0xaecbf43f , 0xbf00e6f1 , 0x20008eb8 , 0x2000734b, + 0x20007356 , 0x2000735e , 0x20008eb4 , 0x20008f88, + 0x20008ee0 , 0x2000629c , 0x20007366 , 0x20007375, + 0x20009334 , 0xf7fcb510 , 0xf7fdfa3d , 0xf000fcb7, + 0xf7fcfe17 , 0xf000fd4f , 0xf7fbffcd , 0xf7fcffa9, + 0xf7fdfdd5 , 0xf000fd89 , 0xb120fb63 , 0x49152015, + 0xfa7ef7fe , 0x4914e00d , 0xf7fe2015 , 0x4913fa15, + 0xf7fe2015 , 0xf000fa11 , 0x2015fc8f , 0xf7fe4910, + 0xf000fa0b , 0x4604fbb9 , 0xfc1ef000 , 0x46034622, + 0x2015490c , 0xf9ecf7fe , 0xfe0cf7fd , 0xfe02f7ff, + 0xffc0f7fe , 0x49082015 , 0xfa5af7fe , 0x4010e8bd, + 0xba7af7fc , 0x200073e5 , 0x20007404 , 0x2000742d, + 0x2000744a , 0x2000743c , 0x2000744d , 0x2802b513, + 0x2014d001 , 0x6848e010 , 0xa9012200 , 0xfafcf001, + 0x46029b01 , 0xb10c781c , 0xe005200b , 0x49036803, + 0xf7fe4620 , 0x4620f9bd , 0xbf00bd1c , 0x20007460, + 0x2803b573 , 0xd001460e , 0xe01f2014 , 0x6848ac01, + 0x46212200 , 0xfae0f001 , 0x46059b01 , 0xb10a781a, + 0xe013200b , 0x462168b0 , 0xfad6f001 , 0x46069b01, + 0xb10c781c , 0xe009200c , 0x462a4905 , 0x46204633, + 0xf996f7fe , 0xf992f7fe , 0x4620602e , 0xbf00bd7c, + 0x20007474 , 0x4a044b03 , 0x42906f18 , 0x4618bf0c, + 0x47702000 , 0x2000bf8c , 0x21636e50 , 0x4c10b510, + 0x6f224b10 , 0xd114429a , 0xc002f894 , 0x4a0f4b0e, + 0x0c02f00c , 0x45842000 , 0x461abf08 , 0xf7fe490c, + 0x4620f96f , 0xff82f7fb , 0xf04378a3 , 0x70a30302, + 0x2000e003 , 0xf7fe4907 , 0x2000f963 , 0xbf00bd10, + 0x2000bf8c , 0x21636e50 , 0x200074f4 , 0x2000775f, + 0x200074fb , 0x20007510 , 0x2801b538 , 0x684cdd22, + 0x46204911 , 0xfa45f001 , 0xb9504605 , 0xf7fe2401, + 0x4628f945 , 0xfb94490d , 0xf7fef2f5 , 0x4620f941, + 0x4620bd38 , 0xf001490a , 0x4604fa34 , 0xf7feb950, + 0xf64cf935 , 0x462053ef , 0x681a4904 , 0xf930f7fe, + 0xbd382001 , 0xbd38200b , 0x20007530 , 0x20006176, + 0x20007538 , 0xb537b40f , 0xf854ac06 , 0xf0015b04, + 0x2100f9d1 , 0x4623462a , 0x94014804 , 0xf87af000, + 0xfc48f7fd , 0x403ee8bd , 0x4770b004 , 0x20004481, + 0x290ab510 , 0xd102460c , 0xf7ff210d , 0xf7fdfff9, + 0x2800fc41 , 0xb2e0d0fb , 0xfc54f7fd , 0xbd102000, + 0x2400b570 , 0xf0014605 , 0xe002f9ad , 0xf7ff2000, + 0x5d29ffe7 , 0x29003401 , 0xe8bdd1f8 , 0xf7fd4070, + 0x0000bc21 , 0x4804b510 , 0xffeaf7ff , 0xe8bd2000, + 0xf7fd4010 , 0xbf00bb49 , 0x20007542 , 0x468eb513, + 0x46044694 , 0x48059300 , 0x46724621 , 0xf7ff4663, + 0xb002ffb1 , 0x4010e8bd , 0xbfe4f7ff , 0x20007561, + 0x4b0fb538 , 0x6f194a0f , 0x42914604 , 0x6edad116, + 0x429a8a83 , 0x480cd905 , 0x4a0d490c , 0xf7ff23a6, + 0x4d07ffdd , 0x46296920 , 0xf0016eea , 0xf8b5fa81, + 0x82e3306c , 0xf04378ab , 0x70ab0304 , 0xbd382000, + 0x2000bf8c , 0x21636e50 , 0x2000758b , 0x200074c8, + 0x200075b8 , 0x000ff000 , 0xdd012809 , 0x47703057, + 0x47703030 , 0x4ff0e92d , 0x4604b093 , 0x46159102, + 0xe188461f , 0x29253501 , 0x9802d001 , 0xf815e006, + 0x2e256b01 , 0xb936d000 , 0x21259802 , 0x280047a0, + 0x8179f000 , 0x2e63e17d , 0x9802d107 , 0x47a06839, + 0xf0402800 , 0x37048176 , 0x2e2de16d , 0xf815bf0a, + 0xf04f6b01 , 0xf04f0a00 , 0x2e300a01 , 0xf815bf04, + 0xf04a6b01 , 0x2e2a0a02 , 0x462bd003 , 0x0900f04f, + 0xf8d7e00a , 0xf8159000 , 0x37046b01 , 0x210ae00a, + 0x2909fb01 , 0x6c01f813 , 0x0230f1a6 , 0x3301461d, + 0xd9f42a09 , 0x6f80f5b9 , 0x8085f200 , 0xd0022e2e, + 0x0800f04f , 0x462be01b , 0x6b01f813 , 0xd0022e2a, + 0x0800f04f , 0xf8d7e00a , 0x786e8000 , 0x1c5d3704, + 0x210ae00a , 0x2808fb01 , 0x6c01f813 , 0x0230f1a6, + 0x3301461d , 0xd9f42a09 , 0x6f80f5b8 , 0x2e73d863, + 0x1d39d109 , 0xf8d79103 , 0x4b94b000 , 0x0f00f1bb, + 0x469bbf08 , 0x2e68e0df , 0xf107d120 , 0x683f0a04, + 0x0f00f1b8 , 0x4657d101 , 0x2600e04d , 0x09005db8, + 0xff70f7ff , 0x98024601 , 0x280047a0 , 0x8109f040, + 0xf7ff5db8 , 0x4601ff67 , 0x47a09802 , 0xf0402800, + 0x36018100 , 0xd1e945b0 , 0xe0f44657 , 0xbf042e6c, + 0x6b01f815 , 0x0a08f04a , 0xd10b2e54 , 0xf000a804, + 0xe9ddfdcd , 0xf04a2304 , 0xe9cd0a08 , 0xf04f2310, + 0xe0510806 , 0x0108f01a , 0x3707d009 , 0x0007f027, + 0x2300e9d0 , 0x0708f100 , 0x2310e9cd , 0x683be003, + 0x93109111 , 0x2e643704 , 0xdc06d015 , 0xd00c2e58, + 0xd00d2e62 , 0xd1062e54 , 0x2e75e036 , 0x2e78d034, + 0x2e70d003 , 0x4d66d001 , 0xf04fe0bd , 0xe02d0c10, + 0x0c02f04f , 0xe9dde02a , 0xb1892310 , 0xf1732a00, + 0xda210c00 , 0xf04f2000 , 0x40504100 , 0xea504059, + 0xf04a0c01 , 0xd0170a04 , 0xeb634252 , 0xe0110343, + 0x0c00f1b2 , 0x2100da10 , 0x4000f04f , 0x404b4042, + 0x0103ea52 , 0x0a04f04a , 0xf1ccd006 , 0x46620c00, + 0x73e2ea4f , 0x2310e9cd , 0x0c0af04f , 0x42954a4c, + 0x8089f000 , 0xf10d2200 , 0xf80b0b48 , 0xf1b82d0b, + 0xbf280f1f , 0x081ff04f , 0xa810e00d , 0x9201210a, + 0xc000f8cd , 0xf9e5f001 , 0xf80b3030 , 0x9a010d01, + 0xc000f8dd , 0x45423201 , 0xdbee4659 , 0x0f00f1b8, + 0x222ed002 , 0x2d01f801 , 0x2310e9dd , 0xd1024313, + 0xf8012230 , 0x46882d01 , 0x4661e014 , 0xf8cda810, + 0xf001c000 , 0x2809f9c6 , 0xc000f8dd , 0x3030dc01, + 0x2e58e004 , 0x3037d101 , 0x3057e000 , 0x0c01f808, + 0x38fff108 , 0x0110e9dd , 0x0201ea50 , 0xd1e446c3, + 0x0804f01a , 0x9703d101 , 0x232de005 , 0x3d01f80b, + 0x0800f04f , 0x46589703 , 0xf80ef001 , 0xf1b84606, + 0xd0030f00 , 0xbfa845c1 , 0xe00e46c1 , 0xbfac4548, + 0x46c84680 , 0xf00ae009 , 0x98020102 , 0xbf142900, + 0x21202130 , 0xbb2047a0 , 0x454e3601 , 0x2700db01, + 0xf01ae007 , 0xd0ee0f01 , 0x9802e7f9 , 0x370147a0, + 0xf81bb9b8 , 0xb1411007 , 0x0801f1b8 , 0xe004d5f5, + 0x21209802 , 0xb96047a0 , 0x454e3601 , 0xf01ada02, + 0xd1f50f01 , 0x78299f03 , 0xf47f2900 , 0x4608ae73, + 0x2003e000 , 0xe8bdb013 , 0xbf008ff0 , 0x2000762c, + 0x20007624 , 0xf000b508 , 0x4b01f83d , 0xbd081ac0, + 0x2000935c , 0xf7ffb510 , 0x4c09fff5 , 0x49094602, + 0xf7fd2000 , 0x6822feed , 0x49072000 , 0xfee8f7fd, + 0x49062000 , 0xf7fd6862 , 0x2000fee3 , 0xbf00bd10, + 0x20009000 , 0x2000763c , 0x20007646 , 0x20007650, + 0xb2c03801 , 0xbf962801 , 0xf04f4b02 , 0xf85330ff, + 0x47700020 , 0x20007674 , 0xb2c03801 , 0xd9012801, + 0x47702000 , 0xeb034b02 , 0x68800080 , 0xbf004770, + 0x20007674 , 0x681b4b02 , 0x1a186898 , 0xbf004770, + 0x20009008 , 0x68584b01 , 0xbf004770 , 0x20009008, + 0x685a4b02 , 0x0202ea40 , 0x4770605a , 0x20009008, + 0x68984b01 , 0xbf004770 , 0x20009008 , 0x41f0e92d, + 0x46044b12 , 0x460d681f , 0xb1e74690 , 0xf7ffe017, + 0x5b81ffd9 , 0x42a11983 , 0xd005789a , 0xf0223203, + 0x32040203 , 0xe00b1996 , 0x0f00f1b8 , 0xf8c8d001, + 0xb10d2000 , 0x602a78da , 0xe8bd1d18 , 0x260081f0, + 0x429e68bb , 0x2000dbe3 , 0x81f0e8bd , 0x20009008, + 0x22014b01 , 0x477060da , 0x20009008 , 0xf5b04806, + 0xd2014f70 , 0x47702001 , 0x3080f5a0 , 0x3f80f5b0, + 0x2002bf34 , 0x47702000 , 0x180049bd , 0x4604b538, + 0xf7ff460d , 0x2801ffeb , 0x2802d002 , 0xe003d11a, + 0x4370f44f , 0xe0082000 , 0x3f80f5b4 , 0xf44fd202, + 0xe0093080 , 0x3380f44f , 0x18c34618 , 0xd201429c, + 0xbd382001 , 0xd30542a0 , 0x42a0192c , 0x2000bf2c, + 0xbd382001 , 0xbd382000 , 0xf7ffb508 , 0x2802ffc7, + 0x4803d901 , 0x4b03bd08 , 0x0080eb03 , 0xbd086900, + 0x2000771c , 0x20007674 , 0x4604b538 , 0xffb6f7ff, + 0x46054284 , 0x2c00d046 , 0x4620d044 , 0xff48f7ff, + 0x3ffff1b0 , 0xd1014604 , 0xbd384820 , 0xf7ff4628, + 0x4b1fff3f , 0x1a2418e4 , 0x78617822 , 0xea427858, + 0x78a22101 , 0x4102ea41 , 0xea4178e2 , 0x781a6102, + 0x2200ea42 , 0xea427898 , 0x78d84200 , 0x6200ea42, + 0xd1214291 , 0x1025f894 , 0x2024f894 , 0x0025f893, + 0x2201ea42 , 0x1026f894 , 0x4201ea42 , 0x1027f894, + 0x6201ea42 , 0x1024f893 , 0x2100ea41 , 0x0026f893, + 0x3027f893 , 0x4100ea41 , 0x6303ea41 , 0xd103429a, + 0xbd381d20 , 0xbd384803 , 0xbd384800 , 0x2000775f, + 0x20000150 , 0x20000154 , 0x47704800 , 0x20007b20, + 0x22014b02 , 0x2000611a , 0xbf004770 , 0x20009008, + 0x6904b538 , 0x20014605 , 0xff96f7ff , 0x46012220, + 0xf0014620 , 0x2002f80b , 0xff8ef7ff , 0x46012220, + 0x0020f104 , 0xf802f001 , 0xff40f7ff , 0xd0012801, + 0xd1032802 , 0xf8842300 , 0xe0020060 , 0xf8842300, + 0xf8843060 , 0xf8843061 , 0xf8843062 , 0xf04f3063, + 0x82eb0364 , 0xbd382000 , 0x6904b538 , 0xf7fc4605, + 0x2220ffb7 , 0x46204601 , 0xffe0f000 , 0xffe6f7fc, + 0x46012220 , 0x0020f104 , 0xffd8f000 , 0xffacf7fc, + 0x46012220 , 0x0040f104 , 0xffd0f000 , 0x0360f04f, + 0x200082eb , 0x0000bd38 , 0x4604b510 , 0x8aa24905, + 0xf0006900 , 0x6920ffc3 , 0xfe3ef000 , 0x82e03001, + 0xbd102000 , 0x20007b20 , 0x4b10b570 , 0xb92b685b, + 0x2015490f , 0x4070e8bd , 0xbd76f7fd , 0x46252400, + 0x40a22201 , 0x685b4b09 , 0xd00b421a , 0x2015b11d, + 0xf7fd4908 , 0x4b08fd69 , 0xf8532015 , 0x35011024, + 0xfd62f7fd , 0x2c0e3401 , 0xbd70d1ea , 0x20009008, + 0x2000771e , 0x20006ef5 , 0x20007690 , 0x41f0e92d, + 0x46802601 , 0x2400460f , 0xf857e034 , 0x49245026, + 0xf0004628 , 0xb120fe2e , 0x49224628 , 0xfe29f000, + 0xf044b910 , 0xe0240401 , 0x491f4628 , 0xfe21f000, + 0xf024b910 , 0xe01c0401 , 0x491c4628 , 0xfe19f000, + 0xf044b910 , 0xe0140404 , 0x49194628 , 0xfe11f000, + 0x4a18b918 , 0xe8bd7510 , 0x462881f0 , 0xf0004916, + 0xb910fe08 , 0x0402f044 , 0xf106e003 , 0xe8bd000a, + 0x360181f0 , 0xdbc84546 , 0x0f01f014 , 0x2000d003, + 0xf7fd490e , 0x490efd11 , 0xf7fd2000 , 0xf7fdfd0d, + 0x4620fcf5 , 0xff58f7fc , 0xe8bd2000 , 0xbf0081f0, + 0x20007726 , 0x2000772b , 0x20007730 , 0x20007735, + 0x2000773c , 0x20009008 , 0x20007743 , 0x2000774c, + 0x20007752 , 0xf7fcb537 , 0x4605fefb , 0xff2ef7fc, + 0xf7fc4604 , 0x4623fef9 , 0x462a9000 , 0x490f2000, + 0xfccef7fd , 0x490e2000 , 0xf7fd4602 , 0x2001fcc9, + 0xfe9af7ff , 0x4602490b , 0xf7fd2000 , 0x2002fcc1, + 0xfe92f7ff , 0x46024908 , 0xf7fd2000 , 0x2000fcb9, + 0x4a074906 , 0xfcb4f7fd , 0xbd3e2000 , 0x20007760, + 0x20007773 , 0x20007780 , 0x2000778d , 0x2000779a, + 0x20007b20 , 0x2101b510 , 0x20244604 , 0xfc1ef7fc, + 0x707af44f , 0xfb66f000 , 0x21002024 , 0xfc16f7fc, + 0xffc2f7fc , 0xf000b108 , 0xf7fbfd45 , 0x4908fc67, + 0x680b4808 , 0x61582200 , 0x701a2003 , 0x68496118, + 0x3218609a , 0x605a60d9 , 0xfa2cf7fe , 0xbd1047a0, + 0x20009008 , 0x706d754a , 0x2801b570 , 0x460c4606, + 0x6848dd18 , 0x460a2100 , 0xfda6f000 , 0x46052e02, + 0x2400d101 , 0x2100e005 , 0x460a68a0 , 0xfd9cf000, + 0xb9054604 , 0x2000b134 , 0x462a4908 , 0xf7fd4623, + 0xe005fc5f , 0x49062000 , 0xfc5af7fd , 0x462c2500, + 0x46214628 , 0xff74f7fc , 0xbd702000 , 0x200077a5, + 0x200077c0 , 0x461fb5f8 , 0x46044b12 , 0x460e681b, + 0xb1eb4615 , 0x4a106959 , 0xd1194291 , 0xdd012dff, + 0xbdf82005 , 0x1cea6899 , 0xf0223104 , 0x188a0203, + 0xf7ff609a , 0x8004fd77 , 0x70c67085 , 0x4628b90d, + 0x3004bdf8 , 0x462a4639 , 0xfdf2f000 , 0xbdf82000, + 0xbdf82001 , 0x20009008 , 0x706d754a , 0x4604b510, + 0x78426880 , 0xea437803 , 0x78822302 , 0x4302ea43, + 0xea5378c2 , 0xd0026302 , 0xd10e2b01 , 0x6920e008, + 0xfe36f7fc , 0xb9404603 , 0x0210f04f , 0xe00582e2, + 0xf7fc3004 , 0x4603fe3f , 0x2302b100 , 0xbd104618, + 0xf7ffb570 , 0x4b20fa6f , 0x28004a20 , 0x4618bf08, + 0x38184b1f , 0x69416018 , 0xd12e4291 , 0x2a006902, + 0x6859dd2b , 0xd1282900 , 0x60993101 , 0x2a0168c1, + 0x6180f441 , 0xd00f6059 , 0xd1012a02 , 0xe0032508, + 0xf1d56845 , 0xd0070518 , 0xb12c6884 , 0xfd1af7ff, + 0x19414622 , 0xfdedf000 , 0x681b4b0d , 0x2a01691a, + 0x2200dc01 , 0x691a609a , 0xdc012a02 , 0x701a2200, + 0x605a2218 , 0x615a3a18 , 0x2100bd70 , 0xe8bd2218, + 0xf0004070 , 0xbf00bdb4 , 0x2000c000 , 0x706d754a, + 0x20009008 , 0x4b07b508 , 0xb10b691b , 0xbd082001, + 0xfd46f7fd , 0xf01043c0 , 0xbf140f0a , 0x20012000, + 0xbf00bd08 , 0x20009008 , 0x4c22b538 , 0x68624922, + 0xf7fd2000 , 0xf7fffb9d , 0x4920fe2f , 0xf7fd2000, + 0xf7fffb97 , 0x491efd59 , 0x20004602 , 0xfb90f7fd, + 0x68a54b1c , 0x20004a1c , 0x4285491c , 0x461abf08, + 0xfb86f7fd , 0x2000491a , 0xfb96f7fd , 0xffcaf7ff, + 0x2000b178 , 0xf7fd4917 , 0x6923fb8f , 0x2000b11b, + 0xf7fd4915 , 0x4b0bfb89 , 0xb12b68db , 0x49132000, + 0x4913e000 , 0xfb80f7fd , 0x49122000 , 0xfb7cf7fd, + 0x7d1a4b04 , 0x2000b11a , 0xf7fd490f , 0x2000fb61, + 0xbf00bd38 , 0x20009008 , 0x200077e6 , 0x20006e58, + 0x200077fc , 0x20007808 , 0x2000780b , 0x2000780f, + 0x2000781b , 0x20007823 , 0x2000782b , 0x20007835, + 0x20007844 , 0x2000775e , 0x2000784e , 0x4605b570, + 0xfcccf7ff , 0x460442a8 , 0x2000d101 , 0xf7ffbd70, + 0xb130ff81 , 0xd1232c01 , 0xd1212d02 , 0x68db4b12, + 0x4628b9f3 , 0xfc54f7ff , 0x3ffff1b0 , 0xd1014606, + 0xbd702005 , 0x42846844 , 0x4628d314 , 0xfc54f7ff, + 0x42841980 , 0x4b09d20e , 0xeb034909 , 0x692a0585, + 0xf7fd2015 , 0x4620fb8d , 0xfe6cf7ff , 0xbd702001, + 0xbd702007 , 0xbd702001 , 0x20009008 , 0x20007674, + 0x20007866 , 0x2806b510 , 0xe8dfd805 , 0x0614f000, + 0x120d0408 , 0x20050016 , 0x2001bd10 , 0x2002e000, + 0x4010e8bd , 0xbfb2f7ff , 0xf7fc2001 , 0x2001fd55, + 0xf7ffbd10 , 0x2000fc75 , 0x2015bd10 , 0xf7fd4904, + 0x2000fb5f , 0xf7fc4601 , 0x2001fe03 , 0xbf00bd10, + 0x2000787a , 0x7d184b01 , 0xbfd4f7ff , 0x20009008, + 0x4604b513 , 0xa80168a1 , 0xf0002202 , 0xf89dfc99, + 0xb9100004 , 0x75184b15 , 0xf89de027 , 0xf0133005, + 0xd0030f02 , 0x75184b11 , 0xe01e2000 , 0xb2db1e43, + 0xd9032b01 , 0xd0012804 , 0xd1042806 , 0x76232300, + 0xf7fe4620 , 0x2015f943 , 0xf89d4909 , 0xf7fd2004, + 0xf89dfb27 , 0xf7ff0004 , 0x2807ffa5 , 0x2002d901, + 0x4b04e003 , 0x0080eb03 , 0xbd1c6d40 , 0x20009008, + 0x2000788d , 0x20007674 , 0x2801b537 , 0xdc01460d, + 0xe0392014 , 0x491d684c , 0xf0004620 , 0xb908fb8a, + 0xe00a3001 , 0x491a4620 , 0xfb83f000 , 0x4620b120, + 0xf0004918 , 0xb918fb7e , 0xf7ff2002 , 0xe023ff3f, + 0x49154620 , 0xfb75f000 , 0xb9104604 , 0xfc00f7ff, + 0xf7ffe019 , 0x4602febf , 0x2007b108 , 0x6868e014, + 0xf000a901 , 0x9b01fba1 , 0x781c4605 , 0x200bb10c, + 0x490ae00a , 0x4620462a , 0xfa62f7fd , 0xfa5ef7fd, + 0xf7ff4628 , 0x4620fdb7 , 0xbf00bd3e , 0x20006969, + 0x20006a3f , 0x20006994 , 0x20006f02 , 0x200078ae, + 0x3f00e850 , 0x0301ea43 , 0x3200e840 , 0x0f00f092, + 0x4770d1f6 , 0xf644b513 , 0x46695054 , 0xf7ffaa01, + 0xb150fb9d , 0x2a019a00 , 0x9a01d107 , 0xd1042a08, + 0x4c056842 , 0x68006022 , 0x4c03e002 , 0x60202000, + 0xfb14f7fc , 0xbd1c6060 , 0x20009028 , 0x4d08b570, + 0x682e4604 , 0xf7fc6046 , 0x6020fa7f , 0x429e682b, + 0x682bd004 , 0xf7fc6063 , 0x6020fa77 , 0xbd704620, + 0x20009028 , 0xa802b51f , 0xffe8f7ff , 0x9b039a02, + 0x49042000 , 0x93019200 , 0xfa0af7fd , 0xb0052000, + 0xbf00bd00 , 0x20007a30 , 0x4668b513 , 0xffd6f7ff, + 0x22082101 , 0xf644466b , 0x466c5054 , 0xfdaaf7ff, + 0x0000bd1c , 0x43f0e92d , 0x4e20b087 , 0xf7ffa804, + 0xf8ddffc5 , 0xf8dd8010 , 0xf8569014 , 0xf7fc7b08, + 0x2400fa2d , 0x0200ea44 , 0x46394610 , 0x0100e9cd, + 0x0008ebb0 , 0x0109eb61 , 0x0102e9cd , 0x49144642, + 0x4620464b , 0xf7fd463d , 0xf7fdf9d3 , 0x2201f9cf, + 0x4b0e40a2 , 0x421a6b1b , 0xe9d6d010 , 0xe9cd2300, + 0xebb22300 , 0xeb630208 , 0xe9cd0309 , 0x49092302, + 0x20004622 , 0xf9bcf7fd , 0xf9b8f7fd , 0x36083401, + 0xd1e42c05 , 0xe8bdb007 , 0xbf0083f0 , 0x20009028, + 0x20007a4a , 0x20007a99 , 0xf7ffb508 , 0x2000ffb3, + 0xb530bd08 , 0x4604b085 , 0x4613460d , 0x4668b93a, + 0xff74f7ff , 0x0100e9dd , 0xe963ab04 , 0xe9d30102, + 0x1b122300 , 0x0305eb63 , 0x0fc043d8 , 0xbd30b005, + 0x4605b538 , 0xf9e8f7fc , 0xf7fc4604 , 0x1b00f9e5, + 0xd3fa42a8 , 0xb513bd38 , 0xdc012801 , 0xe00f2014, + 0x22006848 , 0xf000a901 , 0x9b01faaf , 0xb10c781c, + 0xe005200b , 0x737af44f , 0xf7ff4358 , 0x4620ffe1, + 0x0000bd1c , 0x2a04b5f8 , 0x460c4606 , 0xd9054615, + 0x49144813 , 0x23774a14 , 0xf880f7ff , 0x40a92101, + 0x6b3b4f12 , 0xd0014219 , 0xbdf82006 , 0x05c5eb07, + 0x60ec60ae , 0x0030f107 , 0xff02f7ff , 0x429c683b, + 0x683bd306 , 0xd109429c , 0x681b4b09 , 0xd30542b3, + 0x68584b06 , 0xf960f7fb , 0xbdf82000 , 0xbdf82000, + 0x20007ab9 , 0x200079f0 , 0x20007acf , 0x20009028, + 0x20009358 , 0x4604b570 , 0xf928f7fb , 0x4620b920, + 0x4070e8bd , 0xbf9cf7ff , 0x480bb92c , 0x4a0c490b, + 0xf7ff239c , 0x2500f843 , 0xf7fb4620 , 0x4305fa6f, + 0xf7fbd5fa , 0xf7fbf8fd , 0xf025f90b , 0xe8bd4100, + 0xf7ff4070 , 0xbf00bec5 , 0x20007ade , 0x200079fc, + 0x20007acf , 0xe8534b05 , 0xea211f00 , 0xe8430100, + 0xf0921200 , 0xd1f60f00 , 0xbf004770 , 0x20009058, + 0x47ffe92d , 0x4b30b118 , 0x3201681a , 0xf04f601a, + 0xf04f32ff , 0x466833ff , 0x2302e9cd , 0xfec6f7ff, + 0x8004f8dd , 0x46479e00 , 0xf8d34b27 , 0x4654a030, + 0xfab4e027 , 0xf1c5f584 , 0xeb03051f , 0xe9d303c5, + 0x42860102 , 0x0201eb77 , 0xfa5fd30d , 0x2001f985, + 0xf009fa00 , 0xffc6f7ff , 0xf04f4648 , 0x22004100, + 0xfa66f7fb , 0x68dae008 , 0xd1054542 , 0x9b02689a, + 0xd201429a , 0x0102e9cd , 0xfa132301 , 0xea24f505, + 0x4b110405 , 0xd1d42c00 , 0xea336b1b , 0xd1cb030a, + 0x4c0e9d03 , 0x3ffff1b5 , 0xf7fcd103 , 0x6025f8fd, + 0x9d02e00f , 0xf7fc4628 , 0x6025f8a7 , 0xe9dd4668, + 0xf7ff4502 , 0xe9ddfe7b , 0x42a22300 , 0x0105eb73, + 0xe8bdd2a5 , 0xbf0087ff , 0x20009028 , 0x20009358, + 0x2804b510 , 0xd9054604 , 0x49064805 , 0x23894a06, + 0xffacf7fe , 0x40a02001 , 0x4010e8bd , 0xbf7af7ff, + 0x20007ab9 , 0x20007a04 , 0x20007acf , 0x290ab510, + 0xd104460c , 0x210d2000 , 0xfff8f7ff , 0x4b08b970, + 0x6859681a , 0x05d23201 , 0x428a0dd2 , 0x6819d006, + 0x18c9b2e4 , 0x2000720c , 0xbd10601a , 0xbd102001, + 0x20009060 , 0xf8d3e00f , 0x18d22208 , 0x020cf892, + 0x2208f8d3 , 0xf0023201 , 0x2811027f , 0x2208f8c3, + 0x2813d001 , 0x4b05d108 , 0x1208f8d3 , 0x228cf8d3, + 0xd1e84291 , 0x30fff04f , 0xbf004770 , 0x20009060, + 0x4604b538 , 0xf7ff6905 , 0xb108fc8d , 0xbd382007, + 0xf8d24a12 , 0xf8d21290 , 0x42912294 , 0xbd38d10c, + 0x7a1818d3 , 0x7a1bb128 , 0x3b01f805 , 0x33018ae3, + 0x320182e3 , 0x0dd205d2 , 0xd101428a , 0xe0054b07, + 0x8ae08aa3 , 0x42983b01 , 0xdbe94b04 , 0xf8c32000, + 0x70282294 , 0x33018ae3 , 0xbd3882e3 , 0x20009060, + 0xf7ffb508 , 0xb108fc5f , 0xbd082007 , 0x68114a0d, + 0x05db1c4b , 0xf8c20ddb , 0xf8c21290 , 0xe0093294, + 0x7a001898 , 0xf8c2b118 , 0x20003294 , 0x3301bd08, + 0x0ddb05db , 0x4a03428b , 0xf8c2d1f2 , 0x20003294, + 0xbf00bd08 , 0x20009060 , 0x4604b510 , 0x2000e004, + 0xf7ff3401 , 0xb910ff6b , 0x29007821 , 0x4b06d1f7, + 0x3298f8d3 , 0xf7fcb90b , 0x7820fbe1 , 0xbf142800, + 0x20002003 , 0xbf00bd10 , 0x20009060 , 0x4601b510, + 0xf7ff2000 , 0x4b06ff53 , 0xf8d34604 , 0xb90b3298, + 0xfbccf7fc , 0xbf142c00 , 0x20002003 , 0xbf00bd10, + 0x20009060 , 0x460bb510 , 0x21004602 , 0xf7fe4805, + 0x4b05ff21 , 0xf8d34604 , 0xb90b3298 , 0xfbb6f7fc, + 0xbd104620 , 0x2000559d , 0x20009060 , 0x2400b510, + 0xf7fce024 , 0x4b16fb0b , 0xf8d32813 , 0xd105228c, + 0xf8c32201 , 0xf7fc2298 , 0xe017fb85 , 0xd1052811, + 0xf8c32200 , 0xf7fc2298 , 0xe00ffb99 , 0xf8d33201, + 0xf0021208 , 0x428a027f , 0xf8d3d008 , 0xb2c0128c, + 0xf88118c9 , 0x2401020c , 0x228cf8c3 , 0xfad2f7fc, + 0xd1d62800 , 0xe8bdb11c , 0xf7fc4010 , 0xbd10bd1d, + 0x20009060 , 0x4c16b570 , 0x6298f8d4 , 0x2e006825, + 0xf7fcd125 , 0x2800fab7 , 0xf8d4d021 , 0xb133329c, + 0xf8c46862 , 0x18d3629c , 0x0ddb05db , 0x4b0c6063, + 0x4295685a , 0xe8bdd103 , 0xf7fc4070 , 0x685abb43, + 0x42956859 , 0xf44fbfd8 , 0x1a697500 , 0xf8c3685a, + 0x3308129c , 0xe8bd1898 , 0xf7fc4070 , 0xbd70bb13, + 0x20009060 , 0x4b0bb510 , 0x3298f8d3 , 0xbd10b143, + 0xff20f7fa , 0xf7ffb110 , 0xe001ffc5 , 0xfb3ef7fc, + 0x681a4b04 , 0x429a685b , 0xe8bdd1f2 , 0xf7fc4010, + 0xbf00ba69 , 0x20009060 , 0xe0002300 , 0x5cc23301, + 0xd1fb2a00 , 0x47704618 , 0xd0082820 , 0xd0062809, + 0xd004280d , 0xbf14280a , 0x20012000 , 0x20014770, + 0xf1a04770 , 0x2b190341 , 0x2001d801 , 0x38614770, + 0xbf8c2819 , 0x20012000 , 0x38204770 , 0xbf8c285e, + 0x20012000 , 0xf1a04770 , 0x2b190341 , 0x3020bf98, + 0xe92d4770 , 0x250045f8 , 0x468a4604 , 0x46385d67, + 0xfff1f7ff , 0x6005f81a , 0x46304680 , 0xffebf7ff, + 0x0000ebb8 , 0xb117d103 , 0x2e003501 , 0xe8bdd1ee, + 0xe92d85f8 , 0x460447f0 , 0x4615460e , 0x4610b912, + 0x87f0e8bd , 0xf8142700 , 0x4650a007 , 0xffd3f7ff, + 0x8007f816 , 0x46404681 , 0xffcdf7ff , 0x0000ebb9, + 0xf1bad108 , 0xd0050f00 , 0x0f00f1b8 , 0x3701d002, + 0xd1e842bd , 0x87f0e8bd , 0x4604b5f8 , 0x460e4615, + 0x6030b101 , 0x7b01f814 , 0x4638b17f , 0xff94f7ff, + 0x28004603 , 0x2f30d1f6 , 0xd106463a , 0x29787821, + 0x7862d104 , 0x34022510 , 0x463ae00a , 0x2300b10d, + 0x2f2de006 , 0x462bbf12 , 0x2b01f814 , 0x250a2301, + 0xe01f2000 , 0xdd1f2a2f , 0xbfb42d0a , 0x210a4629, + 0x428a3130 , 0x3a30da01 , 0x2a40e00e , 0xf105dd14, + 0x428a0137 , 0x3a37da01 , 0x2a60e006 , 0xf105dd0c, + 0x428a0157 , 0x3a57da08 , 0x2000fb05 , 0x6034b106, + 0x2b01f814 , 0xd1dd2a00 , 0x4240b103 , 0x0000bdf8, + 0x460eb570 , 0x46054915 , 0xff73f7ff , 0x4628b168, + 0x22034913 , 0xff85f7ff , 0x7828b138 , 0xff63f7ff, + 0x46042866 , 0x286ed001 , 0x2300d103 , 0x20016033, + 0x4628bd70 , 0xf7ff490b , 0xb158ff5c , 0x490a4628, + 0xf7ff2203 , 0xb128ff6e , 0xd0032c74 , 0xd0012c79, + 0xbd702000 , 0x60302001 , 0xbf00bd70 , 0x20007738, + 0x20007b18 , 0x200079bb , 0x20007b1c , 0xf04fb510, + 0x46030c00 , 0xf813e008 , 0xf811400c , 0x3a01000c, + 0xf10c1a20 , 0xd1020c01 , 0xdcf42a00 , 0xbd102000, + 0xea81b530 , 0x18820400 , 0x0f03f014 , 0xf0224603, + 0xd1040c03 , 0xf0241cc4 , 0x42a20403 , 0x4614d205, + 0xf811e003 , 0xf8035c01 , 0x460d5b01 , 0x42a33101, + 0x4629d3f7 , 0xf851e003 , 0xf8434c04 , 0x460c4b04, + 0x45633104 , 0x2100d3f7 , 0xf814e004 , 0xf803c001, + 0x3101c001 , 0x0c03eb01 , 0xd3f64594 , 0xb530bd30, + 0x040cb2c9 , 0x2401ea44 , 0x18821cc5 , 0xf025430c, + 0x46030503 , 0x0c03f022 , 0x6401ea44 , 0xbf3842aa, + 0xe0014615 , 0x1b01f803 , 0xd3fb42ab , 0xf843e001, + 0x45634b04 , 0xe001d3fb , 0x1b01f803 , 0xd3fb4293, + 0xb510bd30 , 0xd9024288 , 0x42981853 , 0xe8bdd303, + 0xf7ff4010 , 0xea81bfa5 , 0x1cc40c00 , 0xf01c1883, + 0xf0240f03 , 0xd1030403 , 0x0c03f023 , 0xd9004560, + 0x18894684 , 0xf811e003 , 0xf8032d01 , 0x45632d01, + 0xe003d8f9 , 0x2d04f851 , 0x2d04f843 , 0xd8f942a3, + 0xf04f461c , 0xe0040c00 , 0x200cf811 , 0xf8033c01, + 0x4284200c , 0x3cfff10c , 0xbd10d8f6 , 0x2a00b530, + 0x2300dd0e , 0x54c4e001 , 0xebc33301 , 0x181d0c02, + 0x0f01f1bc , 0x5cccd002 , 0xd1f42c00 , 0x702b2300, + 0xe92dbd30 , 0x46034ff0 , 0xb931460a , 0x21002000, + 0x0100e9c3 , 0xe8bd4610 , 0x29028ff0 , 0xe9d0d10a, + 0xf0044500 , 0x086d0001 , 0x0434ea4f , 0x4500e9c3, + 0x8ff0e8bd , 0xd1092910 , 0x68426801 , 0x000ff001, + 0xea410909 , 0x60197102 , 0xe00c0912 , 0x8900e9d0, + 0x0f00f1b8 , 0x0101f179 , 0xfbb8d208 , 0xfb02f1f2, + 0x60198011 , 0x605a2200 , 0x8ff0e8bd , 0x46082100, + 0xf04f2400 , 0x26004500 , 0xea042700 , 0xea050a08, + 0x00400b09 , 0x0c0bea5a , 0xf040bf18 , 0x42900001, + 0x1a80db02 , 0x432f4326 , 0x086d3101 , 0x0434ea4f, + 0xd1ea2940 , 0x6700e9c3 , 0x8ff0e8bd , 0x46036802, + 0xf082fab2 , 0x001ff1c0 , 0x40812101 , 0x0201ea22, + 0x4770601a , 0x00000103 , 0x00000129 , 0x0000030b, + 0x0000030c , 0x0000030d , 0x0000030e , 0x0000030f, + 0x00000310 , 0x00000311 , 0x00000106 , 0x00000107, + 0x00000108 , 0x00000109 , 0x0000010a , 0x00000117, + 0x00000128 , 0x0000011d , 0x0000011e , 0x00000019, + 0x00000225 , 0x20006cb8 , 0x200026e5 , 0x20006cf9, + 0x20006d15 , 0x200074e0 , 0x200043f9 , 0x200075ce, + 0x200075e4 , 0x20006e08 , 0x20002a55 , 0x00000000, + 0x20006f0f , 0x20006e14 , 0x20002dc9 , 0x20006f20, + 0x20006f45 , 0x20007a1c , 0x20005275 , 0x00000000, + 0x20007af4 , 0x20006f60 , 0x200030f1 , 0x20006f7b, + 0x20006f82 , 0x20006f68 , 0x2000309d , 0x20006f95, + 0x20006fa2 , 0x2000704c , 0x200034f9 , 0x20007105, + 0x2000712d , 0x20006a6c , 0x20002009 , 0x20006b94, + 0x20006ba6 , 0x200076f0 , 0x20004da9 , 0x200078d3, + 0x200078e0 , 0x20006a74 , 0x20001f25 , 0x00000000, + 0x20006bb9 , 0x20007164 , 0x20003879 , 0x200071dc, + 0x2000720d , 0x2000726c , 0x20003dc5 , 0x200073c1, + 0x200073d3 , 0x20007264 , 0x20003c61 , 0x20007382, + 0x20007395 , 0x200074e8 , 0x2000439d , 0x00000000, + 0x20007603 , 0x2000770c , 0x20004c1d , 0x2000793d, + 0x20007966 , 0x2000745c , 0x200042fd , 0x200074ab, + 0x200074b0 , 0x20007634 , 0x200048b5 , 0x00000000, + 0x2000765a , 0x200076e8 , 0x20004f59 , 0x00000000, + 0x200078c1 , 0x20007704 , 0x20005169 , 0x20007900, + 0x2000791b , 0x20007714 , 0x20004b01 , 0x00000000, + 0x20007974 , 0x200063a8 , 0x20000885 , 0x00000000, + 0x200064ac , 0x20007a24 , 0x20005349 , 0x00000000, + 0x20007b07 , 0x200076fc , 0x20004ce5 , 0x00000000, + 0x200078f1 , 0x20007a14 , 0x20005397 , 0x20007aef, + 0x20007ae1 , 0x20007458 , 0x20004331 , 0x20007489, + 0x20007494 , 0x20002849 , 0x00000010 , 0x00000003, + 0x20002933 , 0x00000011 , 0x00000001 , 0x20002e67, + 0x00000012 , 0x00000003 , 0x20002bc1 , 0x00000013, + 0x00000001 , 0x20002d39 , 0x00000015 , 0x00000003, + 0x200028c5 , 0x00000016 , 0x00000002 , 0x20002fed, + 0x00000093 , 0x00000003 , 0x20002fa9 , 0x00000092, + 0x00000001 , 0x200033e5 , 0x00000000 , 0x00000001, + 0x200033fd , 0x00000001 , 0x00000001 , 0x20003439, + 0x00000003 , 0x00000001 , 0x200035a1 , 0x00000007, + 0x00000001 , 0x200034a1 , 0x00000008 , 0x00000001, + 0x200034d1 , 0x000000b6 , 0x00000001 , 0x20003549, + 0x0000000a , 0x00000001 , 0x20003765 , 0x00000087, + 0x00000001 , 0x2000380d , 0x0000008c , 0x00000001, + 0x200037b9 , 0x0000008f , 0x00000001 , 0x20003a61, + 0x00000060 , 0x00000001 , 0x20003905 , 0x00000061, + 0x00000001 , 0x20003ac9 , 0x00000064 , 0x00000001, + 0x20003929 , 0x00000065 , 0x00000001 , 0x20003ea9, + 0x00000062 , 0x00000001 , 0x20004501 , 0x000000d3, + 0x00000001 , 0x20004b11 , 0x00000002 , 0x00000001, + 0x20004ba9 , 0x00000004 , 0x00000001 , 0x20004b69, + 0x00000005 , 0x00000001 , 0x20004e5d , 0x00000017, + 0x00000003 , 0x200050f1 , 0x000000d2 , 0x00000001, + 0x20005671 , 0x00000097 , 0x00000001 , 0x20005611, + 0x00000098 , 0x00000001 , 0x20001477 , 0x00001388, + 0x2000180d , 0x00001388 , 0x20001d79 , 0x00001388, + 0x20003cd9 , 0x00001388 , 0x200013b5 , 0x00001388, + 0x20005299 , 0x00001388 , 0x200050e5 , 0x00001388, + 0x20001f15 , 0x00001388 , 0x72303172 , 0x31723131, + 0x20707332 , 0x7020726c , 0x00002063 , 0x20006184, + 0x200061a1 , 0x00000000 , 0x200061b7 , 0x200061d8, + 0x00000000 , 0x00000000 , 0x00000000 , 0x200061f7, + 0x2000620d , 0x20006224 , 0x2000623d , 0x2000625e, + 0x00000000 , 0x00000000 , 0x00000000 , 0x2000627d, + 0x20006294 , 0x200062a2 , 0x200062ad , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x200062bc, + 0x200062c6 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x200062d2, + 0x200062df , 0x200062ea , 0x20006300 , 0x2000630d, + 0x63256325 , 0x003a6325 , 0x20202020 , 0x20202020, + 0x4f525000 , 0x53534543 , 0x4e414800 , 0x52454c44, + 0x3d3d0a00 , 0x7325203d , 0x43584520 , 0x49545045, + 0x203a4e4f , 0x78323025 , 0x3d3d3d20 , 0x203d3d3d, + 0x52535078 , 0x3025203a , 0x3d207838 , 0x000a3d3d, + 0x75626544 , 0x76652067 , 0x00746e65 , 0x63726f46, + 0x68206465 , 0x20647261 , 0x6c756166 , 0x65560074, + 0x726f7463 , 0x62617420 , 0x6220656c , 0x66207375, + 0x746c7561 , 0x62202c00 , 0x20726166 , 0x7825203d, + 0x6d202c00 , 0x20726166 , 0x7825203d , 0x6d6d0a00, + 0x3d207366 , 0x2c782520 , 0x68730020 , 0x20727363, + 0x7825203d , 0x6800202c , 0x20727366 , 0x7825203d, + 0x6400202c , 0x20727366 , 0x7825203d , 0x3d0a000a, + 0x3d3d3d3d , 0x3d3d3d3d , 0x50203d3d , 0x65636f72, + 0x53207373 , 0x6b636174 , 0x6e6f4320 , 0x746e6574, + 0x3d3d2073 , 0x3d3d3d3d , 0x3d3d3d3d , 0x250a003d, + 0x3a783830 , 0x30252000 , 0x0a007838 , 0x20646142, + 0x00707370 , 0x74736e49 , 0x74637572 , 0x206e6f69, + 0x65636361 , 0x76207373 , 0x616c6f69 , 0x6e6f6974, + 0x74614400 , 0x63612061 , 0x73736563 , 0x6f697620, + 0x6974616c , 0x55006e6f , 0x6174736e , 0x66206b63, + 0x206d6f72 , 0x65637865 , 0x6f697470 , 0x6976206e, + 0x74616c6f , 0x006e6f69 , 0x63617453 , 0x7266206b, + 0x65206d6f , 0x70656378 , 0x6e6f6974 , 0x6f697620, + 0x6974616c , 0x49006e6f , 0x7274736e , 0x69746375, + 0x62206e6f , 0x65207375 , 0x726f7272 , 0x65725000, + 0x65736963 , 0x74616420 , 0x75622061 , 0x72652073, + 0x00726f72 , 0x72706d49 , 0x73696365 , 0x61642065, + 0x62206174 , 0x65207375 , 0x726f7272 , 0x736e5500, + 0x6b636174 , 0x6f726620 , 0x7865206d , 0x74706563, + 0x206e6f69 , 0x20737562 , 0x6c756166 , 0x74530074, + 0x206b6361 , 0x6d6f7266 , 0x63786520 , 0x69747065, + 0x62206e6f , 0x66207375 , 0x746c7561 , 0x646e5500, + 0x6e696665 , 0x69206465 , 0x7274736e , 0x69746375, + 0x00736e6f , 0x61766e49 , 0x2064696c , 0x74617473, + 0x6e490065 , 0x696c6176 , 0x43502064 , 0x206f4e00, + 0x72706f63 , 0x7365636f , 0x00726f73 , 0x6c616e55, + 0x656e6769 , 0x69440064 , 0x65646976 , 0x20796220, + 0x61480030 , 0x7220746c , 0x65757165 , 0x42007473, + 0x6b616572 , 0x6e696f70 , 0x61440074 , 0x77206174, + 0x68637461 , 0x6e696f70 , 0x72742f74 , 0x00656361, + 0x74636556 , 0x6320726f , 0x68637461 , 0x74784500, + 0x616e7265 , 0x6564206c , 0x20677562 , 0x75716572, + 0x00747365 , 0x00000000 , 0x20000639 , 0x00000100, + 0x00000000 , 0x20003261 , 0x000001e8 , 0x00000000, + 0x200036c1 , 0x000001e8 , 0x00000000 , 0x200021e5, + 0x000001e8 , 0x00000000 , 0x20003fb5 , 0x00000168, + 0x200064bc , 0x200064c7 , 0x200064cd , 0x200064d5, + 0x200064dd , 0x61775f5f , 0x655f7469 , 0x00007476, + 0x6574756d , 0x6f6c5f78 , 0x00006b63 , 0x6b736174, + 0x7465735f , 0x6576655f , 0x0000746e , 0x5f637673, + 0x646e6168 , 0x0072656c , 0x6b736174 , 0x6f666e69, + 0x00000000 , 0x6b736154 , 0x61655220 , 0x4e207964, + 0x20656d61 , 0x20202020 , 0x20202020 , 0x6e657645, + 0x20207374 , 0x20202020 , 0x656d6954 , 0x29732820, + 0x74532020 , 0x6573556b , 0x25000a64 , 0x25206434, + 0x2d252063 , 0x20733631 , 0x78383025 , 0x31312520, + 0x646c362e , 0x33252020 , 0x33252f64 , 0x21000a64, + 0x695f6e69 , 0x7265746e , 0x74707572 , 0x6e6f635f, + 0x74786574 , 0x63002928 , 0x2f65726f , 0x74726f63, + 0x6d2d7865 , 0x7361742f , 0x00632e6b , 0x20746572, + 0x45203d3d , 0x55535f43 , 0x53454343 , 0x61540053, + 0x25206b73 , 0x25282064 , 0x65202973 , 0x65746978, + 0x69002164 , 0x3d212064 , 0x53415420 , 0x44495f4b, + 0x564e495f , 0x44494c41 , 0x63657200 , 0x65766965, + 0x0a0a0072 , 0x63617453 , 0x766f206b , 0x6c667265, + 0x6920776f , 0x7325206e , 0x73617420 , 0x000a216b, + 0x6b736174 , 0x65725f73 , 0x00796461 , 0x6e697250, + 0x61742074 , 0x69206b73 , 0x006f666e , 0x69203c3c, + 0x20656c64 , 0x48003e3e , 0x534b4f4f , 0x534f4800, + 0x444d4354 , 0x4e4f4300 , 0x454c4f53 , 0x59454b00, + 0x4e414353 , 0x23232300 , 0x54415720 , 0x4f444843, + 0x43502047 , 0x3830253d , 0x202f2078 , 0x253d524c, + 0x20783830 , 0x5370202f , 0x30253d50 , 0x00207838, + 0x63786528 , 0x23232029 , 0x28000a23 , 0x6b736174, + 0x29642520 , 0x23232320 , 0x0000000a , 0x6f697067, + 0x7465735f , 0x616c665f , 0x625f7367 , 0x616d5f79, + 0x00006b73 , 0x6c662821 , 0x20736761 , 0x47282026, + 0x5f4f4950 , 0x5f544e49 , 0x4f4c5f46 , 0x207c2057, + 0x4f495047 , 0x544e495f , 0x485f465f , 0x29484749, + 0x68630029 , 0x732f7069 , 0x32336d74 , 0x6970672f, + 0x74732d6f , 0x6632336d , 0x4f00632e , 0x72726576, + 0x6e696469 , 0x73252067 , 0x74697720 , 0x73252068, + 0x206e6f20 , 0x49545845 , 0x73006425 , 0x73006d74, + 0x32336d74 , 0x78303166 , 0x6d747300 , 0x31663233, + 0x752d7830 , 0x6661736e , 0x69680065 , 0x6e726562, + 0x20657461 , 0x20746f6e , 0x70707573 , 0x6574726f, + 0x73202c64 , 0x6572206f , 0x746f6f62 , 0x00676e69, + 0x00000003 , 0x40013804 , 0x00000000 , 0x200068e4, + 0x40010c00 , 0x00000100 , 0x00000312 , 0x20001a8b, + 0x200068ec , 0x40010c00 , 0x00000200 , 0x00000312, + 0x20001a8b , 0x200068f4 , 0x40010c00 , 0x00000400, + 0x00000312 , 0x20001a8b , 0x200068fc , 0x40010c00, + 0x00000800 , 0x00000312 , 0x20001a8b , 0x20006904, + 0x40010c00 , 0x00001000 , 0x00000312 , 0x20001a8b, + 0x2000690c , 0x40010c00 , 0x00002000 , 0x00000312, + 0x20001a8b , 0x20006914 , 0x40010c00 , 0x00004000, + 0x00000312 , 0x20001a8b , 0x2000691c , 0x40010c00, + 0x00008000 , 0x00000312 , 0x20001a8b , 0x20006924, + 0x40010c00 , 0x00000004 , 0x00000010 , 0x00000000, + 0x20006933 , 0x40010800 , 0x00000001 , 0x00000010, + 0x00000000 , 0x2000693e , 0x40010800 , 0x00000004, + 0x000000a1 , 0x00000000 , 0x20006949 , 0x40010800, + 0x00000008 , 0x00000010 , 0x00000000 , 0x20006955, + 0x40010800 , 0x00000100 , 0x00000010 , 0x00000000, + 0x20006960 , 0x40010c00 , 0x00000001 , 0x00000010, + 0x00000000 , 0x2000696c , 0x40010c00 , 0x00000002, + 0x00000010 , 0x00000000 , 0x20006979 , 0x40010c00, + 0x00000020 , 0x00000010 , 0x00000000 , 0x20006984, + 0x40010c00 , 0x00000040 , 0x00000010 , 0x00000000, + 0x2000698d , 0x40010c00 , 0x00000080 , 0x00000010, + 0x00000000 , 0x20006996 , 0x40011000 , 0x00000001, + 0x00000061 , 0x00000000 , 0x2000699f , 0x40011000, + 0x00000002 , 0x00000061 , 0x00000000 , 0x200069a8, + 0x40011000 , 0x00000004 , 0x00000061 , 0x00000000, + 0x200069b1 , 0x40011000 , 0x00000008 , 0x00000061, + 0x00000000 , 0x200069ba , 0x40011000 , 0x00000010, + 0x00000061 , 0x00000000 , 0x200069c3 , 0x40011000, + 0x00000020 , 0x00000061 , 0x00000000 , 0x200069cc, + 0x40011000 , 0x00000040 , 0x00000061 , 0x00000000, + 0x200069d5 , 0x40011000 , 0x00000080 , 0x00000061, + 0x00000000 , 0x200069de , 0x40011000 , 0x00000100, + 0x00000061 , 0x00000000 , 0x200069e7 , 0x40011000, + 0x00000200 , 0x00000061 , 0x00000000 , 0x200069f0, + 0x40011000 , 0x00000400 , 0x00000061 , 0x00000000, + 0x200069f9 , 0x40011000 , 0x00000800 , 0x00000061, + 0x00000000 , 0x20006a02 , 0x40011000 , 0x00001000, + 0x00000061 , 0x00000000 , 0x20006a0b , 0x40011000, + 0x00002000 , 0x00000060 , 0x00000000 , 0x20006a19, + 0x40011000 , 0x00004000 , 0x000000a1 , 0x00000000, + 0x20006a23 , 0x40011400 , 0x00000004 , 0x00000010, + 0x00000000 , 0x20006a28 , 0x40010800 , 0x00000002, + 0x00000020 , 0x00000000 , 0x20006a2f , 0x40010800, + 0x00000000 , 0x00000000 , 0x00000000 , 0x20006a36, + 0x40010800 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x495f424b , 0x0030304e , 0x495f424b, + 0x0031304e , 0x495f424b , 0x0032304e , 0x495f424b, + 0x0033304e , 0x495f424b , 0x0034304e , 0x495f424b, + 0x0035304e , 0x495f424b , 0x0036304e , 0x495f424b, + 0x0037304e , 0x5f44424b , 0x5f525750 , 0x54545542, + 0x4f004e4f , 0x5f4f5a4d , 0x5f594452 , 0x5a4f004c, + 0x525f4f4d , 0x4c5f5453 , 0x55425600 , 0x50555f53, + 0x5445445f , 0x4d5a4f00 , 0x45525f4f , 0x004c5f51, + 0x52414843 , 0x5a5f4547 , 0x004f5245 , 0x52414843, + 0x535f4547 , 0x544e5548 , 0x494d5000 , 0x4e495f43, + 0x004c5f54 , 0x31433249 , 0x4c43535f , 0x43324900, + 0x44535f31 , 0x424b0041 , 0x54554f5f , 0x4b003030, + 0x554f5f42 , 0x00313054 , 0x4f5f424b , 0x32305455, + 0x5f424b00 , 0x3054554f , 0x424b0033 , 0x54554f5f, + 0x4b003430 , 0x554f5f42 , 0x00353054 , 0x4f5f424b, + 0x36305455 , 0x5f424b00 , 0x3054554f , 0x424b0037, + 0x54554f5f , 0x4b003830 , 0x554f5f42 , 0x00393054, + 0x4f5f424b , 0x30315455 , 0x5f424b00 , 0x3154554f, + 0x424b0031 , 0x54554f5f , 0x55003231 , 0x565f4253, + 0x5f535542 , 0x4c525443 , 0x42554800 , 0x5345525f, + 0x57005445 , 0x004c5f50 , 0x505f4c42 , 0x45004d57, + 0x4e495f43 , 0x4e450054 , 0x49524554 , 0x525f474e, + 0x00000057 , 0x20006bcf , 0x20006bd2 , 0x20006be0, + 0x20006bee , 0x20006bf7 , 0x20006bff , 0x20006c10, + 0x20006c15 , 0x20006c23 , 0x20006c2f , 0x706c6568, + 0x00000000 , 0x74736968 , 0x0079726f , 0x64255b1b, + 0x5b1b0044 , 0x6c004331 , 0x00747369 , 0x776f6e4b, + 0x6f63206e , 0x6e616d6d , 0x0a3a7364 , 0x25202000, + 0x7335312d , 0x000a7325 , 0x504c4548 , 0x444d4320, + 0x68203d20 , 0x20706c65 , 0x43206e6f , 0x0a2e444d, + 0x6d6f4300 , 0x646e616d , 0x73252720 , 0x6f6e2027, + 0x6f662074 , 0x20646e75 , 0x6120726f , 0x6769626d, + 0x73756f75 , 0x55000a2e , 0x65676173 , 0x7325203a, + 0x0a732520 , 0x312d2500 , 0x48007335 , 0x20504c45, + 0x5453494c , 0x6d203d20 , 0x2065726f , 0x6f666e69, + 0x4300203b , 0x6f736e6f , 0x6920656c , 0x6e652073, + 0x656c6261 , 0x74203b64 , 0x20657079 , 0x504c4548, + 0x726f6620 , 0x6c656820 , 0x000a2e70 , 0x61726150, + 0x6574656d , 0x64252072 , 0x766e6920 , 0x64696c61, + 0x7257000a , 0x20676e6f , 0x626d756e , 0x6f207265, + 0x61702066 , 0x736d6172 , 0x6f43000a , 0x6e616d6d, + 0x65722064 , 0x6e727574 , 0x65206465 , 0x726f7272, + 0x0a642520 , 0x315b1b00 , 0x5b1b0044 , 0x00436425, + 0x00203e0c , 0x696c205b , 0x7c207473 , 0x616e3c20, + 0x203e656d , 0x7250005d , 0x20746e69 , 0x6d6d6f63, + 0x20646e61 , 0x706c6568 , 0x69725000 , 0x6320746e, + 0x6f736e6f , 0x6820656c , 0x6f747369 , 0x4f007972, + 0x6e55004b , 0x776f6e6b , 0x7265206e , 0x00726f72, + 0x6d696e55 , 0x6d656c70 , 0x65746e65 , 0x764f0064, + 0x6c667265 , 0x5400776f , 0x6f656d69 , 0x49007475, + 0x6c61766e , 0x61206469 , 0x6d756772 , 0x00746e65, + 0x79737542 , 0x63634100 , 0x20737365 , 0x696e6544, + 0x4e006465 , 0x5020746f , 0x7265776f , 0x4e006465, + 0x4320746f , 0x62696c61 , 0x65746172 , 0x00000064, + 0x20006d44 , 0x20006d4c , 0x20006d52 , 0x20006d5a, + 0x20006d62 , 0x20006d68 , 0x20006d6c , 0x20006d73, + 0x20006db1 , 0x20006d78 , 0x20006d7c , 0x20006d85, + 0x20006d8d , 0x20006d96 , 0x20006d9f , 0x20006da3, + 0x20006daf , 0x20006db9 , 0x20006dc0 , 0x20006dc4, + 0x20006dc8 , 0x20006dcf , 0x20006dd6 , 0x20006ddb, + 0x20006de3 , 0x20006de7 , 0x20006ded , 0x20006df7, + 0x20006dfd , 0x20006e03 , 0x6e616863 , 0x00000000, + 0x65766173 , 0x73657200 , 0x65726f74 , 0x20232000, + 0x6b73614d , 0x20202020 , 0x43204520 , 0x6e6e6168, + 0x000a6c65 , 0x20643225 , 0x78383025 , 0x20632520, + 0x000a7325 , 0x2054255b , 0x73205b00 , 0x20657661, + 0x6572207c , 0x726f7473 , 0x207c2065 , 0x73616d3c, + 0x5d203e6b , 0x76615300 , 0x72202c65 , 0x6f747365, + 0x202c6572 , 0x20746567 , 0x7320726f , 0x63207465, + 0x6f736e6f , 0x6320656c , 0x6e6e6168 , 0x6d206c65, + 0x006b7361 , 0x6d6d6f63 , 0x00646e61 , 0x65636361, + 0x6863006c , 0x65677261 , 0x68630072 , 0x65737069, + 0x6c630074 , 0x006b636f , 0x00616d64 , 0x6e657665, + 0x67007374 , 0x006f6970 , 0x00633269 , 0x6279656b, + 0x6472616f , 0x79656b00 , 0x6e616373 , 0x64696c00, + 0x6c676e61 , 0x696c0065 , 0x62746867 , 0x6c007261, + 0x6d006370 , 0x6f69746f , 0x6e65736e , 0x70006573, + 0x736f6864 , 0x646d6374 , 0x726f7000 , 0x00303874, + 0x006d7770 , 0x00697073 , 0x74697773 , 0x73006863, + 0x65747379 , 0x6174006d , 0x74006b73 , 0x6d726568, + 0x75006c61 , 0x75006273 , 0x736d6273 , 0x62737500, + 0x72616863 , 0x75006567 , 0x64706273 , 0x6f627600, + 0x6800746f , 0x006b6f6f , 0x73616c66 , 0x666e6968, + 0x0000006f , 0x73616c66 , 0x00707768 , 0x73796850, + 0x6c616369 , 0x6434253a , 0x0a424b20 , 0x61735500, + 0x3a656c62 , 0x34252020 , 0x424b2064 , 0x7257000a, + 0x3a657469 , 0x25202020 , 0x42206434 , 0x64692820, + 0x206c6165 , 0x42206425 , 0x45000a29 , 0x65736172, + 0x2020203a , 0x20643425 , 0x74282042 , 0x6425206f, + 0x7469622d , 0x000a2973 , 0x746f7250 , 0x3a746365, + 0x64342520 , 0x000a4220 , 0x67616c46 , 0x20203a73, + 0x70772000 , 0x6970675f , 0x73615f6f , 0x74726573, + 0x20006465 , 0x615f6f72 , 0x6f625f74 , 0x2000746f, + 0x5f6c6c61 , 0x625f7461 , 0x00746f6f , 0x5f6f7220, + 0x00776f6e , 0x6c6c6120 , 0x776f6e5f , 0x54532000, + 0x004b4355 , 0x434e4920 , 0x49534e4f , 0x4e455453, + 0x72500054 , 0x6365746f , 0x20646574 , 0x3a776f6e, + 0x20200a00 , 0x2e002020 , 0x65005900 , 0x6c62616e, + 0x69640065 , 0x6c626173 , 0x6f6e0065 , 0x50007772, + 0x746e6972 , 0x616c6620 , 0x69206873 , 0x006f666e, + 0x616e653c , 0x20656c62 , 0x6964207c , 0x6c626173, + 0x207c2065 , 0x20776f6e , 0x7772207c , 0x6e207c20, + 0x3e77726f , 0x646f4d00 , 0x20796669 , 0x73616c66, + 0x72772068 , 0x20657469 , 0x746f7270 , 0x00746365, + 0x6f697067 , 0x00746567 , 0x6f697067 , 0x00746573, + 0x64252020 , 0x25206325 , 0x5b000a73 , 0x656d616e, + 0x6552005d , 0x47206461 , 0x204f4950 , 0x756c6176, + 0x29732865 , 0x6d616e00 , 0x303c2065 , 0x31207c20, + 0x6553003e , 0x20612074 , 0x4f495047 , 0x00000000, + 0x20005f88 , 0x20005f90 , 0x20005f90 , 0x20005f90, + 0x20005f90 , 0x20005fa8 , 0x20005fa8 , 0x20005fb8, + 0x20005fb8 , 0x20005fb8 , 0x20005fb8 , 0x20005fb8, + 0x20005fb8 , 0x20005fb8 , 0x20005fb8 , 0x20005fb8, + 0x20005fb8 , 0x20005fc0 , 0x20005fc0 , 0x20005fc0, + 0x20005fc0 , 0x20005fc0 , 0x20005fc0 , 0x20005fc0, + 0x20005fc0 , 0x20005fc0 , 0x20005fc0 , 0x20005fc8, + 0x20005fc8 , 0x20005fc8 , 0x20007738 , 0x20007150, + 0x20007157 , 0x2000715d , 0x74736f68 , 0x6361705f, + 0x5f74656b , 0x65636572 , 0x00657669 , 0x65646368, + 0x00677562 , 0x74736f48 , 0x6d6f6320 , 0x646e616d, + 0x62656420 , 0x6d206775 , 0x2065646f , 0x25207369, + 0x2b000a73 , 0x20434800 , 0x30257830 , 0x252e7832, + 0x2e253a64 , 0x4800682a , 0x78302043 , 0x78323025, + 0x20434800 , 0x20727265 , 0x48006425 , 0x65722043, + 0x253a7073 , 0x00682a2e , 0x2d746b70 , 0x7365723e, + 0x736e6f70 , 0x616d5f65 , 0x3d3e2078 , 0x7a697320, + 0x28666f65 , 0x75727473 , 0x65207463 , 0x6f685f63, + 0x725f7473 , 0x6f707365 , 0x2965736e , 0x6d6f6300, + 0x2f6e6f6d , 0x74736f68 , 0x6d6f635f , 0x646e616d, + 0x6800632e , 0x6374736f , 0x6920646d , 0x2074696e, + 0x78257830 , 0x64636800 , 0x67756265 , 0x666f5b20, + 0x207c2066 , 0x6d726f6e , 0x7c206c61 , 0x65766520, + 0x7c207972 , 0x72617020 , 0x5d736d61 , 0x74655300, + 0x736f6820 , 0x6f632074 , 0x6e616d6d , 0x65642064, + 0x20677562 , 0x7074756f , 0x6d207475 , 0x0065646f, + 0x6d726f6e , 0x65006c61 , 0x79726576 , 0x72617000, + 0x00736d61 , 0x74736f68 , 0x6e657665 , 0x00000074, + 0x6e657665 , 0x6c632074 , 0x20726165 , 0x78302042, + 0x78383025 , 0x65766500 , 0x6320746e , 0x7261656c, + 0x25783020 , 0x00783830 , 0x6e657665 , 0x65732074, + 0x78302074 , 0x78383025 , 0x656c6300 , 0x63007261, + 0x7261656c , 0x76450062 , 0x73746e65 , 0x2020203a, + 0x25783020 , 0x0a783830 , 0x65764500 , 0x2d73746e, + 0x20203a42 , 0x30257830 , 0x000a7838 , 0x7465735b, + 0x63207c20 , 0x7261656c , 0x63207c20 , 0x7261656c, + 0x207c2062 , 0x20696d73 , 0x6373207c , 0x207c2069, + 0x656b6177 , 0x6d5b205d , 0x5d6b7361 , 0x69725000, + 0x2f20746e , 0x74657320 , 0x736f6820 , 0x76652074, + 0x20746e65 , 0x74617473 , 0x6c630065 , 0x69726165, + 0x6b20676e , 0x6f627965 , 0x20647261 , 0x6f666966, + 0x20424b00 , 0x4f464946 , 0x70656420 , 0x25206874, + 0x65722064 , 0x65686361 , 0x00000064 , 0x02010000, + 0x0000400b , 0x7473736b , 0x00657461 , 0x7270626b, + 0x00737365 , 0x2054255b , 0x2520424b , 0x20003a73, + 0x78323025 , 0x2d2d2000 , 0x62656400 , 0x636e756f, + 0x00206465 , 0x76657270 , 0x20202020 , 0x64002020, + 0x756f6265 , 0x6e69636e , 0x654b0067 , 0x616f6279, + 0x73206472 , 0x206e6163 , 0x61736964 , 0x20656c62, + 0x6b73616d , 0x7830203a , 0x78383025 , 0x654b000a, + 0x616f6279 , 0x73206472 , 0x206e6163 , 0x74617473, + 0x72702065 , 0x69746e69 , 0x2520676e , 0x4b000a73, + 0x69642042 , 0x6c626173 , 0x63735f65 , 0x696e6e61, + 0x6d5f676e , 0x206b7361 , 0x6e616863 , 0x3a646567, + 0x25783020 , 0x00783830 , 0x756d6973 , 0x6574616c, + 0x53002064 , 0x6c756d69 , 0x64657461 , 0x79656b20, + 0x000a3a73 , 0x20642509 , 0x000a6425 , 0x6220424b, + 0x20746f6f , 0x2079656b , 0x69006425 , 0x2074696e, + 0x74617473 , 0x424b0065 , 0x69617720 , 0x424b0074, + 0x6c6f7020 , 0x424b006c , 0x72617720 , 0x6572206d, + 0x746f6f62 , 0x20424b00 , 0x65626968 , 0x74616e72, + 0x736b0065 , 0x74617473 , 0x6f5b2065 , 0x207c206e, + 0x5d66666f , 0x6f685300 , 0x726f2077 , 0x676f7420, + 0x20656c67 , 0x6e697270 , 0x676e6974 , 0x79656b20, + 0x72616f62 , 0x63732064 , 0x73206e61 , 0x65746174, + 0x6f635b00 , 0x6f72206c , 0x305b2077 , 0x31207c20, + 0x53005d5d , 0x6c756d69 , 0x20657461 , 0x7079656b, + 0x73736572 , 0x52415500 , 0x6e692054 , 0x61697469, + 0x657a696c , 0x66612064 , 0x20726574 , 0x6a737973, + 0x00706d75 , 0x2d2d0a0a , 0x4155202d , 0x69205452, + 0x6974696e , 0x7a696c61 , 0x61206465 , 0x72657466, + 0x62657220 , 0x20746f6f , 0x0a2d2d2d , 0x65525b00, + 0x20746573 , 0x73756163 , 0x00203a65 , 0x616d495b, + 0x203a6567 , 0x202c7325 , 0x0a5d7325 , 0x696e4900, + 0x64207374 , 0x00656e6f , 0x00007777 , 0x00007772, + 0x64616572 , 0x25783020 , 0x203d2070 , 0x30257830, + 0x000a7838 , 0x74697277 , 0x78302065 , 0x3d207025, + 0x25783020 , 0x0a783830 , 0x64646100 , 0x61762072, + 0x0065756c , 0x74697257 , 0x20612065 , 0x64726f77, + 0x206f7420 , 0x6f6d656d , 0x61007972 , 0x00726464, + 0x64616552 , 0x77206120 , 0x2064726f , 0x6d6f7266, + 0x6d656d20 , 0x0079726f , 0x74736f68 , 0x6d6f635f, + 0x646e616d , 0x6e61705f , 0x695f6369 , 0x006f666e, + 0x73617263 , 0x00000068 , 0x696e6170 , 0x666e6963, + 0x0000006f , 0x454e2820 , 0x53002957 , 0x64657661, + 0x6e617020 , 0x64206369 , 0x3a617461 , 0x000a7325, + 0x73206f4e , 0x64657661 , 0x6e617020 , 0x64206369, + 0x20617461 , 0x69617661 , 0x6c62616c , 0x000a2e65, + 0x7a766964 , 0x006f7265 , 0x6c616e75 , 0x656e6769, + 0x0a0a0064 , 0x6f626552 , 0x6e69746f , 0x2e2e2e67, + 0x2a0a000a , 0x4150202a , 0x3a43494e , 0x0a732520, + 0x53410a00 , 0x54524553 , 0x204e4f49 , 0x4c494146, + 0x20455255 , 0x27732527 , 0x206e6920 , 0x29287325, + 0x20746120 , 0x253a7325 , 0x70000a64 , 0x61746164, + 0x7274705f , 0x74733e2d , 0x74637572 , 0x7a69735f, + 0x3d3c2065 , 0x67726120 , 0x723e2d73 , 0x6f707365, + 0x5f65736e , 0x0078616d , 0x6d6d6f63 , 0x702f6e6f, + 0x63696e61 , 0x74756f5f , 0x2e747570 , 0x645b0063, + 0x657a7669 , 0x7c206f72 , 0x616e7520 , 0x6e67696c, + 0x005d6465 , 0x73617243 , 0x68742068 , 0x79732065, + 0x6d657473 , 0x6f662820 , 0x65742072 , 0x6e697473, + 0x50002967 , 0x746e6972 , 0x666e6920 , 0x7266206f, + 0x61206d6f , 0x65727020 , 0x756f6976 , 0x61702073, + 0x0063696e , 0x4f525245 , 0x00000052 , 0x4c554e28, + 0x0000294c , 0x656d6873 , 0x0000006d , 0x657a6953, + 0x6436253a , 0x7355000a , 0x253a6465 , 0x000a6436, + 0x3a78614d , 0x64362520 , 0x7250000a , 0x20746e69, + 0x72616873 , 0x6d206465 , 0x726f6d65 , 0x74732079, + 0x00737461 , 0x08000000 , 0x08010000 , 0x0000f000, + 0x00010000 , 0x2000771e , 0x20006969 , 0x20006a3f, + 0x2000799c , 0x200079a2 , 0x200079ac , 0x200079b5, + 0x200079be , 0x20007730 , 0x20007378 , 0x200079c7, + 0x200079d1 , 0x200079da , 0x200073fc , 0x20007726, + 0x20007735 , 0x200079e6 , 0x00000000 , 0x00000002, + 0x00000002 , 0x00000002 , 0x00000002 , 0x00000003, + 0x00000002 , 0x00000004 , 0x69737973 , 0x006f666e, + 0x65626968 , 0x74616e72 , 0x00000065 , 0x73726576, + 0x006e6f69 , 0x6a737973 , 0x00706d75 , 0x6f626572, + 0x0000746f , 0x6c737973 , 0x006b636f , 0x6e75003f, + 0x776f6e6b , 0x6168006e , 0x63006472 , 0x00646c6f, + 0x74666f73 , 0x2d706100 , 0x0066666f , 0x636e6163, + 0x70006c65 , 0x65736572 , 0x00657672 , 0x64726148, + 0x6552002d , 0x746f6f62 , 0x21676e69 , 0x000a0a0a, + 0x70696843 , 0x2020203a , 0x20732520 , 0x25207325, + 0x42000a73 , 0x6472616f , 0x2020203a , 0x000a6425, + 0x203a4f52 , 0x20202020 , 0x0a732520 , 0x3a575200, + 0x20202020 , 0x73252020 , 0x7542000a , 0x3a646c69, + 0x0a732520 , 0x62694800 , 0x616e7265 , 0x676e6974, + 0x726f6620 , 0x2e642520 , 0x64363025 , 0x000a7320, + 0x65626948 , 0x74616e72 , 0x20676e69 , 0x69746e75, + 0x6177206c , 0x7020656b , 0x61206e69 , 0x72657373, + 0x2e646574 , 0x6552000a , 0x20746573 , 0x67616c66, + 0x30203a73 , 0x38302578 , 0x00282078 , 0x79706f43, + 0x2020203a , 0x000a7325 , 0x79006f6e , 0x4a007365, + 0x65706d75 , 0x25203a64 , 0x46000a73 , 0x7367616c, + 0x2000203a , 0x6b636f6c , 0x20006465 , 0x726f6628, + 0x29646563 , 0x756a2000 , 0x642d706d , 0x62617369, + 0x0064656c , 0x6c6e7520 , 0x656b636f , 0x65520064, + 0x746f6f62 , 0x20746120 , 0x74756873 , 0x6e776f64, + 0x6425203a , 0x754a000a , 0x6e69706d , 0x6f742067, + 0x616d6920 , 0x25206567 , 0x79730073 , 0x6d657473, + 0x62696820 , 0x616e7265 , 0x676e6974 , 0x65784500, + 0x69747563 , 0x6820676e , 0x2074736f , 0x6f626572, + 0x6320746f , 0x616d6d6f , 0x2520646e , 0x754a0064, + 0x6e69706d , 0x6f742067 , 0x25783020 , 0x0a783830, + 0x69725000 , 0x7320746e , 0x65747379 , 0x6e69206d, + 0x5b006f66 , 0x5d636573 , 0x73755b20 , 0x005d6365, + 0x65626948 , 0x74616e72 , 0x68742065 , 0x43452065, + 0x69725000 , 0x7620746e , 0x69737265 , 0x00736e6f, + 0x204f525b , 0x5752207c , 0x61207c20 , 0x20726464, + 0x6964207c , 0x6c626173 , 0x4a005d65 , 0x20706d75, + 0x61206f74 , 0x73797320 , 0x206d6574 , 0x67616d69, + 0x726f2065 , 0x64646120 , 0x73736572 , 0x61685b00, + 0x737c6472 , 0x5d74666f , 0x72705b20 , 0x72657365, + 0x205d6576 , 0x2d70615b , 0x5d66666f , 0x61635b20, + 0x6c65636e , 0x6552005d , 0x746f6f62 , 0x65687420, + 0x00434520 , 0x6b636f4c , 0x65687420 , 0x73797320, + 0x2c6d6574 , 0x65766520 , 0x6669206e , 0x20505720, + 0x64207369 , 0x62617369 , 0x0064656c , 0x6568746f, + 0x65720072 , 0x2d746573 , 0x006e6970 , 0x776f7262, + 0x74756f6e , 0x776f7000 , 0x6f2d7265 , 0x6177006e, + 0x64686374 , 0x7200676f , 0x612d6374 , 0x6d72616c, + 0x6b617700 , 0x69702d65 , 0x6f6c006e , 0x61622d77, + 0x72657474 , 0x72700079 , 0x72657365 , 0x00646576, + 0x656d6974 , 0x72615f72 , 0x0000006d , 0x656c7375, + 0x00007065 , 0x656d6974 , 0x61635f72 , 0x6c65636e, + 0x00000000 , 0x74696177 , 0x0000736d , 0x74746567, + 0x00656d69 , 0x656d6974 , 0x666e6972 , 0x0000006f, + 0x656d6954 , 0x7830203a , 0x36313025 , 0x3d20786c, + 0x362e2520 , 0x7320646c , 0x6954000a , 0x203a656d, + 0x20202020 , 0x30257830 , 0x786c3631 , 0x0a737520, + 0x64616544 , 0x656e696c , 0x7830203a , 0x36313025, + 0x2d20786c , 0x3125203e , 0x6c362e31 , 0x20732064, + 0x6d6f7266 , 0x776f6e20 , 0x7463410a , 0x20657669, + 0x656d6974 , 0x0a3a7372 , 0x54202000 , 0x25206b73, + 0x20206432 , 0x30257830 , 0x786c3631 , 0x203e2d20, + 0x2e313125 , 0x0a646c36 , 0x6b737400 , 0x3c206469, + 0x53415420 , 0x44495f4b , 0x554f435f , 0x6300544e, + 0x6f6d6d6f , 0x69742f6e , 0x2e72656d , 0x73750063, + 0x73754200 , 0x61772d79 , 0x66207469 , 0x6d20726f, + 0x00636573 , 0x6e697250 , 0x75632074 , 0x6e657272, + 0x69742074 , 0x5000656d , 0x746e6972 , 0x6d697420, + 0x69207265 , 0x006f666e , 0x00736964 , 0x00616e65, + 0x7263636d , 0x656b736f , 0x31765f79 , 0x322e312e, + 0x2d373034 , 0x62383762 , 0x2d366232 , 0x74726964, + 0x30322079 , 0x302d3531 , 0x37312d33 , 0x3a393120, + 0x313a3730 , 0x69712036 , 0x6e616675 , 0x61642e67, + 0x72644069 , 0x3064696f , 0x00000035 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000, + 0x00202072 , 0x200088a8 , 0x0000001f , 0xffffffff, + 0xffffffff , 0x00000000 , 0xfff85ee0 , 0xffffffff, + 0xfff0bdc0 , 0xffffffff , 0x00000001 , 0x000000fb, + 0x00100101 , 0x23280032 , 0x0bb87530 , 0x000003e8, + 0x000186a0 , 0xffffff14 , 0xa4fff5ff , 0xfa55feff, + 0x000000ca , 0x000000ff , 0xffffffff , 0xea444e45, + 0x00000000 , 0x00000000 , 0x00000000 , 0x00000000 +}; diff --git a/bl2/usb_bl2_cmd.c b/bl2/usb_bl2_cmd.c new file mode 100644 index 0000000..2c21032 --- /dev/null +++ b/bl2/usb_bl2_cmd.c @@ -0,0 +1,344 @@ +/* + * \file usb_bl2_cmd.c + * \brief + * + * \version 1.0.0 + * \date 15/08/21 + * \author Sam.Wu <yihui.wu@amlgic.com> + * + * Copyright (c) 2015 Amlogic. All Rights Reserved. + * + */ +#include <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <fip.h> +#include <debug.h> +#include <platform.h> +#include <platform_def.h> +#include <stdio.h> +#include "bl2_private.h" +#include <serial.h> +#include <plat_init.h> +#include <common.h> +#include <asm/arch/secure_apb.h> +#include <asm/arch/cpu_config.h> +#include <string.h> + +extern unsigned int ddr_init(void); + +static unsigned _fipDownloadedAddr = FM_USB_MODE_LOAD_ADDR;//default loadded addr + +uint64_t usb_boot(uint64_t src, uint64_t des, uint64_t size) +{ + src += _fipDownloadedAddr - BL2_SIZE;//storage_load in bl2_main using offset in u-boot.bin + + /* data is ready in ddr, just need memcpy */ + memcpy((void *)des, (void *)(src), size); + return 0; +} + + +#if 1//usb bl2 para start +//As sram area will not cleared before poweroff, the result maigc must not be equal to para magic and clear before run +#define USB_BL2_RUN_CMD_RESULT_MAGIC (0X7856EFABU)//after run +#define USB_BL2_RUN_CMD_INFO_MAGIC (0X3412CDABU)//before run +#define USB_BL2_RUN_CMD_INFO_VERSION (0x0200) +enum USB_BL2_RUN_CMD_RESULT_ERR_TYPE { + USB_BL2_RUN_CMD_RESULT_ERR_PARA = 0xe2 ,//magic or version error + USB_BL2_RUN_CMD_RESULT_ERR_RUNTYPE_UNDEFINED ,//runtype not defined + USB_BL2_RUN_CMD_RESULT_ERR_NOT_IMPLEMENTED ,//run cmd handle not implemented + + USB_BL2_RUN_CMD_RESULT_ERR_DDR_INIT ,//fail in DDR init + + USB_BL2_RUN_CMD_RESULT_ERR_DATACHECK_GENCRC ,//fail in data check, generated crc != crc from pc + USB_BL2_RUN_CMD_RESULT_ERR_DATACHECK_NOT_IMPLEMENTED ,//not implemented data check type + USB_BL2_RUN_CMD_RESULT_ERR_DATACHECK_UNDEFINED ,//data check type not defined + + + USB_BL2_RUN_CMD_RESULT_ERR_RUN_IMAGE_TYPE_NOT_IMPLEMENTED ,//image type not implemented +}; + + +enum USB_BL2_RUN_CMD_TYPE_enum{ + USB_BL2_RUN_CMD_TYPE_DECOMPRESS = 0X0000C0DE , //ucl decompress + USB_BL2_RUN_CMD_TYPE_DDR_INIT , //init ddr + USB_BL2_RUN_CMD_TYPE_DATA_CHECK , //crc32 check, or simple addsum check + USB_BL2_RUN_CMD_TYPE_RUN_IMG , //run fip image +}; + +#pragma pack(push, 4) +//UsbBl2RunCmdPara_t: common para header for u-boot.bin.usb.bl2 when usb mode +typedef struct _usbbl2_run_cmd_para_s{ + unsigned int paraMagic;//USB_BL2_RUN_CMD_INFO_MAGIC, USB_BL2_RUN_CMD_RESULT_MAGIC + unsigned int paraVersion; + unsigned int runType;//USB_BL2_RUN_CMD_RUN_IN_ADDR,USB_BL2_RUN_CMD_DDR_INSPECT + unsigned int runResult;//running result, 0 is no err, others error + + unsigned int errInfoAddr;//sram addr for save error messages + unsigned int errInfoSz; //error messages length + +}UsbBl2RunCmdPara_t; + +//parameters for ddr init +typedef struct _usbbl2_run_cmd_DDR_INIT{ + UsbBl2RunCmdPara_t runParaHeader; + unsigned int ddrCapacity;//after run, saved the ddr capacity in MB + +}UsbBl2RunCmdPara_DdrInit; + +//parameters for ucl decompress +typedef struct _usbbl2_run_cmd_DECOMPRESS{ + UsbBl2RunCmdPara_t runParaHeader; + unsigned int decompressType;//ucl decompress, others ... + unsigned int srcDataAddr; //data for decompress + unsigned int srcDataLen; + unsigned int decompressedAddr;//data addr after ucl decompress + unsigned int decompressedLen; //data size after ucl decompress +}UsbBl2RunCmdPara_Decompress; + +//parameters for running a image, support normal/fip fomrat/and etc.. +typedef struct _usbbl2_run_cmd_RunImage{ + UsbBl2RunCmdPara_t runParaHeader; + unsigned int runImageType;//2 normal bin, 1 fip image, others reserved + unsigned int imageDataAddr;// + unsigned int imageDataLen; + +}UsbBl2RunCmdPara_RunImage; + +#if 1//for data check +struct _UsbBl2DataCheck_sha1sum{//check data using sha1sum algorithm + unsigned char srcDataCheckValue[20];//for crc and addsum, only 4 bytes used + unsigned char generatedCheckValue[20]; +}; +struct _UsbBl2DataCheck_sha256sum{//check data using sha256sum algorithm + unsigned char srcDataCheckValue[32];//for crc and addsum, only 4 bytes used + unsigned char generatedCheckValue[32]; +}; +struct _UsbBl2DataCheck_sha2sum{//check data using sha2 algorithm + unsigned char srcDataCheckValue[32];//for crc and addsum, only 4 bytes used + unsigned char generatedCheckValue[32]; +}; +struct _UsbBl2DataCheck_addsum{//check data using simple addsum algorithm + unsigned int srcAddSum; + unsigned int generatedAddSum; +}; +struct _UsbBl2DataCheck_crc32{//check data using crc32 algorithm + unsigned int srcAddSum; + unsigned int generatedAddSum; +}; + +//parameters for ddr init +typedef struct _usbbl2_run_cmd_DataCheck{ + UsbBl2RunCmdPara_t runParaHeader; + unsigned int dataCheckAlgorithm;//check algorithm, 1 is addsum, 2 is sha2, 3 is crc32, and other + unsigned int srcDataAddr; //data addr for check + unsigned int srcDataLen; //data length for check + + union { + struct _UsbBl2DataCheck_addsum addsum; + struct _UsbBl2DataCheck_crc32 crc32; + struct _UsbBl2DataCheck_sha256sum sha256sum; + struct _UsbBl2DataCheck_sha2sum sha2sum; + struct _UsbBl2DataCheck_sha1sum sha1sum; + }dataCheckVal; + +}UsbBl2RunCmdPara_DataCheck; + +#endif//#if 1//for data check + +#pragma pack(pop) // #pragma pack(push, 4) + +#define DATA_CHECK_TYPE_ADDSUM 1 +#define DATA_CHECK_TYPE_CRC32 2 +#define DATA_CHECK_TYPE_SHA1 3 +#define DATA_CHECK_TYPE_SHA2 4 +#define DATA_CHECK_TYPE_SHA256 5 + +#define RUN_IMAGE_TYPE_FIP 1 +#define RUN_IMAGE_TYPE_RAW 2 + +#endif//#if 1 usb bl2 para + +// simple add sum data check +static unsigned int usb_add_sum(const unsigned int *data, int size) +{ + unsigned int cksum = 0; + unsigned int wordLen = size>>2; + unsigned int rest = size & 3; + + while (wordLen--) + { + cksum += *data++; + } + + if (rest == 1) + { + cksum += (*data) & 0xff; + } + else if(rest == 2) + { + cksum += (*data) & 0xffff; + } + else if(rest == 3) + { + cksum += (*data) & 0xffffff; + } + + return cksum; +} +// end +// +static int usb_bl2_cmd_run_image(UsbBl2RunCmdPara_RunImage* pRunImgPara) +{ + const int imageType = pRunImgPara->runImageType; + const unsigned srcDataAddr = pRunImgPara->imageDataAddr; + int runResult = 0; + + switch (imageType) + { + case RUN_IMAGE_TYPE_FIP: + { + _fipDownloadedAddr = srcDataAddr;//update fip image loaded addr + + /* Perform platform setup in BL1 */ + bl2_platform_setup(); + + /* Load images */ + bl2_load_image(); + } + break; + + case RUN_IMAGE_TYPE_RAW://raw image bin + { + typedef int (*pfunc_t)(void) ; + pfunc_t entry = (pfunc_t)(unsigned long)srcDataAddr; + entry(); + } + break; + + default: + runResult = USB_BL2_RUN_CMD_RESULT_ERR_RUN_IMAGE_TYPE_NOT_IMPLEMENTED; + break; + } + + return runResult; +} + +static int usb_bl2_cmd_run_datacheck(UsbBl2RunCmdPara_DataCheck* pDataCheckPara) +{ + int runResult = 0; + switch (pDataCheckPara->dataCheckAlgorithm) + { + case DATA_CHECK_TYPE_ADDSUM://addsum + { + const unsigned originAddsum = pDataCheckPara->dataCheckVal.addsum.srcAddSum; + const unsigned* srcData = (const unsigned*)(unsigned long)pDataCheckPara->srcDataAddr; + const unsigned srcDataLen = pDataCheckPara->srcDataLen; + unsigned generatedAddSum = 0; + + generatedAddSum = usb_add_sum(srcData, srcDataLen); + pDataCheckPara->dataCheckVal.addsum.generatedAddSum = generatedAddSum; + if (generatedAddSum != originAddsum) runResult = USB_BL2_RUN_CMD_RESULT_ERR_DATACHECK_GENCRC; + } + break; + case DATA_CHECK_TYPE_CRC32://crc32 + case DATA_CHECK_TYPE_SHA1://sha1 + case DATA_CHECK_TYPE_SHA2://sha2 + case DATA_CHECK_TYPE_SHA256://sha256 + runResult = USB_BL2_RUN_CMD_RESULT_ERR_DATACHECK_NOT_IMPLEMENTED; + default: + runResult = USB_BL2_RUN_CMD_RESULT_ERR_DATACHECK_UNDEFINED; + break; + } + + return runResult; +} + +//usb burning tool must compatibe for old/new code, +//new code not need to support old usb burning tool +static int usb_bl2_run_cmd(void* usbBl2Para) +{ + UsbBl2RunCmdPara_t* pBl2RunPara = (UsbBl2RunCmdPara_t*)usbBl2Para; + const unsigned int paraMagic = pBl2RunPara->paraMagic; + const unsigned int paraVersion = pBl2RunPara->paraVersion; + const unsigned int runType = pBl2RunPara->runType; + int runResult = 0;//no error + + pBl2RunPara->paraMagic = USB_BL2_RUN_CMD_RESULT_MAGIC; + if (paraMagic != USB_BL2_RUN_CMD_INFO_MAGIC || paraVersion != USB_BL2_RUN_CMD_INFO_VERSION) { + pBl2RunPara->runResult = USB_BL2_RUN_CMD_RESULT_ERR_PARA; + return __LINE__; + } + + switch (runType) + { + case USB_BL2_RUN_CMD_TYPE_DDR_INIT: + { + UsbBl2RunCmdPara_DdrInit* pRunDdrPara = (UsbBl2RunCmdPara_DdrInit*)pBl2RunPara; + ddr_init(); + pRunDdrPara->ddrCapacity = (unsigned)get_ddr_size(); + runResult = pRunDdrPara->ddrCapacity ? 0: USB_BL2_RUN_CMD_RESULT_ERR_DDR_INIT; + } + break; + + case USB_BL2_RUN_CMD_TYPE_RUN_IMG: + { + /* + *unsigned int* skipBootReg = (unsigned int*)SEC_AO_RTI_STATUS_REG3; + *const unsigned skipBootRegVal = readl(skipBootReg); + *writel(skipBootRegVal & ( ~( 0XFU << 12 )) , skipBootReg );//clear skip boot flag + */ + writel((readl(SEC_AO_SEC_GP_CFG7) | (1U<<31)), SEC_AO_SEC_GP_CFG7); + + UsbBl2RunCmdPara_RunImage* pRunImgPara = (UsbBl2RunCmdPara_RunImage*)pBl2RunPara; + runResult = usb_bl2_cmd_run_image(pRunImgPara); + } + break; + + case USB_BL2_RUN_CMD_TYPE_DATA_CHECK: + { + UsbBl2RunCmdPara_DataCheck* pDataCheckPara = (UsbBl2RunCmdPara_DataCheck*)pBl2RunPara; + runResult = usb_bl2_cmd_run_datacheck(pDataCheckPara); + } + break; + + case USB_BL2_RUN_CMD_TYPE_DECOMPRESS: + runResult = USB_BL2_RUN_CMD_RESULT_ERR_NOT_IMPLEMENTED; + break; + default: + runResult = USB_BL2_RUN_CMD_RESULT_ERR_RUNTYPE_UNDEFINED; + break; + + } + + pBl2RunPara->runResult = runResult; + return runResult; +} + +int bl2_usb_handler(void) +{ + unsigned int* skipBootReg = (unsigned int*)SEC_AO_RTI_STATUS_REG3; + unsigned skipBootRegVal = readl(skipBootReg); + const unsigned usbBootFlag = ( skipBootRegVal>>12 ) & 0xF; + + /* process usb burning case */ + if (BOOT_DEVICE_USB == get_boot_device() || 2 == usbBootFlag ) + { + serial_puts("BL2 USB \n"); + usb_bl2_run_cmd(USB_BL2_RUN_CMD_PARA_ADDR); + bl2_to_romcode(USB_BL2_RETURN_ROM_ADDR); + } + else if( 1 == usbBootFlag ) + { + serial_puts("Skip usb!\n"); + skipBootRegVal &= ~(0XFU<<12); + writel(skipBootRegVal | ( 2<<12 ), skipBootReg); + bl2_to_romcode(BL2_RETURN_ROM_USB_ADDR); + } + + return 0; +} + + diff --git a/common/aarch64/early_exceptions.S b/common/aarch64/early_exceptions.S new file mode 100644 index 0000000..90f5421 --- /dev/null +++ b/common/aarch64/early_exceptions.S @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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_macros.S> +#include <runtime_svc.h> + + .globl early_exceptions + + .section .vectors, "ax"; .align 11 + + /* ----------------------------------------------------- + * Very simple stackless exception handlers used by BL2 + * and BL3-1 bootloader stages. BL3-1 uses them before + * stacks are setup. BL2 uses them throughout. + * ----------------------------------------------------- + */ + .align 7 +early_exceptions: + /* ----------------------------------------------------- + * Current EL with SP0 : 0x0 - 0x180 + * ----------------------------------------------------- + */ +SynchronousExceptionSP0: + mov x0, #SYNC_EXCEPTION_SP_EL0 + bl plat_report_exception + b SynchronousExceptionSP0 + check_vector_size SynchronousExceptionSP0 + + .align 7 +IrqSP0: + mov x0, #IRQ_SP_EL0 + bl plat_report_exception + b IrqSP0 + check_vector_size IrqSP0 + + .align 7 +FiqSP0: + mov x0, #FIQ_SP_EL0 + bl plat_report_exception + b FiqSP0 + check_vector_size FiqSP0 + + .align 7 +SErrorSP0: + mov x0, #SERROR_SP_EL0 + bl plat_report_exception + b SErrorSP0 + check_vector_size SErrorSP0 + + /* ----------------------------------------------------- + * Current EL with SPx: 0x200 - 0x380 + * ----------------------------------------------------- + */ + .align 7 +SynchronousExceptionSPx: + mov x0, #SYNC_EXCEPTION_SP_ELX + bl plat_report_exception + b SynchronousExceptionSPx + check_vector_size SynchronousExceptionSPx + + .align 7 +IrqSPx: + mov x0, #IRQ_SP_ELX + bl plat_report_exception + b IrqSPx + check_vector_size IrqSPx + + .align 7 +FiqSPx: + mov x0, #FIQ_SP_ELX + bl plat_report_exception + b FiqSPx + check_vector_size FiqSPx + + .align 7 +SErrorSPx: + mov x0, #SERROR_SP_ELX + bl plat_report_exception + b SErrorSPx + check_vector_size SErrorSPx + + /* ----------------------------------------------------- + * Lower EL using AArch64 : 0x400 - 0x580 + * ----------------------------------------------------- + */ + .align 7 +SynchronousExceptionA64: + mov x0, #SYNC_EXCEPTION_AARCH64 + bl plat_report_exception + b SynchronousExceptionA64 + check_vector_size SynchronousExceptionA64 + + .align 7 +IrqA64: + mov x0, #IRQ_AARCH64 + bl plat_report_exception + b IrqA64 + check_vector_size IrqA64 + + .align 7 +FiqA64: + mov x0, #FIQ_AARCH64 + bl plat_report_exception + b FiqA64 + check_vector_size FiqA64 + + .align 7 +SErrorA64: + mov x0, #SERROR_AARCH64 + bl plat_report_exception + b SErrorA64 + check_vector_size SErrorA64 + + /* ----------------------------------------------------- + * Lower EL using AArch32 : 0x0 - 0x180 + * ----------------------------------------------------- + */ + .align 7 +SynchronousExceptionA32: + mov x0, #SYNC_EXCEPTION_AARCH32 + bl plat_report_exception + b SynchronousExceptionA32 + check_vector_size SynchronousExceptionA32 + + .align 7 +IrqA32: + mov x0, #IRQ_AARCH32 + bl plat_report_exception + b IrqA32 + check_vector_size IrqA32 + + .align 7 +FiqA32: + mov x0, #FIQ_AARCH32 + bl plat_report_exception + b FiqA32 + check_vector_size FiqA32 + + .align 7 +SErrorA32: + mov x0, #SERROR_AARCH32 + bl plat_report_exception + b SErrorA32 + check_vector_size SErrorA32 diff --git a/common/bl_common.c b/common/bl_common.c new file mode 100644 index 0000000..f0d32d0 --- /dev/null +++ b/common/bl_common.c @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <debug.h> +#include <io_storage.h> +#include <platform.h> +#include <errno.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> + +unsigned long page_align(unsigned long value, unsigned dir) +{ + unsigned long page_size = 1 << FOUR_KB_SHIFT; + + /* Round up the limit to the next page boundary */ + if (value & (page_size - 1)) { + value &= ~(page_size - 1); + if (dir == UP) + value += page_size; + } + + return value; +} + +static inline unsigned int is_page_aligned (unsigned long addr) { + const unsigned long page_size = 1 << FOUR_KB_SHIFT; + + return (addr & (page_size - 1)) == 0; +} + +void change_security_state(unsigned int target_security_state) +{ + unsigned long scr = read_scr(); + + if (target_security_state == SECURE) + scr &= ~SCR_NS_BIT; + else if (target_security_state == NON_SECURE) + scr |= SCR_NS_BIT; + else + assert(0); + + write_scr(scr); +} + + +/******************************************************************************* + * The next function has a weak definition. Platform specific code can override + * it if it wishes to. + ******************************************************************************/ +#pragma weak init_bl2_mem_layout + +/******************************************************************************* + * Function that takes a memory layout into which BL2 has been either top or + * bottom loaded along with the address where BL2 has been loaded in it. Using + * this information, it populates bl2_mem_layout to tell BL2 how much memory + * it has access to and how much is available for use. + ******************************************************************************/ +void init_bl2_mem_layout(meminfo_t *bl1_mem_layout, + meminfo_t *bl2_mem_layout, + unsigned int load_type, + unsigned long bl2_base) +{ + unsigned tmp; + + if (load_type == BOT_LOAD) { + bl2_mem_layout->total_base = bl2_base; + tmp = bl1_mem_layout->free_base - bl2_base; + bl2_mem_layout->total_size = bl1_mem_layout->free_size + tmp; + + } else { + bl2_mem_layout->total_base = bl1_mem_layout->free_base; + tmp = bl1_mem_layout->total_base + bl1_mem_layout->total_size; + bl2_mem_layout->total_size = tmp - bl1_mem_layout->free_base; + } + + bl2_mem_layout->free_base = bl1_mem_layout->free_base; + bl2_mem_layout->free_size = bl1_mem_layout->free_size; + bl2_mem_layout->attr = load_type; + + flush_dcache_range((unsigned long) bl2_mem_layout, sizeof(meminfo_t)); + return; +} + +static void dump_load_info(unsigned long image_load_addr, + unsigned long image_size, + const meminfo_t *mem_layout) +{ +#if 0 + printf("Trying to load image at address 0x%lx, size = 0x%lx\r\n", + image_load_addr, image_size); + printf("Current memory layout:\r\n"); + printf(" total region = [0x%lx, 0x%lx]\r\n", mem_layout->total_base, + mem_layout->total_base + mem_layout->total_size); + printf(" free region = [0x%lx, 0x%lx]\r\n", mem_layout->free_base, + mem_layout->free_base + mem_layout->free_size); +#endif +} + +/* Generic function to return the size of an image */ +unsigned long image_size(const char *image_name) +{ + uintptr_t dev_handle; + uintptr_t image_handle; + uintptr_t image_spec; + size_t image_size = 0; + int io_result = IO_FAIL; + + assert(image_name != NULL); + + /* Obtain a reference to the image by querying the platform layer */ + io_result = plat_get_image_source(image_name, &dev_handle, &image_spec); + if (io_result != IO_SUCCESS) { + WARN("Failed to obtain reference to image '%s' (%i)\n", + image_name, io_result); + return 0; + } + + /* Attempt to access the image */ + io_result = io_open(dev_handle, image_spec, &image_handle); + if (io_result != IO_SUCCESS) { + WARN("Failed to access image '%s' (%i)\n", + image_name, io_result); + return 0; + } + + /* Find the size of the image */ + io_result = io_size(image_handle, &image_size); + if ((io_result != IO_SUCCESS) || (image_size == 0)) { + WARN("Failed to determine the size of the image '%s' file (%i)\n", + image_name, io_result); + } + io_result = io_close(image_handle); + /* Ignore improbable/unrecoverable error in 'close' */ + + /* TODO: Consider maintaining open device connection from this + * bootloader stage + */ + io_result = io_dev_close(dev_handle); + /* Ignore improbable/unrecoverable error in 'dev_close' */ + + return image_size; +} +/******************************************************************************* + * Generic function to load an image into the trusted RAM, + * given a name, extents of free memory & whether the image should be loaded at + * the bottom or top of the free memory. It updates the memory layout if the + * load is successful. It also updates the image information and the entry point + * information in the params passed. The caller might pass a NULL pointer for + * the entry point if it is not interested in this information, e.g. because + * the image just needs to be loaded in memory but won't ever be executed. + ******************************************************************************/ +int load_image(meminfo_t *mem_layout, + const char *image_name, + unsigned int load_type, + unsigned long fixed_addr, + image_info_t *image_data, + entry_point_info_t *entry_point_info) +{ + uintptr_t dev_handle; + uintptr_t image_handle; + uintptr_t image_spec; + unsigned long temp_image_base = 0; + unsigned long image_base = 0; + long offset = 0; + size_t image_size = 0; + size_t bytes_read = 0; + int io_result = IO_FAIL; + + assert(mem_layout != NULL); + assert(image_name != NULL); + assert(image_data->h.version >= VERSION_1); + + /* Obtain a reference to the image by querying the platform layer */ + io_result = plat_get_image_source(image_name, &dev_handle, &image_spec); + if (io_result != IO_SUCCESS) { + WARN("Failed to obtain reference to image '%s' (%i)\n", + image_name, io_result); + return io_result; + } + + /* Attempt to access the image */ + io_result = io_open(dev_handle, image_spec, &image_handle); + if (io_result != IO_SUCCESS) { + WARN("Failed to access image '%s' (%i)\n", + image_name, io_result); + return io_result; + } + + /* Find the size of the image */ + io_result = io_size(image_handle, &image_size); + if ((io_result != IO_SUCCESS) || (image_size == 0)) { + WARN("Failed to determine the size of the image '%s' file (%i)\n", + image_name, io_result); + goto exit; + } + + /* See if we have enough space */ + if (image_size > mem_layout->free_size) { + WARN("Cannot load '%s' file: Not enough space.\n", + image_name); + dump_load_info(0, image_size, mem_layout); + goto exit; + } + + switch (load_type) { + + case TOP_LOAD: + + /* Load the image in the top of free memory */ + temp_image_base = mem_layout->free_base + mem_layout->free_size; + temp_image_base -= image_size; + + /* Page align base address and check whether the image still fits */ + image_base = page_align(temp_image_base, DOWN); + assert(image_base <= temp_image_base); + + if (image_base < mem_layout->free_base) { + WARN("Cannot load '%s' file: Not enough space.\n", + image_name); + dump_load_info(image_base, image_size, mem_layout); + io_result = -ENOMEM; + goto exit; + } + + /* Calculate the amount of extra memory used due to alignment */ + offset = temp_image_base - image_base; + + break; + + case BOT_LOAD: + + /* Load the BL2 image in the bottom of free memory */ + temp_image_base = mem_layout->free_base; + image_base = page_align(temp_image_base, UP); + assert(image_base >= temp_image_base); + + /* Page align base address and check whether the image still fits */ + if (image_base + image_size > + mem_layout->free_base + mem_layout->free_size) { + WARN("Cannot load '%s' file: Not enough space.\n", + image_name); + dump_load_info(image_base, image_size, mem_layout); + io_result = -ENOMEM; + goto exit; + } + + /* Calculate the amount of extra memory used due to alignment */ + offset = image_base - temp_image_base; + + break; + + default: + assert(0); + + } + + /* + * Some images must be loaded at a fixed address, not a dynamic one. + * + * This has been implemented as a hack on top of the existing dynamic + * loading mechanism, for the time being. If the 'fixed_addr' function + * argument is different from zero, then it will force the load address. + * So we still have this principle of top/bottom loading but the code + * determining the load address is bypassed and the load address is + * forced to the fixed one. + * + * This can result in quite a lot of wasted space because we still use + * 1 sole meminfo structure to represent the extents of free memory, + * where we should use some sort of linked list. + * + * E.g. we want to load BL2 at address 0x04020000, the resulting memory + * layout should look as follows: + * ------------ 0x04040000 + * | | <- Free space (1) + * |----------| + * | BL2 | + * |----------| 0x04020000 + * | | <- Free space (2) + * |----------| + * | BL1 | + * ------------ 0x04000000 + * + * But in the current hacky implementation, we'll need to specify + * whether BL2 is loaded at the top or bottom of the free memory. + * E.g. if BL2 is considered as top-loaded, the meminfo structure + * will give the following view of the memory, hiding the chunk of + * free memory above BL2: + * ------------ 0x04040000 + * | | + * | | + * | BL2 | + * |----------| 0x04020000 + * | | <- Free space (2) + * |----------| + * | BL1 | + * ------------ 0x04000000 + */ + if (fixed_addr != 0) { + /* Load the image at the given address. */ + image_base = fixed_addr; + + /* Check whether the image fits. */ + if ((image_base < mem_layout->free_base) || + (image_base + image_size > + mem_layout->free_base + mem_layout->free_size)) { + WARN("Cannot load '%s' file: Not enough space.\n", + image_name); + dump_load_info(image_base, image_size, mem_layout); + io_result = -ENOMEM; + goto exit; + } + + /* Check whether the fixed load address is page-aligned. */ + if (!is_page_aligned(image_base)) { + WARN("Cannot load '%s' file at unaligned address 0x%lx\n", + image_name, fixed_addr); + io_result = -ENOMEM; + goto exit; + } + + /* + * Calculate the amount of extra memory used due to fixed + * loading. + */ + if (load_type == TOP_LOAD) { + unsigned long max_addr, space_used; + /* + * ------------ max_addr + * | /wasted/ | | offset + * |..........|.............................. + * | image | | image_flen + * |----------| fixed_addr + * | | + * | | + * ------------ total_base + */ + max_addr = mem_layout->total_base + mem_layout->total_size; + /* + * Compute the amount of memory used by the image. + * Corresponds to all space above the image load + * address. + */ + space_used = max_addr - fixed_addr; + /* + * Calculate the amount of wasted memory within the + * amount of memory used by the image. + */ + offset = space_used - image_size; + } else /* BOT_LOAD */ + /* + * ------------ + * | | + * | | + * |----------| + * | image | + * |..........| fixed_addr + * | /wasted/ | | offset + * ------------ total_base + */ + offset = fixed_addr - mem_layout->total_base; + } + + /* We have enough space so load the image now */ + /* TODO: Consider whether to try to recover/retry a partially successful read */ + io_result = io_read(image_handle, image_base, image_size, &bytes_read); + if ((io_result != IO_SUCCESS) || (bytes_read < image_size)) { + WARN("Failed to load '%s' file (%i)\n", image_name, io_result); + goto exit; + } + + image_data->image_base = image_base; + image_data->image_size = image_size; + + if (entry_point_info != NULL) + entry_point_info->pc = image_base; + + /* + * File has been successfully loaded. Update the free memory + * data structure & flush the contents of the TZRAM so that + * the next EL can see it. + */ + /* Update the memory contents */ + flush_dcache_range(image_base, image_size); + + mem_layout->free_size -= image_size + offset; + + /* Update the base of free memory since its moved up */ + if (load_type == BOT_LOAD) + mem_layout->free_base += offset + image_size; + +exit: + io_close(image_handle); + /* Ignore improbable/unrecoverable error in 'close' */ + + /* TODO: Consider maintaining open device connection from this bootloader stage */ + io_dev_close(dev_handle); + /* Ignore improbable/unrecoverable error in 'dev_close' */ + + return io_result; +}
\ No newline at end of file diff --git a/common/debug.c b/common/debug.c new file mode 100644 index 0000000..4657d55 --- /dev/null +++ b/common/debug.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <serial.h> +#include <debug.h> +#include <stdio.h> + +/****************************************************************** +* This function is invoked from assembler error handling routines and +* prints out the string and the value in 64 bit hex format. These +* are passed to the function as input parameters. +********************************************************************/ +void print_string_value(char *s, unsigned long *mem) +{ + unsigned char i, temp; + unsigned long val; + + while (*s) { + i = 16; + while (*s) + serial_putc(*s++); + + s++; + + serial_putc('\t'); + serial_putc(':'); + serial_putc('0'); + serial_putc('x'); + + val = *mem++; + + while (i--) { + temp = (val >> (i << 2)) & 0xf; + if (temp < 0xa) + serial_putc('0' + temp); + else + serial_putc('A' + (temp - 0xa)); + } + serial_putc('\n'); + } +} + +/*********************************************************** + * The common implementation of do_panic for all BL stages + ***********************************************************/ + +#if DEBUG +void __dead2 do_panic(const char *file, int line) +{ + serial_puts("PANIC in file: "); + serial_puts(file); + serial_puts(" line: "); + serial_put_dec(line); + serial_puts("\n"); + while (1) + ; +} +#else +void __dead2 do_panic(void) +{ + unsigned long pc_reg; + __asm__ volatile("mov %0, x30\n" + : "=r" (pc_reg) : ); + + /* x30 reports the next eligible instruction whereas we want the + * place where panic() is invoked. Hence decrement by 4. + */ + //printf("PANIC in PC location 0x%016X\n", pc_reg - 0x4); + serial_puts("PANIC in PC location 0x"); + serial_put_hex(pc_reg - 0x4, 64); + serial_puts("\n"); + while (1) + ; + +} +#endif diff --git a/common/fip.c b/common/fip.c new file mode 100644 index 0000000..cdc579a --- /dev/null +++ b/common/fip.c @@ -0,0 +1,248 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/common/fip.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <arch.h> +#include <arch_helpers.h> +#include <fip.h> +#include <storage.h> +#include <string.h> +#include <platform.h> +#include <platform_def.h> +#include <stdio.h> +#include <asm/arch/cpu_config.h> +#include <storage.h> +#include <sha2.h> +#include <mailbox.h> +#include <asm/arch/romboot.h> +#include <cache.h> +#include <fip.h> +#include <asm/arch/watchdog.h> +#include <timer.h> +#include <io.h> + +static int aml_check(unsigned long pBufferSRC,unsigned long pBufferDST,unsigned int nLength,unsigned int nAESFlag); + +void bl2_load_image(void){ + /* dump ddr data when function enabled and flag set */ + dump_ddr_data(); + + //meminfo_t *bl2_tzram_layout; + bl31_params_t *bl2_to_bl31_params; + entry_point_info_t *bl31_ep_info; + //meminfo_t bl33_mem_info; + unsigned int * pCHK = (unsigned int *)FM_FIP_HEADER_LOAD_ADDR; + unsigned int nAESFlag = 1; + unsigned int nBL3XLoadAddr = readl(0xc8100228); + nBL3XLoadAddr = readl(0xc8100228); + int nSecFlag = nBL3XLoadAddr & (1<<4); + /*load fip header*/ + aml_fip_header_t *fip_header; + fip_header = (aml_fip_header_t *)(uint64_t)FM_FIP_HEADER_LOAD_ADDR; +#if defined(CONFIG_AML_SECURE_UBOOT) + extern void platform_stack_set_bl2 (unsigned long); + platform_stack_set_bl2(BL2_SEC_BOOT_SP_BASE); +#endif + storage_load(BL2_SIZE, (uint64_t)fip_header, sizeof(aml_fip_header_t), "fip header"); + memcpy((void*)FM_FIP_BL3X_TEMP_LOAD_ADDR,(void*)FM_FIP_HEADER_LOAD_ADDR,sizeof(aml_fip_header_t)); + if (TOC_HEADER_NAME == *pCHK && TOC_HEADER_SERIAL_NUMBER == *(pCHK+1)) + { + nAESFlag = 0; + } + + aml_check(FM_FIP_BL3X_TEMP_LOAD_ADDR,FM_FIP_HEADER_LOAD_ADDR,sizeof(aml_fip_header_t),nAESFlag); + + /*load and process bl30*/ + image_info_t bl30_image_info; + entry_point_info_t bl30_ep_info; + nBL3XLoadAddr = nSecFlag ? FM_FIP_BL3X_TEMP_LOAD_ADDR : FM_BL30_LOAD_ADDR; + storage_load(BL2_SIZE + (fip_header->bl30_entry.offset),nBL3XLoadAddr, (fip_header->bl30_entry.size), "bl30"); + parse_blx(&bl30_image_info, &bl30_ep_info,nBL3XLoadAddr, FM_BL30_LOAD_ADDR, (fip_header->bl30_entry.size),nAESFlag); + /*process bl30*/ + process_bl30x(&bl30_image_info, &bl30_ep_info, "bl30"); + +#if (NEED_BL301) + /*load and process bl301*/ + image_info_t bl301_image_info; + entry_point_info_t bl301_ep_info; + nBL3XLoadAddr = nSecFlag ? FM_FIP_BL3X_TEMP_LOAD_ADDR : FM_BL301_LOAD_ADDR; + storage_load(BL2_SIZE + (fip_header->bl301_entry.offset),nBL3XLoadAddr, (fip_header->bl301_entry.size), "bl301"); + parse_blx(&bl301_image_info, &bl301_ep_info, nBL3XLoadAddr ,FM_BL301_LOAD_ADDR, (fip_header->bl301_entry.size),nAESFlag); + /*process bl301*/ + process_bl30x(&bl301_image_info, &bl301_ep_info, "bl301"); +#endif + + /*load and process bl31*/ + bl2_to_bl31_params = bl2_plat_get_bl31_params(); + bl31_ep_info = bl2_plat_get_bl31_ep_info(); + /* Set the X0 parameter to bl31 */ + bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params; + nBL3XLoadAddr = nSecFlag ? FM_FIP_BL3X_TEMP_LOAD_ADDR : FM_BL31_LOAD_ADDR; + storage_load(BL2_SIZE + (fip_header->bl31_entry.offset), nBL3XLoadAddr, (fip_header->bl31_entry.size), "bl31"); + parse_blx(bl2_to_bl31_params->bl31_image_info, bl31_ep_info,nBL3XLoadAddr, FM_BL31_LOAD_ADDR, (fip_header->bl31_entry.size),nAESFlag); + bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info, bl31_ep_info); + +#if (NEED_BL32) + /* + * Load the BL32 image if there's one. It is upto to platform + * to specify where BL32 should be loaded if it exists. It + * could create space in the secure sram or point to a + * completely different memory. + * + * If a platform does not want to attempt to load BL3-2 image + * it must leave NEED_BL32=0 + */ + meminfo_t bl32_mem_info; + bl2_plat_get_bl32_meminfo(&bl32_mem_info); + nBL3XLoadAddr = nSecFlag ? FM_FIP_BL3X_TEMP_LOAD_ADDR : FM_BL32_LOAD_ADDR; + storage_load(BL2_SIZE + fip_header->bl32_entry.offset, nBL3XLoadAddr , fip_header->bl32_entry.size, "bl32"); + parse_blx(bl2_to_bl31_params->bl32_image_info, bl2_to_bl31_params->bl32_ep_info, + nBL3XLoadAddr, FM_BL32_LOAD_ADDR, fip_header->bl32_entry.size,nAESFlag); + bl2_plat_set_bl32_ep_info(bl2_to_bl31_params->bl32_image_info, bl2_to_bl31_params->bl32_ep_info); +#endif /* NEED_BL32 */ + + /*load and process bl33*/ + nBL3XLoadAddr = nSecFlag ? FM_FIP_BL3X_TEMP_LOAD_ADDR : FM_BL33_LOAD_ADDR; + storage_load(BL2_SIZE + fip_header->bl33_entry.offset,nBL3XLoadAddr, fip_header->bl33_entry.size, "bl33"); + parse_blx(bl2_to_bl31_params->bl33_image_info, bl2_to_bl31_params->bl33_ep_info, + nBL3XLoadAddr, FM_BL33_LOAD_ADDR, fip_header->bl33_entry.size,nAESFlag); + //bl2_plat_get_bl33_meminfo(&bl33_mem_info); + bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info, bl2_to_bl31_params->bl33_ep_info); + + /* Flush the params to be passed to memory */ + bl2_plat_flush_bl31_params(); + + /*disable mmu and dcache, flush dcache, then enter next firmware*/ + disable_mmu_el1(); + watchdog_disable(); + /* + * Run BL31 via an SMC to BL1. Information on how to pass control to + * the BL32 (if present) and BL33 software images will be passed to + * BL31 as an argument. + */ + + smc(RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0); + +/* + typedef unsigned long (*FUNC_TPL)(void ); + unsigned long bl33_entry = FM_BL33_LOAD_ADDR; + serial_puts("bl33 entry: 0x"); + serial_put_hex(bl33_entry, 32); + serial_puts("\n"); + FUNC_TPL func_tpl=(FUNC_TPL)bl33_entry; + func_tpl(); +*/ +} + +static int aml_check(unsigned long pBufferSRC,unsigned long pBufferDST,unsigned int nLength,unsigned int nAESFlag) +{ + int nReturn = aml_data_check(pBufferSRC,pBufferDST,nLength,nAESFlag); + if (nReturn) + { + //printf("aml log : SIG CHK : %d for address 0x%08X\n",nReturn,pBufferSRC); + serial_puts("aml log : SIG CHK : "); + serial_put_dec(nReturn); + serial_puts(" for address 0x"); + serial_put_hex(pBufferSRC, 32); + serial_puts("\n"); + //while(1); + check_handler(); + } + + return nReturn; +} + +/*blx header parse function*/ +void parse_blx(image_info_t *image_data, + entry_point_info_t *entry_point_info, + unsigned int src, + unsigned int dst, + unsigned int length, + unsigned int nAESFlag) +{ + image_data->image_base = dst; + image_data->image_size = length; + if (entry_point_info != NULL) + entry_point_info->pc = dst; + + aml_check(src,dst,length,nAESFlag); +} + +/*process bl30x, transfer to m3, etc..*/ +void process_bl30x(image_info_t *image_data, + entry_point_info_t *entry_point_info, const char * name) +{ + //serial_puts("start sha2\n"); + uint8_t _sha2[32] = {0}; + sha2((const uint8_t *)image_data->image_base, + image_data->image_size, + _sha2, + 0); /*0 means sha256, else means sha224*/ + +#if 0 + serial_puts(name); + serial_puts(" sha2:"); + int print_loop = 0; + for (print_loop=0; print_loop<32; print_loop++) { + if (0 == (print_loop % 16)) + serial_puts("\n"); + serial_put_hex(_sha2[print_loop], 8); + serial_puts(" "); + } + serial_puts("\n"); +#endif + + send_bl30x(image_data->image_base, image_data->image_size, \ + _sha2, sizeof(_sha2), name); + return; +} + +void bl2_to_romcode(uintptr_t entry) +{ + bl31_params_t *bl2_to_bl31_params; + entry_point_info_t *bl31_ep_info; + + bl2_to_bl31_params = bl2_plat_get_bl31_params(); + bl31_ep_info = bl2_plat_get_bl31_ep_info(); + /* Set the X0 parameter to bl31 */ + bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params; + + bl31_ep_info->pc = entry; + SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE); + bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, + (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_DBG_BIT)); + + watchdog_disable(); + disable_mmu_el1(); + + bl31_ep_info->args.arg0 = 0; + smc(RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0); +} + +void check_handler(void) { + if (BOOT_DEVICE_USB == get_boot_device()) { + serial_puts("USB mode!\n"); + bl2_to_romcode(USB_BL2_RETURN_ROM_ADDR); + } + else{ + serial_puts("reset...\n"); + reset_system(); + } +} diff --git a/common/memtest.c b/common/memtest.c new file mode 100644 index 0000000..e7bdb6b --- /dev/null +++ b/common/memtest.c @@ -0,0 +1,369 @@ +/********************************************************************** + * + * Filename: memtest.c + * + * Description: General-purpose memory testing functions. + * + * Notes: This software can be easily ported to systems with + * different data bus widths by redefining 'unsigned int'. + * + * + * Copyright (c) 1998 by Michael Barr. This software is placed into + * the public domain and may be used for any purpose. However, this + * notice must not be changed or removed and no warranty is either + * expressed or implied by its publication or distribution. + **********************************************************************/ + +#define MEM_TEST_DEBUG 0 + +#include <stdio.h> + +/********************************************************************** + * + * Function: memTestDataBus() + * + * Description: Test the data bus wiring in a memory region by + * performing a walking 1's test at a fixed address + * within that region. The address (and hence the + * memory region) is selected by the caller. + * + * Notes: + * + * Returns: 0 if the test succeeds. + * A non-zero result is the first pattern that failed. + * + **********************************************************************/ +unsigned int +memTestDataBus(volatile unsigned int * address) +{ + unsigned int pattern; + unsigned int data; + unsigned int ret = 0; + /* + * Perform a walking 1's test at the given address. + */ + for (pattern = 1; pattern != 0; pattern <<= 1) + { + /* + * Write the test pattern. + */ + *address = pattern; + data = *address; + /* + * Read it back (immediately is okay for this test). + */ + if (data != pattern) + { +#if (MEM_TEST_DEBUG) + //printf(" memTestDataBus - write: 0x%8x, read back: 0x%8x\n", pattern, data); + serial_puts(" memTestDataBus - write: 0x"); + serial_put_hex(pattern, 32); + serial_puts(", read back: 0x"); + serial_put_hex(data, 32); + serial_puts("\n"); + ret = 1; +#else + return (pattern); +#endif + } + } + return (ret); +} /* memTestDataBus() */ + + +/********************************************************************** + * + * Function: memTestAddressBus() + * + * Description: Test the address bus wiring in a memory region by + * performing a walking 1's test on the relevant bits + * of the address and checking for aliasing. This test + * will find single-bit address failures such as stuck + * -high, stuck-low, and shorted pins. The base address + * and size of the region are selected by the caller. + * + * Notes: For best results, the selected base address should + * have enough LSB 0's to guarantee single address bit + * changes. For example, to test a 64-Kbyte region, + * select a base address on a 64-Kbyte boundary. Also, + * select the region size as a power-of-two--if at all + * possible. + * + * Returns: NULL if the test succeeds. + * A non-zero result is the first address at which an + * aliasing problem was uncovered. By examining the + * contents of memory, it may be possible to gather + * additional information about the problem. + * + **********************************************************************/ +unsigned int +memTestAddressBus(volatile unsigned int * baseAddress, unsigned int nBytes) +{ + unsigned int addressMask = (nBytes/sizeof(unsigned int) - 1); + unsigned int offset; + unsigned int testOffset; + + unsigned int pattern = (unsigned int) 0xAAAAAAAA; + unsigned int antipattern = (unsigned int) 0x55555555; + + unsigned int data1, data2; + + /* align the mask address */ + unsigned int temp_i=1, temp_j=0; + temp_j = addressMask; + do { + temp_i=(temp_i<<1); + temp_j=(temp_j>>1); + }while((temp_j)); + addressMask=((temp_i)-1); + + unsigned int ret = 0; + + /* + * Write the default pattern at each of the power-of-two offsets. + */ + for (offset = 1; (offset & addressMask) != 0; offset <<= 1) + { + baseAddress[offset] = pattern; + } + + /* + * Check for address bits stuck high. + */ + testOffset = 0; + baseAddress[testOffset] = antipattern; + + for (offset = 1; (offset & addressMask) != 0; offset <<= 1) + { + data1 = baseAddress[offset]; + data2 = baseAddress[offset]; + if (data1 != data2) + { +#if (MEM_TEST_DEBUG) + //printf(" memTestAddressBus - read twice different[offset]: 0x%8x-0x%8x\n", data1, data2); + serial_puts(" memTestAddressBus - read twice different[offset]: 0x"); + serial_put_hex(data1, 32); + serial_puts("-0x"); + serial_put_hex(data2, 32); + serial_puts("\n"); +#endif + ret = 1; + } + if (data1 != pattern) + { +#if (MEM_TEST_DEBUG) + /*printf(" memTestAddressBus - write[0x%8x]: 0x%8x, read[0x%8x]: 0x%8x\n", \ + offset, pattern, offset, data1); + */ + serial_puts(" memTestAddressBus - write[0x"); + serial_put_hex(offset, 32); + serial_puts("]: 0x"); + serial_put_hex(pattern, 32); + serial_puts(", read[0x"); + serial_put_hex(offset, 32); + serial_puts("]: 0x"); + serial_put_hex(data1, 32); + serial_puts("\n"); + ret = 1; +#else + return ((unsigned int)(unsigned long) &baseAddress[offset]); +#endif + } + } + + baseAddress[testOffset] = pattern; + + /* + * Check for address bits stuck low or shorted. + */ + for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1) + { + baseAddress[testOffset] = antipattern; + + if (baseAddress[0] != pattern) + { +#if (MEM_TEST_DEBUG) + /*printf(" memTestAddressBus2 - write baseAddress[0x%8x]: 0x%8x, read baseAddress[0]: 0x%8x\n", \ + testOffset, antipattern, baseAddress[0]); + */ + serial_puts(" memTestAddressBus2 - write baseAddress[0x"); + serial_put_hex(testOffset, 32); + serial_puts("]: 0x"); + serial_put_hex(antipattern, 32); + serial_puts(", read baseAddress[0]: 0x"); + serial_put_hex(baseAddress[0], 32); + serial_puts("\n"); + ret = 1; +#else + return ((unsigned int)(unsigned long) &baseAddress[testOffset]); +#endif + } + + for (offset = 1; (offset & addressMask) != 0; offset <<= 1) + { + data1 = baseAddress[offset]; + if ((data1 != pattern) && (offset != testOffset)) + { +#if (MEM_TEST_DEBUG) + /*printf(" memTestAddressBus3 - write baseAddress[0x%8x]: 0x%8x, read baseAddress[0x%8x]: 0x%8x\n", \ + testOffset, antipattern, testOffset, data1); + */ + serial_puts(" memTestAddressBus3 - write baseAddress[0x"); + serial_put_hex(testOffset, 32); + serial_puts("]: 0x"); + serial_put_hex(antipattern, 32); + serial_puts(", read baseAddress[0x"); + serial_put_hex(testOffset, 32); + serial_puts("]: 0x"); + serial_put_hex(data1, 32); + serial_puts("\n"); + ret = 1; +#else + return ((unsigned int)(unsigned long) &baseAddress[testOffset]); +#endif + } + } + + baseAddress[testOffset] = pattern; + } + return (ret); +} /* memTestAddressBus() */ + + +/********************************************************************** + * + * Function: memTestDevice() + * + * Description: Test the integrity of a physical memory device by + * performing an increment/decrement test over the + * entire region. In the process every storage bit + * in the device is tested as a zero and a one. The + * base address and the size of the region are + * selected by the caller. + * + * Notes: + * + * Returns: NULL if the test succeeds. + * + * A non-zero result is the first address at which an + * incorrect value was read back. By examining the + * contents of memory, it may be possible to gather + * additional information about the problem. + * + **********************************************************************/ +/*#define AML_DEBUG_ROM*/ +#if MEM_TEST_DEVICE +unsigned int +memTestDevice(volatile unsigned int * baseAddress, unsigned int nBytes) +{ + + unsigned int offset; + unsigned int nWords = nBytes / sizeof(unsigned int); + unsigned int ret = 0; + unsigned int data; + unsigned int pattern; + unsigned int antipattern; + serial_puts("\nTotal Size 0x"); + serial_put_hex(nBytes, 32); + serial_puts("\n"); + + /* + * Fill memory with a known pattern. + */ + for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) + { + baseAddress[offset] = pattern; +#ifdef AML_DEBUG_ROM + if ((offset&0x3ffff) == 0) + { + serial_puts("\r0x"); + serial_put_hex(offset<<2, 32); + } +#endif + + } + serial_puts("\n"); + + /* + * Check each location and invert it for the second pass. + */ + for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) + { + data = baseAddress[offset]; + if ( data!= pattern) + { +#if (MEM_TEST_DEBUG) + /*printf(" memTestDevice - write baseAddress[0x%8x]: 0x%8x, read baseAddress[0x%8x]: 0x%8x\n", \ + offset, pattern, offset, data); + */ + serial_puts(" memTestDevice - write baseAddress[0x"); + serial_put_hex(offset, 32); + serial_puts("]: 0x"); + serial_put_hex(pattern, 32); + serial_puts(", read baseAddress[0x"); + serial_put_hex(offset, 32); + serial_puts("]: 0x"); + serial_put_hex(data, 32); + serial_puts("\n"); + ret = 1; +#else + return ((unsigned int)(unsigned long) &baseAddress[offset]); +#endif + } + + antipattern = ~pattern; + baseAddress[offset] = antipattern; +#ifdef AML_DEBUG_ROM + if ((offset&0x3ffff) == 0) + { + serial_puts("\r0x"); + serial_put_hex((offset<<2), 32); + } +#endif + + } + serial_puts("\n"); + + /* + * Check each location for the inverted pattern and zero it. + */ + for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) + { + antipattern = ~pattern; + data = baseAddress[offset]; + if (data != antipattern) + { +#if (MEM_TEST_DEBUG) + /*printf(" memTestDevice2 - write baseAddress[0x%8x]: 0x%8x, read baseAddress[0x%8x]: 0x%8x\n", \ + offset, antipattern, offset, data); + */ + serial_puts(" memTestDevice2 - write baseAddress[0x"); + serial_put_hex(offset, 32); + serial_puts("]: 0x"); + serial_put_hex(pattern, 32); + serial_puts(", read baseAddress[0x"); + serial_put_hex(offset, 32); + serial_puts("]: 0x"); + serial_put_hex(data, 32); + serial_puts("\n"); + ret = 1; +#else + return ((unsigned int)(unsigned long) &baseAddress[offset]); +#endif + } +#ifdef AML_DEBUG_ROM + if ((offset&0x3ffff) == 0) + { + serial_puts("\r0x"); + serial_put_hex((offset<<2), 32); + } +#endif + + } +#undef AML_DEBUG_ROM + serial_puts("\n"); + + return (ret); +} /* memTestDevice() */ +#endif// #if MEM_TEST_DEVICE + diff --git a/contributing.md b/contributing.md new file mode 100644 index 0000000..6b24fb5 --- /dev/null +++ b/contributing.md @@ -0,0 +1,121 @@ +Contributing to ARM Trusted Firmware +==================================== + +Before you start contributing to this project you must sign the ARM +Contributor License Agreement (CLA). + +Individuals who want to contribute their own work must sign and return an +Individual CLA. Companies that want to contribute must sign and return a +Corporate CLA if their employees' intellectual property has been assigned to +the employer. Copies of the CLAs are available from the [contributing page] of +the ARM website. + +For this project, ARM also requires the GitHub account name(s) associated with +each individual contributor or the designated employees of corporate +contributors. Only contributions originating from these accounts will be +considered covered by the CLA. To avoid delay, you should provide the Github +account name(s) at the same time as the signed CLA. + +ARM reserves the right to not accept a contribution. This may be for technical, +commercial or legal reasons. + + +Getting Started +--------------- + +* Make sure you have a [GitHub account]. +* Create an [issue] for your work if one does not already exist. This gives + everyone visibility of whether others are working on something similar. ARM + licensees may contact ARM directly via their partner managers instead if + they prefer. + * Note that the [issue] tracker for this project is in a separate + [issue tracking repository]. Please follow the guidelines in that + repository. + * If you intend to include Third Party IP in your contribution, please + raise a separate [issue] for this and ensure that the changes that + include Third Party IP are made on a separate topic branch. +* [Fork][] [arm-trusted-firmware][] on GitHub. +* Clone the fork to your own machine. +* Create a local topic branch based on the [arm-trusted-firmware][] `master` + branch. + + +Making Changes +-------------- + +* Make commits of logical units. See these general [Git guidelines] for + contributing to a project. +* Follow the [Linux coding style]; this style is enforced for the ARM Trusted + Firmware project (style errors only, not warnings). + * Use the checkpatch.pl script provided with the Linux source tree. A + Makefile target is provided for convenience (see section 2 in the + [User Guide]). +* Keep the commits on topic. If you need to fix another bug or make another + enhancement, please create a separate [issue] and address it on a separate + topic branch. +* Avoid long commit series. If you do have a long series, consider whether + some commits should be squashed together or addressed in a separate topic. +* Make sure your commit messages are in the proper format. If a commit fixes + a GitHub [issue], include a reference (e.g. + "fixes arm-software/tf-issues#45"); this ensures the [issue] is + [automatically closed] when merged into the [arm-trusted-firmware] `master` + branch. +* Where appropriate, please update the documentation. + * Consider whether the [User Guide], [Porting Guide], [Firmware Design] or + other in-source documentation needs updating. + * If this is your first contribution, you may add your name or your + company name to the [Acknowledgements] file. + * For topics with multiple commits, you should make all documentation + changes (and nothing else) in the last commit of the series. Otherwise, + include the documentation changes within the single commit. +* Please test your changes. As a minimum, ensure UEFI boots to the shell on + the Foundation FVP. See the "[Running the software]" section of the + [User Guide] for more information. + + +Submitting Changes +------------------ + +* Ensure we have your signed CLA. +* Push your local changes to your fork of the repository. +* Submit a [pull request] to the [arm-trusted-firmware] `integration` branch. + * The changes in the [pull request] will then undergo further review and + testing. Any review comments will be made as comments on the [pull + request]. This may require you to do some rework. +* When the changes are accepted, ARM will integrate them. + * Typically, ARM will merge the [pull request] into the `integration` + branch within the GitHub UI, creating a merge commit. + * Please avoid creating merge commits in the [pull request] itself. + * If the [pull request] is not based on a recent commit, ARM may rebase + it onto the `master` branch first, or ask you to do this. + * If the [pull request] cannot be automatically merged, ARM will ask you + to rebase it onto the `master` branch. + * After final integration testing, ARM will push your merge commit to the + `master` branch. If a problem is found at this stage, the merge commit + will be removed from the `integration` branch and ARM will ask you to + create a new pull request to resolve the problem. + * Please do not delete your topic branch until it is safely merged into + the `master` branch. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - + +_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._ + + +[User Guide]: ./docs/user-guide.md +[Running the software]: ./docs/user-guide.md#6--running-the-software +[Porting Guide]: ./docs/porting-guide.md +[Firmware Design]: ./docs/firmware-design.md +[Acknowledgements]: ./acknowledgements.md "Contributor acknowledgements" + +[contributing page]: http://www.arm.com/community/open-source-contributing.php +[GitHub account]: https://github.com/signup/free +[Fork]: https://help.github.com/articles/fork-a-repo +[issue tracking repository]: https://github.com/ARM-software/tf-issues +[issue]: https://github.com/ARM-software/tf-issues/issues +[pull request]: https://help.github.com/articles/using-pull-requests +[automatically closed]: https://help.github.com/articles/closing-issues-via-commit-messages +[Git guidelines]: http://git-scm.com/book/ch5-2.html +[Linux coding style]: https://www.kernel.org/doc/Documentation/CodingStyle +[arm-trusted-firmware]: https://github.com/ARM-software/arm-trusted-firmware diff --git a/docs/change-log.md b/docs/change-log.md new file mode 100644 index 0000000..c7ad084 --- /dev/null +++ b/docs/change-log.md @@ -0,0 +1,361 @@ +ARM Trusted Firmware - version 0.4 +================================== + +New features +------------ + +* Makefile improvements: + + * Improved dependency checking when building. + + * Removed `dump` target (build now always produces dump files). + + * Enabled platform ports to optionally make use of parts of the Trusted + Firmware (e.g. BL3-1 only), rather than being forced to use all parts. + Also made the `fip` target optional. + + * Specified the full path to source files and removed use of the `vpath` + keyword. + +* Provided translation table library code for potential re-use by platforms + other than the FVPs. + +* Moved architectural timer setup to platform-specific code. + +* Added standby state support to PSCI cpu_suspend implementation. + +* SRAM usage improvements: + + * Started using the `-ffunction-sections`, `-fdata-sections` and + `--gc-sections` compiler/linker options to remove unused code and data + from the images. Previously, all common functions were being built into + all binary images, whether or not they were actually used. + + * Placed all assembler functions in their own section to allow more unused + functions to be removed from images. + + * Updated BL1 and BL2 to use a single coherent stack each, rather than one + per CPU. + + * Changed variables that were unnecessarily declared and initialized as + non-const (i.e. in the .data section) so they are either uninitialized + (zero init) or const. + +* Moved the Test Secure-EL1 Payload (BL3-2) to execute in Trusted SRAM by + default. The option for it to run in Trusted DRAM remains. + +* Implemented a TrustZone Address Space Controller (TZC-400) driver. A + default configuration is provided for the Base FVPs. This means the model + parameter `-C bp.secure_memory=1` is now supported. + +* Started saving the PSCI cpu_suspend 'power_state' parameter prior to + suspending a CPU. This allows platforms that implement multiple power-down + states at the same affinity level to identify a specific state. + +* Refactored the entire codebase to reduce the amount of nesting in header + files and to make the use of system/user includes more consistent. Also + split platform.h to separate out the platform porting declarations from the + required platform porting definitions and the definitions/declarations + specific to the platform port. + +* Optimized the data cache clean/invalidate operations. + +* Improved the BL3-1 unhandled exception handling and reporting. Unhandled + exceptions now result in a dump of registers to the console. + +* Major rework to the handover interface between BL stages, in particular the + interface to BL3-1. The interface now conforms to a specification and is + more future proof. + +* Added support for optionally making the BL3-1 entrypoint a reset handler + (instead of BL1). This allows platforms with an alternative image loading + architecture to re-use BL3-1 with fewer modifications to generic code. + +* Reserved some DDR DRAM for secure use on FVP platforms to avoid future + compatibility problems with non-secure software. + +* Added support for secure interrupts targeting the Secure-EL1 Payload (SP) + (using GICv2 routing only). Demonstrated this working by adding an interrupt + target and supporting test code to the TSP. Also demonstrated non-secure + interrupt handling during TSP processing. + + +Issues resolved since last release +---------------------------------- + +* Now support use of the model parameter `-C bp.secure_memory=1` in the Base + FVPs (see **New features**). + +* Support for secure world interrupt handling now available (see **New + features**). + +* Made enough SRAM savings (see **New features**) to enable the Test Secure-EL1 + Payload (BL3-2) to execute in Trusted SRAM by default. + +* The tested filesystem used for this release (Linaro AArch64 OpenEmbedded + 14.04) now correctly reports progress in the console. + +* Improved the Makefile structure to make it easier to separate out parts of + the Trusted Firmware for re-use in platform ports. Also, improved target + dependency checking. + + +Known issues +------------ + +* GICv3 support is experimental. The Linux kernel patches to support this are + not widely available. There are known issues with GICv3 initialization in + the ARM Trusted Firmware. + +* Dynamic image loading is not available yet. The current image loader + implementation (used to load BL2 and all subsequent images) has some + limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead + to loading errors, even if the images should theoretically fit in memory. + +* The ARM Trusted Firmware still uses too much on-chip Trusted SRAM. A number + of RAM usage enhancements have been identified to rectify this situation. + +* CPU idle does not work on the advertised version of the Foundation FVP. + Some FVP fixes are required that are not available externally at the time + of writing. This can be worked around by disabling CPU idle in the Linux + kernel. + +* Various bugs in ARM Trusted Firmware, UEFI and the Linux kernel have been + observed when using Linaro toolchain versions later than 13.11. Although + most of these have been fixed, some remain at the time of writing. These + mainly seem to relate to a subtle change in the way the compiler converts + between 64-bit and 32-bit values (e.g. during casting operations), which + reveals previously hidden bugs in client code. + +* The firmware design documentation for the Test Secure-EL1 Payload (TSP) and + its dispatcher (TSPD) is incomplete. Similarly for the PSCI section. + + +ARM Trusted Firmware - version 0.3 +================================== + +New features +------------ + +* Support for Foundation FVP Version 2.0 added. + The documented UEFI configuration disables some devices that are unavailable + in the Foundation FVP, including MMC and CLCD. The resultant UEFI binary can + be used on the AEMv8 and Cortex-A57-A53 Base FVPs, as well as the Foundation + FVP. + + NOTE: The software will not work on Version 1.0 of the Foundation FVP. + +* Enabled third party contributions. Added a new contributing.md containing + instructions for how to contribute and updated copyright text in all files + to acknowledge contributors. + +* The PSCI CPU_SUSPEND API has been stabilised to the extent where it can be + used for entry into power down states with the following restrictions: + - Entry into standby states is not supported. + - The API is only supported on the AEMv8 and Cortex-A57-A53 Base FVPs. + +* The PSCI AFFINITY_INFO api has undergone limited testing on the Base FVPs to + allow experimental use. + +* Required C library and runtime header files are now included locally in ARM + Trusted Firmware instead of depending on the toolchain standard include + paths. The local implementation has been cleaned up and reduced in scope. + +* Added I/O abstraction framework, primarily to allow generic code to load + images in a platform-independent way. The existing image loading code has + been reworked to use the new framework. Semi-hosting and NOR flash I/O + drivers are provided. + +* Introduced Firmware Image Package (FIP) handling code and tools. A FIP + combines multiple firmware images with a Table of Contents (ToC) into a + single binary image. The new FIP driver is another type of I/O driver. The + Makefile builds a FIP by default and the FVP platform code expect to load a + FIP from NOR flash, although some support for image loading using semi- + hosting is retained. + + NOTE: Building a FIP by default is a non-backwards-compatible change. + + NOTE: Generic BL2 code now loads a BL3-3 (non-trusted firmware) image into + DRAM instead of expecting this to be pre-loaded at known location. This is + also a non-backwards-compatible change. + + NOTE: Some non-trusted firmware (e.g. UEFI) will need to be rebuilt so that + it knows the new location to execute from and no longer needs to copy + particular code modules to DRAM itself. + +* Reworked BL2 to BL3-1 handover interface. A new composite structure + (bl31_args) holds the superset of information that needs to be passed from + BL2 to BL3-1, including information on how handover execution control to + BL3-2 (if present) and BL3-3 (non-trusted firmware). + +* Added library support for CPU context management, allowing the saving and + restoring of + - Shared system registers between Secure-EL1 and EL1. + - VFP registers. + - Essential EL3 system registers. + +* Added a framework for implementing EL3 runtime services. Reworked the PSCI + implementation to be one such runtime service. + +* Reworked the exception handling logic, making use of both SP_EL0 and SP_EL3 + stack pointers for determining the type of exception, managing general + purpose and system register context on exception entry/exit, and handling + SMCs. SMCs are directed to the correct EL3 runtime service. + +* Added support for a Test Secure-EL1 Payload (TSP) and a corresponding + Dispatcher (TSPD), which is loaded as an EL3 runtime service. The TSPD + implements Secure Monitor functionality such as world switching and + EL1 context management, and is responsible for communication with the TSP. + NOTE: The TSPD does not yet contain support for secure world interrupts. + NOTE: The TSP/TSPD is not built by default. + + +Issues resolved since last release +---------------------------------- + +* Support has been added for switching context between secure and normal + worlds in EL3. + +* PSCI API calls `AFFINITY_INFO` & `PSCI_VERSION` have now been tested (to + a limited extent). + +* The ARM Trusted Firmware build artifacts are now placed in the `./build` + directory and sub-directories instead of being placed in the root of the + project. + +* The ARM Trusted Firmware is now free from build warnings. Build warnings + are now treated as errors. + +* The ARM Trusted Firmware now provides C library support locally within the + project to maintain compatibility between toolchains/systems. + +* The PSCI locking code has been reworked so it no longer takes locks in an + incorrect sequence. + +* The RAM-disk method of loading a Linux file-system has been confirmed to + work with the ARM Trusted Firmware and Linux kernel version (based on + version 3.13) used in this release, for both Foundation and Base FVPs. + + +Known issues +------------ + +The following is a list of issues which are expected to be fixed in the future +releases of the ARM Trusted Firmware. + +* The TrustZone Address Space Controller (TZC-400) is not being programmed + yet. Use of model parameter `-C bp.secure_memory=1` is not supported. + +* No support yet for secure world interrupt handling. + +* GICv3 support is experimental. The Linux kernel patches to support this are + not widely available. There are known issues with GICv3 initialization in + the ARM Trusted Firmware. + +* Dynamic image loading is not available yet. The current image loader + implementation (used to load BL2 and all subsequent images) has some + limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead + to loading errors, even if the images should theoretically fit in memory. + +* The ARM Trusted Firmware uses too much on-chip Trusted SRAM. Currently the + Test Secure-EL1 Payload (BL3-2) executes in Trusted DRAM since there is not + enough SRAM. A number of RAM usage enhancements have been identified to + rectify this situation. + +* CPU idle does not work on the advertised version of the Foundation FVP. + Some FVP fixes are required that are not available externally at the time + of writing. + +* Various bugs in ARM Trusted Firmware, UEFI and the Linux kernel have been + observed when using Linaro toolchain versions later than 13.11. Although + most of these have been fixed, some remain at the time of writing. These + mainly seem to relate to a subtle change in the way the compiler converts + between 64-bit and 32-bit values (e.g. during casting operations), which + reveals previously hidden bugs in client code. + +* The tested filesystem used for this release (Linaro AArch64 OpenEmbedded + 14.01) does not report progress correctly in the console. It only seems to + produce error output, not standard output. It otherwise appears to function + correctly. Other filesystem versions on the same software stack do not + exhibit the problem. + +* The Makefile structure doesn't make it easy to separate out parts of the + Trusted Firmware for re-use in platform ports, for example if only BL3-1 is + required in a platform port. Also, dependency checking in the Makefile is + flawed. + +* The firmware design documentation for the Test Secure-EL1 Payload (TSP) and + its dispatcher (TSPD) is incomplete. Similarly for the PSCI section. + + +ARM Trusted Firmware - version 0.2 +================================== + +New features +------------ + +* First source release. + +* Code for the PSCI suspend feature is supplied, although this is not enabled + by default since there are known issues (see below). + + +Issues resolved since last release +---------------------------------- + +* The "psci" nodes in the FDTs provided in this release now fully comply + with the recommendations made in the PSCI specification. + + +Known issues +------------ + +The following is a list of issues which are expected to be fixed in the future +releases of the ARM Trusted Firmware. + +* The TrustZone Address Space Controller (TZC-400) is not being programmed + yet. Use of model parameter `-C bp.secure_memory=1` is not supported. + +* No support yet for secure world interrupt handling or for switching context + between secure and normal worlds in EL3. + +* GICv3 support is experimental. The Linux kernel patches to support this are + not widely available. There are known issues with GICv3 initialization in + the ARM Trusted Firmware. + +* Dynamic image loading is not available yet. The current image loader + implementation (used to load BL2 and all subsequent images) has some + limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead + to loading errors, even if the images should theoretically fit in memory. + +* Although support for PSCI `CPU_SUSPEND` is present, it is not yet stable + and ready for use. + +* PSCI API calls `AFFINITY_INFO` & `PSCI_VERSION` are implemented but have not + been tested. + +* The ARM Trusted Firmware make files result in all build artifacts being + placed in the root of the project. These should be placed in appropriate + sub-directories. + +* The compilation of ARM Trusted Firmware is not free from compilation + warnings. Some of these warnings have not been investigated yet so they + could mask real bugs. + +* The ARM Trusted Firmware currently uses toolchain/system include files like + stdio.h. It should provide versions of these within the project to maintain + compatibility between toolchains/systems. + +* The PSCI code takes some locks in an incorrect sequence. This may cause + problems with suspend and hotplug in certain conditions. + +* The Linux kernel used in this release is based on version 3.12-rc4. Using + this kernel with the ARM Trusted Firmware fails to start the file-system as + a RAM-disk. It fails to execute user-space `init` from the RAM-disk. As an + alternative, the VirtioBlock mechanism can be used to provide a file-system + to the kernel. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - + +_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._ diff --git a/docs/diagrams/non-sec-int-handling.png b/docs/diagrams/non-sec-int-handling.png Binary files differnew file mode 100644 index 0000000..1a5f629 --- /dev/null +++ b/docs/diagrams/non-sec-int-handling.png diff --git a/docs/diagrams/rt-svc-descs-layout.png b/docs/diagrams/rt-svc-descs-layout.png Binary files differnew file mode 100644 index 0000000..1a9fa5b --- /dev/null +++ b/docs/diagrams/rt-svc-descs-layout.png diff --git a/docs/diagrams/sec-int-handling.png b/docs/diagrams/sec-int-handling.png Binary files differnew file mode 100644 index 0000000..2ebbca4 --- /dev/null +++ b/docs/diagrams/sec-int-handling.png diff --git a/docs/firmware-design.md b/docs/firmware-design.md new file mode 100644 index 0000000..1700007 --- /dev/null +++ b/docs/firmware-design.md @@ -0,0 +1,1313 @@ +ARM Trusted Firmware Design +=========================== + +Contents : + +1. Introduction +2. Cold boot +3. EL3 runtime services framework +4. Power State Coordination Interface +5. Secure-EL1 Payloads and Dispatchers +6. Crash Reporting in BL3-1 +7. Memory layout on FVP platforms +8. Firmware Image Package (FIP) +9. Code Structure +10. References + + +1. Introduction +---------------- + +The ARM Trusted Firmware implements a subset of the Trusted Board Boot +Requirements (TBBR) Platform Design Document (PDD) [1] for ARM reference +platforms. The TBB sequence starts when the platform is powered on and runs up +to the stage where it hands-off control to firmware running in the normal +world in DRAM. This is the cold boot path. + +The ARM Trusted Firmware also implements the Power State Coordination Interface +([PSCI]) PDD [2] as a runtime service. PSCI is the interface from normal world +software to firmware implementing power management use-cases (for example, +secondary CPU boot, hotplug and idle). Normal world software can access ARM +Trusted Firmware runtime services via the ARM SMC (Secure Monitor Call) +instruction. The SMC instruction must be used as mandated by the [SMC Calling +Convention PDD][SMCCC] [3]. + +The ARM Trusted Firmware implements a framework for configuring and managing +interrupts generated in either security state. The details of the interrupt +management framework and its design can be found in [ARM Trusted +Firmware Interrupt Management Design guide][INTRG] [4]. + +2. Cold boot +------------- + +The cold boot path starts when the platform is physically turned on. One of +the CPUs released from reset is chosen as the primary CPU, and the remaining +CPUs are considered secondary CPUs. The primary CPU is chosen through +platform-specific means. The cold boot path is mainly executed by the primary +CPU, other than essential CPU initialization executed by all CPUs. The +secondary CPUs are kept in a safe platform-specific state until the primary +CPU has performed enough initialization to boot them. + +The cold boot path in this implementation of the ARM Trusted Firmware is divided +into five steps (in order of execution): + +* Boot Loader stage 1 (BL1) _AP Trusted ROM_ +* Boot Loader stage 2 (BL2) _Trusted Boot Firmware_ +* Boot Loader stage 3-1 (BL3-1) _EL3 Runtime Firmware_ +* Boot Loader stage 3-2 (BL3-2) _Secure-EL1 Payload_ (optional) +* Boot Loader stage 3-3 (BL3-3) _Non-trusted Firmware_ + +The ARM Fixed Virtual Platforms (FVPs) provide trusted ROM, trusted SRAM and +trusted DRAM regions. Each boot loader stage uses one or more of these +memories for its code and data. + +The sections below provide the following details: + +* initialization and execution of the first three stages during cold boot +* specification of the BL3-1 entrypoint requirements for use by alternative + Trusted Boot Firmware in place of the provided BL1 and BL2 +* changes in BL3-1 behavior when using the `RESET_TO_BL31` option which + allows BL3-1 to run without BL1 and BL2 + + +### BL1 + +This stage begins execution from the platform's reset vector in trusted ROM at +EL3. BL1 code starts at `0x00000000` (trusted ROM) in the FVP memory map. The +BL1 data section is placed at the start of trusted SRAM, `0x04000000`. The +functionality implemented by this stage is as follows. + +#### Determination of boot path + +Whenever a CPU is released from reset, BL1 needs to distinguish between a warm +boot and a cold boot. This is done using a platform-specific mechanism. The +ARM FVPs implement a simple power controller at `0x1c100000`. The `PSYS` +register (`0x10`) is used to distinguish between a cold and warm boot. This +information is contained in the `PSYS.WK[25:24]` field. Additionally, a +per-CPU mailbox is maintained in trusted DRAM (`0x00600000`), to which BL1 +writes an entrypoint. Each CPU jumps to this entrypoint upon warm boot. During +cold boot, BL1 places the secondary CPUs in a safe platform-specific state while +the primary CPU executes the remaining cold boot path as described in the +following sections. + +#### Architectural initialization + +BL1 performs minimal architectural initialization as follows. + +* Exception vectors + + BL1 sets up simple exception vectors for both synchronous and asynchronous + exceptions. The default behavior upon receiving an exception is to set a + status code. In the case of the FVP this code is written to the Versatile + Express System LED register in the following format: + + SYS_LED[0] - Security state (Secure=0/Non-Secure=1) + SYS_LED[2:1] - Exception Level (EL3=0x3, EL2=0x2, EL1=0x1, EL0=0x0) + SYS_LED[7:3] - Exception Class (Sync/Async & origin). The values for + each exception class are: + + 0x0 : Synchronous exception from Current EL with SP_EL0 + 0x1 : IRQ exception from Current EL with SP_EL0 + 0x2 : FIQ exception from Current EL with SP_EL0 + 0x3 : System Error exception from Current EL with SP_EL0 + 0x4 : Synchronous exception from Current EL with SP_ELx + 0x5 : IRQ exception from Current EL with SP_ELx + 0x6 : FIQ exception from Current EL with SP_ELx + 0x7 : System Error exception from Current EL with SP_ELx + 0x8 : Synchronous exception from Lower EL using aarch64 + 0x9 : IRQ exception from Lower EL using aarch64 + 0xa : FIQ exception from Lower EL using aarch64 + 0xb : System Error exception from Lower EL using aarch64 + 0xc : Synchronous exception from Lower EL using aarch32 + 0xd : IRQ exception from Lower EL using aarch32 + 0xe : FIQ exception from Lower EL using aarch32 + 0xf : System Error exception from Lower EL using aarch32 + + A write to the LED register reflects in the System LEDs (S6LED0..7) in the + CLCD window of the FVP. This behavior is because this boot loader stage + does not expect to receive any exceptions other than the SMC exception. + For the latter, BL1 installs a simple stub. The stub expects to receive + only a single type of SMC (determined by its function ID in the general + purpose register `X0`). This SMC is raised by BL2 to make BL1 pass control + to BL3-1 (loaded by BL2) at EL3. Any other SMC leads to an assertion + failure. + +* MMU setup + + BL1 sets up EL3 memory translation by creating page tables to cover the + first 4GB of physical address space. This covers all the memories and + peripherals needed by BL1. + +* Control register setup + - `SCTLR_EL3`. Instruction cache is enabled by setting the `SCTLR_EL3.I` + bit. Alignment and stack alignment checking is enabled by setting the + `SCTLR_EL3.A` and `SCTLR_EL3.SA` bits. Exception endianness is set to + little-endian by clearing the `SCTLR_EL3.EE` bit. + + - `CPUECTLR`. When the FVP includes a model of a specific ARM processor + implementation (for example A57 or A53), then intra-cluster coherency is + enabled by setting the `CPUECTLR.SMPEN` bit. The AEMv8 Base FVP is + inherently coherent so does not implement `CPUECTLR`. + + - `SCR`. Use of the HVC instruction from EL1 is enabled by setting the + `SCR.HCE` bit. FIQ exceptions are configured to be taken in EL3 by + setting the `SCR.FIQ` bit. The register width of the next lower + exception level is set to AArch64 by setting the `SCR.RW` bit. + + - `CPTR_EL3`. Accesses to the `CPACR_EL1` register from EL1 or EL2, or the + `CPTR_EL2` register from EL2 are configured to not trap to EL3 by + clearing the `CPTR_EL3.TCPAC` bit. Access to the trace functionality is + configured not to trap to EL3 by clearing the `CPTR_EL3.TTA` bit. + Instructions that access the registers associated with Floating Point + and Advanced SIMD execution are configured to not trap to EL3 by + clearing the `CPTR_EL3.TFP` bit. + +#### Platform initialization + +BL1 enables issuing of snoop and DVM (Distributed Virtual Memory) requests from +the CCI-400 slave interface corresponding to the cluster that includes the +primary CPU. BL1 also initializes UART0 (PL011 console), which enables access to +the `printf` family of functions in BL1. + +#### BL2 image load and execution + +BL1 execution continues as follows: + +1. BL1 determines the amount of free trusted SRAM memory available by + calculating the extent of its own data section, which also resides in + trusted SRAM. BL1 loads a BL2 raw binary image from platform storage, at a + platform-specific base address. If the BL2 image file is not present or if + there is not enough free trusted SRAM the following error message is + printed: + + "Failed to load boot loader stage 2 (BL2) firmware." + + If the load is successful, BL1 updates the limits of the remaining free + trusted SRAM. It also populates information about the amount of trusted + SRAM used by the BL2 image. The exact load location of the image is + provided as a base address in the platform header. Further description of + the memory layout can be found later in this document. + +2. BL1 prints the following string from the primary CPU to indicate successful + execution of the BL1 stage: + + "Booting trusted firmware boot loader stage 1" + +3. BL1 passes control to the BL2 image at Secure EL1, starting from its load + address. + +4. BL1 also passes information about the amount of trusted SRAM used and + available for use. This information is populated at a platform-specific + memory address. + + +### BL2 + +BL1 loads and passes control to BL2 at Secure-EL1. BL2 is linked against and +loaded at a platform-specific base address (more information can be found later +in this document). The functionality implemented by BL2 is as follows. + +#### Architectural initialization + +BL2 performs minimal architectural initialization required for subsequent +stages of the ARM Trusted Firmware and normal world software. It sets up +Secure EL1 memory translation by creating page tables to address the first 4GB +of the physical address space in a similar way to BL1. EL1 and EL0 are given +access to Floating Point & Advanced SIMD registers by clearing the `CPACR.FPEN` +bits. + +#### Platform initialization + +BL2 copies the information regarding the trusted SRAM populated by BL1 using a +platform-specific mechanism. It calculates the limits of DRAM (main memory) +to determine whether there is enough space to load the BL3-3 image. A platform +defined base address is used to specify the load address for the BL3-1 image. +It also defines the extents of memory available for use by the BL3-2 image. +BL2 also initializes UART0 (PL011 console), which enables access to the +`printf` family of functions in BL2. Platform security is initialized to allow +access to access controlled components. On the Base FVP a TrustZone controller +(TZC-400) is configured to give full access to the platform DRAM. The storage +abstraction layer is initialized which is used to load further bootloader +images. + +#### BL3-0 (System Control Processor Firmware) image load + +Some systems have a separate System Control Processor (SCP) for power, clock, +reset and system control. BL2 loads the optional BL3-0 image from platform +storage into a platform-specific region of secure memory. The subsequent +handling of BL3-0 is platform specific. Typically the image is transferred into +SCP memory using a platform-specific protocol. The SCP executes BL3-0 and +signals to the Application Processor (AP) for BL2 execution to continue. + +#### BL3-1 (EL3 Runtime Firmware) image load + +BL2 loads the BL3-1 image from platform storage into a platform-specific address +in trusted SRAM. If there is not enough memory to load the image or image is +missing it leads to an assertion failure. If the BL3-1 image loads successfully, +BL2 updates the amount of trusted SRAM used and available for use by BL3-1. +This information is populated at a platform-specific memory address. + +#### BL3-2 (Secure-EL1 Payload) image load + +BL2 loads the optional BL3-2 image from platform storage into a platform- +specific region of secure memory. The image executes in the secure world. BL2 +relies on BL3-1 to pass control to the BL3-2 image, if present. Hence, BL2 +populates a platform-specific area of memory with the entrypoint/load-address +of the BL3-2 image. The value of the Saved Processor Status Register (`SPSR`) +for entry into BL3-2 is not determined by BL2, it is initialized by the +Secure-EL1 Payload Dispatcher (see later) within BL3-1, which is responsible for +managing interaction with BL3-2. This information is passed to BL3-1. + +#### BL3-3 (Non-trusted Firmware) image load + +BL2 loads the BL3-3 image (e.g. UEFI or other test or boot software) from +platform storage into non-secure memory as defined by the platform +(`0x88000000` for FVPs). + +BL2 relies on BL3-1 to pass control to BL3-3 once secure state initialization is +complete. Hence, BL2 populates a platform-specific area of memory with the +entrypoint and Saved Program Status Register (`SPSR`) of the normal world +software image. The entrypoint is the load address of the BL3-3 image. The +`SPSR` is determined as specified in Section 5.13 of the [PSCI PDD] [PSCI]. This +information is passed to BL3-1. + +#### BL3-1 (EL3 Runtime Firmware) execution + +BL2 execution continues as follows: + +1. BL2 passes control back to BL1 by raising an SMC, providing BL1 with the + BL3-1 entrypoint. The exception is handled by the SMC exception handler + installed by BL1. + +2. BL1 turns off the MMU and flushes the caches. It clears the + `SCTLR_EL3.M/I/C` bits, flushes the data cache to the point of coherency + and invalidates the TLBs. + +3. BL1 passes control to BL3-1 at the specified entrypoint at EL3. + + +### BL3-1 + +The image for this stage is loaded by BL2 and BL1 passes control to BL3-1 at +EL3. BL3-1 executes solely in trusted SRAM. BL3-1 is linked against and +loaded at a platform-specific base address (more information can be found later +in this document). The functionality implemented by BL3-1 is as follows. + +#### Architectural initialization + +Currently, BL3-1 performs a similar architectural initialization to BL1 as +far as system register settings are concerned. Since BL1 code resides in ROM, +architectural initialization in BL3-1 allows override of any previous +initialization done by BL1. BL3-1 creates page tables to address the first +4GB of physical address space and initializes the MMU accordingly. It initializes +a buffer of frequently used pointers, called per-cpu pointer cache, in memory for +faster access. Currently the per-cpu pointer cache contains only the pointer +to crash stack. It then replaces the exception vectors populated by BL1 with its +own. BL3-1 exception vectors implement more elaborate support for +handling SMCs since this is the only mechanism to access the runtime services +implemented by BL3-1 (PSCI for example). BL3-1 checks each SMC for validity as +specified by the [SMC calling convention PDD][SMCCC] before passing control to +the required SMC handler routine. BL3-1 programs the `CNTFRQ_EL0` register with +the clock frequency of the system counter, which is provided by the platform. + +#### Platform initialization + +BL3-1 performs detailed platform initialization, which enables normal world +software to function correctly. It also retrieves entrypoint information for +the BL3-3 image loaded by BL2 from the platform defined memory address populated +by BL2. BL3-1 also initializes UART0 (PL011 console), which enables +access to the `printf` family of functions in BL3-1. It enables the system +level implementation of the generic timer through the memory mapped interface. + +* GICv2 initialization: + + - Enable group0 interrupts in the GIC CPU interface. + - Configure group0 interrupts to be asserted as FIQs. + - Disable the legacy interrupt bypass mechanism. + - Configure the priority mask register to allow interrupts of all + priorities to be signaled to the CPU interface. + - Mark SGIs 8-15, the secure physical timer interrupt (#29) and the + trusted watchdog interrupt (#56) as group0 (secure). + - Target the trusted watchdog interrupt to CPU0. + - Enable these group0 interrupts in the GIC distributor. + - Configure all other interrupts as group1 (non-secure). + - Enable signaling of group0 interrupts in the GIC distributor. + +* GICv3 initialization: + + If a GICv3 implementation is available in the platform, BL3-1 initializes + the GICv3 in GICv2 emulation mode with settings as described for GICv2 + above. + +* Power management initialization: + + BL3-1 implements a state machine to track CPU and cluster state. The state + can be one of `OFF`, `ON_PENDING`, `SUSPEND` or `ON`. All secondary CPUs are + initially in the `OFF` state. The cluster that the primary CPU belongs to is + `ON`; any other cluster is `OFF`. BL3-1 initializes the data structures that + implement the state machine, including the locks that protect them. BL3-1 + accesses the state of a CPU or cluster immediately after reset and before + the MMU is enabled in the warm boot path. It is not currently possible to + use 'exclusive' based spinlocks, therefore BL3-1 uses locks based on + Lamport's Bakery algorithm instead. BL3-1 allocates these locks in device + memory. They are accessible irrespective of MMU state. + +* Runtime services initialization: + + The runtime service framework and its initialization is described in the + "EL3 runtime services framework" section below. + + Details about the PSCI service are provided in the "Power State Coordination + Interface" section below. + +* BL3-2 (Secure-EL1 Payload) image initialization + + If a BL3-2 image is present then there must be a matching Secure-EL1 Payload + Dispatcher (SPD) service (see later for details). During initialization + that service must register a function to carry out initialization of BL3-2 + once the runtime services are fully initialized. BL3-1 invokes such a + registered function to initialize BL3-2 before running BL3-3. + + Details on BL3-2 initialization and the SPD's role are described in the + "Secure-EL1 Payloads and Dispatchers" section below. + +* BL3-3 (Non-trusted Firmware) execution + + BL3-1 initializes the EL2 or EL1 processor context for normal-world cold + boot, ensuring that no secure state information finds its way into the + non-secure execution state. BL3-1 uses the entrypoint information provided + by BL2 to jump to the Non-trusted firmware image (BL3-3) at the highest + available Exception Level (EL2 if available, otherwise EL1). + + +### Using alternative Trusted Boot Firmware in place of BL1 and BL2 + +Some platforms have existing implementations of Trusted Boot Firmware that +would like to use ARM Trusted Firmware BL3-1 for the EL3 Runtime Firmware. To +enable this firmware architecture it is important to provide a fully documented +and stable interface between the Trusted Boot Firmware and BL3-1. + +Future changes to the BL3-1 interface will be done in a backwards compatible +way, and this enables these firmware components to be independently enhanced/ +updated to develop and exploit new functionality. + +#### Required CPU state when calling `bl31_entrypoint()` during cold boot + +This function must only be called by the primary CPU, if this is called by any +other CPU the firmware will abort. + +On entry to this function the calling primary CPU must be executing in AArch64 +EL3, little-endian data access, and all interrupt sources masked: + + PSTATE.EL = 3 + PSTATE.RW = 1 + PSTATE.DAIF = 0xf + CTLR_EL3.EE = 0 + +X0 and X1 can be used to pass information from the Trusted Boot Firmware to the +platform code in BL3-1: + + X0 : Reserved for common Trusted Firmware information + X1 : Platform specific information + +BL3-1 zero-init sections (e.g. `.bss`) should not contain valid data on entry, +these will be zero filled prior to invoking platform setup code. + +##### Use of the X0 and X1 parameters + +The parameters are platform specific and passed from `bl31_entrypoint()` to +`bl31_early_platform_setup()`. The value of these parameters is never directly +used by the common BL3-1 code. + +The convention is that `X0` conveys information regarding the BL3-1, BL3-2 and +BL3-3 images from the Trusted Boot firmware and `X1` can be used for other +platform specific purpose. This convention allows platforms which use ARM +Trusted Firmware's BL1 and BL2 images to transfer additional platform specific +information from Secure Boot without conflicting with future evolution of the +Trusted Firmware using `X0` to pass a `bl31_params` structure. + +BL3-1 common and SPD initialization code depends on image and entrypoint +information about BL3-3 and BL3-2, which is provided via BL3-1 platform APIs. +This information is required until the start of execution of BL3-3. This +information can be provided in a platform defined manner, e.g. compiled into +the platform code in BL3-1, or provided in a platform defined memory location +by the Trusted Boot firmware, or passed from the Trusted Boot Firmware via the +Cold boot Initialization parameters. This data may need to be cleaned out of +the CPU caches if it is provided by an earlier boot stage and then accessed by +BL3-1 platform code before the caches are enabled. + +ARM Trusted Firmware's BL2 implementation passes a `bl31_params` structure in +`X0` and the FVP port interprets this in the BL3-1 platform code. + +##### MMU, Data caches & Coherency + +BL3-1 does not depend on the enabled state of the MMU, data caches or +interconnect coherency on entry to `bl31_entrypoint()`. If these are disabled +on entry, these should be enabled during `bl31_plat_arch_setup()`. + +##### Data structures used in the BL3-1 cold boot interface + +These structures are designed to support compatibility and independent +evolution of the structures and the firmware images. For example, a version of +BL3-1 that can interpret the BL3-x image information from different versions of +BL2, a platform that uses an extended entry_point_info structure to convey +additional register information to BL3-1, or a ELF image loader that can convey +more details about the firmware images. + +To support these scenarios the structures are versioned and sized, which enables +BL3-1 to detect which information is present and respond appropriately. The +`param_header` is defined to capture this information: + + typedef struct param_header { + uint8_t type; /* type of the structure */ + uint8_t version; /* version of this structure */ + uint16_t size; /* size of this structure in bytes */ + uint32_t attr; /* attributes: unused bits SBZ */ + } param_header_t; + +The structures using this format are `entry_point_info`, `image_info` and +`bl31_params`. The code that allocates and populates these structures must set +the header fields appropriately, and the `SET_PARA_HEAD()` a macro is defined +to simplify this action. + +#### Required CPU state for BL3-1 Warm boot initialization + +When requesting a CPU power-on, or suspending a running CPU, ARM Trusted +Firmware provides the platform power management code with a Warm boot +initialization entry-point, to be invoked by the CPU immediately after the +reset handler. On entry to the Warm boot initialization function the calling +CPU must be in AArch64 EL3, little-endian data access and all interrupt sources +masked: + + PSTATE.EL = 3 + PSTATE.RW = 1 + PSTATE.DAIF = 0xf + SCTLR_EL3.EE = 0 + +The PSCI implementation will initialize the processor state and ensure that the +platform power management code is then invoked as required to initialize all +necessary system, cluster and CPU resources. + + +### Using BL3-1 as the CPU reset vector + +On some platforms the runtime firmware (BL3-x images) for the application +processors are loaded by trusted firmware running on a secure system processor +on the SoC, rather than by BL1 and BL2 running on the primary application +processor. For this type of SoC it is desirable for the application processor +to always reset to BL3-1 which eliminates the need for BL1 and BL2. + +ARM Trusted Firmware provides a build-time option `RESET_TO_BL31` that includes +some additional logic in the BL3-1 entrypoint to support this use case. + +In this configuration, the platform's Trusted Boot Firmware must ensure that +BL3-1 is loaded to its runtime address, which must match the CPU's RVBAR reset +vector address, before the application processor is powered on. Additionally, +platform software is responsible for loading the other BL3-x images required and +providing entry point information for them to BL3-1. Loading these images might +be done by the Trusted Boot Firmware or by platform code in BL3-1. + +The ARM FVP port supports the `RESET_TO_BL31` configuration, in which case the +`bl31.bin` image must be loaded to its run address in Trusted SRAM and all CPU +reset vectors be changed from the default `0x0` to this run address. See the +[User Guide] for details of running the FVP models in this way. + +This configuration requires some additions and changes in the BL3-1 +functionality: + +#### Determination of boot path + +In this configuration, BL3-1 uses the same reset framework and code as the one +described for BL1 above. On a warm boot a CPU is directed to the PSCI +implementation via a platform defined mechanism. On a cold boot, the platform +must place any secondary CPUs into a safe state while the primary CPU executes +a modified BL3-1 initialization, as described below. + +#### Architectural initialization + +As the first image to execute in this configuration BL3-1 must ensure that +interconnect coherency is enabled (if required) before enabling the MMU. + +#### Platform initialization + +In this configuration, when the CPU resets to BL3-1 there are no parameters +that can be passed in registers by previous boot stages. Instead, the platform +code in BL3-1 needs to know, or be able to determine, the location of the BL3-2 +(if required) and BL3-3 images and provide this information in response to the +`bl31_plat_get_next_image_ep_info()` function. + +As the first image to execute in this configuration BL3-1 must also ensure that +any security initialisation, for example programming a TrustZone address space +controller, is carried out during early platform initialisation. + + +3. EL3 runtime services framework +---------------------------------- + +Software executing in the non-secure state and in the secure state at exception +levels lower than EL3 will request runtime services using the Secure Monitor +Call (SMC) instruction. These requests will follow the convention described in +the SMC Calling Convention PDD ([SMCCC]). The [SMCCC] assigns function +identifiers to each SMC request and describes how arguments are passed and +returned. + +The EL3 runtime services framework enables the development of services by +different providers that can be easily integrated into final product firmware. +The following sections describe the framework which facilitates the +registration, initialization and use of runtime services in EL3 Runtime +Firmware (BL3-1). + +The design of the runtime services depends heavily on the concepts and +definitions described in the [SMCCC], in particular SMC Function IDs, Owning +Entity Numbers (OEN), Fast and Standard calls, and the SMC32 and SMC64 calling +conventions. Please refer to that document for more detailed explanation of +these terms. + +The following runtime services are expected to be implemented first. They have +not all been instantiated in the current implementation. + +1. Standard service calls + + This service is for management of the entire system. The Power State + Coordination Interface ([PSCI]) is the first set of standard service calls + defined by ARM (see PSCI section later). + + NOTE: Currently this service is called PSCI since there are no other + defined standard service calls. + +2. Secure-EL1 Payload Dispatcher service + + If a system runs a Trusted OS or other Secure-EL1 Payload (SP) then + it also requires a _Secure Monitor_ at EL3 to switch the EL1 processor + context between the normal world (EL1/EL2) and trusted world (Secure-EL1). + The Secure Monitor will make these world switches in response to SMCs. The + [SMCCC] provides for such SMCs with the Trusted OS Call and Trusted + Application Call OEN ranges. + + The interface between the EL3 Runtime Firmware and the Secure-EL1 Payload is + not defined by the [SMCCC] or any other standard. As a result, each + Secure-EL1 Payload requires a specific Secure Monitor that runs as a runtime + service - within ARM Trusted Firmware this service is referred to as the + Secure-EL1 Payload Dispatcher (SPD). + + ARM Trusted Firmware provides a Test Secure-EL1 Payload (TSP) and its + associated Dispatcher (TSPD). Details of SPD design and TSP/TSPD operation + are described in the "Secure-EL1 Payloads and Dispatchers" section below. + +3. CPU implementation service + + This service will provide an interface to CPU implementation specific + services for a given platform e.g. access to processor errata workarounds. + This service is currently unimplemented. + +Additional services for ARM Architecture, SiP and OEM calls can be implemented. +Each implemented service handles a range of SMC function identifiers as +described in the [SMCCC]. + + +### Registration + +A runtime service is registered using the `DECLARE_RT_SVC()` macro, specifying +the name of the service, the range of OENs covered, the type of service and +initialization and call handler functions. This macro instantiates a `const +struct rt_svc_desc` for the service with these details (see `runtime_svc.h`). +This structure is allocated in a special ELF section `rt_svc_descs`, enabling +the framework to find all service descriptors included into BL3-1. + +The specific service for a SMC Function is selected based on the OEN and call +type of the Function ID, and the framework uses that information in the service +descriptor to identify the handler for the SMC Call. + +The service descriptors do not include information to identify the precise set +of SMC function identifiers supported by this service implementation, the +security state from which such calls are valid nor the capability to support +64-bit and/or 32-bit callers (using SMC32 or SMC64). Responding appropriately +to these aspects of a SMC call is the responsibility of the service +implementation, the framework is focused on integration of services from +different providers and minimizing the time taken by the framework before the +service handler is invoked. + +Details of the parameters, requirements and behavior of the initialization and +call handling functions are provided in the following sections. + + +### Initialization + +`runtime_svc_init()` in `runtime_svc.c` initializes the runtime services +framework running on the primary CPU during cold boot as part of the BL3-1 +initialization. This happens prior to initializing a Trusted OS and running +Normal world boot firmware that might in turn use these services. +Initialization involves validating each of the declared runtime service +descriptors, calling the service initialization function and populating the +index used for runtime lookup of the service. + +The BL3-1 linker script collects all of the declared service descriptors into a +single array and defines symbols that allow the framework to locate and traverse +the array, and determine its size. + +The framework does basic validation of each descriptor to halt firmware +initialization if service declaration errors are detected. The framework does +not check descriptors for the following error conditions, and may behave in an +unpredictable manner under such scenarios: + +1. Overlapping OEN ranges +2. Multiple descriptors for the same range of OENs and `call_type` +3. Incorrect range of owning entity numbers for a given `call_type` + +Once validated, the service `init()` callback is invoked. This function carries +out any essential EL3 initialization before servicing requests. The `init()` +function is only invoked on the primary CPU during cold boot. If the service +uses per-CPU data this must either be initialized for all CPUs during this call, +or be done lazily when a CPU first issues an SMC call to that service. If +`init()` returns anything other than `0`, this is treated as an initialization +error and the service is ignored: this does not cause the firmware to halt. + +The OEN and call type fields present in the SMC Function ID cover a total of +128 distinct services, but in practice a single descriptor can cover a range of +OENs, e.g. SMCs to call a Trusted OS function. To optimize the lookup of a +service handler, the framework uses an array of 128 indices that map every +distinct OEN/call-type combination either to one of the declared services or to +indicate the service is not handled. This `rt_svc_descs_indices[]` array is +populated for all of the OENs covered by a service after the service `init()` +function has reported success. So a service that fails to initialize will never +have it's `handle()` function invoked. + +The following figure shows how the `rt_svc_descs_indices[]` index maps the SMC +Function ID call type and OEN onto a specific service handler in the +`rt_svc_descs[]` array. + +![Image 1](diagrams/rt-svc-descs-layout.png?raw=true) + + +### Handling an SMC + +When the EL3 runtime services framework receives a Secure Monitor Call, the SMC +Function ID is passed in W0 from the lower exception level (as per the +[SMCCC]). If the calling register width is AArch32, it is invalid to invoke an +SMC Function which indicates the SMC64 calling convention: such calls are +ignored and return the Unknown SMC Function Identifier result code `0xFFFFFFFF` +in R0/X0. + +Bit[31] (fast/standard call) and bits[29:24] (owning entity number) of the SMC +Function ID are combined to index into the `rt_svc_descs_indices[]` array. The +resulting value might indicate a service that has no handler, in this case the +framework will also report an Unknown SMC Function ID. Otherwise, the value is +used as a further index into the `rt_svc_descs[]` array to locate the required +service and handler. + +The service's `handle()` callback is provided with five of the SMC parameters +directly, the others are saved into memory for retrieval (if needed) by the +handler. The handler is also provided with an opaque `handle` for use with the +supporting library for parameter retrieval, setting return values and context +manipulation; and with `flags` indicating the security state of the caller. The +framework finally sets up the execution stack for the handler, and invokes the +services `handle()` function. + +On return from the handler the result registers are populated in X0-X3 before +restoring the stack and CPU state and returning from the original SMC. + + +4. Power State Coordination Interface +-------------------------------------- + +TODO: Provide design walkthrough of PSCI implementation. + +The complete PSCI API is not yet implemented. The following functions are +currently implemented: + +- `PSCI_VERSION` +- `CPU_OFF` +- `CPU_ON` +- `CPU_SUSPEND` +- `AFFINITY_INFO` + +The `CPU_ON`, `CPU_OFF` and `CPU_SUSPEND` functions implement the warm boot +path in ARM Trusted Firmware. `CPU_ON` and `CPU_OFF` have undergone testing +on all the supported FVPs. `CPU_SUSPEND` & `AFFINITY_INFO` have undergone +testing only on the AEM v8 Base FVP. Support for `AFFINITY_INFO` is still +experimental. Support for `CPU_SUSPEND` is stable for entry into power down +states. Standby states are currently not supported. `PSCI_VERSION` is +present but completely untested in this version of the software. + +Unsupported PSCI functions can be divided into ones that can return +execution to the caller and ones that cannot. The following functions +return with a error code as documented in the [Power State Coordination +Interface PDD] [PSCI]. + +- `MIGRATE` : -1 (NOT_SUPPORTED) +- `MIGRATE_INFO_TYPE` : 2 (Trusted OS is either not present or does not + require migration) +- `MIGRATE_INFO_UP_CPU` : 0 (Return value is UNDEFINED) + +The following unsupported functions do not return and signal an assertion +failure if invoked. + +- `SYSTEM_OFF` +- `SYSTEM_RESET` + + +5. Secure-EL1 Payloads and Dispatchers +--------------------------------------- + +On a production system that includes a Trusted OS running in Secure-EL1/EL0, +the Trusted OS is coupled with a companion runtime service in the BL3-1 +firmware. This service is responsible for the initialisation of the Trusted +OS and all communications with it. The Trusted OS is the BL3-2 stage of the +boot flow in ARM Trusted Firmware. The firmware will attempt to locate, load +and execute a BL3-2 image. + +ARM Trusted Firmware uses a more general term for the BL3-2 software that runs +at Secure-EL1 - the _Secure-EL1 Payload_ - as it is not always a Trusted OS. + +The ARM Trusted Firmware provides a Test Secure-EL1 Payload (TSP) and a Test +Secure-EL1 Payload Dispatcher (TSPD) service as an example of how a Trusted OS +is supported on a production system using the Runtime Services Framework. On +such a system, the Test BL3-2 image and service are replaced by the Trusted OS +and its dispatcher service. + +The TSP runs in Secure-EL1. It is designed to demonstrate synchronous +communication with the normal-world software running in EL1/EL2. Communication +is initiated by the normal-world software + +* either directly through a Fast SMC (as defined in the [SMCCC]) + +* or indirectly through a [PSCI] SMC. The [PSCI] implementation in turn + informs the TSPD about the requested power management operation. This allows + the TSP to prepare for or respond to the power state change + +The TSPD service is responsible for. + +* Initializing the TSP + +* Routing requests and responses between the secure and the non-secure + states during the two types of communications just described + +### Initializing a BL3-2 Image + +The Secure-EL1 Payload Dispatcher (SPD) service is responsible for initializing +the BL3-2 image. It needs access to the information passed by BL2 to BL3-1 to do +so. This is provided by: + + entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t); + +which returns a reference to the `entry_point_info` structure corresponding to +the image which will be run in the specified security state. The SPD uses this +API to get entry point information for the SECURE image, BL3-2. + +In the absence of a BL3-2 image, BL3-1 passes control to the normal world +bootloader image (BL3-3). When the BL3-2 image is present, it is typical +that the SPD wants control to be passed to BL3-2 first and then later to BL3-3. + +To do this the SPD has to register a BL3-2 initialization function during +initialization of the SPD service. The BL3-2 initialization function has this +prototype: + + int32_t init(); + +and is registered using the `bl31_register_bl32_init()` function. + +Trusted Firmware supports two approaches for the SPD to pass control to BL3-2 +before returning through EL3 and running the non-trusted firmware (BL3-3): + +1. In the BL3-2 initialization function, set up a secure context (see below + for more details of CPU context support) for this CPU and use + `bl31_set_next_image_type()` to request that the exit from `bl31_main()` is + to the BL3-2 entrypoint in Secure-EL1. + + When the BL3-2 has completed initialization at Secure-EL1, it returns to + BL3-1 by issuing an SMC, using a Function ID allocated to the SPD. On + receipt of this SMC, the SPD service handler should switch the CPU context + from trusted to normal world and use the `bl31_set_next_image_type()` and + `bl31_prepare_next_image_entry()` functions to set up the initial return to + the normal world firmware BL3-3. On return from the handler the framework + will exit to EL2 and run BL3-3. + +2. In the BL3-2 initialization function, use an SPD-defined mechanism to + invoke a 'world-switch synchronous call' to Secure-EL1 to run the BL3-2 + entrypoint. + NOTE: The Test SPD service included with the Trusted Firmware provides one + implementation of such a mechanism. + + On completion BL3-2 returns control to BL3-1 via a SMC, and on receipt the + SPD service handler invokes the synchronous call return mechanism to return + to the BL3-2 initialization function. On return from this function, + `bl31_main()` will set up the return to the normal world firmware BL3-3 and + continue the boot process in the normal world. + +6. Crash Reporting in BL3-1 +---------------------------------- + +The BL3-1 implements a scheme for reporting the processor state when an unhandled +exception is encountered. The reporting mechanism attempts to preserve all the +register contents and report it via the default serial output. The general purpose +registers, EL3, Secure EL1 and some EL2 state registers are reported. + +A dedicated per-cpu crash stack is maintained by BL3-1 and this is retrieved via +the per-cpu pointer cache. The implementation attempts to minimise the memory +required for this feature. The file `crash_reporting.S` contains the +implementation for crash reporting. + +The sample crash output is shown below. + + x0 :0x000000004F00007C + x1 :0x0000000007FFFFFF + x2 :0x0000000004014D50 + x3 :0x0000000000000000 + x4 :0x0000000088007998 + x5 :0x00000000001343AC + x6 :0x0000000000000016 + x7 :0x00000000000B8A38 + x8 :0x00000000001343AC + x9 :0x00000000000101A8 + x10 :0x0000000000000002 + x11 :0x000000000000011C + x12 :0x00000000FEFDC644 + x13 :0x00000000FED93FFC + x14 :0x0000000000247950 + x15 :0x00000000000007A2 + x16 :0x00000000000007A4 + x17 :0x0000000000247950 + x18 :0x0000000000000000 + x19 :0x00000000FFFFFFFF + x20 :0x0000000004014D50 + x21 :0x000000000400A38C + x22 :0x0000000000247950 + x23 :0x0000000000000010 + x24 :0x0000000000000024 + x25 :0x00000000FEFDC868 + x26 :0x00000000FEFDC86A + x27 :0x00000000019EDEDC + x28 :0x000000000A7CFDAA + x29 :0x0000000004010780 + x30 :0x000000000400F004 + scr_el3 :0x0000000000000D3D + sctlr_el3 :0x0000000000C8181F + cptr_el3 :0x0000000000000000 + tcr_el3 :0x0000000080803520 + daif :0x00000000000003C0 + mair_el3 :0x00000000000004FF + spsr_el3 :0x00000000800003CC + elr_el3 :0x000000000400C0CC + ttbr0_el3 :0x00000000040172A0 + esr_el3 :0x0000000096000210 + sp_el3 :0x0000000004014D50 + far_el3 :0x000000004F00007C + spsr_el1 :0x0000000000000000 + elr_el1 :0x0000000000000000 + spsr_abt :0x0000000000000000 + spsr_und :0x0000000000000000 + spsr_irq :0x0000000000000000 + spsr_fiq :0x0000000000000000 + sctlr_el1 :0x0000000030C81807 + actlr_el1 :0x0000000000000000 + cpacr_el1 :0x0000000000300000 + csselr_el1 :0x0000000000000002 + sp_el1 :0x0000000004028800 + esr_el1 :0x0000000000000000 + ttbr0_el1 :0x000000000402C200 + ttbr1_el1 :0x0000000000000000 + mair_el1 :0x00000000000004FF + amair_el1 :0x0000000000000000 + tcr_el1 :0x0000000000003520 + tpidr_el1 :0x0000000000000000 + tpidr_el0 :0x0000000000000000 + tpidrro_el0 :0x0000000000000000 + dacr32_el2 :0x0000000000000000 + ifsr32_el2 :0x0000000000000000 + par_el1 :0x0000000000000000 + far_el1 :0x0000000000000000 + afsr0_el1 :0x0000000000000000 + afsr1_el1 :0x0000000000000000 + contextidr_el1 :0x0000000000000000 + vbar_el1 :0x0000000004027000 + cntp_ctl_el0 :0x0000000000000000 + cntp_cval_el0 :0x0000000000000000 + cntv_ctl_el0 :0x0000000000000000 + cntv_cval_el0 :0x0000000000000000 + cntkctl_el1 :0x0000000000000000 + fpexc32_el2 :0x0000000004000700 + sp_el0 :0x0000000004010780 + + +7. Memory layout on FVP platforms +---------------------------------- + +On FVP platforms, we use the Trusted ROM and Trusted SRAM to store the trusted +firmware binaries. BL1 is originally sitting in the Trusted ROM at address +`0x0`. Its read-write data are relocated at the base of the Trusted SRAM at +runtime. BL1 loads BL2 image near the top of the trusted SRAM. BL2 loads BL3-1 +image between BL1 and BL2. Optionally, BL2 then loads the TSP as the BL3-2 +image. By default it is loaded in Trusted SRAM, in this case it sits between +BL3-1 and BL2. This memory layout is illustrated by the following diagram. + + Trusted SRAM + +----------+ 0x04040000 + | | + |----------| + | BL2 | + |----------| + | | + |----------| + | BL32 | (optional) + |----------| + | | + |----------| + | BL31 | + |----------| + | | + |----------| + | BL1 (rw) | + +----------+ 0x04000000 + + Trusted ROM + +----------+ 0x04000000 + | BL1 (ro) | + +----------+ 0x00000000 + +The TSP image may be loaded in Trusted DRAM instead. This doesn't change the +memory layout of the other boot loader images in Trusted SRAM. + +Although the goal at long term is to give complete flexibility over the memory +layout, all platforms should conform to this layout at the moment. This is +because of some limitations in the implementation of the image loader in the +Trusted Firmware. Refer to the "Limitations of the image loader" section below. + +Each bootloader stage image layout is described by its own linker script. The +linker scripts export some symbols into the program symbol table. Their values +correspond to particular addresses. The trusted firmware code can refer to these +symbols to figure out the image memory layout. + +Linker symbols follow the following naming convention in the trusted firmware. + +* `__<SECTION>_START__` + + Start address of a given section named `<SECTION>`. + +* `__<SECTION>_END__` + + End address of a given section named `<SECTION>`. If there is an alignment + constraint on the section's end address then `__<SECTION>_END__` corresponds + to the end address of the section's actual contents, rounded up to the right + boundary. Refer to the value of `__<SECTION>_UNALIGNED_END__` to know the + actual end address of the section's contents. + +* `__<SECTION>_UNALIGNED_END__` + + End address of a given section named `<SECTION>` without any padding or + rounding up due to some alignment constraint. + +* `__<SECTION>_SIZE__` + + Size (in bytes) of a given section named `<SECTION>`. If there is an + alignment constraint on the section's end address then `__<SECTION>_SIZE__` + corresponds to the size of the section's actual contents, rounded up to the + right boundary. In other words, `__<SECTION>_SIZE__ = __<SECTION>_END__ - + _<SECTION>_START__`. Refer to the value of `__<SECTION>_UNALIGNED_SIZE__` + to know the actual size of the section's contents. + +* `__<SECTION>_UNALIGNED_SIZE__` + + Size (in bytes) of a given section named `<SECTION>` without any padding or + rounding up due to some alignment constraint. In other words, + `__<SECTION>_UNALIGNED_SIZE__ = __<SECTION>_UNALIGNED_END__ - + __<SECTION>_START__`. + +Some of the linker symbols are mandatory as the trusted firmware code relies on +them to be defined. They are listed in the following subsections. Some of them +must be provided for each bootloader stage and some are specific to a given +bootloader stage. + +The linker scripts define some extra, optional symbols. They are not actually +used by any code but they help in understanding the bootloader images' memory +layout as they are easy to spot in the link map files. + +### Common linker symbols + +Early setup code needs to know the extents of the BSS section to zero-initialise +it before executing any C code. The following linker symbols are defined for +this purpose: + +* `__BSS_START__` This address must be aligned on a 16-byte boundary. +* `__BSS_SIZE__` + +Similarly, the coherent memory section must be zero-initialised. Also, the MMU +setup code needs to know the extents of this section to set the right memory +attributes for it. The following linker symbols are defined for this purpose: + +* `__COHERENT_RAM_START__` This address must be aligned on a page-size boundary. +* `__COHERENT_RAM_END__` This address must be aligned on a page-size boundary. +* `__COHERENT_RAM_UNALIGNED_SIZE__` + +### BL1's linker symbols + +BL1's early setup code needs to know the extents of the .data section to +relocate it from ROM to RAM before executing any C code. The following linker +symbols are defined for this purpose: + +* `__DATA_ROM_START__` This address must be aligned on a 16-byte boundary. +* `__DATA_RAM_START__` This address must be aligned on a 16-byte boundary. +* `__DATA_SIZE__` + +BL1's platform setup code needs to know the extents of its read-write data +region to figure out its memory layout. The following linker symbols are defined +for this purpose: + +* `__BL1_RAM_START__` This is the start address of BL1 RW data. +* `__BL1_RAM_END__` This is the end address of BL1 RW data. + +### BL2's, BL3-1's and TSP's linker symbols + +BL2, BL3-1 and TSP need to know the extents of their read-only section to set +the right memory attributes for this memory region in their MMU setup code. The +following linker symbols are defined for this purpose: + +* `__RO_START__` +* `__RO_END__` + +### How to choose the right base addresses for each bootloader stage image + +There is currently no support for dynamic image loading in the Trusted Firmware. +This means that all bootloader images need to be linked against their ultimate +runtime locations and the base addresses of each image must be chosen carefully +such that images don't overlap each other in an undesired way. As the code +grows, the base addresses might need adjustments to cope with the new memory +layout. + +The memory layout is completely specific to the platform and so there is no +general recipe for choosing the right base addresses for each bootloader image. +However, there are tools to aid in understanding the memory layout. These are +the link map files: `build/<platform>/<build-type>/bl<x>/bl<x>.map`, with `<x>` +being the stage bootloader. They provide a detailed view of the memory usage of +each image. Among other useful information, they provide the end address of +each image. + +* `bl1.map` link map file provides `__BL1_RAM_END__` address. +* `bl2.map` link map file provides `__BL2_END__` address. +* `bl31.map` link map file provides `__BL31_END__` address. +* `bl32.map` link map file provides `__BL32_END__` address. + +For each bootloader image, the platform code must provide its start address +as well as a limit address that it must not overstep. The latter is used in the +linker scripts to check that the image doesn't grow past that address. If that +happens, the linker will issue a message similar to the following: + + aarch64-none-elf-ld: BLx has exceeded its limit. + +On FVP platforms, the base addresses have been chosen such that all images can +reside concurrently in Trusted RAM without overlapping each other. Note that +this is not a requirement, as not all images live in memory at the same time. +For example, when the BL3-1 image takes over execution, BL1 and BL2 images are +not needed anymore. + +### Limitations of the image loader + +The current implementation of the image loader can result in wasted space +because of the simplified data structure used to represent the extents of free +memory. For example, to load BL2 at address `0x0402D000`, the resulting memory +layout should be as follows: + + ------------ 0x04040000 + | | <- Free space (1) + |----------| + | BL2 | + |----------| BL2_BASE (0x0402D000) + | | <- Free space (2) + |----------| + | BL1 | + ------------ 0x04000000 + +In the current implementation, we need to specify whether BL2 is loaded at the +top or bottom of the free memory. BL2 is top-loaded so in the example above, +the free space (1) above BL2 is hidden, resulting in the following view of +memory: + + ------------ 0x04040000 + | | + | | + | BL2 | + |----------| BL2_BASE (0x0402D000) + | | <- Free space (2) + |----------| + | BL1 | + ------------ 0x04000000 + +BL3-1 is bottom-loaded above BL1. For example, if BL3-1 is bottom-loaded at +`0x0400E000`, the memory layout should look like this: + + ------------ 0x04040000 + | | + | | + | BL2 | + |----------| BL2_BASE (0x0402D000) + | | <- Free space (2) + | | + |----------| + | | + | BL31 | + |----------| BL31_BASE (0x0400E000) + | | <- Free space (3) + |----------| + | BL1 | + ------------ 0x04000000 + +But the free space (3) between BL1 and BL3-1 is wasted, resulting in the +following view: + + ------------ 0x04040000 + | | + | | + | BL2 | + |----------| BL2_BASE (0x0402D000) + | | <- Free space (2) + | | + |----------| + | | + | | + | BL31 | BL31_BASE (0x0400E000) + | | + |----------| + | BL1 | + ------------ 0x04000000 + + +8. Firmware Image Package (FIP) +-------------------------------- + +Using a Firmware Image Package (FIP) allows for packing bootloader images (and +potentially other payloads) into a single archive that can be loaded by the ARM +Trusted Firmware from non-volatile platform storage. A driver to load images +from a FIP has been added to the storage layer and allows a package to be read +from supported platform storage. A tool to create Firmware Image Packages is +also provided and described below. + +### Firmware Image Package layout + +The FIP layout consists of a table of contents (ToC) followed by payload data. +The ToC itself has a header followed by one or more table entries. The ToC is +terminated by an end marker entry. All ToC entries describe some payload data +that has been appended to the end of the binary package. With the information +provided in the ToC entry the corresponding payload data can be retrieved. + + ------------------ + | ToC Header | + |----------------| + | ToC Entry 0 | + |----------------| + | ToC Entry 1 | + |----------------| + | ToC End Marker | + |----------------| + | | + | Data 0 | + | | + |----------------| + | | + | Data 1 | + | | + ------------------ + +The ToC header and entry formats are described in the header file +`include/firmware_image_package.h`. This file is used by both the tool and the +ARM Trusted firmware. + +The ToC header has the following fields: + `name`: The name of the ToC. This is currently used to validate the header. + `serial_number`: A non-zero number provided by the creation tool + `flags`: Flags associated with this data. None are yet defined. + +A ToC entry has the following fields: + `uuid`: All files are referred to by a pre-defined Universally Unique + IDentifier [UUID] . The UUIDs are defined in + `include/firmware_image_package`. The platform translates the requested + image name into the corresponding UUID when accessing the package. + `offset_address`: The offset address at which the corresponding payload data + can be found. The offset is calculated from the ToC base address. + `size`: The size of the corresponding payload data in bytes. + `flags`: Flags associated with this entry. Non are yet defined. + +### Firmware Image Package creation tool + +The FIP creation tool can be used to pack specified images into a binary package +that can be loaded by the ARM Trusted Firmware from platform storage. The tool +currently only supports packing bootloader images. Additional image definitions +can be added to the tool as required. + +The tool can be found in `tools/fip_create`. + +### Loading from a Firmware Image Package (FIP) + +The Firmware Image Package (FIP) driver can load images from a binary package on +non-volatile platform storage. For the FVPs this is currently NOR FLASH. + +Bootloader images are loaded according to the platform policy as specified in +`plat/<platform>/plat_io_storage.c`. For the FVPs this means the platform will +attempt to load images from a Firmware Image Package located at the start of NOR +FLASH0. + +Currently the FVP's policy only allows loading of a known set of images. The +platform policy can be modified to allow additional images. + + +9. Code Structure +------------------ + +Trusted Firmware code is logically divided between the three boot loader +stages mentioned in the previous sections. The code is also divided into the +following categories (present as directories in the source code): + +* **Architecture specific.** This could be AArch32 or AArch64. +* **Platform specific.** Choice of architecture specific code depends upon + the platform. +* **Common code.** This is platform and architecture agnostic code. +* **Library code.** This code comprises of functionality commonly used by all + other code. +* **Stage specific.** Code specific to a boot stage. +* **Drivers.** +* **Services.** EL3 runtime services, e.g. PSCI or SPD. Specific SPD services + reside in the `services/spd` directory (e.g. `services/spd/tspd`). + +Each boot loader stage uses code from one or more of the above mentioned +categories. Based upon the above, the code layout looks like this: + + Directory Used by BL1? Used by BL2? Used by BL3-1? + bl1 Yes No No + bl2 No Yes No + bl31 No No Yes + arch Yes Yes Yes + plat Yes Yes Yes + drivers Yes No Yes + common Yes Yes Yes + lib Yes Yes Yes + services No No Yes + +All assembler files have the `.S` extension. The linker source files for each +boot stage have the extension `.ld.S`. These are processed by GCC to create the +linker scripts which have the extension `.ld`. + +FDTs provide a description of the hardware platform and are used by the Linux +kernel at boot time. These can be found in the `fdts` directory. + + +10. References +-------------- + +1. Trusted Board Boot Requirements CLIENT PDD (ARM DEN 0006B-5). Available + under NDA through your ARM account representative. + +2. [Power State Coordination Interface PDD (ARM DEN 0022B.b)][PSCI]. + +3. [SMC Calling Convention PDD (ARM DEN 0028A)][SMCCC]. + +4. [ARM Trusted Firmware Interrupt Management Design guide][INTRG]. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - + +_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._ + + +[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022b/index.html "Power State Coordination Interface PDD (ARM DEN 0022B.b)" +[SMCCC]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)" +[UUID]: https://tools.ietf.org/rfc/rfc4122.txt "A Universally Unique IDentifier (UUID) URN Namespace" +[User Guide]: ./user-guide.md +[INTRG]: ./interrupt-framework-design.md diff --git a/docs/interrupt-framework-design.md b/docs/interrupt-framework-design.md new file mode 100644 index 0000000..f96f764 --- /dev/null +++ b/docs/interrupt-framework-design.md @@ -0,0 +1,848 @@ +ARM Trusted Firmware Interrupt Management Design guide +====================================================== + +Contents : + +1. Introduction + * Assumptions + * Concepts + - Interrupt Types + - Routing Model + - Valid Routing Models + + Secure-EL1 Interrupts + + Non-secure Interrupts + - Mapping of Interrupt Type to Signal + +2. Interrupt Management + * Software Components + * Interrupt Registration + - EL3 Runtime Firmware + - Secure Payload Dispatcher + + Test Secure Payload Dispatcher behavior + - Secure Payload + + Secure Payload IHF design w.r.t Secure-EL1 interrupts + + Secure Payload IHF design w.r.t Non-secure interrupts + + Test Secure Payload behavior + * Interrupt Handling + - EL3 Runtime Firmware + - Secure Payload Dispatcher + + Interrupt Entry + + Interrupt Exit + + Test Secure Payload Dispatcher behavior + - Secure Payload + + Test Secure Payload behavior + + +1. Introduction +---------------- +This document describes the design of the Interrupt management framework in ARM +Trusted Firmware. This section briefly describes the requirements from this +framework. It also briefly explains some concepts and assumptions. They will +help in understanding the implementation of the framework explained in +subsequent sections. + +This framework is responsible for managing interrupts routed to EL3. It also +allows EL3 software to configure the interrupt routing behavior. Its main +objective is to implement the following two requirements. + +1. It should be possible to route interrupts meant to be handled by secure + software (Secure interrupts) to EL3, when execution is in non-secure state + (normal world). The framework should then take care of handing control of + the interrupt to either software in EL3 or Secure-EL1 depending upon the + software configuration and the GIC implementation. This requirement ensures + that secure interrupts are under the control of the secure software with + respect to their delivery and handling without the possibility of + intervention from non-secure software. + +2. It should be possible to route interrupts meant to be handled by + non-secure software (Non-secure interrupts) to the last executed exception + level in the normal world when the execution is in secure world at + exception levels lower than EL3. This could be done with or without the + knowledge of software executing in Secure-EL1/Secure-EL0. The choice of + approach should be governed by the secure software. This requirement + ensures that non-secure software is able to execute in tandem with the + secure software without overriding it. + +### 1.1 Assumptions +The framework makes the following assumptions to simplify its implementation. + +1. All secure interrupts are handled in Secure-EL1. They can be delivered to + Secure-EL1 via EL3 but they cannot be handled in EL3. It will be possible + to extend the framework to handle secure interrupts in EL3 in the future. + +2. Interrupt exceptions (`PSTATE.I` and `F` bits) are masked during execution + in EL3. + +### 1.2 Concepts + +#### 1.2.1 Interrupt types +The framework categorises an interrupt to be one of the following depending upon +the exception level(s) it is handled in. + +1. Secure EL1 interrupt. This type of interrupt can be routed to EL3 or + Secure-EL1 depending upon the security state of the current execution + context. It is always handled in Secure-EL1. + +2. Non-secure interrupt. This type of interrupt can be routed to EL3, + Secure-EL1, Non-secure EL1 or EL2 depending upon the security state of the + current execution context. It is always handled in either Non-secure EL1 + or EL2. + +3. EL3 interrupt. This type of interrupt can be routed to EL3 or Secure-EL1 + depending upon the security state of the current execution context. It is + always handled in EL3. + +In the current implementation of the framework, all secure interrupts are +treated as Secure EL1 interrupts. It will be possible for EL3 software to +configure a secure interrupt as an EL3 interrupt in future implementations. The +following constants define the various interrupt types in the framework +implementation. + + #define INTR_TYPE_S_EL1 0 + #define INTR_TYPE_EL3 1 + #define INTR_TYPE_NS 2 + + +#### 1.2.2 Routing model +A type of interrupt can be either generated as an FIQ or an IRQ. The target +exception level of an interrupt type is configured through the FIQ and IRQ bits +in the Secure Configuration Register at EL3 (`SCR_EL3.FIQ` and `SCR_EL3.IRQ` +bits). When `SCR_EL3.FIQ`=1, FIQs are routed to EL3. Otherwise they are routed +to the First Exception Level (FEL) capable of handling interrupts. When +`SCR_EL3.IRQ`=1, IRQs are routed to EL3. Otherwise they are routed to the +FEL. This register is configured independently by EL3 software for each security +state prior to entry into a lower exception level in that security state. + +A routing model for a type of interrupt (generated as FIQ or IRQ) is defined as +its target exception level for each security state. It is represented by a +single bit for each security state. A value of `0` means that the interrupt +should be routed to the FEL. A value of `1` means that the interrupt should be +routed to EL3. A routing model is applicable only when execution is not in EL3. + +The default routing model for an interrupt type is to route it to the FEL in +either security state. + +#### 1.2.3 Valid routing models +The framework considers certain routing models for each type of interrupt to be +incorrect as they conflict with the requirements mentioned in Section 1. The +following sub-sections describe all the possible routing models and specify +which ones are valid or invalid. Only the Secure-EL1 and Non-secure interrupt +types are considered as EL3 interrupts are currently unsupported (See 1.1). The +terminology used in the following sub-sections is explained below. + +1. __CSS__. Current Security State. `0` when secure and `1` when non-secure + +2. __TEL3__. Target Exception Level 3. `0` when targeted to the FEL. `1` when + targeted to EL3. + + +##### 1.2.3.1 Secure-EL1 interrupts + +1. __CSS=0, TEL3=0__. Interrupt is routed to the FEL when execution is in + secure state. This is a valid routing model as secure software is in + control of handling secure interrupts. + +2. __CSS=0, TEL3=1__. Interrupt is routed to EL3 when execution is in secure + state. This is a valid routing model as secure software in EL3 can + handover the interrupt to Secure-EL1 for handling. + +3. __CSS=1, TEL3=0__. Interrupt is routed to the FEL when execution is in + non-secure state. This is an invalid routing model as a secure interrupt + is not visible to the secure software which violates the motivation behind + the ARM Security Extensions. + +4. __CSS=1, TEL3=1__. Interrupt is routed to EL3 when execution is in secure + state. This is a valid routing model as secure software in EL3 can + handover the interrupt to Secure-EL1 for handling. + + +##### 1.2.3.2 Non-secure interrupts + +1. __CSS=0, TEL3=0__. Interrupt is routed to the FEL when execution is in + secure state. This allows the secure software to trap non-secure + interrupts, perform its bookeeping and hand the interrupt to the + non-secure software through EL3. This is a valid routing model as secure + software is in control of how its execution is pre-empted by non-secure + interrupts. + +2. __CSS=0, TEL3=1__. Interrupt is routed to EL3 when execution is in secure + state. This is a valid routing model as secure software in EL3 can save + the state of software in Secure-EL1/Secure-EL0 before handing the + interrupt to non-secure software. This model requires additional + coordination between Secure-EL1 and EL3 software to ensure that the + former's state is correctly saved by the latter. + +3. __CSS=1, TEL3=0__. Interrupt is routed to FEL when execution is in + non-secure state. This is an valid routing model as a non-secure interrupt + is handled by non-secure software. + +4. __CSS=1, TEL3=1__. Interrupt is routed to EL3 when execution is in + non-secure state. This is an invalid routing model as there is no valid + reason to route the interrupt to EL3 software and then hand it back to + non-secure software for handling. + + +#### 1.2.4 Mapping of interrupt type to signal +The framework is meant to work with any interrupt controller implemented by a +platform. A interrupt controller could generate a type of interrupt as either an +FIQ or IRQ signal to the CPU depending upon the current security state.The +mapping between the type and signal is known only to the platform. The framework +uses this information to determine whether the IRQ or the FIQ bit should be +programmed in `SCR_EL3` while applying the routing model for a type of +interrupt. The platform provides this information through the +`plat_interrupt_type_to_line()` API (described in the [Porting +Guide]). For example, on the FVP port when the platform uses an ARM GICv2 +interrupt controller, Secure-EL1 interrupts are signalled through the FIQ signal +while Non-secure interrupts are signalled through the IRQ signal. This applies +when execution is in either security state. + + +2. Interrupt management +----------------------- +The following sections describe how interrupts are managed by the interrupt +handling framework. This entails: + +1. Providing an interface to allow registration of a handler and specification + of the routing model for a type of interrupt. + +2. Implementing support to hand control of an interrupt type to its registered + handler when the interrupt is generated. + +Both aspects of interrupt management involve various components in the secure +software stack spanning from EL3 to Secure-EL1. These components are described +in the section 2.1. The framework stores information associated with each type +of interrupt in the following data structure. + +``` +typedef struct intr_type_desc { + interrupt_type_handler_t handler; + uint32_t flags; + uint32_t scr_el3[2]; +} intr_type_desc_t; +``` + +The `flags` field stores the routing model for the interrupt type in +bits[1:0]. Bit[0] stores the routing model when execution is in the secure +state. Bit[1] stores the routing model when execution is in the non-secure +state. As mentioned in Section 1.2.2, a value of `0` implies that the interrupt +should be targeted to the FEL. A value of `1` implies that it should be targeted +to EL3. The remaining bits are reserved and SBZ. The helper macro +`set_interrupt_rm_flag()` should be used to set the bits in the `flags` +parameter. + +The `scr_el3[2]` field also stores the routing model but as a mapping of the +model in the `flags` field to the corresponding bit in the `SCR_EL3` for each +security state. + +The framework also depends upon the platform port to configure the interrupt +controller to distinguish between secure and non-secure interrupts. The platform +is expected to be aware of the secure devices present in the system and their +associated interrupt numbers. It should configure the interrupt controller to +enable the secure interrupts, ensure that their priority is always higher than +the non-secure interrupts and target them to the primary CPU. It should also +export the interface described in the the [Porting Guide][PRTG] to enable +handling of interrupts. + +In the remainder of this document, for the sake of simplicity it is assumed that +the FIQ signal is used to generate Secure-EL1 interrupts and the IRQ signal is +used to generate non-secure interrupts in either security state. + +### 2.1 Software components +Roles and responsibilities for interrupt management are sub-divided between the +following components of software running in EL3 and Secure-EL1. Each component is +briefly described below. + +1. EL3 Runtime Firmware. This component is common to all ports of the ARM + Trusted Firmware. + +2. Secure Payload Dispatcher (SPD) service. This service interfaces with the + Secure Payload (SP) software which runs in exception levels lower than EL3 + i.e. Secure-EL1/Secure-EL0. It is responsible for switching execution + between software running in secure and non-secure states at exception + levels lower than EL3. A switch is triggered by a Secure Monitor Call from + either state. It uses the APIs exported by the Context management library + to implement this functionality. Switching execution between the two + security states is a requirement for interrupt management as well. This + results in a significant dependency on the SPD service. ARM Trusted + firmware implements an example Test Secure Payload Dispatcher (TSPD) + service. + + An SPD service plugs into the EL3 runtime firmware and could be common to + some ports of the ARM Trusted Firmware. + +3. Secure Payload (SP). On a production system, the Secure Payload corresponds + to a Secure OS which runs in Secure-EL1/Secure-EL0. It interfaces with the + SPD service to manage communication with non-secure software. ARM Trusted + Firmware implements an example secure payload called Test Secure Payload + (TSP) which runs only in Secure-EL1. + + A Secure payload implementation could be common to some ports of the ARM + Trusted Firmware just like the SPD service. + + +### 2.2 Interrupt registration +This section describes in detail the role of each software component (see 2.1) +during the registration of a handler for an interrupt type. + + +#### 2.2.1 EL3 runtime firmware +This component declares the following prototype for a handler of an interrupt type. + + typedef uint64_t (*interrupt_type_handler_t)(uint32_t id, + uint32_t flags, + void *handle, + void *cookie); + +The value of the `id` parameter depends upon the definition of the +`IMF_READ_INTERRUPT_ID` build time flag. When the flag is defined, `id` contains +the number of the highest priority pending interrupt of the type that this +handler was registered for. When the flag is not defined `id` contains +`INTR_ID_UNAVAILABLE`. + +The `flags` parameter contains miscellaneous information as follows. + +1. Security state, bit[0]. This bit indicates the security state of the lower + exception level when the interrupt was generated. A value of `1` means + that it was in the non-secure state. A value of `0` indicates that it was + in the secure state. This bit can be used by the handler to ensure that + interrupt was generated and routed as per the routing model specified + during registration. + +2. Reserved, bits[31:1]. The remaining bits are reserved for future use. + +The `handle` parameter points to the `cpu_context` structure of the current CPU +for the security state specified in the `flags` parameter. + +Once the handler routine completes, execution will return to either the secure +or non-secure state. The handler routine should return a pointer to +`cpu_context` structure of the current CPU for the the target security state. It +should treat all error conditions as critical errors and take appropriate action +within its implementation e.g. use assertion failures. + +The runtime firmware provides the following API for registering a handler for a +particular type of interrupt. A Secure Payload Dispatcher service should use +this API to register a handler for Secure-EL1 and optionally for non-secure +interrupts. This API also requires the caller to specify the routing model for +the type of interrupt. + + int32_t register_interrupt_type_handler(uint32_t type, + interrupt_type_handler handler, + uint64_t flags); + + +The `type` parameter can be one of the three interrupt types listed above i.e. +`INTR_TYPE_S_EL1`, `INTR_TYPE_NS` & `INTR_TYPE_EL3` (currently unimplemented). +The `flags` parameter is as described in Section 2. + +The function will return `0` upon a successful registration. It will return +`-EALREADY` in case a handler for the interrupt type has already been +registered. If the `type` is unrecognised or the `flags` or the `handler` are +invalid it will return `-EINVAL`. It will return `-ENOTSUP` if the specified +`type` is not supported by the framework i.e. `INTR_TYPE_EL3`. + +Interrupt routing is governed by the configuration of the `SCR_EL3.FIQ/IRQ` bits +prior to entry into a lower exception level in either security state. The +context management library maintains a copy of the `SCR_EL3` system register for +each security state in the `cpu_context` structure of each CPU. It exports the +following APIs to let EL3 Runtime Firmware program and retrieve the routing +model for each security state for the current CPU. The value of `SCR_EL3` stored +in the `cpu_context` is used by the `el3_exit()` function to program the +`SCR_EL3` register prior to returning from the EL3 exception level. + + uint32_t cm_get_scr_el3(uint32_t security_state); + void cm_write_scr_el3_bit(uint32_t security_state, + uint32_t bit_pos, + uint32_t value); + +`cm_get_scr_el3()` returns the value of the `SCR_EL3` register for the specified +security state of the current CPU. `cm_write_scr_el3()` writes a `0` or `1` to +the bit specified by `bit_pos`. `register_interrupt_type_handler()` invokes +`set_routing_model()` API which programs the `SCR_EL3` according to the routing +model using the `cm_get_scr_el3()` and `cm_write_scr_el3_bit()` APIs. + +It is worth noting that in the current implementation of the framework, the EL3 +runtime firmware is responsible for programming the routing model. The SPD is +responsible for ensuring that the routing model has been adhered to upon +receiving an interrupt. + +#### 2.2.2 Secure payload dispatcher +A SPD service is responsible for determining and maintaining the interrupt +routing model supported by itself and the Secure Payload. It is also responsible +for ferrying interrupts between secure and non-secure software depending upon +the routing model. It could determine the routing model at build time or at +runtime. It must use this information to register a handler for each interrupt +type using the `register_interrupt_type_handler()` API in EL3 runtime firmware. + +If the routing model is not known to the SPD service at build time, then it must +be provided by the SP as the result of its initialisation. The SPD should +program the routing model only after SP initialisation has completed e.g. in the +SPD initialisation function pointed to by the `bl32_init` variable. + +The SPD should determine the mechanism to pass control to the Secure Payload +after receiving an interrupt from the EL3 runtime firmware. This information +could either be provided to the SPD service at build time or by the SP at +runtime. + +#### 2.2.2.1 Test secure payload dispatcher behavior +The TSPD only handles Secure-EL1 interrupts and is provided with the following +routing model at build time. + +* Secure-EL1 interrupts are routed to EL3 when execution is in non-secure + state and are routed to the FEL when execution is in the secure state + i.e __CSS=0, TEL3=0__ & __CSS=1, TEL3=1__ for Secure-EL1 interrupts + +* The default routing model is used for non-secure interrupts i.e they are + routed to the FEL in either security state i.e __CSS=0, TEL3=0__ & + __CSS=1, TEL3=0__ for Non-secure interrupts + +It performs the following actions in the `tspd_init()` function to fulfill the +requirements mentioned earlier. + +1. It passes control to the Test Secure Payload to perform its + initialisation. The TSP provides the address of the vector table + `tsp_vectors` in the SP which also includes the handler for Secure-EL1 + interrupts in the `fiq_entry` field. The TSPD passes control to the TSP at + this address when it receives a Secure-EL1 interrupt. + + The handover agreement between the TSP and the TSPD requires that the TSPD + masks all interrupts (`PSTATE.DAIF` bits) when it calls + `tsp_fiq_entry()`. The TSP has to preserve the callee saved general + purpose, SP_EL1/Secure-EL0, LR, VFP and system registers. It can use + `x0-x18` to enable its C runtime. + +2. The TSPD implements a handler function for Secure-EL1 interrupts. It + registers it with the EL3 runtime firmware using the + `register_interrupt_type_handler()` API as follows + + /* Forward declaration */ + interrupt_type_handler tspd_secure_el1_interrupt_handler; + int32_t rc, flags = 0; + set_interrupt_rm_flag(flags, NON_SECURE); + rc = register_interrupt_type_handler(INTR_TYPE_S_EL1, + tspd_secure_el1_interrupt_handler, + flags); + assert(rc == 0); + +#### 2.2.3 Secure payload +A Secure Payload must implement an interrupt handling framework at Secure-EL1 +(Secure-EL1 IHF) to support its chosen interrupt routing model. Secure payload +execution will alternate between the below cases. + +1. In the code where IRQ, FIQ or both interrupts are enabled, if an interrupt + type is targeted to the FEL, then it will be routed to the Secure-EL1 + exception vector table. This is defined as the asynchronous model of + handling interrupts. This mode applies to both Secure-EL1 and non-secure + interrupts. + +2. In the code where both interrupts are disabled, if an interrupt type is + targeted to the FEL, then execution will eventually migrate to the + non-secure state. Any non-secure interrupts will be handled as described + in the routing model where __CSS=1 and TEL3=0__. Secure-EL1 interrupts + will be routed to EL3 (as per the routing model where __CSS=1 and + TEL3=1__) where the SPD service will hand them to the SP. This is defined + as the synchronous mode of handling interrupts. + +The interrupt handling framework implemented by the SP should support one or +both these interrupt handling models depending upon the chosen routing model. + +The following list briefly describes how the choice of a valid routing model +(See 1.2.3) effects the implementation of the Secure-EL1 IHF. If the choice of +the interrupt routing model is not known to the SPD service at compile time, +then the SP should pass this information to the SPD service at runtime during +its initialisation phase. + +As mentioned earlier, it is assumed that the FIQ signal is used to generate +Secure-EL1 interrupts and the IRQ signal is used to generate non-secure +interrupts in either security state. + +##### 2.2.3.1 Secure payload IHF design w.r.t secure-EL1 interrupts +1. __CSS=0, TEL3=0__. If `PSTATE.F=0`, Secure-EL1 interrupts will be + trigerred at one of the Secure-EL1 FIQ exception vectors. The Secure-EL1 + IHF should implement support for handling FIQ interrupts asynchronously. + + If `PSTATE.F=1` then Secure-EL1 interrupts will be handled as per the + synchronous interrupt handling model. The SP could implement this scenario + by exporting a seperate entrypoint for Secure-EL1 interrupts to the SPD + service during the registration phase. The SPD service would also need to + know the state of the system, general purpose and the `PSTATE` registers + in which it should arrange to return execution to the SP. The SP should + provide this information in an implementation defined way during the + registration phase if it is not known to the SPD service at build time. + +2. __CSS=1, TEL3=1__. Interrupts are routed to EL3 when execution is in + non-secure state. They should be handled through the synchronous interrupt + handling model as described in 1. above. + +3. __CSS=0, TEL3=1__. Secure interrupts are routed to EL3 when execution is in + secure state. They will not be visible to the SP. The `PSTATE.F` bit in + Secure-EL1/Secure-EL0 will not mask FIQs. The EL3 runtime firmware will + call the handler registered by the SPD service for Secure-EL1 + interrupts. Secure-EL1 IHF should then handle all Secure-EL1 interrupt + through the synchronous interrupt handling model described in 1. above. + + +##### 2.2.3.2 Secure payload IHF design w.r.t non-secure interrupts +1. __CSS=0, TEL3=0__. If `PSTATE.I=0`, non-secure interrupts will be + trigerred at one of the Secure-EL1 IRQ exception vectors . The Secure-EL1 + IHF should co-ordinate with the SPD service to transfer execution to the + non-secure state where the interrupt should be handled e.g the SP could + allocate a function identifier to issue a SMC64 or SMC32 to the SPD + service which indicates that the SP execution has been pre-empted by a + non-secure interrupt. If this function identifier is not known to the SPD + service at compile time then the SP could provide it during the + registration phase. + + If `PSTATE.I=1` then the non-secure interrupt will pend until execution + resumes in the non-secure state. + +2. __CSS=0, TEL3=1__. Non-secure interrupts are routed to EL3. They will not + be visible to the SP. The `PSTATE.I` bit in Secure-EL1/Secure-EL0 will + have not effect. The SPD service should register a non-secure interrupt + handler which should save the SP state correctly and resume execution in + the non-secure state where the interrupt will be handled. The Secure-EL1 + IHF does not need to take any action. + +3. __CSS=1, TEL3=0__. Non-secure interrupts are handled in the FEL in + non-secure state (EL1/EL2) and are not visible to the SP. This routing + model does not affect the SP behavior. + + +A Secure Payload must also ensure that all Secure-EL1 interrupts are correctly +configured at the interrupt controller by the platform port of the EL3 runtime +firmware. It should configure any additional Secure-EL1 interrupts which the EL3 +runtime firmware is not aware of through its platform port. + +#### 2.2.3.3 Test secure payload behavior +The routing model for Secure-EL1 and non-secure interrupts chosen by the TSP is +described in Section 2.2.2. It is known to the TSPD service at build time. + +The TSP implements an entrypoint (`tsp_fiq_entry()`) for handling Secure-EL1 +interrupts taken in non-secure state and routed through the TSPD service +(synchronous handling model). It passes the reference to this entrypoint via +`tsp_vectors` to the TSPD service. + +The TSP also replaces the default exception vector table referenced through the +`early_exceptions` variable, with a vector table capable of handling FIQ and IRQ +exceptions taken at the same (Secure-EL1) exception level. This table is +referenced through the `tsp_exceptions` variable and programmed into the +VBAR_EL1. It caters for the asynchronous handling model. + +The TSP also programs the Secure Physical Timer in the ARM Generic Timer block +to raise a periodic interrupt (every half a second) for the purpose of testing +interrupt management across all the software components listed in 2.1 + + +### 2.3 Interrupt handling +This section describes in detail the role of each software component (see +Section 2.1) in handling an interrupt of a particular type. + +#### 2.3.1 EL3 runtime firmware +The EL3 runtime firmware populates the IRQ and FIQ exception vectors referenced +by the `runtime_exceptions` variable as follows. + +1. IRQ and FIQ exceptions taken from the current exception level with + `SP_EL0` or `SP_EL3` are reported as irrecoverable error conditions. As + mentioned earlier, EL3 runtime firmware always executes with the + `PSTATE.I` and `PSTATE.F` bits set. + +2. The following text describes how the IRQ and FIQ exceptions taken from a + lower exception level using AArch64 or AArch32 are handled. + +When an interrupt is generated, the vector for each interrupt type is +responsible for: + +1. Saving the entire general purpose register context (x0-x30) immediately + upon exception entry. The registers are saved in the per-cpu `cpu_context` + data structure referenced by the `SP_EL3`register. + +2. Saving the `ELR_EL3`, `SP_EL0` and `SPSR_EL3` system registers in the + per-cpu `cpu_context` data structure referenced by the `SP_EL3` register. + +3. Switching to the C runtime stack by restoring the `CTX_RUNTIME_SP` value + from the per-cpu `cpu_context` data structure in `SP_EL0` and + executing the `msr spsel, #0` instruction. + +4. Determining the type of interrupt. Secure-EL1 interrupts will be signalled + at the FIQ vector. Non-secure interrupts will be signalled at the IRQ + vector. The platform should implement the following API to determine the + type of the pending interrupt. + + uint32_t plat_ic_get_interrupt_type(void); + + It should return either `INTR_TYPE_S_EL1` or `INTR_TYPE_NS`. + +5. Determining the handler for the type of interrupt that has been generated. + The following API has been added for this purpose. + + interrupt_type_handler get_interrupt_type_handler(uint32_t interrupt_type); + + It returns the reference to the registered handler for this interrupt + type. The `handler` is retrieved from the `intr_type_desc_t` structure as + described in Section 2. `NULL` is returned if no handler has been + registered for this type of interrupt. This scenario is reported as an + irrecoverable error condition. + +6. Calling the registered handler function for the interrupt type generated. + The firmware also determines the interrupt id if the IMF_READ_INTERRUPT_ID + build time flag is set. The id is set to `INTR_ID_UNAVAILABLE` if the flag + is not set. The id along with the current security state and a reference to + the `cpu_context_t` structure for the current security state are passed to + the handler function as its arguments. + + The handler function returns a reference to the per-cpu `cpu_context_t` + structure for the target security state. + +7. Calling `el3_exit()` to return from EL3 into a lower exception level in + the security state determined by the handler routine. The `el3_exit()` + function is responsible for restoring the register context from the + `cpu_context_t` data structure for the target security state. + + +#### 2.3.2 Secure payload dispatcher + +##### 2.3.2.1 Interrupt entry +The SPD service begins handling an interrupt when the EL3 runtime firmware calls +the handler function for that type of interrupt. The SPD service is responsible +for the following: + +1. Validating the interrupt. This involves ensuring that the interrupt was + generating according to the interrupt routing model specified by the SPD + service during registration. It should use the interrupt id and the + security state of the exception level (passed in the `flags` parameter of + the handler) where the interrupt was taken from to determine this. If the + interrupt is not recognised then the handler should treat it as an + irrecoverable error condition. + + A SPD service can register a handler for Secure-EL1 and/or Non-secure + interrupts. The following text describes further error scenarios keeping + this in mind: + + 1. __SPD service has registered a handler for Non-secure interrupts__: + When an interrupt is received by the handler, it could check its id + to ensure it has been configured as a non-secure interrupt at the + interrupt controller. A secure interrupt should never be handed to + the non-secure interrupt handler. A non-secure interrupt should + never be routed to EL3 when execution is in non-secure state. The + handler could check the security state flag to ensure this. + + 2. __SPD service has registered a handler for Secure-EL1 interrupts__: + When an interrupt is received by the handler, it could check its id + to ensure it has been configured as a secure interrupt at the + interrupt controller. A non-secure interrupt should never be handed + to the secure interrupt handler. If the routing model chosen is such + that Secure-EL1 interrupts are not routed to EL3 when execution is + in non-secure state, then a Secure-EL1 interrupt generated in the + secure state would be invalid. The handler could use the security + state flag to check this. + + The SPD service should use the platform API: + `plat_ic_get_interrupt_type()` to determine the type of interrupt for the + specified id. + +2. Determining whether the security state of the exception level for handling + the interrupt is the same as the security state of the exception level + where the interrupt was generated. This depends upon the routing model and + type of the interrupt. The SPD should use this information to determine if + a context switch is required. The following two cases would require a + context switch from secure to non-secure or vice-versa. + + 1. A Secure-EL1 interrupt taken from the non-secure state should be + routed to the Secure Payload. + + 2. A non-secure interrupt taken from the secure state should be routed + to the last known non-secure exception level. + + The SPD service must save the system register context of the current + security state. It must then restore the system register context of the + target security state. It should use the `cm_set_next_eret_context()` API + to ensure that the next `cpu_context` to be restored is of the target + security state. + + If the target state is secure then execution should be handed to the SP as + per the synchronous interrupt handling model it implements. A Secure-EL1 + interrupt can be routed to EL3 while execution is in the SP. This implies + that SP execution can be preempted while handling an interrupt by a + another higher priority Secure-EL1 interrupt (or a EL3 interrupt in the + future). The SPD service should manage secure interrupt priorities before + handing control to the SP to prevent this type of preemption which can + leave the system in an inconsistent state. + +3. Setting the return value of the handler to the per-cpu `cpu_context` if + the interrupt has been successfully validated and ready to be handled at a + lower exception level. + +The routing model allows non-secure interrupts to be taken to Secure-EL1 when in +secure state. The SPD service and the SP should implement a mechanism for +routing these interrupts to the last known exception level in the non-secure +state. The former should save the SP context, restore the non-secure context and +arrange for entry into the non-secure state so that the interrupt can be +handled. + +##### 2.3.2.2 Interrupt exit +When the Secure Payload has finished handling a Secure-EL1 interrupt, it could +return control back to the SPD service through a SMC32 or SMC64. The SPD service +should handle this secure monitor call so that execution resumes in the +exception level and the security state from where the Secure-EL1 interrupt was +originally taken. + +##### 2.3.2.1 Test secure payload dispatcher behavior +The example TSPD service registers a handler for Secure-EL1 interrupts taken +from the non-secure state. Its handler `tspd_secure_el1_interrupt_handler()` +takes the following actions upon being invoked. + +1. It uses the `id` parameter to query the interrupt controller to ensure + that the interrupt is a Secure-EL1 interrupt. It asserts if this is not + the case. + +2. It uses the security state provided in the `flags` parameter to ensure + that the secure interrupt originated from the non-secure state. It asserts + if this is not the case. + +3. It saves the system register context for the non-secure state by calling + `cm_el1_sysregs_context_save(NON_SECURE);`. + +4. It sets the `ELR_EL3` system register to `tsp_fiq_entry` and sets the + `SPSR_EL3.DAIF` bits in the secure CPU context. It sets `x0` to + `TSP_HANDLE_FIQ_AND_RETURN`. If the TSP was in the middle of handling a + standard SMC, then the `ELR_EL3` and `SPSR_EL3` registers in the secure CPU + context are saved first. + +5. It restores the system register context for the secure state by calling + `cm_el1_sysregs_context_restore(SECURE);`. + +6. It ensures that the secure CPU context is used to program the next + exception return from EL3 by calling `cm_set_next_eret_context(SECURE);`. + +7. It returns the per-cpu `cpu_context` to indicate that the interrupt can + now be handled by the SP. `x1` is written with the value of `elr_el3` + register for the non-secure state. This information is used by the SP for + debugging purposes. + +The figure below describes how the interrupt handling is implemented by the TSPD +when a Secure-EL1 interrupt is generated when execution is in the non-secure +state. + +![Image 1](diagrams/sec-int-handling.png?raw=true) + +The TSP issues an SMC with `TSP_HANDLED_S_EL1_FIQ` as the function identifier to +signal completion of interrupt handling. + +The TSP issues an SMC with `TSP_PREEMPTED` as the function identifier to signal +generation of a non-secure interrupt in Secure-EL1. + +The TSPD service takes the following actions in `tspd_smc_handler()` function +upon receiving an SMC with `TSP_HANDLED_S_EL1_FIQ` and `TSP_PREEMPTED` as the +function identifiers: + +1. It ensures that the call originated from the secure state otherwise + execution returns to the non-secure state with `SMC_UNK` in `x0`. + +2. If the function identifier is `TSP_HANDLED_S_EL1_FIQ`, it restores the + saved `ELR_EL3` and `SPSR_EL3` system registers back to the secure CPU + context (see step 4 above) in case the TSP had been preempted by a non + secure interrupt earlier. It does not save the secure context since the + TSP is expected to preserve it (see Section 2.2.2.1) + +3. If the function identifier is `TSP_PREEMPTED`, it saves the system + register context for the secure state by calling + `cm_el1_sysregs_context_save(SECURE)`. + +4. It restores the system register context for the non-secure state by + calling `cm_el1_sysregs_context_restore(NON_SECURE)`. It sets `x0` to + `SMC_PREEMPTED` if the incoming function identifier is + `TSP_PREEMPTED`. The Normal World is expected to resume the TSP after the + non-secure interrupt handling by issuing an SMC with `TSP_FID_RESUME` as + the function identifier. + +5. It ensures that the non-secure CPU context is used to program the next + exception return from EL3 by calling + `cm_set_next_eret_context(NON_SECURE)`. + +6. `tspd_smc_handler()` returns a reference to the non-secure `cpu_context` + as the return value. + +As mentioned in 4. above, if a non-secure interrupt preempts the TSP execution +then the non-secure software issues an SMC with `TSP_FID_RESUME` as the function +identifier to resume TSP execution. The TSPD service takes the following actions +in `tspd_smc_handler()` function upon receiving this SMC: + +1. It ensures that the call originated from the non secure state. An + assertion is raised otherwise. + +2. Checks whether the TSP needs a resume i.e check if it was preempted. It + then saves the system register context for the secure state by calling + `cm_el1_sysregs_context_save(NON_SECURE)`. + +3. Restores the secure context by calling + `cm_el1_sysregs_context_restore(SECURE)` + +4. It ensures that the secure CPU context is used to program the next + exception return from EL3 by calling `cm_set_next_eret_context(SECURE)`. + +5. `tspd_smc_handler()` returns a reference to the secure `cpu_context` as the + return value. + +The figure below describes how the TSP/TSPD handle a non-secure interrupt when +it is generated during execution in the TSP with `PSTATE.I` = 0. + +![Image 2](diagrams/non-sec-int-handling.png?raw=true) + + +#### 2.3.3 Secure payload +The SP should implement one or both of the synchronous and asynchronous +interrupt handling models depending upon the interrupt routing model it has +chosen (as described in 2.2.3). + +In the synchronous model, it should begin handling a Secure-EL1 interrupt after +receiving control from the SPD service at an entrypoint agreed upon during build +time or during the registration phase. Before handling the interrupt, the SP +should save any Secure-EL1 system register context which is needed for resuming +normal execution in the SP later e.g. `SPSR_EL1, `ELR_EL1`. After handling the +interrupt, the SP could return control back to the exception level and security +state where the interrupt was originally taken from. The SP should use an SMC32 +or SMC64 to ask the SPD service to do this. + +In the asynchronous model, the Secure Payload is responsible for handling +non-secure and Secure-EL1 interrupts at the IRQ and FIQ vectors in its exception +vector table when `PSTATE.I` and `PSTATE.F` bits are 0. As described earlier, +when a non-secure interrupt is generated, the SP should coordinate with the SPD +service to pass control back to the non-secure state in the last known exception +level. This will allow the non-secure interrupt to be handled in the non-secure +state. + +##### 2.3.3.1 Test secure payload behavior +The TSPD hands control of a Secure-EL1 interrupt to the TSP at the +`tsp_fiq_entry()`. The TSP handles the interrupt while ensuring that the +handover agreement described in Section 2.2.2.1 is maintained. It updates some +statistics by calling `tsp_update_sync_fiq_stats()`. It then calls +`tsp_fiq_handler()` which. + +1. Checks whether the interrupt is the secure physical timer interrupt. It + uses the platform API `plat_ic_get_pending_interrupt_id()` to get the + interrupt number. + +2. Handles the interrupt by acknowledging it using the + `plat_ic_acknowledge_interrupt()` platform API, calling + `tsp_generic_timer_handler()` to reprogram the secure physical generic + timer and calling the `plat_ic_end_of_interrupt()` platform API to signal + end of interrupt processing. + +The TSP passes control back to the TSPD by issuing an SMC64 with +`TSP_HANDLED_S_EL1_FIQ` as the function identifier. + +The TSP handles interrupts under the asynchronous model as follows. + +1. Secure-EL1 interrupts are handled by calling the `tsp_fiq_handler()` + function. The function has been described above. + +2. Non-secure interrupts are handled by issuing an SMC64 with `TSP_PREEMPTED` + as the function identifier. Execution resumes at the instruction that + follows this SMC instruction when the TSPD hands control to the TSP in + response to an SMC with `TSP_FID_RESUME` as the function identifier from + the non-secure state (see section 2.3.2.1). + +- - - - - - - - - - - - - - - - - - - - - - - - - - + +_Copyright (c) 2014, ARM Limited and Contributors. All rights reserved._ + +[Porting Guide]: ./porting-guide.md diff --git a/docs/porting-guide.md b/docs/porting-guide.md new file mode 100644 index 0000000..d970190 --- /dev/null +++ b/docs/porting-guide.md @@ -0,0 +1,1372 @@ +ARM Trusted Firmware Porting Guide +================================== + +Contents +-------- + +1. Introduction +2. Common Modifications + * Common mandatory modifications + * Handling reset + * Common optional modifications +3. Boot Loader stage specific modifications + * Boot Loader stage 1 (BL1) + * Boot Loader stage 2 (BL2) + * Boot Loader stage 3-1 (BL3-1) + * PSCI implementation (in BL3-1) + * Interrupt Management framework (in BL3-1) +4. C Library +5. Storage abstraction layer + +- - - - - - - - - - - - - - - - - - + +1. Introduction +---------------- + +Porting the ARM Trusted Firmware to a new platform involves making some +mandatory and optional modifications for both the cold and warm boot paths. +Modifications consist of: + +* Implementing a platform-specific function or variable, +* Setting up the execution context in a certain way, or +* Defining certain constants (for example #defines). + +The platform-specific functions and variables are all declared in +[include/plat/common/platform.h]. The firmware provides a default implementation +of variables and functions to fulfill the optional requirements. These +implementations are all weakly defined; they are provided to ease the porting +effort. Each platform port can override them with its own implementation if the +default implementation is inadequate. + +Some modifications are common to all Boot Loader (BL) stages. Section 2 +discusses these in detail. The subsequent sections discuss the remaining +modifications for each BL stage in detail. + +This document should be read in conjunction with the ARM Trusted Firmware +[User Guide]. + + +2. Common modifications +------------------------ + +This section covers the modifications that should be made by the platform for +each BL stage to correctly port the firmware stack. They are categorized as +either mandatory or optional. + + +2.1 Common mandatory modifications +---------------------------------- +A platform port must enable the Memory Management Unit (MMU) with identity +mapped page tables, and enable both the instruction and data caches for each BL +stage. In the ARM FVP port, each BL stage configures the MMU in its platform- +specific architecture setup function, for example `blX_plat_arch_setup()`. + +Each platform must allocate a block of identity mapped secure memory with +Device-nGnRE attributes aligned to page boundary (4K) for each BL stage. This +memory is identified by the section name `tzfw_coherent_mem` so that its +possible for the firmware to place variables in it using the following C code +directive: + + __attribute__ ((section("tzfw_coherent_mem"))) + +Or alternatively the following assembler code directive: + + .section tzfw_coherent_mem + +The `tzfw_coherent_mem` section is used to allocate any data structures that are +accessed both when a CPU is executing with its MMU and caches enabled, and when +it's running with its MMU and caches disabled. Examples are given below. + +The following variables, functions and constants must be defined by the platform +for the firmware to work correctly. + + +### File : platform_def.h [mandatory] + +Each platform must ensure that a header file of this name is in the system +include path with the following constants defined. This may require updating the +list of `PLAT_INCLUDES` in the `platform.mk` file. In the ARM FVP port, this +file is found in [plat/fvp/include/platform_def.h]. + +* **#define : PLATFORM_LINKER_FORMAT** + + Defines the linker format used by the platform, for example + `elf64-littleaarch64` used by the FVP. + +* **#define : PLATFORM_LINKER_ARCH** + + Defines the processor architecture for the linker by the platform, for + example `aarch64` used by the FVP. + +* **#define : PLATFORM_STACK_SIZE** + + Defines the normal stack memory available to each CPU. This constant is used + by [plat/common/aarch64/platform_mp_stack.S] and + [plat/common/aarch64/platform_up_stack.S]. + +* **#define : PCPU_DV_MEM_STACK_SIZE** + + Defines the coherent stack memory available to each CPU. This constant is used + by [plat/common/aarch64/platform_mp_stack.S] and + [plat/common/aarch64/platform_up_stack.S]. + +* **#define : FIRMWARE_WELCOME_STR** + + Defines the character string printed by BL1 upon entry into the `bl1_main()` + function. + +* **#define : BL2_IMAGE_NAME** + + Name of the BL2 binary image on the host file-system. This name is used by + BL1 to load BL2 into secure memory from non-volatile storage. + +* **#define : BL31_IMAGE_NAME** + + Name of the BL3-1 binary image on the host file-system. This name is used by + BL2 to load BL3-1 into secure memory from platform storage. + +* **#define : BL33_IMAGE_NAME** + + Name of the BL3-3 binary image on the host file-system. This name is used by + BL2 to load BL3-3 into non-secure memory from platform storage. + +* **#define : PLATFORM_CACHE_LINE_SIZE** + + Defines the size (in bytes) of the largest cache line across all the cache + levels in the platform. + +* **#define : PLATFORM_CLUSTER_COUNT** + + Defines the total number of clusters implemented by the platform in the + system. + +* **#define : PLATFORM_CORE_COUNT** + + Defines the total number of CPUs implemented by the platform across all + clusters in the system. + +* **#define : PLATFORM_MAX_CPUS_PER_CLUSTER** + + Defines the maximum number of CPUs that can be implemented within a cluster + on the platform. + +* **#define : PRIMARY_CPU** + + Defines the `MPIDR` of the primary CPU on the platform. This value is used + after a cold boot to distinguish between primary and secondary CPUs. + +* **#define : TZROM_BASE** + + Defines the base address of secure ROM on the platform, where the BL1 binary + is loaded. This constant is used by the linker scripts to ensure that the + BL1 image fits into the available memory. + +* **#define : TZROM_SIZE** + + Defines the size of secure ROM on the platform. This constant is used by the + linker scripts to ensure that the BL1 image fits into the available memory. + +* **#define : TZRAM_BASE** + + Defines the base address of the secure RAM on platform, where the data + section of the BL1 binary is loaded. The BL2 and BL3-1 images are also + loaded in this secure RAM region. This constant is used by the linker + scripts to ensure that the BL1 data section and BL2/BL3-1 binary images fit + into the available memory. + +* **#define : TZRAM_SIZE** + + Defines the size of the secure RAM on the platform. This constant is used by + the linker scripts to ensure that the BL1 data section and BL2/BL3-1 binary + images fit into the available memory. + +* **#define : BL1_RO_BASE** + + Defines the base address in secure ROM where BL1 originally lives. Must be + aligned on a page-size boundary. + +* **#define : BL1_RO_LIMIT** + + Defines the maximum address in secure ROM that BL1's actual content (i.e. + excluding any data section allocated at runtime) can occupy. + +* **#define : BL1_RW_BASE** + + Defines the base address in secure RAM where BL1's read-write data will live + at runtime. Must be aligned on a page-size boundary. + +* **#define : BL1_RW_LIMIT** + + Defines the maximum address in secure RAM that BL1's read-write data can + occupy at runtime. + +* **#define : BL2_BASE** + + Defines the base address in secure RAM where BL1 loads the BL2 binary image. + Must be aligned on a page-size boundary. + +* **#define : BL2_LIMIT** + + Defines the maximum address in secure RAM that the BL2 image can occupy. + +* **#define : BL31_BASE** + + Defines the base address in secure RAM where BL2 loads the BL3-1 binary + image. Must be aligned on a page-size boundary. + +* **#define : BL31_LIMIT** + + Defines the maximum address in secure RAM that the BL3-1 image can occupy. + +* **#define : NS_IMAGE_OFFSET** + + Defines the base address in non-secure DRAM where BL2 loads the BL3-3 binary + image. Must be aligned on a page-size boundary. + +If the BL3-2 image is supported by the platform, the following constants must +be defined as well: + +* **#define : TSP_SEC_MEM_BASE** + + Defines the base address of the secure memory used by the BL3-2 image on the + platform. + +* **#define : TSP_SEC_MEM_SIZE** + + Defines the size of the secure memory used by the BL3-2 image on the + platform. + +* **#define : BL32_BASE** + + Defines the base address in secure memory where BL2 loads the BL3-2 binary + image. Must be inside the secure memory identified by `TSP_SEC_MEM_BASE` and + `TSP_SEC_MEM_SIZE` constants. Must also be aligned on a page-size boundary. + +* **#define : BL32_LIMIT** + + Defines the maximum address that the BL3-2 image can occupy. Must be inside + the secure memory identified by `TSP_SEC_MEM_BASE` and `TSP_SEC_MEM_SIZE` + constants. + + +### File : plat_macros.S [mandatory] + +Each platform must ensure a file of this name is in the system include path with +the following macro defined. In the ARM FVP port, this file is found in +[plat/fvp/include/plat_macros.S]. + +* **Macro : plat_print_gic_regs** + + This macro allows the crash reporting routine to print GIC registers + in case of an unhandled IRQ or FIQ in BL3-1. This aids in debugging and + this macro can be defined to be empty in case GIC register reporting is + not desired. + +### Other mandatory modifications + +The following mandatory modifications may be implemented in any file +the implementer chooses. In the ARM FVP port, they are implemented in +[plat/fvp/aarch64/plat_common.c]. + +* **Function : uint64_t plat_get_syscnt_freq(void)** + + This function is used by the architecture setup code to retrieve the + counter frequency for the CPU's generic timer. This value will be + programmed into the `CNTFRQ_EL0` register. + In the ARM FVP port, it returns the base frequency of the system counter, + which is retrieved from the first entry in the frequency modes table. + + +2.2 Handling Reset +------------------ + +BL1 by default implements the reset vector where execution starts from a cold +or warm boot. BL3-1 can be optionally set as a reset vector using the +RESET_TO_BL31 make variable. + +For each CPU, the reset vector code is responsible for the following tasks: + +1. Distinguishing between a cold boot and a warm boot. + +2. In the case of a cold boot and the CPU being a secondary CPU, ensuring that + the CPU is placed in a platform-specific state until the primary CPU + performs the necessary steps to remove it from this state. + +3. In the case of a warm boot, ensuring that the CPU jumps to a platform- + specific address in the BL3-1 image in the same processor mode as it was + when released from reset. + +The following functions need to be implemented by the platform port to enable +reset vector code to perform the above tasks. + + +### Function : platform_get_entrypoint() [mandatory] + + Argument : unsigned long + Return : unsigned int + +This function is called with the `SCTLR.M` and `SCTLR.C` bits disabled. The CPU +is identified by its `MPIDR`, which is passed as the argument. The function is +responsible for distinguishing between a warm and cold reset using platform- +specific means. If it's a warm reset then it returns the entrypoint into the +BL3-1 image that the CPU must jump to. If it's a cold reset then this function +must return zero. + +This function is also responsible for implementing a platform-specific mechanism +to handle the condition where the CPU has been warm reset but there is no +entrypoint to jump to. + +This function does not follow the Procedure Call Standard used by the +Application Binary Interface for the ARM 64-bit architecture. The caller should +not assume that callee saved registers are preserved across a call to this +function. + +This function fulfills requirement 1 and 3 listed above. + + +### Function : plat_secondary_cold_boot_setup() [mandatory] + + Argument : void + Return : void + +This function is called with the MMU and data caches disabled. It is responsible +for placing the executing secondary CPU in a platform-specific state until the +primary CPU performs the necessary actions to bring it out of that state and +allow entry into the OS. + +In the ARM FVP port, each secondary CPU powers itself off. The primary CPU is +responsible for powering up the secondary CPU when normal world software +requires them. + +This function fulfills requirement 2 above. + + +### Function : platform_mem_init() [mandatory] + + Argument : void + Return : void + +This function is called before any access to data is made by the firmware, in +order to carry out any essential memory initialization. + +The ARM FVP port uses this function to initialize the mailbox memory used for +providing the warm-boot entry-point addresses. + + + +2.3 Common optional modifications +--------------------------------- + +The following are helper functions implemented by the firmware that perform +common platform-specific tasks. A platform may choose to override these +definitions. + + +### Function : platform_get_core_pos() + + Argument : unsigned long + Return : int + +A platform may need to convert the `MPIDR` of a CPU to an absolute number, which +can be used as a CPU-specific linear index into blocks of memory (for example +while allocating per-CPU stacks). This routine contains a simple mechanism +to perform this conversion, using the assumption that each cluster contains a +maximum of 4 CPUs: + + linear index = cpu_id + (cluster_id * 4) + + cpu_id = 8-bit value in MPIDR at affinity level 0 + cluster_id = 8-bit value in MPIDR at affinity level 1 + + +### Function : platform_set_coherent_stack() + + Argument : unsigned long + Return : void + +A platform may need stack memory that is coherent with main memory to perform +certain operations like: + +* Turning the MMU on, or +* Flushing caches prior to powering down a CPU or cluster. + +Each BL stage allocates this coherent stack memory for each CPU in the +`tzfw_coherent_mem` section. + +This function sets the current stack pointer to the coherent stack that +has been allocated for the CPU specified by MPIDR. For BL images that only +require a stack for the primary CPU the parameter is ignored. The size of +the stack allocated to each CPU is specified by the platform defined constant +`PCPU_DV_MEM_STACK_SIZE`. + +Common implementations of this function for the UP and MP BL images are +provided in [plat/common/aarch64/platform_up_stack.S] and +[plat/common/aarch64/platform_mp_stack.S] + + +### Function : platform_is_primary_cpu() + + Argument : unsigned long + Return : unsigned int + +This function identifies a CPU by its `MPIDR`, which is passed as the argument, +to determine whether this CPU is the primary CPU or a secondary CPU. A return +value of zero indicates that the CPU is not the primary CPU, while a non-zero +return value indicates that the CPU is the primary CPU. + + +### Function : platform_set_stack() + + Argument : unsigned long + Return : void + +This function sets the current stack pointer to the normal memory stack that +has been allocated for the CPU specificed by MPIDR. For BL images that only +require a stack for the primary CPU the parameter is ignored. The size of +the stack allocated to each CPU is specified by the platform defined constant +`PLATFORM_STACK_SIZE`. + +Common implementations of this function for the UP and MP BL images are +provided in [plat/common/aarch64/platform_up_stack.S] and +[plat/common/aarch64/platform_mp_stack.S] + + +### Function : platform_get_stack() + + Argument : unsigned long + Return : unsigned long + +This function returns the base address of the normal memory stack that +has been allocated for the CPU specificed by MPIDR. For BL images that only +require a stack for the primary CPU the parameter is ignored. The size of +the stack allocated to each CPU is specified by the platform defined constant +`PLATFORM_STACK_SIZE`. + +Common implementations of this function for the UP and MP BL images are +provided in [plat/common/aarch64/platform_up_stack.S] and +[plat/common/aarch64/platform_mp_stack.S] + + +### Function : plat_report_exception() + + Argument : unsigned int + Return : void + +A platform may need to report various information about its status when an +exception is taken, for example the current exception level, the CPU security +state (secure/non-secure), the exception type, and so on. This function is +called in the following circumstances: + +* In BL1, whenever an exception is taken. +* In BL2, whenever an exception is taken. + +The default implementation doesn't do anything, to avoid making assumptions +about the way the platform displays its status information. + +This function receives the exception type as its argument. Possible values for +exceptions types are listed in the [include/runtime_svc.h] header file. Note +that these constants are not related to any architectural exception code; they +are just an ARM Trusted Firmware convention. + + +3. Modifications specific to a Boot Loader stage +------------------------------------------------- + +3.1 Boot Loader Stage 1 (BL1) +----------------------------- + +BL1 implements the reset vector where execution starts from after a cold or +warm boot. For each CPU, BL1 is responsible for the following tasks: + +1. Handling the reset as described in section 2.2 + +2. In the case of a cold boot and the CPU being the primary CPU, ensuring that + only this CPU executes the remaining BL1 code, including loading and passing + control to the BL2 stage. + +3. Loading the BL2 image from non-volatile storage into secure memory at the + address specified by the platform defined constant `BL2_BASE`. + +4. Populating a `meminfo` structure with the following information in memory, + accessible by BL2 immediately upon entry. + + meminfo.total_base = Base address of secure RAM visible to BL2 + meminfo.total_size = Size of secure RAM visible to BL2 + meminfo.free_base = Base address of secure RAM available for + allocation to BL2 + meminfo.free_size = Size of secure RAM available for allocation to BL2 + + BL1 places this `meminfo` structure at the beginning of the free memory + available for its use. Since BL1 cannot allocate memory dynamically at the + moment, its free memory will be available for BL2's use as-is. However, this + means that BL2 must read the `meminfo` structure before it starts using its + free memory (this is discussed in Section 3.2). + + In future releases of the ARM Trusted Firmware it will be possible for + the platform to decide where it wants to place the `meminfo` structure for + BL2. + + BL1 implements the `init_bl2_mem_layout()` function to populate the + BL2 `meminfo` structure. The platform may override this implementation, for + example if the platform wants to restrict the amount of memory visible to + BL2. Details of how to do this are given below. + +The following functions need to be implemented by the platform port to enable +BL1 to perform the above tasks. + + +### Function : bl1_plat_arch_setup() [mandatory] + + Argument : void + Return : void + +This function performs any platform-specific and architectural setup that the +platform requires. Platform-specific setup might include configuration of +memory controllers, configuration of the interconnect to allow the cluster +to service cache snoop requests from another cluster, and so on. + +In the ARM FVP port, this function enables CCI snoops into the cluster that the +primary CPU is part of. It also enables the MMU. + +This function helps fulfill requirement 2 above. + + +### Function : bl1_platform_setup() [mandatory] + + Argument : void + Return : void + +This function executes with the MMU and data caches enabled. It is responsible +for performing any remaining platform-specific setup that can occur after the +MMU and data cache have been enabled. + +This function is also responsible for initializing the storage abstraction layer +which is used to load further bootloader images. + +This function helps fulfill requirement 3 above. + + +### Function : bl1_plat_sec_mem_layout() [mandatory] + + Argument : void + Return : meminfo * + +This function should only be called on the cold boot path. It executes with the +MMU and data caches enabled. The pointer returned by this function must point to +a `meminfo` structure containing the extents and availability of secure RAM for +the BL1 stage. + + meminfo.total_base = Base address of secure RAM visible to BL1 + meminfo.total_size = Size of secure RAM visible to BL1 + meminfo.free_base = Base address of secure RAM available for allocation + to BL1 + meminfo.free_size = Size of secure RAM available for allocation to BL1 + +This information is used by BL1 to load the BL2 image in secure RAM. BL1 also +populates a similar structure to tell BL2 the extents of memory available for +its own use. + +This function helps fulfill requirement 3 above. + + +### Function : init_bl2_mem_layout() [optional] + + Argument : meminfo *, meminfo *, unsigned int, unsigned long + Return : void + +BL1 needs to tell the next stage the amount of secure RAM available +for it to use. This information is populated in a `meminfo` +structure. + +Depending upon where BL2 has been loaded in secure RAM (determined by +`BL2_BASE`), BL1 calculates the amount of free memory available for BL2 to use. +BL1 also ensures that its data sections resident in secure RAM are not visible +to BL2. An illustration of how this is done in the ARM FVP port is given in the +[User Guide], in the Section "Memory layout on Base FVP". + + +### Function : bl1_plat_set_bl2_ep_info() [mandatory] + + Argument : image_info *, entry_point_info * + Return : void + +This function is called after loading BL2 image and it can be used to overwrite +the entry point set by loader and also set the security state and SPSR which +represents the entry point system state for BL2. + +On FVP, we are setting the security state and the SPSR for the BL2 entrypoint + + +3.2 Boot Loader Stage 2 (BL2) +----------------------------- + +The BL2 stage is executed only by the primary CPU, which is determined in BL1 +using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at +`BL2_BASE`. BL2 executes in Secure EL1 and is responsible for: + +1. Loading the BL3-1 binary image into secure RAM from non-volatile storage. To + load the BL3-1 image, BL2 makes use of the `meminfo` structure passed to it + by BL1. This structure allows BL2 to calculate how much secure RAM is + available for its use. The platform also defines the address in secure RAM + where BL3-1 is loaded through the constant `BL31_BASE`. BL2 uses this + information to determine if there is enough memory to load the BL3-1 image. + +2. Loading the normal world BL3-3 binary image into non-secure DRAM from + platform storage and arranging for BL3-1 to pass control to this image. This + address is determined using the `plat_get_ns_image_entrypoint()` function + described below. + +3. BL2 populates an `entry_point_info` structure in memory provided by the + platform with information about how BL3-1 should pass control to the + other BL images. + +4. (Optional) Loading the BL3-2 binary image (if present) from platform + provided non-volatile storage. To load the BL3-2 image, BL2 makes use of + the `meminfo` returned by the `bl2_plat_get_bl32_meminfo()` function. + The platform also defines the address in memory where BL3-2 is loaded + through the optional constant `BL32_BASE`. BL2 uses this information + to determine if there is enough memory to load the BL3-2 image. + If `BL32_BASE` is not defined then this and the next step is not performed. + +5. (Optional) Arranging to pass control to the BL3-2 image (if present) that + has been pre-loaded at `BL32_BASE`. BL2 populates an `entry_point_info` + structure in memory provided by the platform with information about how + BL3-1 should pass control to the BL3-2 image. + +The following functions must be implemented by the platform port to enable BL2 +to perform the above tasks. + + +### Function : bl2_early_platform_setup() [mandatory] + + Argument : meminfo * + Return : void + +This function executes with the MMU and data caches disabled. It is only called +by the primary CPU. The arguments to this function is the address of the +`meminfo` structure populated by BL1. + +The platform must copy the contents of the `meminfo` structure into a private +variable as the original memory may be subsequently overwritten by BL2. The +copied structure is made available to all BL2 code through the +`bl2_plat_sec_mem_layout()` function. + + +### Function : bl2_plat_arch_setup() [mandatory] + + Argument : void + Return : void + +This function executes with the MMU and data caches disabled. It is only called +by the primary CPU. + +The purpose of this function is to perform any architectural initialization +that varies across platforms, for example enabling the MMU (since the memory +map differs across platforms). + + +### Function : bl2_platform_setup() [mandatory] + + Argument : void + Return : void + +This function may execute with the MMU and data caches enabled if the platform +port does the necessary initialization in `bl2_plat_arch_setup()`. It is only +called by the primary CPU. + +The purpose of this function is to perform any platform initialization +specific to BL2. Platform security components are configured if required. +For the Base FVP the TZC-400 TrustZone controller is configured to only +grant non-secure access to DRAM. This avoids aliasing between secure and +non-secure accesses in the TLB and cache - secure execution states can use +the NS attributes in the MMU translation tables to access the DRAM. + +This function is also responsible for initializing the storage abstraction layer +which is used to load further bootloader images. + + +### Function : bl2_plat_sec_mem_layout() [mandatory] + + Argument : void + Return : meminfo * + +This function should only be called on the cold boot path. It may execute with +the MMU and data caches enabled if the platform port does the necessary +initialization in `bl2_plat_arch_setup()`. It is only called by the primary CPU. + +The purpose of this function is to return a pointer to a `meminfo` structure +populated with the extents of secure RAM available for BL2 to use. See +`bl2_early_platform_setup()` above. + + +### Function : bl2_plat_get_bl31_params() [mandatory] + + Argument : void + Return : bl31_params * + +BL2 platform code needs to return a pointer to a `bl31_params` structure it +will use for passing information to BL3-1. The `bl31_params` structure carries +the following information. + - Header describing the version information for interpreting the bl31_param + structure + - Information about executing the BL3-3 image in the `bl33_ep_info` field + - Information about executing the BL3-2 image in the `bl32_ep_info` field + - Information about the type and extents of BL3-1 image in the + `bl31_image_info` field + - Information about the type and extents of BL3-2 image in the + `bl32_image_info` field + - Information about the type and extents of BL3-3 image in the + `bl33_image_info` field + +The memory pointed by this structure and its sub-structures should be +accessible from BL3-1 initialisation code. BL3-1 might choose to copy the +necessary content, or maintain the structures until BL3-3 is initialised. + + +### Funtion : bl2_plat_get_bl31_ep_info() [mandatory] + + Argument : void + Return : entry_point_info * + +BL2 platform code returns a pointer which is used to populate the entry point +information for BL3-1 entry point. The location pointed by it should be +accessible from BL1 while processing the synchronous exception to run to BL3-1. + +On FVP this is allocated inside an bl2_to_bl31_params_mem structure which +is allocated at an address pointed by PARAMS_BASE. + + +### Function : bl2_plat_set_bl31_ep_info() [mandatory] + + Argument : image_info *, entry_point_info * + Return : void + +This function is called after loading BL3-1 image and it can be used to +overwrite the entry point set by loader and also set the security state +and SPSR which represents the entry point system state for BL3-1. + +On FVP, we are setting the security state and the SPSR for the BL3-1 +entrypoint. + +### Function : bl2_plat_set_bl32_ep_info() [mandatory] + + Argument : image_info *, entry_point_info * + Return : void + +This function is called after loading BL3-2 image and it can be used to +overwrite the entry point set by loader and also set the security state +and SPSR which represents the entry point system state for BL3-2. + +On FVP, we are setting the security state and the SPSR for the BL3-2 +entrypoint + +### Function : bl2_plat_set_bl33_ep_info() [mandatory] + + Argument : image_info *, entry_point_info * + Return : void + +This function is called after loading BL3-3 image and it can be used to +overwrite the entry point set by loader and also set the security state +and SPSR which represents the entry point system state for BL3-3. + +On FVP, we are setting the security state and the SPSR for the BL3-3 +entrypoint + +### Function : bl2_plat_get_bl32_meminfo() [mandatory] + + Argument : meminfo * + Return : void + +This function is used to get the memory limits where BL2 can load the +BL3-2 image. The meminfo provided by this is used by load_image() to +validate whether the BL3-2 image can be loaded with in the given +memory from the given base. + +### Function : bl2_plat_get_bl33_meminfo() [mandatory] + + Argument : meminfo * + Return : void + +This function is used to get the memory limits where BL2 can load the +BL3-3 image. The meminfo provided by this is used by load_image() to +validate whether the BL3-3 image can be loaded with in the given +memory from the given base. + +### Function : bl2_plat_flush_bl31_params() [mandatory] + + Argument : void + Return : void + +Once BL2 has populated all the structures that needs to be read by BL1 +and BL3-1 including the bl31_params structures and its sub-structures, +the bl31_ep_info structure and any platform specific data. It flushes +all these data to the main memory so that it is available when we jump to +later Bootloader stages with MMU off + +### Function : plat_get_ns_image_entrypoint() [mandatory] + + Argument : void + Return : unsigned long + +As previously described, BL2 is responsible for arranging for control to be +passed to a normal world BL image through BL3-1. This function returns the +entrypoint of that image, which BL3-1 uses to jump to it. + +BL2 is responsible for loading the normal world BL3-3 image (e.g. UEFI). + + +3.2 Boot Loader Stage 3-1 (BL3-1) +--------------------------------- + +During cold boot, the BL3-1 stage is executed only by the primary CPU. This is +determined in BL1 using the `platform_is_primary_cpu()` function. BL1 passes +control to BL3-1 at `BL31_BASE`. During warm boot, BL3-1 is executed by all +CPUs. BL3-1 executes at EL3 and is responsible for: + +1. Re-initializing all architectural and platform state. Although BL1 performs + some of this initialization, BL3-1 remains resident in EL3 and must ensure + that EL3 architectural and platform state is completely initialized. It + should make no assumptions about the system state when it receives control. + +2. Passing control to a normal world BL image, pre-loaded at a platform- + specific address by BL2. BL3-1 uses the `entry_point_info` structure that BL2 + populated in memory to do this. + +3. Providing runtime firmware services. Currently, BL3-1 only implements a + subset of the Power State Coordination Interface (PSCI) API as a runtime + service. See Section 3.3 below for details of porting the PSCI + implementation. + +4. Optionally passing control to the BL3-2 image, pre-loaded at a platform- + specific address by BL2. BL3-1 exports a set of apis that allow runtime + services to specify the security state in which the next image should be + executed and run the corresponding image. BL3-1 uses the `entry_point_info` + structure populated by BL2 to do this. + +If BL3-1 is a reset vector, It also needs to handle the reset as specified in +section 2.2 before the tasks described above. + +The following functions must be implemented by the platform port to enable BL3-1 +to perform the above tasks. + + +### Function : bl31_early_platform_setup() [mandatory] + + Argument : bl31_params *, void * + Return : void + +This function executes with the MMU and data caches disabled. It is only called +by the primary CPU. The arguments to this function are: + +* The address of the `bl31_params` structure populated by BL2. +* An opaque pointer that the platform may use as needed. + +The platform can copy the contents of the `bl31_params` structure and its +sub-structures into private variables if the original memory may be +subsequently overwritten by BL3-1 and similarly the `void *` pointing +to the platform data also needs to be saved. + +On the ARM FVP port, BL2 passes a pointer to a `bl31_params` structure populated +in the secure DRAM at address `0x6000000` in the bl31_params * argument and it +does not use opaque pointer mentioned earlier. BL3-1 does not copy this +information to internal data structures as it guarantees that the secure +DRAM memory will not be overwritten. It maintains an internal reference to this +information in the `bl2_to_bl31_params` variable. + +### Function : bl31_plat_arch_setup() [mandatory] + + Argument : void + Return : void + +This function executes with the MMU and data caches disabled. It is only called +by the primary CPU. + +The purpose of this function is to perform any architectural initialization +that varies across platforms, for example enabling the MMU (since the memory +map differs across platforms). + + +### Function : bl31_platform_setup() [mandatory] + + Argument : void + Return : void + +This function may execute with the MMU and data caches enabled if the platform +port does the necessary initialization in `bl31_plat_arch_setup()`. It is only +called by the primary CPU. + +The purpose of this function is to complete platform initialization so that both +BL3-1 runtime services and normal world software can function correctly. + +The ARM FVP port does the following: +* Initializes the generic interrupt controller. +* Configures the CLCD controller. +* Enables system-level implementation of the generic timer counter. +* Grants access to the system counter timer module +* Initializes the FVP power controller device +* Detects the system topology. + + +### Function : bl31_get_next_image_info() [mandatory] + + Argument : unsigned int + Return : entry_point_info * + +This function may execute with the MMU and data caches enabled if the platform +port does the necessary initializations in `bl31_plat_arch_setup()`. + +This function is called by `bl31_main()` to retrieve information provided by +BL2 for the next image in the security state specified by the argument. BL3-1 +uses this information to pass control to that image in the specified security +state. This function must return a pointer to the `entry_point_info` structure +(that was copied during `bl31_early_platform_setup()`) if the image exists. It +should return NULL otherwise. + + +3.3 Power State Coordination Interface (in BL3-1) +------------------------------------------------ + +The ARM Trusted Firmware's implementation of the PSCI API is based around the +concept of an _affinity instance_. Each _affinity instance_ can be uniquely +identified in a system by a CPU ID (the processor `MPIDR` is used in the PSCI +interface) and an _affinity level_. A processing element (for example, a +CPU) is at level 0. If the CPUs in the system are described in a tree where the +node above a CPU is a logical grouping of CPUs that share some state, then +affinity level 1 is that group of CPUs (for example, a cluster), and affinity +level 2 is a group of clusters (for example, the system). The implementation +assumes that the affinity level 1 ID can be computed from the affinity level 0 +ID (for example, a unique cluster ID can be computed from the CPU ID). The +current implementation computes this on the basis of the recommended use of +`MPIDR` affinity fields in the ARM Architecture Reference Manual. + +BL3-1's platform initialization code exports a pointer to the platform-specific +power management operations required for the PSCI implementation to function +correctly. This information is populated in the `plat_pm_ops` structure. The +PSCI implementation calls members of the `plat_pm_ops` structure for performing +power management operations for each affinity instance. For example, the target +CPU is specified by its `MPIDR` in a PSCI `CPU_ON` call. The `affinst_on()` +handler (if present) is called for each affinity instance as the PSCI +implementation powers up each affinity level implemented in the `MPIDR` (for +example, CPU, cluster and system). + +The following functions must be implemented to initialize PSCI functionality in +the ARM Trusted Firmware. + + +### Function : plat_get_aff_count() [mandatory] + + Argument : unsigned int, unsigned long + Return : unsigned int + +This function may execute with the MMU and data caches enabled if the platform +port does the necessary initializations in `bl31_plat_arch_setup()`. It is only +called by the primary CPU. + +This function is called by the PSCI initialization code to detect the system +topology. Its purpose is to return the number of affinity instances implemented +at a given `affinity level` (specified by the first argument) and a given +`MPIDR` (specified by the second argument). For example, on a dual-cluster +system where first cluster implements 2 CPUs and the second cluster implements 4 +CPUs, a call to this function with an `MPIDR` corresponding to the first cluster +(`0x0`) and affinity level 0, would return 2. A call to this function with an +`MPIDR` corresponding to the second cluster (`0x100`) and affinity level 0, +would return 4. + + +### Function : plat_get_aff_state() [mandatory] + + Argument : unsigned int, unsigned long + Return : unsigned int + +This function may execute with the MMU and data caches enabled if the platform +port does the necessary initializations in `bl31_plat_arch_setup()`. It is only +called by the primary CPU. + +This function is called by the PSCI initialization code. Its purpose is to +return the state of an affinity instance. The affinity instance is determined by +the affinity ID at a given `affinity level` (specified by the first argument) +and an `MPIDR` (specified by the second argument). The state can be one of +`PSCI_AFF_PRESENT` or `PSCI_AFF_ABSENT`. The latter state is used to cater for +system topologies where certain affinity instances are unimplemented. For +example, consider a platform that implements a single cluster with 4 CPUs and +another CPU implemented directly on the interconnect with the cluster. The +`MPIDR`s of the cluster would range from `0x0-0x3`. The `MPIDR` of the single +CPU would be 0x100 to indicate that it does not belong to cluster 0. Cluster 1 +is missing but needs to be accounted for to reach this single CPU in the +topology tree. Hence it is marked as `PSCI_AFF_ABSENT`. + + +### Function : plat_get_max_afflvl() [mandatory] + + Argument : void + Return : int + +This function may execute with the MMU and data caches enabled if the platform +port does the necessary initializations in `bl31_plat_arch_setup()`. It is only +called by the primary CPU. + +This function is called by the PSCI implementation both during cold and warm +boot, to determine the maximum affinity level that the power management +operations should apply to. ARMv8-A has support for 4 affinity levels. It is +likely that hardware will implement fewer affinity levels. This function allows +the PSCI implementation to consider only those affinity levels in the system +that the platform implements. For example, the Base AEM FVP implements two +clusters with a configurable number of CPUs. It reports the maximum affinity +level as 1, resulting in PSCI power control up to the cluster level. + + +### Function : platform_setup_pm() [mandatory] + + Argument : plat_pm_ops ** + Return : int + +This function may execute with the MMU and data caches enabled if the platform +port does the necessary initializations in `bl31_plat_arch_setup()`. It is only +called by the primary CPU. + +This function is called by PSCI initialization code. Its purpose is to export +handler routines for platform-specific power management actions by populating +the passed pointer with a pointer to BL3-1's private `plat_pm_ops` structure. + +A description of each member of this structure is given below. Please refer to +the ARM FVP specific implementation of these handlers in [plat/fvp/plat_pm.c] +as an example. A platform port may choose not implement some of the power +management operations. For example, the ARM FVP port does not implement the +`affinst_standby()` function. + +#### plat_pm_ops.affinst_standby() + +Perform the platform-specific setup to enter the standby state indicated by the +passed argument. + +#### plat_pm_ops.affinst_on() + +Perform the platform specific setup to power on an affinity instance, specified +by the `MPIDR` (first argument) and `affinity level` (fourth argument). The +`state` (fifth argument) contains the current state of that affinity instance +(ON or OFF). This is useful to determine whether any action must be taken. For +example, while powering on a CPU, the cluster that contains this CPU might +already be in the ON state. The platform decides what actions must be taken to +transition from the current state to the target state (indicated by the power +management operation). + +#### plat_pm_ops.affinst_off() + +Perform the platform specific setup to power off an affinity instance in the +`MPIDR` of the calling CPU. It is called by the PSCI `CPU_OFF` API +implementation. + +The `MPIDR` (first argument), `affinity level` (second argument) and `state` +(third argument) have a similar meaning as described in the `affinst_on()` +operation. They are used to identify the affinity instance on which the call +is made and its current state. This gives the platform port an indication of the +state transition it must make to perform the requested action. For example, if +the calling CPU is the last powered on CPU in the cluster, after powering down +affinity level 0 (CPU), the platform port should power down affinity level 1 +(the cluster) as well. + +This function is called with coherent stacks. This allows the PSCI +implementation to flush caches at a given affinity level without running into +stale stack state after turning off the caches. On ARMv8-A cache hits do not +occur after the cache has been turned off. + +#### plat_pm_ops.affinst_suspend() + +Perform the platform specific setup to power off an affinity instance in the +`MPIDR` of the calling CPU. It is called by the PSCI `CPU_SUSPEND` API +implementation. + +The `MPIDR` (first argument), `affinity level` (third argument) and `state` +(fifth argument) have a similar meaning as described in the `affinst_on()` +operation. They are used to identify the affinity instance on which the call +is made and its current state. This gives the platform port an indication of the +state transition it must make to perform the requested action. For example, if +the calling CPU is the last powered on CPU in the cluster, after powering down +affinity level 0 (CPU), the platform port should power down affinity level 1 +(the cluster) as well. + +The difference between turning an affinity instance off versus suspending it +is that in the former case, the affinity instance is expected to re-initialize +its state when its next powered on (see `affinst_on_finish()`). In the latter +case, the affinity instance is expected to save enough state so that it can +resume execution by restoring this state when its powered on (see +`affinst_suspend_finish()`). + +This function is called with coherent stacks. This allows the PSCI +implementation to flush caches at a given affinity level without running into +stale stack state after turning off the caches. On ARMv8-A cache hits do not +occur after the cache has been turned off. + +#### plat_pm_ops.affinst_on_finish() + +This function is called by the PSCI implementation after the calling CPU is +powered on and released from reset in response to an earlier PSCI `CPU_ON` call. +It performs the platform-specific setup required to initialize enough state for +this CPU to enter the normal world and also provide secure runtime firmware +services. + +The `MPIDR` (first argument), `affinity level` (second argument) and `state` +(third argument) have a similar meaning as described in the previous operations. + +This function is called with coherent stacks. This allows the PSCI +implementation to flush caches at a given affinity level without running into +stale stack state after turning off the caches. On ARMv8-A cache hits do not +occur after the cache has been turned off. + +#### plat_pm_ops.affinst_on_suspend() + +This function is called by the PSCI implementation after the calling CPU is +powered on and released from reset in response to an asynchronous wakeup +event, for example a timer interrupt that was programmed by the CPU during the +`CPU_SUSPEND` call. It performs the platform-specific setup required to +restore the saved state for this CPU to resume execution in the normal world +and also provide secure runtime firmware services. + +The `MPIDR` (first argument), `affinity level` (second argument) and `state` +(third argument) have a similar meaning as described in the previous operations. + +This function is called with coherent stacks. This allows the PSCI +implementation to flush caches at a given affinity level without running into +stale stack state after turning off the caches. On ARMv8-A cache hits do not +occur after the cache has been turned off. + +BL3-1 platform initialization code must also detect the system topology and +the state of each affinity instance in the topology. This information is +critical for the PSCI runtime service to function correctly. More details are +provided in the description of the `plat_get_aff_count()` and +`plat_get_aff_state()` functions above. + +3.4 Interrupt Management framework (in BL3-1) +---------------------------------------------- +BL3-1 implements an Interrupt Management Framework (IMF) to manage interrupts +generated in either security state and targeted to EL1 or EL2 in the non-secure +state or EL3/S-EL1 in the secure state. The design of this framework is +described in the [IMF Design Guide] + +A platform should export the following APIs to support the IMF. The following +text briefly describes each api and its implementation on the FVP port. The API +implementation depends upon the type of interrupt controller present in the +platform. The FVP implements an ARM Generic Interrupt Controller (ARM GIC) as +per the version 2.0 of the [ARM GIC Architecture Specification] + +### Function : plat_interrupt_type_to_line() [mandatory] + + Argument : uint32_t, uint32_t + Return : uint32_t + +The ARM processor signals an interrupt exception either through the IRQ or FIQ +interrupt line. The specific line that is signaled depends on how the interrupt +controller (IC) reports different interrupt types from an execution context in +either security state. The IMF uses this API to determine which interrupt line +the platform IC uses to signal each type of interrupt supported by the framework +from a given security state. + +The first parameter will be one of the `INTR_TYPE_*` values (see [IMF Design +Guide]) indicating the target type of the interrupt, the second parameter is the +security state of the originating execution context. The return result is the +bit position in the `SCR_EL3` register of the respective interrupt trap: IRQ=1, +FIQ=2. + +The FVP port configures the ARM GIC to signal S-EL1 interrupts as FIQs and +Non-secure interrupts as IRQs from either security state. + + +### Function : plat_ic_get_pending_interrupt_type() [mandatory] + + Argument : void + Return : uint32_t + +This API returns the type of the highest priority pending interrupt at the +platform IC. The IMF uses the interrupt type to retrieve the corresponding +handler function. `INTR_TYPE_INVAL` is returned when there is no interrupt +pending. The valid interrupt types that can be returned are `INTR_TYPE_EL3`, +`INTR_TYPE_S_EL1` and `INTR_TYPE_NS`. + +The FVP port reads the _Highest Priority Pending Interrupt Register_ +(`GICC_HPPIR`) to determine the id of the pending interrupt. The type of interrupt +depends upon the id value as follows. + +1. id < 1022 is reported as a S-EL1 interrupt +2. id = 1022 is reported as a Non-secure interrupt. +3. id = 1023 is reported as an invalid interrupt type. + + +### Function : plat_ic_get_pending_interrupt_id() [mandatory] + + Argument : void + Return : uint32_t + +This API returns the id of the highest priority pending interrupt at the +platform IC. The IMF passes the id returned by this API to the registered +handler for the pending interrupt if the `IMF_READ_INTERRUPT_ID` build time flag +is set. INTR_ID_UNAVAILABLE is returned when there is no interrupt pending. + +The FVP port reads the _Highest Priority Pending Interrupt Register_ +(`GICC_HPPIR`) to determine the id of the pending interrupt. The id that is +returned by API depends upon the value of the id read from the interrupt +controller as follows. + +1. id < 1022. id is returned as is. +2. id = 1022. The _Aliased Highest Priority Pending Interrupt Register_ + (`GICC_AHPPIR`) is read to determine the id of the non-secure interrupt. This + id is returned by the API. +3. id = 1023. `INTR_ID_UNAVAILABLE` is returned. + + +### Function : plat_ic_acknowledge_interrupt() [mandatory] + + Argument : void + Return : uint32_t + +This API is used by the CPU to indicate to the platform IC that processing of +the highest pending interrupt has begun. It should return the id of the +interrupt which is being processed. + +The FVP port reads the _Interrupt Acknowledge Register_ (`GICC_IAR`). This +changes the state of the highest priority pending interrupt from pending to +active in the interrupt controller. It returns the value read from the +`GICC_IAR`. This value is the id of the interrupt whose state has been changed. + +The TSP uses this API to start processing of the secure physical timer +interrupt. + + +### Function : plat_ic_end_of_interrupt() [mandatory] + + Argument : uint32_t + Return : void + +This API is used by the CPU to indicate to the platform IC that processing of +the interrupt corresponding to the id (passed as the parameter) has +finished. The id should be the same as the id returned by the +`plat_ic_acknowledge_interrupt()` API. + +The FVP port writes the id to the _End of Interrupt Register_ +(`GICC_EOIR`). This deactivates the corresponding interrupt in the interrupt +controller. + +The TSP uses this API to finish processing of the secure physical timer +interrupt. + + +### Function : plat_ic_get_interrupt_type() [mandatory] + + Argument : uint32_t + Return : uint32_t + +This API returns the type of the interrupt id passed as the parameter. +`INTR_TYPE_INVAL` is returned if the id is invalid. If the id is valid, a valid +interrupt type (one of `INTR_TYPE_EL3`, `INTR_TYPE_S_EL1` and `INTR_TYPE_NS`) is +returned depending upon how the interrupt has been configured by the platform +IC. + +The FVP port configures S-EL1 interrupts as Group0 interrupts and Non-secure +interrupts as Group1 interrupts. It reads the group value corresponding to the +interrupt id from the relevant _Interrupt Group Register_ (`GICD_IGROUPRn`). It +uses the group value to determine the type of interrupt. + + +4. C Library +------------- + +To avoid subtle toolchain behavioral dependencies, the header files provided +by the compiler are not used. The software is built with the `-nostdinc` flag +to ensure no headers are included from the toolchain inadvertently. Instead the +required headers are included in the ARM Trusted Firmware source tree. The +library only contains those C library definitions required by the local +implementation. If more functionality is required, the needed library functions +will need to be added to the local implementation. + +Versions of [FreeBSD] headers can be found in `include/stdlib`. Some of these +headers have been cut down in order to simplify the implementation. In order to +minimize changes to the header files, the [FreeBSD] layout has been maintained. +The generic C library definitions can be found in `include/stdlib` with more +system and machine specific declarations in `include/stdlib/sys` and +`include/stdlib/machine`. + +The local C library implementations can be found in `lib/stdlib`. In order to +extend the C library these files may need to be modified. It is recommended to +use a release version of [FreeBSD] as a starting point. + +The C library header files in the [FreeBSD] source tree are located in the +`include` and `sys/sys` directories. [FreeBSD] machine specific definitions +can be found in the `sys/<machine-type>` directories. These files define things +like 'the size of a pointer' and 'the range of an integer'. Since an AArch64 +port for [FreeBSD] does not yet exist, the machine specific definitions are +based on existing machine types with similar properties (for example SPARC64). + +Where possible, C library function implementations were taken from [FreeBSD] +as found in the `lib/libc` directory. + +A copy of the [FreeBSD] sources can be downloaded with `git`. + + git clone git://github.com/freebsd/freebsd.git -b origin/release/9.2.0 + + +5. Storage abstraction layer +----------------------------- + +In order to improve platform independence and portability an storage abstraction +layer is used to load data from non-volatile platform storage. + +Each platform should register devices and their drivers via the Storage layer. +These drivers then need to be initialized by bootloader phases as +required in their respective `blx_platform_setup()` functions. Currently +storage access is only required by BL1 and BL2 phases. The `load_image()` +function uses the storage layer to access non-volatile platform storage. + +It is mandatory to implement at least one storage driver. For the FVP the +Firmware Image Package(FIP) driver is provided as the default means to load data +from storage (see the "Firmware Image Package" section in the [User Guide]). +The storage layer is described in the header file `include/io_storage.h`. The +implementation of the common library is in `lib/io_storage.c` and the driver +files are located in `drivers/io/`. + +Each IO driver must provide `io_dev_*` structures, as described in +`drivers/io/io_driver.h`. These are returned via a mandatory registration +function that is called on platform initialization. The semi-hosting driver +implementation in `io_semihosting.c` can be used as an example. + +The Storage layer provides mechanisms to initialize storage devices before +IO operations are called. The basic operations supported by the layer +include `open()`, `close()`, `read()`, `write()`, `size()` and `seek()`. +Drivers do not have to implement all operations, but each platform must +provide at least one driver for a device capable of supporting generic +operations such as loading a bootloader image. + +The current implementation only allows for known images to be loaded by the +firmware. These images are specified by using their names, as defined in +[include/plat/common/platform.h]. The platform layer (`plat_get_image_source()`) +then returns a reference to a device and a driver-specific `spec` which will be +understood by the driver to allow access to the image data. + +The layer is designed in such a way that is it possible to chain drivers with +other drivers. For example, file-system drivers may be implemented on top of +physical block devices, both represented by IO devices with corresponding +drivers. In such a case, the file-system "binding" with the block device may +be deferred until the file-system device is initialised. + +The abstraction currently depends on structures being statically allocated +by the drivers and callers, as the system does not yet provide a means of +dynamically allocating memory. This may also have the affect of limiting the +amount of open resources per driver. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - + +_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._ + + +[ARM GIC Architecture Specification]: http://arminfo.emea.arm.com/help/topic/com.arm.doc.ihi0048b/IHI0048B_gic_architecture_specification.pdf +[IMF Design Guide]: interrupt-framework-design.md +[User Guide]: user-guide.md +[FreeBSD]: http://www.freebsd.org + +[plat/common/aarch64/platform_mp_stack.S]: ../plat/common/aarch64/platform_mp_stack.S +[plat/common/aarch64/platform_up_stack.S]: ../plat/common/aarch64/platform_up_stack.S +[plat/fvp/include/platform_def.h]: ../plat/fvp/include/platform_def.h +[plat/fvp/include/plat_macros.S]: ../plat/fvp/include/plat_macros.S +[plat/fvp/aarch64/plat_common.c]: ../plat/fvp/aarch64/plat_common.c +[plat/fvp/plat_pm.c]: ../plat/fvp/plat_pm.c +[include/runtime_svc.h]: ../include/runtime_svc.h +[include/plat/common/platform.h]: ../include/plat/common/platform.h diff --git a/docs/rt-svc-writers-guide.md b/docs/rt-svc-writers-guide.md new file mode 100644 index 0000000..2d13f74 --- /dev/null +++ b/docs/rt-svc-writers-guide.md @@ -0,0 +1,309 @@ +EL3 Runtime Service Writers Guide for ARM Trusted Firmware +========================================================== + +Contents +-------- + +1. Introduction +2. Owning Entities, Call Types and Function IDs +3. Getting started +4. Registering a runtime service +5. Initializing a runtime service +6. Handling runtime service requests +7. Services that contain multiple sub-services +8. Secure-EL1 Payload Dispatcher service (SPD) + +- - - - - - - - - - - - - - - - - - + +1. Introduction +---------------- + +This document describes how to add a runtime service to the EL3 Runtime +Firmware component of ARM Trusted Firmware (BL3-1). + +Software executing in the normal world and in the trusted world at exception +levels lower than EL3 will request runtime services using the Secure Monitor +Call (SMC) instruction. These requests will follow the convention described in +the SMC Calling Convention PDD ([SMCCC]). The [SMCCC] assigns function +identifiers to each SMC request and describes how arguments are passed and +results are returned. + +SMC Functions are grouped together based on the implementor of the service, for +example a subset of the Function IDs are designated as "OEM Calls" (see [SMCCC] +for full details). The EL3 runtime services framework in BL3-1 enables the +independent implementation of services for each group, which are then compiled +into the BL3-1 image. This simplifies the integration of common software from +ARM to support [PSCI], Secure Monitor for a Trusted OS and SoC specific +software. The common runtime services framework ensures that SMC Functions are +dispatched to their respective service implementation - the [Firmware Design] +provides details of how this is achieved. + +The interface and operation of the runtime services depends heavily on the +concepts and definitions described in the [SMCCC], in particular SMC Function +IDs, Owning Entity Numbers (OEN), Fast and Standard calls, and the SMC32 and +SMC64 calling conventions. Please refer to that document for a full explanation +of these terms. + + +2. Owning Entities, Call Types and Function IDs +------------------------------------------------ + +The SMC Function Identifier includes a OEN field. These values and their +meaning are described in [SMCCC] and summarized in table 1 below. Some entities +are allocated a range of of OENs. The OEN must be interpreted in conjunction +with the SMC call type, which is either _Fast_ or _Standard_. Fast calls are +uninterruptible whereas Standard calls can be pre-empted. The majority of +Owning Entities only have allocated ranges for Fast calls: Standard calls are +reserved exclusively for Trusted OS providers or for interoperability with +legacy 32-bit software that predates the [SMCCC]. + + Type OEN Service + Fast 0 ARM Architecture calls + Fast 1 CPU Service calls + Fast 2 SiP Service calls + Fast 3 OEM Service calls + Fast 4 Standard Service calls + Fast 5-47 Reserved for future use + Fast 48-49 Trusted Application calls + Fast 50-63 Trusted OS calls + + Std 0- 1 Reserved for existing ARMv7 calls + Std 2-63 Trusted OS Standard Calls + +_Table 1: Service types and their corresponding Owning Entity Numbers_ + +Each individual entity can allocate the valid identifiers within the entity +range as they need - it is not necessary to coordinate with other entities of +the same type. For example, two SoC providers can use the same Function ID +within the SiP Service calls OEN range to mean different things - as these +calls should be specific to the SoC. The Standard Runtime Calls OEN is used for +services defined by ARM standards, such as [PSCI]. + +The SMC Function ID also indicates whether the call has followed the SMC32 +calling convention, where all parameters are 32-bit, or the SMC64 calling +convention, where the parameters are 64-bit. The framework identifies and +rejects invalid calls that use the SMC64 calling convention but that originate +from an AArch32 caller. + +The EL3 runtime services framework uses the call type and OEN to identify a +specific handler for each SMC call, but it is expected that an individual +handler will be responsible for all SMC Functions within a given service type. + + +3. Getting started +------------------- + +ARM Trusted Firmware has a [`services`] directory in the source tree under which +each owning entity can place the implementation of its runtime service. The +[PSCI] implementation is located here in the [`services/std_svc/psci`] +directory. + +Runtime service sources will need to include the [`runtime_svc.h`] header file. + + +4. Registering a runtime service +--------------------------------- + +A runtime service is registered using the `DECLARE_RT_SVC()` macro, specifying +the name of the service, the range of OENs covered, the type of service and +initialization and call handler functions. + + #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) + +* `_name` is used to identify the data structure declared by this macro, and + is also used for diagnostic purposes + +* `_start` and `_end` values must be based on the `OEN_*` values defined in + [`runtime_svc.h`] + +* `_type` must be one of `SMC_TYPE_FAST` or `SMC_TYPE_STD` + +* `_setup` is the initialization function with the `rt_svc_init` signature: + + typedef int32_t (*rt_svc_init)(void); + +* `_smch` is the SMC handler function with the `rt_svc_handle` signature: + + typedef uint64_t (*rt_svc_handle)(uint32_t smc_fid, + uint64_t x1, uint64_t x2, + uint64_t x3, uint64_t x4, + void *reserved, + void *handle, + uint64_t flags); + +Details of the requirements and behavior of the two callbacks is provided in +the following sections. + +During initialization the services framework validates each declared service +to ensure that the following conditions are met: + +1. The `_start` OEN is not greater than the `_end` OEN +2. The `_end` OEN does not exceed the maximum OEN value (63) +3. The `_type` is one of `SMC_TYPE_FAST` or `SMC_TYPE_STD` +4. `_setup` and `_smch` routines have been specified + +[`std_svc_setup.c`] provides an example of registering a runtime service: + + /* Register Standard Service Calls as runtime service */ + DECLARE_RT_SVC( + std_svc, + OEN_STD_START, + OEN_STD_END, + SMC_TYPE_FAST, + std_svc_setup, + std_svc_smc_handler + ); + + +5. Initializing a runtime service +--------------------------------- + +Runtime services are initialized once, during cold boot, by the primary CPU +after platform and architectural initialization is complete. The framework +performs basic validation of the declared service before calling +the service initialization function (`_setup` in the declaration). This +function must carry out any essential EL3 initialization prior to receiving a +SMC Function call via the handler function. + +On success, the initialization function must return `0`. Any other return value +will cause the framework to issue a diagnostic: + + Error initializing runtime service <name of the service> + +and then ignore the service - the system will continue to boot but SMC calls +will not be passed to the service handler and instead return the _Unknown SMC +Function ID_ result `0xFFFFFFFF`. + +If the system must not be allowed to proceed without the service, the +initialization function must itself cause the firmware boot to be halted. + +If the service uses per-CPU data this must either be initialized for all CPUs +during this call, or be done lazily when a CPU first issues an SMC call to that +service. + + +6. Handling runtime service requests +------------------------------------- + +SMC calls for a service are forwarded by the framework to the service's SMC +handler function (`_smch` in the service declaration). This function must have +the following signature: + + typedef uint64_t (*rt_svc_handle)(uint32_t smc_fid, + uint64_t x1, uint64_t x2, + uint64_t x3, uint64_t x4, + void *reserved, + void *handle, + uint64_t flags); + +The handler is responsible for: + +1. Determining that `smc_fid` is a valid and supported SMC Function ID, + otherwise completing the request with the _Unknown SMC Function ID_: + + SMC_RET1(handle, SMC_UNK); + +2. Determining if the requested function is valid for the calling security + state. SMC Calls can be made from both the normal and trusted worlds and + the framework will forward all calls to the service handler. + + The `flags` parameter to this function indicates the caller security state + in bit[0], where a value of `1` indicates a non-secure caller. The + `is_caller_secure(flags)` and `is_caller_non_secure(flags)` can be used to + test this condition. + + If invalid, the request should be completed with: + + SMC_RET1(handle, SMC_UNK); + +3. Truncating parameters for calls made using the SMC32 calling convention. + Such calls can be determined by checking the CC field in bit[30] of the + `smc_fid` parameter, for example by using: + + if (GET_SMC_CC(smc_fid) == SMC_32) ... + + For such calls, the upper bits of the parameters x1-x4 and the saved + parameters X5-X7 are UNDEFINED and must be explicitly ignored by the + handler. This can be done by truncating the values to a suitable 32-bit + integer type before use, for example by ensuring that functions defined + to handle individual SMC Functions use appropriate 32-bit parameters. + +4. Providing the service requested by the SMC Function, utilizing the + immediate parameters x1-x4 and/or the additional saved parameters X5-X7. + The latter can be retrieved using the `SMC_GET_GP(handle, ref)` function, + supplying the appropriate `CTX_GPREG_Xn` reference, e.g. + + uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + +5. Implementing the standard SMC32 Functions that provide information about + the implementation of the service. These are the Call Count, Implementor + UID and Revision Details for each service documented in section 6 of the + [SMCCC]. + + The ARM Trusted Firmware expects owning entities to follow this + recommendation. + +5. Returning the result to the caller. The [SMCCC] allows for up to 256 bits + of return value in SMC64 using X0-X3 and 128 bits in SMC32 using W0-W3. The + framework provides a family of macros to set the multi-register return + value and complete the handler: + + SMC_RET1(handle, x0); + SMC_RET2(handle, x0, x1); + SMC_RET3(handle, x0, x1, x2); + SMC_RET4(handle, x0, x1, x2, x3); + +The `reserved` parameter to the handler is reserved for future use and can be +ignored. The value returned by a SMC handler is also reserved for future use - +completion of the handler function must always be via one of the `SMC_RETn()` +macros. + +NOTE: The PSCI and Test Secure-EL1 Payload Dispatcher services do not follow +all of the above requirements yet. + + +7. Services that contain multiple sub-services +----------------------------------------------- + +It is possible that a single owning entity implements multiple sub-services. For +example, the Standard calls service handles `0x84000000`-`0x8400FFFF` and +`0xC4000000`-`0xC400FFFF` functions. Within that range, the [PSCI] service +handles the `0x84000000`-`0x8400001F` and `0xC4000000`-`0xC400001F` functions. +In that respect, [PSCI] is a 'sub-service' of the Standard calls service. In +future, there could be additional such sub-services in the Standard calls +service which perform independent functions. + +In this situation it may be valuable to introduce a second level framework to +enable independent implementation of sub-services. Such a framework might look +very similar to the current runtime services framework, but using a different +part of the SMC Function ID to identify the sub-service. Trusted Firmware does +not provide such a framework at present. + + +8. Secure-EL1 Payload Dispatcher service (SPD) +----------------------------------------------- + +Services that handle SMC Functions targeting a Trusted OS, Trusted Application, +or other Secure-EL1 Payload are special. These services need to manage the +Secure-EL1 context, provide the _Secure Monitor_ functionality of switching +between the normal and secure worlds, deliver SMC Calls through to Secure-EL1 +and generally manage the Secure-EL1 Payload through CPU power-state transitions. + +TODO: Provide details of the additional work required to implement a SPD and +the BL3-1 support for these services. Or a reference to the document that will +provide this information.... + + +- - - - - - - - - - - - - - - - - - - - - - - - - - + +_Copyright (c) 2014, ARM Limited and Contributors. All rights reserved._ + + +[Firmware Design]: ./firmware-design.md + +[`services`]: ../services +[`services/std_svc/psci`]: ../services/std_svc/psci +[`std_svc_setup.c`]: ../services/std_svc/std_svc_setup.c +[`runtime_svc.h`]: ../include/runtime_svc.h +[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022b/index.html "Power State Coordination Interface PDD (ARM DEN 0022B.b)" +[SMCCC]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)" diff --git a/docs/user-guide.md b/docs/user-guide.md new file mode 100644 index 0000000..40a7955 --- /dev/null +++ b/docs/user-guide.md @@ -0,0 +1,841 @@ +ARM Trusted Firmware User Guide +=============================== + +Contents : + +1. Introduction +2. Host machine requirements +3. Tools +4. Building the Trusted Firmware +5. Obtaining the normal world software +6. Running the software + + +1. Introduction +---------------- +This document describes how to build ARM Trusted Firmware and run it with a +tested set of other software components using defined configurations on ARM +Fixed Virtual Platform (FVP) models. It is possible to use other software +components, configurations and platforms but that is outside the scope of this +document. + +This document should be used in conjunction with the [Firmware Design]. + + +2. Host machine requirements +----------------------------- + +The minimum recommended machine specification for building the software and +running the FVP models is a dual-core processor running at 2GHz with 12GB of +RAM. For best performance, use a machine with a quad-core processor running at +2.6GHz with 16GB of RAM. + +The software has been tested on Ubuntu 12.04.04 (64-bit). Packages used +for building the software were installed from that distribution unless +otherwise specified. + + +3. Tools +--------- + +The following tools are required to use the ARM Trusted Firmware: + +* `git` package to obtain source code + +* `ia32-libs` package + +* `build-essential` and `uuid-dev` packages for building UEFI and the Firmware + Image Package(FIP) tool + +* `bc` and `ncurses-dev` packages for building Linux + +* Baremetal GNU GCC tools. Verified packages can be downloaded from [Linaro] + [Linaro Toolchain]. The rest of this document assumes that the + `gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz` tools are used. + + wget http://releases.linaro.org/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz + tar -xf gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz + +* The Device Tree Compiler (DTC) included with Linux kernel 3.15-rc6 is used + to build the Flattened Device Tree (FDT) source files (`.dts` files) + provided with this software. + +* (Optional) For debugging, ARM [Development Studio 5 (DS-5)][DS-5] v5.18. + + +4. Building the Trusted Firmware +--------------------------------- + +To build the software for the FVPs, follow these steps: + +1. Clone the ARM Trusted Firmware repository from GitHub: + + git clone https://github.com/ARM-software/arm-trusted-firmware.git + +2. Change to the trusted firmware directory: + + cd arm-trusted-firmware + +3. Set the compiler path, specify a Non-trusted Firmware image (BL3-3) and + build: + + CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \ + BL33=<path-to>/<bl33_image> \ + make PLAT=fvp all fip + + See the "Summary of build options" for information on available build + options. + + By default this produces a release version of the build. To produce a debug + version instead, refer to the "Debugging options" section below. UEFI can be + used as the BL3-3 image, refer to the "Obtaining the normal world software" + section below. By default this won't compile the TSP in, refer to the + "Building the Test Secure Payload" section below. + + The build process creates products in a `build` directory tree, building + the objects and binaries for each boot loader stage in separate + sub-directories. The following boot loader binary files are created from + the corresponding ELF files: + + * `build/<platform>/<build-type>/bl1.bin` + * `build/<platform>/<build-type>/bl2.bin` + * `build/<platform>/<build-type>/bl31.bin` + + ... where `<platform>` currently defaults to `fvp` and `<build-type>` is + either `debug` or `release`. A Firmare Image Package(FIP) will be created as + part of the build. It contains all boot loader images except for `bl1.bin`. + + * `build/<platform>/<build-type>/fip.bin` + + For more information on FIPs, see the "Firmware Image Package" section in + the [Firmware Design]. + +4. Copy the `bl1.bin` and `fip.bin` binary files to the directory from which + the FVP will be launched. Symbolic links of the same names may be created + instead. + +5. (Optional) Build products for a specific build variant can be removed using: + + make DEBUG=<D> PLAT=fvp clean + + ... where `<D>` is `0` or `1`, as specified when building. + + The build tree can be removed completely using: + + make realclean + +### Summary of build options + +ARM Trusted Firmware build system supports the following build options. Unless +mentioned otherwise, these options are expected to be specified at the build +command line and are not to be modified in any component makefiles. Note that +the build system doesn't track dependency for build options. Therefore, if any +of the build options are changed from a previous build, a clean build must be +performed. + +* `BL33`: Path to BL33 image in the host file system. This is mandatory for + `fip` target + +* `BL30`: Path to BL3-0 image in the host file system. This image is optional. + If a BL3-0 image is present then this option must be passed for the `fip` + target + +* `CROSS_COMPILE`: Prefix to tool chain binaries. Please refer to examples in + this document for usage + +* `DEBUG`: Chooses between a debug and release build. It can take either 0 + (release) or 1 (debug) as values. 0 is the default + +* `NS_TIMER_SWITCH`: Enable save and restore for non-secure timer register + contents upon world switch. It can take either 0 (don't save and restore) or + 1 (do save and restore). 0 is the default. An SPD could set this to 1 if it + wants the timer registers to be saved and restored + +* `PLAT`: Choose a platform to build ARM Trusted Firmware for. The chosen + platform name must be the name of one of the directories under the `plat/` + directory other than `common` + +* `SPD`: Choose a Secure Payload Dispatcher component to be built into the + Trusted Firmware. The value should be the path to the directory containing + SPD source; the directory is expected to contain `spd.mk` makefile + +* `V`: Verbose build. If assigned anything other than 0, the build commands + are printed. Default is 0 + +* `FVP_GIC_ARCH`: Choice of ARM GIC architecture version used by the FVP port + for implementing the platform GIC API. This API is used by the interrupt + management framework. Default is 2 i.e. version 2.0 + +* `IMF_READ_INTERRUPT_ID`: Boolean flag used by the interrupt management + framework to enable passing of the interrupt id to its handler. The id is + read using a platform GIC API. `INTR_ID_UNAVAILABLE` is passed instead if + this option set to 0. Default is 0. + +* `RESET_TO_BL31`: Enable BL3-1 entrypoint as the CPU reset vector in place + of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1 + entrypoint) or 1 (CPU reset to BL3-1 entrypoint). + The default value is 0. + + +### Creating a Firmware Image Package + +FIPs are automatically created as part of the build instructions described in +the previous section. It is also possible to independently build the FIP +creation tool and FIPs if required. To do this, follow these steps: + +Build the tool: + + make -C tools/fip_create + +It is recommended to remove the build artifacts before rebuilding: + + make -C tools/fip_create clean + +Create a Firmware package that contains existing FVP BL2 and BL3-1 images: + + # fip_create --help to print usage information + # fip_create <fip_name> <images to add> [--dump to show result] + ./tools/fip_create/fip_create fip.bin --dump \ + --bl2 build/fvp/debug/bl2.bin --bl31 build/fvp/debug/bl31.bin + + Firmware Image Package ToC: + --------------------------- + - Trusted Boot Firmware BL2: offset=0x88, size=0x81E8 + file: 'build/fvp/debug/bl2.bin' + - EL3 Runtime Firmware BL3-1: offset=0x8270, size=0xC218 + file: 'build/fvp/debug/bl31.bin' + --------------------------- + Creating "fip.bin" + +View the contents of an existing Firmware package: + + ./tools/fip_create/fip_create fip.bin --dump + + Firmware Image Package ToC: + --------------------------- + - Trusted Boot Firmware BL2: offset=0x88, size=0x81E8 + - EL3 Runtime Firmware BL3-1: offset=0x8270, size=0xC218 + --------------------------- + +Existing package entries can be individially updated: + + # Change the BL2 from Debug to Release version + ./tools/fip_create/fip_create fip.bin --dump \ + --bl2 build/fvp/release/bl2.bin + + Firmware Image Package ToC: + --------------------------- + - Trusted Boot Firmware BL2: offset=0x88, size=0x7240 + file: 'build/fvp/release/bl2.bin' + - EL3 Runtime Firmware BL3-1: offset=0x72C8, size=0xC218 + --------------------------- + Updating "fip.bin" + + +### Debugging options + +To compile a debug version and make the build more verbose use + + CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \ + BL33=<path-to>/<bl33_image> \ + make PLAT=fvp DEBUG=1 V=1 all fip + +AArch64 GCC uses DWARF version 4 debugging symbols by default. Some tools (for +example DS-5) might not support this and may need an older version of DWARF +symbols to be emitted by GCC. This can be achieved by using the +`-gdwarf-<version>` flag, with the version being set to 2 or 3. Setting the +version to 2 is recommended for DS-5 versions older than 5.16. + +When debugging logic problems it might also be useful to disable all compiler +optimizations by using `-O0`. + +NOTE: Using `-O0` could cause output images to be larger and base addresses +might need to be recalculated (see the later memory layout section). + +Extra debug options can be passed to the build system by setting `CFLAGS`: + + CFLAGS='-O0 -gdwarf-2' \ + CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \ + BL33=<path-to>/<bl33_image> \ + make PLAT=fvp DEBUG=1 V=1 all fip + + +NOTE: The Foundation FVP does not provide a debugger interface. + + +### Building the Test Secure Payload + +The TSP is coupled with a companion runtime service in the BL3-1 firmware, +called the TSPD. Therefore, if you intend to use the TSP, the BL3-1 image +must be recompiled as well. For more information on SPs and SPDs, see the +"Secure-EL1 Payloads and Dispatchers" section in the [Firmware Design]. + +First clean the Trusted Firmware build directory to get rid of any previous +BL3-1 binary. Then to build the TSP image and include it into the FIP use: + + CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \ + BL33=<path-to>/<bl33_image> \ + make PLAT=fvp SPD=tspd all fip + +An additional boot loader binary file is created in the `build` directory: + + * `build/<platform>/<build-type>/bl32.bin` + +The Firmware Package contains this new image: + + Firmware Image Package ToC: + --------------------------- + - Trusted Boot Firmware BL2: offset=0xD8, size=0x6000 + file: './build/fvp/release/bl2.bin' + - EL3 Runtime Firmware BL3-1: offset=0x60D8, size=0x9000 + file: './build/fvp/release/bl31.bin' + - Secure Payload BL3-2 (Trusted OS): offset=0xF0D8, size=0x3000 + file: './build/fvp/release/bl32.bin' + - Non-Trusted Firmware BL3-3: offset=0x120D8, size=0x280000 + file: '../FVP_AARCH64_EFI.fd' + --------------------------- + Creating "build/fvp/release/fip.bin" + +On FVP, the TSP binary runs from Trusted SRAM by default. It is also possible +to run it from Trusted DRAM. This is controlled by the build configuration +`TSP_RAM_LOCATION`: + + CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \ + BL33=<path-to>/<bl33_image> \ + make PLAT=fvp SPD=tspd TSP_RAM_LOCATION=tdram all fip + + +### Checking source code style + +When making changes to the source for submission to the project, the source +must be in compliance with the Linux style guide, and to assist with this check +the project Makefile contains two targets, which both utilise the checkpatch.pl +script that ships with the Linux source tree. + +To check the entire source tree, you must first download a copy of checkpatch.pl +(or the full Linux source), set the CHECKPATCH environment variable to point to +the script and build the target checkcodebase: + + make CHECKPATCH=../linux/scripts/checkpatch.pl checkcodebase + +To just check the style on the files that differ between your local branch and +the remote master, use: + + make CHECKPATCH=../linux/scripts/checkpatch.pl checkpatch + +If you wish to check your patch against something other than the remote master, +set the BASE_COMMIT variable to your desired branch. By default, BASE_COMMIT +is set to 'origin/master'. + + +5. Obtaining the normal world software +--------------------------------------- + +### Obtaining EDK2 + +Potentially any kind of non-trusted firmware may be used with the ARM Trusted +Firmware but the software has only been tested with the EFI Development Kit 2 +(EDK2) open source implementation of the UEFI specification. + +Clone the [EDK2 source code][EDK2] from GitHub. This version supports the Base +and Foundation FVPs: + + git clone -n https://github.com/tianocore/edk2.git + cd edk2 + git checkout 129ff94661bd3a6c759b1e154c143d0136bedc7d + + +To build the software to be compatible with Foundation and Base FVPs, follow +these steps: + +1. Copy build config templates to local workspace + + # in edk2/ + . edksetup.sh + +2. Build the EDK2 host tools + + make -C BaseTools clean + make -C BaseTools + +3. Build the EDK2 software + + CROSS_COMPILE=<absolute-path-to-aarch64-gcc>/bin/aarch64-none-elf- \ + make -f ArmPlatformPkg/Scripts/Makefile EDK2_ARCH=AARCH64 \ + EDK2_DSC=ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc \ + EDK2_TOOLCHAIN=ARMGCC EDK2_MACROS="-n 6 -D ARM_FOUNDATION_FVP=1" + + The EDK2 binary for use with the ARM Trusted Firmware can then be found + here: + + Build/ArmVExpress-FVP-AArch64/DEBUG_ARMGCC/FV/FVP_AARCH64_EFI.fd + + This will build EDK2 for the default settings as used by the FVPs. The EDK2 + binary `FVP_AARCH64_EFI.fd` should be specified as `BL33` in in the `make` + command line when building the Trusted Firmware. See the "Building the + Trusted Firmware" section above. + +4. (Optional) To boot Linux using a VirtioBlock file-system, the command line + passed from EDK2 to the Linux kernel must be modified as described in the + "Obtaining a root file-system" section below. + +5. (Optional) If legacy GICv2 locations are used, the EDK2 platform description + must be updated. This is required as EDK2 does not support probing for the + GIC location. To do this, first clean the EDK2 build directory. + + make -f ArmPlatformPkg/Scripts/Makefile EDK2_ARCH=AARCH64 \ + EDK2_DSC=ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc \ + EDK2_TOOLCHAIN=ARMGCC clean + + Then rebuild EDK2 as described in step 3, using the following flag: + + -D ARM_FVP_LEGACY_GICV2_LOCATION=1 + + Finally rebuild the Trusted Firmware to generate a new FIP using the + instructions in the "Building the Trusted Firmware" section. + + +### Obtaining a Linux kernel + +The software has been verified using a Linux kernel based on version 3.15-rc6. +Patches have been applied in order to enable the CPU idle feature. + +Preparing a Linux kernel for use on the FVPs with CPU idle support can +be done as follows (GICv2 support only): + +1. Clone Linux: + + git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git + + Not all CPU idle features are included in the mainline kernel yet. To + use these, add the patches from Sudeep Holla's kernel: + + cd linux + git remote add -f --tags arm64_idle_v3.15-rc6 git://linux-arm.org/linux-skn.git + git checkout -b cpuidle arm64_idle_v3.15-rc6 + +2. Build with the Linaro GCC tools. + + # in linux/ + make mrproper + make ARCH=arm64 defconfig + + # Enable CPU idle + make ARCH=arm64 menuconfig + # CPU Power Management ---> CPU Idle ---> [*] CPU idle PM support + # CPU Power Management ---> CPU Idle ---> ARM64 CPU Idle Drivers ---> [*] Generic ARM64 CPU idle Driver + + CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \ + make -j6 ARCH=arm64 + +3. Copy the Linux image `arch/arm64/boot/Image` to the working directory from + where the FVP is launched. Alternatively a symbolic link may be used. + +### Obtaining the Flattened Device Trees + +Depending on the FVP configuration and Linux configuration used, different +FDT files are required. FDTs for the Foundation and Base FVPs can be found in +the Trusted Firmware source directory under `fdts/`. The Foundation FVP has a +subset of the Base FVP components. For example, the Foundation FVP lacks CLCD +and MMC support, and has only one CPU cluster. + +* `fvp-base-gicv2-psci.dtb` + + (Default) For use with both AEMv8 and Cortex-A57-A53 Base FVPs with + Base memory map configuration. + +* `fvp-base-gicv2legacy-psci.dtb` + + For use with AEMv8 Base FVP with legacy VE GIC memory map configuration. + +* `fvp-base-gicv3-psci.dtb` + + For use with both AEMv8 and Cortex-A57-A53 Base FVPs with Base memory map + configuration and Linux GICv3 support. + +* `fvp-foundation-gicv2-psci.dtb` + + (Default) For use with Foundation FVP with Base memory map configuration. + +* `fvp-foundation-gicv2legacy-psci.dtb` + + For use with Foundation FVP with legacy VE GIC memory map configuration. + +* `fvp-foundation-gicv3-psci.dtb` + + For use with Foundation FVP with Base memory map configuration and Linux + GICv3 support. + + +Copy the chosen FDT blob as `fdt.dtb` to the directory from which the FVP +is launched. Alternatively a symbolic link may be used. + +### Obtaining a root file-system + +To prepare a Linaro LAMP based Open Embedded file-system, the following +instructions can be used as a guide. The file-system can be provided to Linux +via VirtioBlock or as a RAM-disk. Both methods are described below. + +#### Prepare VirtioBlock + +To prepare a VirtioBlock file-system, do the following: + +1. Download and unpack the disk image. + + NOTE: The unpacked disk image grows to 3 GiB in size. + + wget http://releases.linaro.org/14.04/openembedded/aarch64/vexpress64-openembedded_lamp-armv8-gcc-4.8_20140417-630.img.gz + gunzip vexpress64-openembedded_lamp-armv8-gcc-4.8_20140417-630.img.gz + +2. Make sure the Linux kernel has Virtio support enabled using + `make ARCH=arm64 menuconfig`. + + Device Drivers ---> Virtio drivers ---> <*> Platform bus driver for memory mapped virtio devices + Device Drivers ---> [*] Block devices ---> <*> Virtio block driver + File systems ---> <*> The Extended 4 (ext4) filesystem + + If some of these configurations are missing, enable them, save the kernel + configuration, then rebuild the kernel image using the instructions + provided in the section "Obtaining a Linux kernel". + +3. Change the Kernel command line to include `root=/dev/vda2`. This can either + be done in the EDK2 boot menu or in the platform file. Editing the platform + file and rebuilding EDK2 will make the change persist. To do this: + + 1. In EDK2, edit the following file: + + ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc + + 2. Add `root=/dev/vda2` to: + + gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"<Other default options>" + + 3. Remove the entry: + + gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|"" + + 4. Rebuild EDK2 (see "Obtaining UEFI" section above). + +4. The file-system image file should be provided to the model environment by + passing it the correct command line option. In the FVPs the following + option should be provided in addition to the ones described in the + "Running the software" section below. + + NOTE: A symbolic link to this file cannot be used with the FVP; the path + to the real file must be provided. + + On the Base FVPs: + + -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>" + + On the Foundation FVP: + + --block-device="<path-to>/<file-system-image>" + + +5. Ensure that the FVP doesn't output any error messages. If the following + error message is displayed: + + ERROR: BlockDevice: Failed to open "<path-to>/<file-system-image>"! + + then make sure the path to the file-system image in the model parameter is + correct and that read permission is correctly set on the file-system image + file. + +#### Prepare RAM-disk + +To prepare a RAM-disk root file-system, do the following: + +1. Download the file-system image: + + wget http://releases.linaro.org/14.04/openembedded/aarch64/linaro-image-lamp-genericarmv8-20140417-667.rootfs.tar.gz + +2. Modify the Linaro image: + + # Prepare for use as RAM-disk. Normally use MMC, NFS or VirtioBlock. + # Be careful, otherwise you could damage your host file-system. + mkdir tmp; cd tmp + sudo sh -c "zcat ../linaro-image-lamp-genericarmv8-20140417-667.rootfs.tar.gz | cpio -id" + sudo ln -s sbin/init . + sudo sh -c "echo 'devtmpfs /dev devtmpfs mode=0755,nosuid 0 0' >> etc/fstab" + sudo sh -c "find . | cpio --quiet -H newc -o | gzip -3 -n > ../filesystem.cpio.gz" + cd .. + +3. Copy the resultant `filesystem.cpio.gz` to the directory where the FVP is + launched from. Alternatively a symbolic link may be used. + + +6. Running the software +------------------------ + +This version of the ARM Trusted Firmware has been tested on the following ARM +FVPs (64-bit versions only). + +* `Foundation_v8` (Version 2.0, Build 0.8.5206) +* `FVP_Base_AEMv8A-AEMv8A` (Version 5.6, Build 0.8.5602) +* `FVP_Base_Cortex-A57x4-A53x4` (Version 5.6, Build 0.8.5602) +* `FVP_Base_Cortex-A57x1-A53x1` (Version 5.6, Build 0.8.5602) +* `FVP_Base_Cortex-A57x2-A53x4` (Version 5.6, Build 0.8.5602) + +NOTE: The software will not work on Version 1.0 of the Foundation FVP. +The commands below would report an `unhandled argument` error in this case. + +Please refer to the FVP documentation for a detailed description of the model +parameter options. A brief description of the important ones that affect the +ARM Trusted Firmware and normal world software behavior is provided below. + +The Foundation FVP is a cut down version of the AArch64 Base FVP. It can be +downloaded for free from [ARM's website][ARM FVP website]. + + +### Running on the Foundation FVP with reset to BL1 entrypoint + +The following `Foundation_v8` parameters should be used to boot Linux with +4 CPUs using the ARM Trusted Firmware. + +NOTE: Using the `--block-device` parameter is not necessary if a Linux RAM-disk +file-system is used (see the "Obtaining a File-system" section above). + +NOTE: The `--data="<path to FIP binary>"@0x8000000` parameter is used to load a +Firmware Image Package at the start of NOR FLASH0 (see the "Building the +Trusted Firmware" section above). + + <path-to>/Foundation_v8 \ + --cores=4 \ + --no-secure-memory \ + --visualization \ + --gicv3 \ + --data="<path-to>/<bl1-binary>"@0x0 \ + --data="<path-to>/<FIP-binary>"@0x8000000 \ + --block-device="<path-to>/<file-system-image>" + +The default use-case for the Foundation FVP is to enable the GICv3 device in +the model but use the GICv2 FDT, in order for Linux to drive the GIC in GICv2 +emulation mode. + +The memory mapped addresses `0x0` and `0x8000000` correspond to the start of +trusted ROM and NOR FLASH0 respectively. + +### Notes regarding Base FVP configuration options + +1. The `-C bp.flashloader0.fname` parameter is used to load a Firmware Image +Package at the start of NOR FLASH0 (see the "Building the Trusted Firmware" +section above). + +2. Using `cache_state_modelled=1` makes booting very slow. The software will +still work (and run much faster) without this option but this will hide any +cache maintenance defects in the software. + +3. Using the `-C bp.virtioblockdevice.image_path` parameter is not necessary +if a Linux RAM-disk file-system is used (see the "Obtaining a root file-system" +section above). + +4. Setting the `-C bp.secure_memory` parameter to `1` is only supported on +Base FVP versions 5.4 and newer. Setting this parameter to `0` is also +supported. The `-C bp.tzc_400.diagnostics=1` parameter is optional. It +instructs the FVP to provide some helpful information if a secure memory +violation occurs. + +5. The `--data="<path-to><bl31/bl32/bl33-binary>"@base address of binaries` +parameter is used to load bootloader images in the Base FVP memory (see the +"Building the Trusted Firmware" section above). The base address used to +load the binaries with --data should match the image base addresses in +platform_def.h used while linking the images. +BL3-2 image is only needed if BL3-1 has been built to expect a secure-EL1 +payload. + + +### Running on the AEMv8 Base FVP with reset to BL1 entrypoint + +Please read "Notes regarding Base FVP configuration options" section above for +information about some of the options to run the software. + +The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux +with 8 CPUs using the ARM Trusted Firmware. + + <path-to>/FVP_Base_AEMv8A-AEMv8A \ + -C pctl.startup=0.0.0.0 \ + -C bp.secure_memory=1 \ + -C bp.tzc_400.diagnostics=1 \ + -C cluster0.NUM_CORES=4 \ + -C cluster1.NUM_CORES=4 \ + -C cache_state_modelled=1 \ + -C bp.pl011_uart0.untimed_fifos=1 \ + -C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \ + -C bp.flashloader0.fname="<path-to>/<FIP-binary>" \ + -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>" + +### Running on the Cortex-A57-A53 Base FVP with reset to BL1 entrypoint + +Please read "Notes regarding Base FVP configuration options" section above for +information about some of the options to run the software. + +The following `FVP_Base_Cortex-A57x4-A53x4` model parameters should be used to +boot Linux with 8 CPUs using the ARM Trusted Firmware. + + <path-to>/FVP_Base_Cortex-A57x4-A53x4 \ + -C pctl.startup=0.0.0.0 \ + -C bp.secure_memory=1 \ + -C bp.tzc_400.diagnostics=1 \ + -C cache_state_modelled=1 \ + -C bp.pl011_uart0.untimed_fifos=1 \ + -C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \ + -C bp.flashloader0.fname="<path-to>/<FIP-binary>" \ + -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>" + +### Running on the AEMv8 Base FVP with reset to BL3-1 entrypoint + +Please read "Notes regarding Base FVP configuration options" section above for +information about some of the options to run the software. + +The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux +with 8 CPUs using the ARM Trusted Firmware. + +NOTE: Uses the `-c clusterX.cpuX.RVBAR=@base address of BL3-1` where X is +the cluster number in clusterX and cpu number in cpuX is used to set the reset +vector for each core. + + <path-to>/FVP_Base_AEMv8A-AEMv8A \ + -C pctl.startup=0.0.0.0 \ + -C bp.secure_memory=1 \ + -C bp.tzc_400.diagnostics=1 \ + -C cluster0.NUM_CORES=4 \ + -C cluster1.NUM_CORES=4 \ + -C cache_state_modelled=1 \ + -C bp.pl011_uart0.untimed_fifos=1 \ + -C cluster0.cpu0.RVBAR=0x04006000 \ + -C cluster0.cpu1.RVBAR=0x04006000 \ + -C cluster0.cpu2.RVBAR=0x04006000 \ + -C cluster0.cpu3.RVBAR=0x04006000 \ + -C cluster1.cpu0.RVBAR=0x04006000 \ + -C cluster1.cpu1.RVBAR=0x04006000 \ + -C cluster1.cpu2.RVBAR=0x04006000 \ + -C cluster1.cpu3.RVBAR=0x04006000 \ + --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04006000 \ + --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04024000 \ + --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000 \ + -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>" + +### Running on the Cortex-A57-A53 Base FVP with reset to BL3-1 entrypoint + +Please read "Notes regarding Base FVP configuration options" section above for +information about some of the options to run the software. + +The following `FVP_Base_Cortex-A57x4-A53x4` model parameters should be used to +boot Linux with 8 CPUs using the ARM Trusted Firmware. + +NOTE: Uses the `-c clusterX.cpuX.RVBARADDR=@base address of BL3-1` where X is +the cluster number in clusterX and cpu number in cpuX is used to set the reset +vector for each core. + + <path-to>/FVP_Base_Cortex-A57x4-A53x4 \ + -C pctl.startup=0.0.0.0 \ + -C bp.secure_memory=1 \ + -C bp.tzc_400.diagnostics=1 \ + -C cache_state_modelled=1 \ + -C bp.pl011_uart0.untimed_fifos=1 \ + -C cluster0.cpu0.RVBARADDR=0x04006000 \ + -C cluster0.cpu1.RVBARADDR=0x04006000 \ + -C cluster0.cpu2.RVBARADDR=0x04006000 \ + -C cluster0.cpu3.RVBARADDR=0x04006000 \ + -C cluster1.cpu0.RVBARADDR=0x04006000 \ + -C cluster1.cpu1.RVBARADDR=0x04006000 \ + -C cluster1.cpu2.RVBARADDR=0x04006000 \ + -C cluster1.cpu3.RVBARADDR=0x04006000 \ + --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04006000 \ + --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04024000 \ + --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000 \ + -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>" + +### Configuring the GICv2 memory map + +The Base FVP models support GICv2 with the default model parameters at the +following addresses. The Foundation FVP also supports these addresses when +configured for GICv3 in GICv2 emulation mode. + + GICv2 Distributor Interface 0x2f000000 + GICv2 CPU Interface 0x2c000000 + GICv2 Virtual CPU Interface 0x2c010000 + GICv2 Hypervisor Interface 0x2c02f000 + +The AEMv8 Base FVP can be configured to support GICv2 at addresses +corresponding to the legacy (Versatile Express) memory map as follows. These are +the default addresses when using the Foundation FVP in GICv2 mode. + + GICv2 Distributor Interface 0x2c001000 + GICv2 CPU Interface 0x2c002000 + GICv2 Virtual CPU Interface 0x2c004000 + GICv2 Hypervisor Interface 0x2c006000 + +The choice of memory map is reflected in the build variant field (bits[15:12]) +in the `SYS_ID` register (Offset `0x0`) in the Versatile Express System +registers memory map (`0x1c010000`). + +* `SYS_ID.Build[15:12]` + + `0x1` corresponds to the presence of the Base GIC memory map. This is the + default value on the Base FVPs. + +* `SYS_ID.Build[15:12]` + + `0x0` corresponds to the presence of the Legacy VE GIC memory map. This is + the default value on the Foundation FVP. + +This register can be configured as described in the following sections. + +NOTE: If the legacy VE GIC memory map is used, then the corresponding FDT and +BL3-3 images should be used. + +#### Configuring AEMv8 Foundation FVP GIC for legacy VE memory map + +The following parameters configure the Foundation FVP to use GICv2 with the +legacy VE memory map: + + <path-to>/Foundation_v8 \ + --cores=4 \ + --no-secure-memory \ + --visualization \ + --no-gicv3 \ + --data="<path-to>/<bl1-binary>"@0x0 \ + --data="<path-to>/<FIP-binary>"@0x8000000 \ + --block-device="<path-to>/<file-system-image>" + +Explicit configuration of the `SYS_ID` register is not required. + +#### Configuring AEMv8 Base FVP GIC for legacy VE memory map + +The following parameters configure the AEMv8 Base FVP to use GICv2 with the +legacy VE memory map. They must added to the parameters described in the +"Running on the AEMv8 Base FVP" section above: + + -C cluster0.gic.GICD-offset=0x1000 \ + -C cluster0.gic.GICC-offset=0x2000 \ + -C cluster0.gic.GICH-offset=0x4000 \ + -C cluster0.gic.GICH-other-CPU-offset=0x5000 \ + -C cluster0.gic.GICV-offset=0x6000 \ + -C cluster0.gic.PERIPH-size=0x8000 \ + -C cluster1.gic.GICD-offset=0x1000 \ + -C cluster1.gic.GICC-offset=0x2000 \ + -C cluster1.gic.GICH-offset=0x4000 \ + -C cluster1.gic.GICH-other-CPU-offset=0x5000 \ + -C cluster1.gic.GICV-offset=0x6000 \ + -C cluster1.gic.PERIPH-size=0x8000 \ + -C gic_distributor.GICD-alias=0x2c001000 \ + -C bp.variant=0x0 + +The `bp.variant` parameter corresponds to the build variant field of the +`SYS_ID` register. Setting this to `0x0` allows the ARM Trusted Firmware to +detect the legacy VE memory map while configuring the GIC. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - + +_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._ + + +[Firmware Design]: ./firmware-design.md + +[ARM FVP website]: http://www.arm.com/fvp +[Linaro Toolchain]: http://releases.linaro.org/13.11/components/toolchain/binaries/ +[EDK2]: http://github.com/tianocore/edk2 +[DS-5]: http://www.arm.com/products/tools/software-tools/ds-5/index.php diff --git a/drivers/arm/cci400/cci400.c b/drivers/arm/cci400/cci400.c new file mode 100644 index 0000000..af10f21 --- /dev/null +++ b/drivers/arm/cci400/cci400.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <cci400.h> +#include <mmio.h> +#include <platform_def.h> + +static inline unsigned long get_slave_iface_base(unsigned long mpidr) +{ + return CCI400_BASE + SLAVE_IFACE_OFFSET(CCI400_SL_IFACE_INDEX(mpidr)); +} + +void cci_enable_coherency(unsigned long mpidr) +{ + /* Enable Snoops and DVM messages */ + mmio_write_32(get_slave_iface_base(mpidr) + SNOOP_CTRL_REG, + DVM_EN_BIT | SNOOP_EN_BIT); + + /* Wait for the dust to settle down */ + while (mmio_read_32(CCI400_BASE + STATUS_REG) & CHANGE_PENDING_BIT) + ; +} + +void cci_disable_coherency(unsigned long mpidr) +{ + /* Disable Snoops and DVM messages */ + mmio_write_32(get_slave_iface_base(mpidr) + SNOOP_CTRL_REG, + ~(DVM_EN_BIT | SNOOP_EN_BIT)); + + /* Wait for the dust to settle down */ + while (mmio_read_32(CCI400_BASE + STATUS_REG) & CHANGE_PENDING_BIT) + ; +} + diff --git a/drivers/arm/gic/aarch64/gic_v3_sysregs.S b/drivers/arm/gic/aarch64/gic_v3_sysregs.S new file mode 100644 index 0000000..ddf85a8 --- /dev/null +++ b/drivers/arm/gic/aarch64/gic_v3_sysregs.S @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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_macros.S> + + .globl read_icc_sre_el1 + .globl read_icc_sre_el2 + .globl read_icc_sre_el3 + .globl write_icc_sre_el1 + .globl write_icc_sre_el2 + .globl write_icc_sre_el3 + .globl write_icc_pmr_el1 + + +/* + * Register definitions used by GCC for GICv3 access. + * These are defined by ARMCC, so keep them in the GCC specific code for now. + */ +#define ICC_SRE_EL1 S3_0_C12_C12_5 +#define ICC_SRE_EL2 S3_4_C12_C9_5 +#define ICC_SRE_EL3 S3_6_C12_C12_5 +#define ICC_CTLR_EL1 S3_0_C12_C12_4 +#define ICC_CTLR_EL3 S3_6_C12_C12_4 +#define ICC_PMR_EL1 S3_0_C4_C6_0 + +func read_icc_sre_el1 + mrs x0, ICC_SRE_EL1 + ret + + +func read_icc_sre_el2 + mrs x0, ICC_SRE_EL2 + ret + + +func read_icc_sre_el3 + mrs x0, ICC_SRE_EL3 + ret + + +func write_icc_sre_el1 + msr ICC_SRE_EL1, x0 + ret + + +func write_icc_sre_el2 + msr ICC_SRE_EL2, x0 + ret + + +func write_icc_sre_el3 + msr ICC_SRE_EL3, x0 + ret + + +func write_icc_pmr_el1 + msr ICC_PMR_EL1, x0 + ret diff --git a/drivers/arm/gic/gic_v2.c b/drivers/arm/gic/gic_v2.c new file mode 100644 index 0000000..27a39b9 --- /dev/null +++ b/drivers/arm/gic/gic_v2.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <assert.h> +#include <gic_v2.h> +#include <interrupt_mgmt.h> +#include <mmio.h> + +/******************************************************************************* + * GIC Distributor interface accessors for reading entire registers + ******************************************************************************/ + +unsigned int gicd_read_igroupr(unsigned int base, unsigned int id) +{ + unsigned n = id >> IGROUPR_SHIFT; + return mmio_read_32(base + GICD_IGROUPR + (n << 2)); +} + +unsigned int gicd_read_isenabler(unsigned int base, unsigned int id) +{ + unsigned n = id >> ISENABLER_SHIFT; + return mmio_read_32(base + GICD_ISENABLER + (n << 2)); +} + +unsigned int gicd_read_icenabler(unsigned int base, unsigned int id) +{ + unsigned n = id >> ICENABLER_SHIFT; + return mmio_read_32(base + GICD_ICENABLER + (n << 2)); +} + +unsigned int gicd_read_ispendr(unsigned int base, unsigned int id) +{ + unsigned n = id >> ISPENDR_SHIFT; + return mmio_read_32(base + GICD_ISPENDR + (n << 2)); +} + +unsigned int gicd_read_icpendr(unsigned int base, unsigned int id) +{ + unsigned n = id >> ICPENDR_SHIFT; + return mmio_read_32(base + GICD_ICPENDR + (n << 2)); +} + +unsigned int gicd_read_isactiver(unsigned int base, unsigned int id) +{ + unsigned n = id >> ISACTIVER_SHIFT; + return mmio_read_32(base + GICD_ISACTIVER + (n << 2)); +} + +unsigned int gicd_read_icactiver(unsigned int base, unsigned int id) +{ + unsigned n = id >> ICACTIVER_SHIFT; + return mmio_read_32(base + GICD_ICACTIVER + (n << 2)); +} + +unsigned int gicd_read_ipriorityr(unsigned int base, unsigned int id) +{ + unsigned n = id >> IPRIORITYR_SHIFT; + return mmio_read_32(base + GICD_IPRIORITYR + (n << 2)); +} + +unsigned int gicd_read_itargetsr(unsigned int base, unsigned int id) +{ + unsigned n = id >> ITARGETSR_SHIFT; + return mmio_read_32(base + GICD_ITARGETSR + (n << 2)); +} + +unsigned int gicd_read_icfgr(unsigned int base, unsigned int id) +{ + unsigned n = id >> ICFGR_SHIFT; + return mmio_read_32(base + GICD_ICFGR + (n << 2)); +} + +unsigned int gicd_read_cpendsgir(unsigned int base, unsigned int id) +{ + unsigned n = id >> CPENDSGIR_SHIFT; + return mmio_read_32(base + GICD_CPENDSGIR + (n << 2)); +} + +unsigned int gicd_read_spendsgir(unsigned int base, unsigned int id) +{ + unsigned n = id >> SPENDSGIR_SHIFT; + return mmio_read_32(base + GICD_SPENDSGIR + (n << 2)); +} + +/******************************************************************************* + * GIC Distributor interface accessors for writing entire registers + ******************************************************************************/ + +void gicd_write_igroupr(unsigned int base, unsigned int id, unsigned int val) +{ + unsigned n = id >> IGROUPR_SHIFT; + mmio_write_32(base + GICD_IGROUPR + (n << 2), val); +} + +void gicd_write_isenabler(unsigned int base, unsigned int id, unsigned int val) +{ + unsigned n = id >> ISENABLER_SHIFT; + mmio_write_32(base + GICD_ISENABLER + (n << 2), val); +} + +void gicd_write_icenabler(unsigned int base, unsigned int id, unsigned int val) +{ + unsigned n = id >> ICENABLER_SHIFT; + mmio_write_32(base + GICD_ICENABLER + (n << 2), val); +} + +void gicd_write_ispendr(unsigned int base, unsigned int id, unsigned int val) +{ + unsigned n = id >> ISPENDR_SHIFT; + mmio_write_32(base + GICD_ISPENDR + (n << 2), val); +} + +void gicd_write_icpendr(unsigned int base, unsigned int id, unsigned int val) +{ + unsigned n = id >> ICPENDR_SHIFT; + mmio_write_32(base + GICD_ICPENDR + (n << 2), val); +} + +void gicd_write_isactiver(unsigned int base, unsigned int id, unsigned int val) +{ + unsigned n = id >> ISACTIVER_SHIFT; + mmio_write_32(base + GICD_ISACTIVER + (n << 2), val); +} + +void gicd_write_icactiver(unsigned int base, unsigned int id, unsigned int val) +{ + unsigned n = id >> ICACTIVER_SHIFT; + mmio_write_32(base + GICD_ICACTIVER + (n << 2), val); +} + +void gicd_write_ipriorityr(unsigned int base, unsigned int id, unsigned int val) +{ + unsigned n = id >> IPRIORITYR_SHIFT; + mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val); +} + +void gicd_write_itargetsr(unsigned int base, unsigned int id, unsigned int val) +{ + unsigned n = id >> ITARGETSR_SHIFT; + mmio_write_32(base + GICD_ITARGETSR + (n << 2), val); +} + +void gicd_write_icfgr(unsigned int base, unsigned int id, unsigned int val) +{ + unsigned n = id >> ICFGR_SHIFT; + mmio_write_32(base + GICD_ICFGR + (n << 2), val); +} + +void gicd_write_cpendsgir(unsigned int base, unsigned int id, unsigned int val) +{ + unsigned n = id >> CPENDSGIR_SHIFT; + mmio_write_32(base + GICD_CPENDSGIR + (n << 2), val); +} + +void gicd_write_spendsgir(unsigned int base, unsigned int id, unsigned int val) +{ + unsigned n = id >> SPENDSGIR_SHIFT; + mmio_write_32(base + GICD_SPENDSGIR + (n << 2), val); +} + +/******************************************************************************* + * GIC Distributor interface accessors for individual interrupt manipulation + ******************************************************************************/ +unsigned int gicd_get_igroupr(unsigned int base, unsigned int id) +{ + unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); + unsigned int reg_val = gicd_read_igroupr(base, id); + + return (reg_val >> bit_num) & 0x1; +} + +void gicd_set_igroupr(unsigned int base, unsigned int id) +{ + unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); + unsigned int reg_val = gicd_read_igroupr(base, id); + + gicd_write_igroupr(base, id, reg_val | (1 << bit_num)); +} + +void gicd_clr_igroupr(unsigned int base, unsigned int id) +{ + unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); + unsigned int reg_val = gicd_read_igroupr(base, id); + + gicd_write_igroupr(base, id, reg_val & ~(1 << bit_num)); +} + +void gicd_set_isenabler(unsigned int base, unsigned int id) +{ + unsigned bit_num = id & ((1 << ISENABLER_SHIFT) - 1); + + gicd_write_isenabler(base, id, (1 << bit_num)); +} + +void gicd_set_icenabler(unsigned int base, unsigned int id) +{ + unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1); + + gicd_write_icenabler(base, id, (1 << bit_num)); +} + +void gicd_set_ispendr(unsigned int base, unsigned int id) +{ + unsigned bit_num = id & ((1 << ISPENDR_SHIFT) - 1); + + gicd_write_ispendr(base, id, (1 << bit_num)); +} + +void gicd_set_icpendr(unsigned int base, unsigned int id) +{ + unsigned bit_num = id & ((1 << ICPENDR_SHIFT) - 1); + + gicd_write_icpendr(base, id, (1 << bit_num)); +} + +void gicd_set_isactiver(unsigned int base, unsigned int id) +{ + unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1); + + gicd_write_isactiver(base, id, (1 << bit_num)); +} + +void gicd_set_icactiver(unsigned int base, unsigned int id) +{ + unsigned bit_num = id & ((1 << ICACTIVER_SHIFT) - 1); + + gicd_write_icactiver(base, id, (1 << bit_num)); +} + +/* + * Make sure that the interrupt's group is set before expecting + * this function to do its job correctly. + */ +void gicd_set_ipriorityr(unsigned int base, unsigned int id, unsigned int pri) +{ + unsigned int reg = base + GICD_IPRIORITYR + (id & ~3); + unsigned int shift = (id & 3) << 3; + unsigned int reg_val = mmio_read_32(reg); + + /* + * Enforce ARM recommendation to manage priority values such + * that group1 interrupts always have a lower priority than + * group0 interrupts. + * Note, lower numerical values are higher priorities so the comparison + * checks below are reversed from what might be expected. + */ + assert(gicd_get_igroupr(base, id) == GRP1 ? + pri >= GIC_HIGHEST_NS_PRIORITY && + pri <= GIC_LOWEST_NS_PRIORITY : + pri >= GIC_HIGHEST_SEC_PRIORITY && + pri <= GIC_LOWEST_SEC_PRIORITY); + + reg_val &= ~(GIC_PRI_MASK << shift); + reg_val |= (pri & GIC_PRI_MASK) << shift; + mmio_write_32(reg, reg_val); +} + +void gicd_set_itargetsr(unsigned int base, unsigned int id, unsigned int iface) +{ + unsigned byte_off = id & ((1 << ITARGETSR_SHIFT) - 1); + unsigned int reg_val = gicd_read_itargetsr(base, id); + + gicd_write_itargetsr(base, id, reg_val | + (1 << iface) << (byte_off << 3)); +} + +/******************************************************************************* + * This function allows the interrupt management framework to determine (through + * the platform) which interrupt line (IRQ/FIQ) to use for an interrupt type to + * route it to EL3. The interrupt line is represented as the bit position of the + * IRQ or FIQ bit in the SCR_EL3. + ******************************************************************************/ +uint32_t gicv2_interrupt_type_to_line(uint32_t cpuif_base, uint32_t type) +{ + uint32_t gicc_ctlr; + + /* Non-secure interrupts are signalled on the IRQ line always */ + if (type == INTR_TYPE_NS) + return __builtin_ctz(SCR_IRQ_BIT); + + /* + * Secure interrupts are signalled using the IRQ line if the FIQ_EN + * bit is not set else they are signalled using the FIQ line. + */ + gicc_ctlr = gicc_read_ctlr(cpuif_base); + if (gicc_ctlr & FIQ_EN) + return __builtin_ctz(SCR_FIQ_BIT); + else + return __builtin_ctz(SCR_IRQ_BIT); +} diff --git a/drivers/arm/gic/gic_v3.c b/drivers/arm/gic/gic_v3.c new file mode 100644 index 0000000..f429662 --- /dev/null +++ b/drivers/arm/gic/gic_v3.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <debug.h> +#include <gic_v3.h> + +uintptr_t gicv3_get_rdist(uintptr_t gicr_base, uint64_t mpidr) +{ + uint32_t cpu_aff, gicr_aff; + uint64_t gicr_typer; + uintptr_t addr; + + /* Construct the affinity as used by GICv3. MPIDR and GIC affinity level + * mask is the same. + */ + cpu_aff = ((mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK) << + GICV3_AFF0_SHIFT; + cpu_aff |= ((mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK) << + GICV3_AFF1_SHIFT; + cpu_aff |= ((mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK) << + GICV3_AFF2_SHIFT; + cpu_aff |= ((mpidr >> MPIDR_AFF3_SHIFT) & MPIDR_AFFLVL_MASK) << + GICV3_AFF3_SHIFT; + + addr = gicr_base; + do { + gicr_typer = gicr_read_typer(addr); + + gicr_aff = (gicr_typer >> GICR_TYPER_AFF_SHIFT) & + GICR_TYPER_AFF_MASK; + if (cpu_aff == gicr_aff) { + /* Disable this print for now as it appears every time + * when using PSCI CPU_SUSPEND. + * TODO: Print this only the first time for each CPU. + * INFO("GICv3 - Found RDIST for MPIDR(0x%lx) at 0x%lx\n", + * mpidr, addr); + */ + return addr; + } + + /* TODO: + * For GICv4 we need to adjust the Base address based on + * GICR_TYPER.VLPIS + */ + addr += (1 << GICR_PCPUBASE_SHIFT); + + } while (!(gicr_typer & GICR_TYPER_LAST)); + + /* If we get here we did not find a match. */ + ERROR("GICv3 - Did not find RDIST for CPU with MPIDR 0x%lx\n", mpidr); + return (uintptr_t)NULL; +} diff --git a/drivers/arm/pl011/pl011.c b/drivers/arm/pl011/pl011.c new file mode 100644 index 0000000..e296c23 --- /dev/null +++ b/drivers/arm/pl011/pl011.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <pl011.h> + +void pl011_setbaudrate(unsigned long base_addr, unsigned int baudrate) +{ + unsigned int divisor; + assert(baudrate); + divisor = (PL011_CLK_IN_HZ * 4) / baudrate; + pl011_write_ibrd(base_addr, divisor >> 6); + pl011_write_fbrd(base_addr, divisor & 0x3F); +} diff --git a/drivers/arm/pl011/pl011_console.c b/drivers/arm/pl011/pl011_console.c new file mode 100644 index 0000000..a26c00e --- /dev/null +++ b/drivers/arm/pl011/pl011_console.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <console.h> +#include <pl011.h> + +static unsigned long uart_base; + +void console_init(unsigned long base_addr) +{ + /* TODO: assert() internally calls printf() and will result in + * an infinite loop. This needs to be fixed with some kind of + * exception mechanism or early panic support. This also applies + * to the other assert() calls below. + */ + assert(base_addr); + + /* Initialise internal base address variable */ + uart_base = base_addr; + + /* Baud Rate */ +#if defined(PL011_INTEGER) && defined(PL011_FRACTIONAL) + pl011_write_ibrd(uart_base, PL011_INTEGER); + pl011_write_fbrd(uart_base, PL011_FRACTIONAL); +#else + pl011_setbaudrate(uart_base, PL011_BAUDRATE); +#endif + + pl011_write_lcr_h(uart_base, PL011_LINE_CONTROL); + + /* Clear any pending errors */ + pl011_write_ecr(uart_base, 0); + + /* Enable tx, rx, and uart overall */ + pl011_write_cr(uart_base, PL011_UARTCR_RXE | PL011_UARTCR_TXE | + PL011_UARTCR_UARTEN); + +} + +#define WAIT_UNTIL_UART_FREE(base) \ + while ((pl011_read_fr(base) & PL011_UARTFR_TXFF)) \ + continue + +int console_putc(int c) +{ + assert(uart_base); + + if (c == '\n') { + WAIT_UNTIL_UART_FREE(uart_base); + pl011_write_dr(uart_base, '\r'); + } + + WAIT_UNTIL_UART_FREE(uart_base); + pl011_write_dr(uart_base, c); + return c; +} + +int console_getc(void) +{ + assert(uart_base); + + while ((pl011_read_fr(uart_base) & PL011_UARTFR_RXFE) != 0) + ; + return pl011_read_dr(uart_base); +} diff --git a/drivers/arm/serial/serial.c b/drivers/arm/serial/serial.c new file mode 100644 index 0000000..8f7f0b1 --- /dev/null +++ b/drivers/arm/serial/serial.c @@ -0,0 +1,101 @@ +#include <serial.h> +#include <io.h> +#include <stdint.h> +#include <asm/arch/secure_apb.h> + +void serial_set_pin_port(unsigned port_base) +{ + setbits_le32(P_AO_RTI_PIN_MUX_REG,3<<11); +} + +#define UART_STP_BIT UART_CNTL_MASK_STP_1BIT +#define UART_PRTY_BIT 0 +#define UART_CHAR_LEN UART_CNTL_MASK_CHAR_8BIT + +void serial_init(unsigned set) +{ + /* baud rate */ + writel(set| UART_STP_BIT + | UART_PRTY_BIT + | UART_CHAR_LEN + //please do not remove these setting , jerry.yu + | UART_CNTL_MASK_TX_EN + | UART_CNTL_MASK_RX_EN + | UART_CNTL_MASK_RST_TX + | UART_CNTL_MASK_RST_RX + | UART_CNTL_MASK_CLR_ERR + ,P_UART_CONTROL(UART_PORT_CONS)); + serial_set_pin_port(UART_PORT_CONS); + clrbits_le32(P_UART_CONTROL(UART_PORT_CONS), + UART_CNTL_MASK_RST_TX | UART_CNTL_MASK_RST_RX | UART_CNTL_MASK_CLR_ERR); +} + +int serial_putc(int c) +{ + if (c == '\n') { + while ((readl(P_UART_STATUS(UART_PORT_CONS)) & UART_STAT_MASK_TFIFO_FULL)); + writel('\r', P_UART_WFIFO(UART_PORT_CONS)); + } + /* Wait till dataTx register is not full */ + while ((readl(P_UART_STATUS(UART_PORT_CONS)) & UART_STAT_MASK_TFIFO_FULL)); + writel(c, P_UART_WFIFO(UART_PORT_CONS)); + /* Wait till dataTx register is empty */ + return c; +} + +int serial_getc(void) +{ + unsigned char ch; + /* Wait till character is placed in fifo */ + while ((readl(P_UART_STATUS(UART_PORT_CONS)) & UART_STAT_MASK_RFIFO_CNT) == 0) ; + + /* Also check for overflow errors */ + if (readl(P_UART_STATUS(UART_PORT_CONS)) & (UART_STAT_MASK_PRTY_ERR | UART_STAT_MASK_FRAM_ERR)) + { + setbits_le32(P_UART_CONTROL(UART_PORT_CONS),UART_CNTL_MASK_CLR_ERR); + clrbits_le32(P_UART_CONTROL(UART_PORT_CONS),UART_CNTL_MASK_CLR_ERR); + } + + ch = readl(P_UART_RFIFO(UART_PORT_CONS)) & 0x00ff; + return ((int)ch); +} + +int serial_puts(const char *s){ + while (*s) { + serial_putc(*s++); + } + return 0; +} + +//support 64bit number, serial_put_hex(data, 64); +void serial_put_hex(unsigned long data,unsigned int bitlen) +{ + int i; + for (i=bitlen-4;i>=0;i-=4) { + if ((data>>i) == 0) + { + serial_putc(0x30); + continue; + } + unsigned char s = (data>>i)&0xf; + if (s<10) + serial_putc(0x30+s); + else + serial_putc(0x61+s-10); + } +} + +void serial_put_dec(unsigned long data) +{ + char szTxt[10]; + szTxt[0] = 0x30; + int i = 0; + + do { + szTxt[i++] = (data % 10) + 0x30; + data = data / 10; + } while(data); + + for (--i;i >=0;--i) + serial_putc(szTxt[i]); +}
\ No newline at end of file diff --git a/drivers/arm/tzc400/tzc400.c b/drivers/arm/tzc400/tzc400.c new file mode 100644 index 0000000..c1716db --- /dev/null +++ b/drivers/arm/tzc400/tzc400.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <debug.h> +#include <mmio.h> +#include <stddef.h> +#include <tzc400.h> + +static uint32_t tzc_read_build_config(uint64_t base) +{ + return mmio_read_32(base + BUILD_CONFIG_OFF); +} + +static uint32_t tzc_read_gate_keeper(uint64_t base) +{ + return mmio_read_32(base + GATE_KEEPER_OFF); +} + +static void tzc_write_gate_keeper(uint64_t base, uint32_t val) +{ + mmio_write_32(base + GATE_KEEPER_OFF, val); +} + +static void tzc_write_action(uint64_t base, tzc_action_t action) +{ + mmio_write_32(base + ACTION_OFF, action); +} + +static void tzc_write_region_base_low(uint64_t base, uint32_t region, uint32_t val) +{ + mmio_write_32(base + REGION_BASE_LOW_OFF + REGION_NUM_OFF(region), val); +} + +static void tzc_write_region_base_high(uint64_t base, uint32_t region, uint32_t val) +{ + mmio_write_32(base + REGION_BASE_HIGH_OFF + REGION_NUM_OFF(region), val); +} + +static void tzc_write_region_top_low(uint64_t base, uint32_t region, uint32_t val) +{ + mmio_write_32(base + REGION_TOP_LOW_OFF + REGION_NUM_OFF(region), val); +} + +static void tzc_write_region_top_high(uint64_t base, uint32_t region, uint32_t val) +{ + mmio_write_32(base + REGION_TOP_HIGH_OFF + REGION_NUM_OFF(region), val); +} + +static void tzc_write_region_attributes(uint64_t base, uint32_t region, uint32_t val) +{ + mmio_write_32(base + REGION_ATTRIBUTES_OFF + REGION_NUM_OFF(region), val); +} + +static void tzc_write_region_id_access(uint64_t base, uint32_t region, uint32_t val) +{ + mmio_write_32(base + REGION_ID_ACCESS_OFF + REGION_NUM_OFF(region), val); +} + +static uint32_t tzc_read_component_id(uint64_t base) +{ + uint32_t id; + + id = mmio_read_8(base + CID0_OFF); + id |= (mmio_read_8(base + CID1_OFF) << 8); + id |= (mmio_read_8(base + CID2_OFF) << 16); + id |= (mmio_read_8(base + CID3_OFF) << 24); + + return id; +} + +static uint32_t tzc_get_gate_keeper(uint64_t base, uint8_t filter) +{ + uint32_t tmp; + + tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) & + GATE_KEEPER_OS_MASK; + + return tmp >> filter; +} + +/* This function is not MP safe. */ +static void tzc_set_gate_keeper(uint64_t base, uint8_t filter, uint32_t val) +{ + uint32_t tmp; + + /* Upper half is current state. Lower half is requested state. */ + tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) & + GATE_KEEPER_OS_MASK; + + if (val) + tmp |= (1 << filter); + else + tmp &= ~(1 << filter); + + tzc_write_gate_keeper(base, (tmp & GATE_KEEPER_OR_MASK) << + GATE_KEEPER_OR_SHIFT); + + /* Wait here until we see the change reflected in the TZC status. */ + while (((tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) & + GATE_KEEPER_OS_MASK) != tmp) + ; +} + + +void tzc_init(tzc_instance_t *controller) +{ + uint32_t tzc_id, tzc_build; + + assert(controller != NULL); + + /* + * We expect to see a tzc400. Check component ID. The TZC-400 TRM shows + * component ID is expected to be "0xB105F00D". + */ + tzc_id = tzc_read_component_id(controller->base); + if (tzc_id != TZC400_COMPONENT_ID) { + ERROR("TZC : Wrong device ID (0x%x).\n", tzc_id); + panic(); + } + + /* Save values we will use later. */ + tzc_build = tzc_read_build_config(controller->base); + controller->num_filters = ((tzc_build >> BUILD_CONFIG_NF_SHIFT) & + BUILD_CONFIG_NF_MASK) + 1; + controller->addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) & + BUILD_CONFIG_AW_MASK) + 1; + controller->num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) & + BUILD_CONFIG_NR_MASK) + 1; +} + + +/* + * `tzc_configure_region` is used to program regions into the TrustZone + * controller. A region can be associated with more than one filter. The + * associated filters are passed in as a bitmap (bit0 = filter0). + * NOTE: + * The region 0 covers the whole address space and is enabled on all filters, + * this cannot be changed. It is, however, possible to change some region 0 + * permissions. + */ +void tzc_configure_region(const tzc_instance_t *controller, + uint32_t filters, + uint8_t region, + uint64_t region_base, + uint64_t region_top, + tzc_region_attributes_t sec_attr, + uint32_t ns_device_access) +{ + uint64_t max_addr; + + assert(controller != NULL); + + /* Do range checks on filters and regions. */ + assert(((filters >> controller->num_filters) == 0) && + (region < controller->num_regions)); + + /* + * Do address range check based on TZC configuration. A 64bit address is + * the max and expected case. + */ + max_addr = UINT64_MAX >> (64 - controller->addr_width); + if ((region_top > max_addr) || (region_base >= region_top)) + assert(0); + + /* region_base and (region_top + 1) must be 4KB aligned */ + assert(((region_base | (region_top + 1)) & (4096 - 1)) == 0); + + assert(sec_attr <= TZC_REGION_S_RDWR); + + /* + * Inputs look ok, start programming registers. + * All the address registers are 32 bits wide and have a LOW and HIGH + * component used to construct a up to a 64bit address. + */ + tzc_write_region_base_low(controller->base, region, (uint32_t)(region_base)); + tzc_write_region_base_high(controller->base, region, (uint32_t)(region_base >> 32)); + + tzc_write_region_top_low(controller->base, region, (uint32_t)(region_top)); + tzc_write_region_top_high(controller->base, region, (uint32_t)(region_top >> 32)); + + /* Assign the region to a filter and set secure attributes */ + tzc_write_region_attributes(controller->base, region, + (sec_attr << REGION_ATTRIBUTES_SEC_SHIFT) | filters); + + /* + * Specify which non-secure devices have permission to access this + * region. + */ + tzc_write_region_id_access(controller->base, region, ns_device_access); +} + + +void tzc_set_action(const tzc_instance_t *controller, tzc_action_t action) +{ + assert(controller != NULL); + + /* + * - Currently no handler is provided to trap an error via interrupt + * or exception. + * - The interrupt action has not been tested. + */ + tzc_write_action(controller->base, action); +} + + +void tzc_enable_filters(const tzc_instance_t *controller) +{ + uint32_t state; + uint32_t filter; + + assert(controller != NULL); + + for (filter = 0; filter < controller->num_filters; filter++) { + state = tzc_get_gate_keeper(controller->base, filter); + if (state) { + ERROR("TZC : Filter %d Gatekeeper already enabled.\n", + filter); + panic(); + } + tzc_set_gate_keeper(controller->base, filter, 1); + } +} + + +void tzc_disable_filters(const tzc_instance_t *controller) +{ + uint32_t filter; + + assert(controller != NULL); + + /* + * We don't do the same state check as above as the Gatekeepers are + * disabled after reset. + */ + for (filter = 0; filter < controller->num_filters; filter++) + tzc_set_gate_keeper(controller->base, filter, 0); +} diff --git a/drivers/io/io_fip.c b/drivers/io/io_fip.c new file mode 100644 index 0000000..cb76797 --- /dev/null +++ b/drivers/io/io_fip.c @@ -0,0 +1,420 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <bl_common.h> +#include <debug.h> +#include <errno.h> +#include <firmware_image_package.h> +#include <io_driver.h> +#include <io_fip.h> +#include <io_storage.h> +#include <platform.h> +#include <platform_def.h> +#include <stdint.h> +#include <string.h> +#include <uuid.h> + +/* Useful for printing UUIDs when debugging.*/ +#define PRINT_UUID2(x) \ + "%08x-%04hx-%04hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", \ + x.time_low, x.time_mid, x.time_hi_and_version, \ + x.clock_seq_hi_and_reserved, x.clock_seq_low, \ + x.node[0], x.node[1], x.node[2], x.node[3], \ + x.node[4], x.node[5] + +typedef struct { + const char *name; + const uuid_t uuid; +} plat_fip_name_uuid_t; + +typedef struct { + /* Put file_pos above the struct to allow {0} on static init. + * It is a workaround for a known bug in GCC + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119 + */ + unsigned int file_pos; + fip_toc_entry_t entry; +} file_state_t; + +static const plat_fip_name_uuid_t name_uuid[] = { + {BL2_IMAGE_NAME, UUID_TRUSTED_BOOT_FIRMWARE_BL2}, +#ifdef BL30_IMAGE_NAME + {BL30_IMAGE_NAME, UUID_SCP_FIRMWARE_BL30}, +#endif + {BL31_IMAGE_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31}, +#ifdef BL32_IMAGE_NAME + /* BL3-2 is optional in the platform */ + {BL32_IMAGE_NAME, UUID_SECURE_PAYLOAD_BL32}, +#endif /* BL32_IMAGE_NAME */ + {BL33_IMAGE_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33}, +}; + +static const uuid_t uuid_null = {0}; +static file_state_t current_file = {0}; +static uintptr_t backend_dev_handle; +static uintptr_t backend_image_spec; + + +/* Firmware Image Package driver functions */ +static int fip_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info); +static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec, + io_entity_t *entity); +static int fip_file_len(io_entity_t *entity, size_t *length); +static int fip_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, + size_t *length_read); +static int fip_file_close(io_entity_t *entity); +static int fip_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params); +static int fip_dev_close(io_dev_info_t *dev_info); + + +static inline int copy_uuid(uuid_t *dst, const uuid_t *src) +{ + memcpy(dst, src, sizeof(uuid_t)); + return 0; +} + + +/* Return 0 for equal uuids. */ +static inline int compare_uuids(const uuid_t *uuid1, const uuid_t *uuid2) +{ + return memcmp(uuid1, uuid2, sizeof(uuid_t)); +} + + +/* TODO: We could check version numbers or do a package checksum? */ +static inline int is_valid_header(fip_toc_header_t *header) +{ + if ((header->name == TOC_HEADER_NAME) && (header->serial_number != 0)) { + return 1; + } else { + return 0; + } +} + + +static int file_to_uuid(const char *filename, uuid_t *uuid) +{ + int i; + int status = -EINVAL; + + for (i = 0; i < (sizeof(name_uuid) / sizeof(name_uuid[0])); i++) { + if (strcmp(filename, name_uuid[i].name) == 0) { + copy_uuid(uuid, &name_uuid[i].uuid); + status = 0; + break; + } + } + return status; +} + + +/* Identify the device type as a virtual driver */ +io_type_t device_type_fip(void) +{ + return IO_TYPE_FIRMWARE_IMAGE_PACKAGE; +} + + +static const io_dev_connector_t fip_dev_connector = { + .dev_open = fip_dev_open +}; + + +static const io_dev_funcs_t fip_dev_funcs = { + .type = device_type_fip, + .open = fip_file_open, + .seek = NULL, + .size = fip_file_len, + .read = fip_file_read, + .write = NULL, + .close = fip_file_close, + .dev_init = fip_dev_init, + .dev_close = fip_dev_close, +}; + + +/* No state associated with this device so structure can be const */ +static const io_dev_info_t fip_dev_info = { + .funcs = &fip_dev_funcs, + .info = (uintptr_t)NULL +}; + + +/* Open a connection to the FIP device */ +static int fip_dev_open(const uintptr_t dev_spec __attribute__((unused)), + io_dev_info_t **dev_info) +{ + assert(dev_info != NULL); + *dev_info = (io_dev_info_t *)&fip_dev_info; /* cast away const */ + + return IO_SUCCESS; +} + + +/* Do some basic package checks. */ +static int fip_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params) +{ + int result = IO_FAIL; + char *image_name = (char *)init_params; + uintptr_t backend_handle; + fip_toc_header_t header; + size_t bytes_read; + + /* Obtain a reference to the image by querying the platform layer */ + result = plat_get_image_source(image_name, &backend_dev_handle, + &backend_image_spec); + if (result != IO_SUCCESS) { + WARN("Failed to obtain reference to image '%s' (%i)\n", + image_name, result); + result = IO_FAIL; + goto fip_dev_init_exit; + } + + /* Attempt to access the FIP image */ + result = io_open(backend_dev_handle, backend_image_spec, + &backend_handle); + if (result != IO_SUCCESS) { + WARN("Failed to access image '%s' (%i)\n", image_name, result); + result = IO_FAIL; + goto fip_dev_init_exit; + } + + result = io_read(backend_handle, (uintptr_t)&header, sizeof(header), + &bytes_read); + if (result == IO_SUCCESS) { + if (!is_valid_header(&header)) { + WARN("Firmware Image Package header check failed.\n"); + result = IO_FAIL; + } else { + INFO("FIP header looks OK.\n"); + } + } + + io_close(backend_handle); + + fip_dev_init_exit: + return result; +} + +/* Close a connection to the FIP device */ +static int fip_dev_close(io_dev_info_t *dev_info) +{ + /* TODO: Consider tracking open files and cleaning them up here */ + + /* Clear the backend. */ + backend_dev_handle = (uintptr_t)NULL; + backend_image_spec = (uintptr_t)NULL; + + return IO_SUCCESS; +} + + +/* Open a file for access from package. */ +static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec, + io_entity_t *entity) +{ + int result = IO_FAIL; + uintptr_t backend_handle; + uuid_t file_uuid; + const io_file_spec_t *file_spec = (io_file_spec_t *)spec; + size_t bytes_read; + int found_file = 0; + + assert(file_spec != NULL); + assert(entity != NULL); + + /* Can only have one file open at a time for the moment. We need to + * track state like file cursor position. We know the header lives at + * offset zero, so this entry should never be zero for an active file. + * When the system supports dynamic memory allocation we can allow more + * than one open file at a time if needed. + */ + if (current_file.entry.offset_address != 0) { + WARN("fip_file_open : Only one open file at a time.\n"); + return IO_RESOURCES_EXHAUSTED; + } + + /* Attempt to access the FIP image */ + result = io_open(backend_dev_handle, backend_image_spec, + &backend_handle); + if (result != IO_SUCCESS) { + WARN("Failed to open Firmware Image Package (%i)\n", result); + result = IO_FAIL; + goto fip_file_open_exit; + } + + /* Seek past the FIP header into the Table of Contents */ + result = io_seek(backend_handle, IO_SEEK_SET, sizeof(fip_toc_header_t)); + if (result != IO_SUCCESS) { + WARN("fip_file_open: failed to seek\n"); + result = IO_FAIL; + goto fip_file_open_close; + } + + file_to_uuid(file_spec->path, &file_uuid); + + found_file = 0; + do { + result = io_read(backend_handle, + (uintptr_t)¤t_file.entry, + sizeof(current_file.entry), + &bytes_read); + if (result == IO_SUCCESS) { + if (compare_uuids(¤t_file.entry.uuid, + &file_uuid) == 0) { + found_file = 1; + break; + } + } else { + WARN("Failed to read FIP (%i)\n", result); + goto fip_file_open_close; + } + } while (compare_uuids(¤t_file.entry.uuid, &uuid_null) != 0); + + if (found_file == 1) { + /* All fine. Update entity info with file state and return. Set + * the file position to 0. The 'current_file.entry' holds the + * base and size of the file. + */ + current_file.file_pos = 0; + entity->info = (uintptr_t)¤t_file; + } else { + /* Did not find the file in the FIP. */ + current_file.entry.offset_address = 0; + result = IO_FAIL; + } + + fip_file_open_close: + io_close(backend_handle); + + fip_file_open_exit: + return result; +} + + +/* Return the size of a file in package */ +static int fip_file_len(io_entity_t *entity, size_t *length) +{ + assert(entity != NULL); + assert(length != NULL); + + *length = ((file_state_t *)entity->info)->entry.size; + + return IO_SUCCESS; +} + + +/* Read data from a file in package */ +static int fip_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, + size_t *length_read) +{ + int result = IO_FAIL; + file_state_t *fp; + size_t file_offset; + size_t bytes_read; + uintptr_t backend_handle; + + assert(entity != NULL); + assert(buffer != (uintptr_t)NULL); + assert(length_read != NULL); + assert(entity->info != (uintptr_t)NULL); + + /* Open the backend, attempt to access the blob image */ + result = io_open(backend_dev_handle, backend_image_spec, + &backend_handle); + if (result != IO_SUCCESS) { + WARN("Failed to open FIP (%i)\n", result); + result = IO_FAIL; + goto fip_file_read_exit; + } + + fp = (file_state_t *)entity->info; + + /* Seek to the position in the FIP where the payload lives */ + file_offset = fp->entry.offset_address + fp->file_pos; + result = io_seek(backend_handle, IO_SEEK_SET, file_offset); + if (result != IO_SUCCESS) { + WARN("fip_file_read: failed to seek\n"); + result = IO_FAIL; + goto fip_file_read_close; + } + + result = io_read(backend_handle, buffer, length, &bytes_read); + if (result != IO_SUCCESS) { + /* We cannot read our data. Fail. */ + WARN("Failed to read payload (%i)\n", result); + result = IO_FAIL; + goto fip_file_read_close; + } else { + /* Set caller length and new file position. */ + *length_read = bytes_read; + fp->file_pos += bytes_read; + } + +/* Close the backend. */ + fip_file_read_close: + io_close(backend_handle); + + fip_file_read_exit: + return result; +} + + +/* Close a file in package */ +static int fip_file_close(io_entity_t *entity) +{ + /* Clear our current file pointer. + * If we had malloc() we would free() here. + */ + if (current_file.entry.offset_address != 0) { + memset(¤t_file, 0, sizeof(current_file)); + } + + /* Clear the Entity info. */ + entity->info = 0; + + return IO_SUCCESS; +} + +/* Exported functions */ + +/* Register the Firmware Image Package driver with the IO abstraction */ +int register_io_dev_fip(const io_dev_connector_t **dev_con) +{ + int result = IO_FAIL; + assert(dev_con != NULL); + + result = io_register_device(&fip_dev_info); + if (result == IO_SUCCESS) + *dev_con = &fip_dev_connector; + + return result; +} diff --git a/drivers/io/io_memmap.c b/drivers/io/io_memmap.c new file mode 100644 index 0000000..fc06fbb --- /dev/null +++ b/drivers/io/io_memmap.c @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <debug.h> +#include <io_driver.h> +#include <io_storage.h> +#include <string.h> + +/* As we need to be able to keep state for seek, only one file can be open + * at a time. Make this a structure and point to the entity->info. When we + * can malloc memory we can change this to support more open files. + */ +typedef struct { + /* Use the 'in_use' flag as any value for base and file_pos could be + * valid. + */ + int in_use; + uintptr_t base; + size_t file_pos; +} file_state_t; + +static file_state_t current_file = {0}; + +/* Identify the device type as memmap */ +io_type_t device_type_memmap(void) +{ + return IO_TYPE_MEMMAP; +} + +/* Memmap device functions */ +static int memmap_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info); +static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec, + io_entity_t *entity); +static int memmap_block_seek(io_entity_t *entity, int mode, + ssize_t offset); +static int memmap_block_read(io_entity_t *entity, uintptr_t buffer, + size_t length, size_t *length_read); +static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer, + size_t length, size_t *length_written); +static int memmap_block_close(io_entity_t *entity); +static int memmap_dev_close(io_dev_info_t *dev_info); + + +static const io_dev_connector_t memmap_dev_connector = { + .dev_open = memmap_dev_open +}; + + +static const io_dev_funcs_t memmap_dev_funcs = { + .type = device_type_memmap, + .open = memmap_block_open, + .seek = memmap_block_seek, + .size = NULL, + .read = memmap_block_read, + .write = memmap_block_write, + .close = memmap_block_close, + .dev_init = NULL, + .dev_close = memmap_dev_close, +}; + + +/* No state associated with this device so structure can be const */ +static const io_dev_info_t memmap_dev_info = { + .funcs = &memmap_dev_funcs, + .info = (uintptr_t)NULL +}; + + +/* Open a connection to the memmap device */ +static int memmap_dev_open(const uintptr_t dev_spec __attribute__((unused)), + io_dev_info_t **dev_info) +{ + assert(dev_info != NULL); + *dev_info = (io_dev_info_t *)&memmap_dev_info; /* cast away const */ + + return IO_SUCCESS; +} + + + +/* Close a connection to the memmap device */ +static int memmap_dev_close(io_dev_info_t *dev_info) +{ + /* NOP */ + /* TODO: Consider tracking open files and cleaning them up here */ + return IO_SUCCESS; +} + + +/* Open a file on the memmap device */ +/* TODO: Can we do any sensible limit checks on requested memory */ +static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec, + io_entity_t *entity) +{ + int result = IO_FAIL; + const io_block_spec_t *block_spec = (io_block_spec_t *)spec; + + /* Since we need to track open state for seek() we only allow one open + * spec at a time. When we have dynamic memory we can malloc and set + * entity->info. + */ + if (current_file.in_use == 0) { + assert(block_spec != NULL); + assert(entity != NULL); + + current_file.in_use = 1; + current_file.base = block_spec->offset; + /* File cursor offset for seek and incremental reads etc. */ + current_file.file_pos = 0; + entity->info = (uintptr_t)¤t_file; + result = IO_SUCCESS; + } else { + WARN("A Memmap device is already active. Close first.\n"); + result = IO_RESOURCES_EXHAUSTED; + } + + return result; +} + + +/* Seek to a particular file offset on the memmap device */ +static int memmap_block_seek(io_entity_t *entity, int mode, ssize_t offset) +{ + int result = IO_FAIL; + + /* We only support IO_SEEK_SET for the moment. */ + if (mode == IO_SEEK_SET) { + assert(entity != NULL); + + /* TODO: can we do some basic limit checks on seek? */ + ((file_state_t *)entity->info)->file_pos = offset; + result = IO_SUCCESS; + } else { + result = IO_FAIL; + } + + return result; +} + + +/* Read data from a file on the memmap device */ +static int memmap_block_read(io_entity_t *entity, uintptr_t buffer, + size_t length, size_t *length_read) +{ + file_state_t *fp; + + assert(entity != NULL); + assert(buffer != (uintptr_t)NULL); + assert(length_read != NULL); + + fp = (file_state_t *)entity->info; + + memcpy((void *)buffer, (void *)(fp->base + fp->file_pos), length); + + *length_read = length; + /* advance the file 'cursor' for incremental reads */ + fp->file_pos += length; + + return IO_SUCCESS; +} + + +/* Write data to a file on the memmap device */ +static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer, + size_t length, size_t *length_written) +{ + file_state_t *fp; + + assert(entity != NULL); + assert(buffer != (uintptr_t)NULL); + assert(length_written != NULL); + + fp = (file_state_t *)entity->info; + + memcpy((void *)(fp->base + fp->file_pos), (void *)buffer, length); + + *length_written = length; + + /* advance the file 'cursor' for incremental writes */ + fp->file_pos += length; + + return IO_SUCCESS; +} + + +/* Close a file on the memmap device */ +static int memmap_block_close(io_entity_t *entity) +{ + assert(entity != NULL); + + entity->info = 0; + + /* This would be a mem free() if we had malloc.*/ + memset((void *)¤t_file, 0, sizeof(current_file)); + + return IO_SUCCESS; +} + + +/* Exported functions */ + +/* Register the memmap driver with the IO abstraction */ +int register_io_dev_memmap(const io_dev_connector_t **dev_con) +{ + int result = IO_FAIL; + assert(dev_con != NULL); + + result = io_register_device(&memmap_dev_info); + if (result == IO_SUCCESS) + *dev_con = &memmap_dev_connector; + + return result; +} diff --git a/drivers/io/io_semihosting.c b/drivers/io/io_semihosting.c new file mode 100644 index 0000000..3c92c6d --- /dev/null +++ b/drivers/io/io_semihosting.c @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <io_driver.h> +#include <io_storage.h> +#include <semihosting.h> + + + +/* Identify the device type as semihosting */ +static io_type_t device_type_sh(void) +{ + return IO_TYPE_SEMIHOSTING; +} + + +/* Semi-hosting functions, device info and handle */ + +static int sh_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info); +static int sh_file_open(io_dev_info_t *dev_info, const uintptr_t spec, + io_entity_t *entity); +static int sh_file_seek(io_entity_t *entity, int mode, ssize_t offset); +static int sh_file_len(io_entity_t *entity, size_t *length); +static int sh_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, + size_t *length_read); +static int sh_file_write(io_entity_t *entity, const uintptr_t buffer, + size_t length, size_t *length_written); +static int sh_file_close(io_entity_t *entity); + +static const io_dev_connector_t sh_dev_connector = { + .dev_open = sh_dev_open +}; + + +static const io_dev_funcs_t sh_dev_funcs = { + .type = device_type_sh, + .open = sh_file_open, + .seek = sh_file_seek, + .size = sh_file_len, + .read = sh_file_read, + .write = sh_file_write, + .close = sh_file_close, + .dev_init = NULL, /* NOP */ + .dev_close = NULL, /* NOP */ +}; + + +/* No state associated with this device so structure can be const */ +static const io_dev_info_t sh_dev_info = { + .funcs = &sh_dev_funcs, + .info = (uintptr_t)NULL +}; + + +/* Open a connection to the semi-hosting device */ +static int sh_dev_open(const uintptr_t dev_spec __unused, + io_dev_info_t **dev_info) +{ + int result = IO_SUCCESS; + assert(dev_info != NULL); + *dev_info = (io_dev_info_t *)&sh_dev_info; /* cast away const */ + return result; +} + + +/* Open a file on the semi-hosting device */ +static int sh_file_open(io_dev_info_t *dev_info __attribute__((unused)), + const uintptr_t spec, io_entity_t *entity) +{ + int result = IO_FAIL; + long sh_result = -1; + const io_file_spec_t *file_spec = (const io_file_spec_t *)spec; + + assert(file_spec != NULL); + assert(entity != NULL); + + sh_result = semihosting_file_open(file_spec->path, file_spec->mode); + + if (sh_result > 0) { + entity->info = (uintptr_t)sh_result; + result = IO_SUCCESS; + } else { + result = IO_FAIL; + } + return result; +} + + +/* Seek to a particular file offset on the semi-hosting device */ +static int sh_file_seek(io_entity_t *entity, int mode, ssize_t offset) +{ + int result = IO_FAIL; + long file_handle, sh_result; + + assert(entity != NULL); + + file_handle = (long)entity->info; + + sh_result = semihosting_file_seek(file_handle, offset); + + result = (sh_result == 0) ? IO_SUCCESS : IO_FAIL; + + return result; +} + + +/* Return the size of a file on the semi-hosting device */ +static int sh_file_len(io_entity_t *entity, size_t *length) +{ + int result = IO_FAIL; + + assert(entity != NULL); + assert(length != NULL); + + long sh_handle = (long)entity->info; + long sh_result = semihosting_file_length(sh_handle); + + if (sh_result >= 0) { + result = IO_SUCCESS; + *length = (size_t)sh_result; + } + + return result; +} + + +/* Read data from a file on the semi-hosting device */ +static int sh_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, + size_t *length_read) +{ + int result = IO_FAIL; + long sh_result = -1; + size_t bytes = length; + long file_handle; + + assert(entity != NULL); + assert(buffer != (uintptr_t)NULL); + assert(length_read != NULL); + + file_handle = (long)entity->info; + + sh_result = semihosting_file_read(file_handle, &bytes, buffer); + + if (sh_result >= 0) { + *length_read = (bytes != length) ? bytes : length; + result = IO_SUCCESS; + } else + result = IO_FAIL; + + return result; +} + + +/* Write data to a file on the semi-hosting device */ +static int sh_file_write(io_entity_t *entity, const uintptr_t buffer, + size_t length, size_t *length_written) +{ + int result = IO_FAIL; + long sh_result = -1; + long file_handle; + size_t bytes = length; + + assert(entity != NULL); + assert(buffer != (uintptr_t)NULL); + assert(length_written != NULL); + + file_handle = (long)entity->info; + + sh_result = semihosting_file_write(file_handle, &bytes, buffer); + + if (sh_result >= 0) { + *length_written = sh_result; + result = IO_SUCCESS; + } else + result = IO_FAIL; + + return result; +} + + +/* Close a file on the semi-hosting device */ +static int sh_file_close(io_entity_t *entity) +{ + int result = IO_FAIL; + long sh_result = -1; + long file_handle; + + assert(entity != NULL); + + file_handle = (long)entity->info; + + sh_result = semihosting_file_close(file_handle); + + result = (sh_result >= 0) ? IO_SUCCESS : IO_FAIL; + + return result; +} + + +/* Exported functions */ + +/* Register the semi-hosting driver with the IO abstraction */ +int register_io_dev_sh(const io_dev_connector_t **dev_con) +{ + int result = IO_FAIL; + assert(dev_con != NULL); + + result = io_register_device(&sh_dev_info); + if (result == IO_SUCCESS) + *dev_con = &sh_dev_connector; + + return result; +} diff --git a/fdts/fvp-base-gicv2-psci.dtb b/fdts/fvp-base-gicv2-psci.dtb Binary files differnew file mode 100644 index 0000000..efe83be --- /dev/null +++ b/fdts/fvp-base-gicv2-psci.dtb diff --git a/fdts/fvp-base-gicv2-psci.dts b/fdts/fvp-base-gicv2-psci.dts new file mode 100644 index 0000000..2b2c2b0 --- /dev/null +++ b/fdts/fvp-base-gicv2-psci.dts @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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. + */ + +/dts-v1/; + +/memreserve/ 0x80000000 0x00010000; + +/ { +}; + +/ { + model = "FVP Base"; + compatible = "arm,vfp-base", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + }; + + psci { + compatible = "arm,psci"; + method = "smc"; + cpu_suspend = <0xc4000001>; + cpu_off = <0x84000002>; + cpu_on = <0xc4000003>; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "psci"; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "psci"; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "psci"; + }; + cpu@100 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x100>; + enable-method = "psci"; + }; + cpu@101 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x101>; + enable-method = "psci"; + }; + cpu@102 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x102>; + enable-method = "psci"; + }; + cpu@103 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x103>; + enable-method = "psci"; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0 0x7F000000>, + <0x00000008 0x80000000 0 0x80000000>; + }; + + gic: interrupt-controller@2f000000 { + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x0 0x2f000000 0 0x10000>, + <0x0 0x2c000000 0 0x2000>, + <0x0 0x2c010000 0 0x2000>, + <0x0 0x2c02F000 0 0x2000>; + interrupts = <1 9 0xf04>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 0xff01>, + <1 14 0xff01>, + <1 11 0xff01>, + <1 10 0xff01>; + clock-frequency = <100000000>; + }; + + timer@2a810000 { + compatible = "arm,armv7-timer-mem"; + reg = <0x0 0x2a810000 0x0 0x10000>; + clock-frequency = <100000000>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + frame@2a830000 { + frame-number = <1>; + interrupts = <0 26 4>; + reg = <0x0 0x2a830000 0x0 0x10000>; + }; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + }; + + smb { + compatible = "simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + + /include/ "rtsm_ve-motherboard.dtsi" + }; + + panels { + panel@0 { + compatible = "panel"; + mode = "XVGA"; + refresh = <60>; + xres = <1024>; + yres = <768>; + pixclock = <15748>; + left_margin = <152>; + right_margin = <48>; + upper_margin = <23>; + lower_margin = <3>; + hsync_len = <104>; + vsync_len = <4>; + sync = <0>; + vmode = "FB_VMODE_NONINTERLACED"; + tim2 = "TIM2_BCD", "TIM2_IPC"; + cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)"; + caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888"; + bpp = <16>; + }; + }; +}; diff --git a/fdts/fvp-base-gicv2legacy-psci.dtb b/fdts/fvp-base-gicv2legacy-psci.dtb Binary files differnew file mode 100644 index 0000000..7243c06 --- /dev/null +++ b/fdts/fvp-base-gicv2legacy-psci.dtb diff --git a/fdts/fvp-base-gicv2legacy-psci.dts b/fdts/fvp-base-gicv2legacy-psci.dts new file mode 100644 index 0000000..620bc05 --- /dev/null +++ b/fdts/fvp-base-gicv2legacy-psci.dts @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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. + */ + +/dts-v1/; + +/memreserve/ 0x80000000 0x00010000; + +/ { +}; + +/ { + model = "FVP Base"; + compatible = "arm,vfp-base", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + }; + + psci { + compatible = "arm,psci"; + method = "smc"; + cpu_suspend = <0xc4000001>; + cpu_off = <0x84000002>; + cpu_on = <0xc4000003>; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "psci"; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "psci"; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "psci"; + }; + cpu@100 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x100>; + enable-method = "psci"; + }; + cpu@101 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x101>; + enable-method = "psci"; + }; + cpu@102 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x102>; + enable-method = "psci"; + }; + cpu@103 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x103>; + enable-method = "psci"; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0 0x7F000000>, + <0x00000008 0x80000000 0 0x80000000>; + }; + + gic: interrupt-controller@2c001000 { + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x0 0x2c001000 0 0x1000>, + <0x0 0x2c002000 0 0x1000>, + <0x0 0x2c004000 0 0x2000>, + <0x0 0x2c006000 0 0x2000>; + interrupts = <1 9 0xf04>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 0xff01>, + <1 14 0xff01>, + <1 11 0xff01>, + <1 10 0xff01>; + clock-frequency = <100000000>; + }; + + timer@2a810000 { + compatible = "arm,armv7-timer-mem"; + reg = <0x0 0x2a810000 0x0 0x10000>; + clock-frequency = <100000000>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + frame@2a830000 { + frame-number = <1>; + interrupts = <0 26 4>; + reg = <0x0 0x2a830000 0x0 0x10000>; + }; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + }; + + smb { + compatible = "simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + + /include/ "rtsm_ve-motherboard.dtsi" + }; + + panels { + panel@0 { + compatible = "panel"; + mode = "XVGA"; + refresh = <60>; + xres = <1024>; + yres = <768>; + pixclock = <15748>; + left_margin = <152>; + right_margin = <48>; + upper_margin = <23>; + lower_margin = <3>; + hsync_len = <104>; + vsync_len = <4>; + sync = <0>; + vmode = "FB_VMODE_NONINTERLACED"; + tim2 = "TIM2_BCD", "TIM2_IPC"; + cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)"; + caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888"; + bpp = <16>; + }; + }; +}; diff --git a/fdts/fvp-base-gicv3-psci.dtb b/fdts/fvp-base-gicv3-psci.dtb Binary files differnew file mode 100644 index 0000000..b9fe1cf --- /dev/null +++ b/fdts/fvp-base-gicv3-psci.dtb diff --git a/fdts/fvp-base-gicv3-psci.dts b/fdts/fvp-base-gicv3-psci.dts new file mode 100644 index 0000000..d111a99 --- /dev/null +++ b/fdts/fvp-base-gicv3-psci.dts @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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. + */ + +/dts-v1/; + +/memreserve/ 0x80000000 0x00010000; + +/ { +}; + +/ { + model = "FVP Base"; + compatible = "arm,vfp-base", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + }; + + psci { + compatible = "arm,psci"; + method = "smc"; + cpu_suspend = <0xc4000001>; + cpu_off = <0x84000002>; + cpu_on = <0xc4000003>; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "psci"; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "psci"; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "psci"; + }; + cpu@100 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x100>; + enable-method = "psci"; + }; + cpu@101 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x101>; + enable-method = "psci"; + }; + cpu@102 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x102>; + enable-method = "psci"; + }; + cpu@103 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x103>; + enable-method = "psci"; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0 0x7F000000>, + <0x00000008 0x80000000 0 0x80000000>; + }; + + gic: interrupt-controller@2f000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + interrupt-controller; + reg = <0x0 0x2f000000 0 0x10000>, // GICD + <0x0 0x2f100000 0 0x200000>, // GICR + <0x0 0x2c000000 0 0x2000>, // GICC + <0x0 0x2c010000 0 0x2000>, // GICH + <0x0 0x2c02f000 0 0x2000>; // GICV + interrupts = <1 9 4>; + + its: its@2f020000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0x2f020000 0x0 0x20000>; // GITS + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 0xff01>, + <1 14 0xff01>, + <1 11 0xff01>, + <1 10 0xff01>; + clock-frequency = <100000000>; + }; + + timer@2a810000 { + compatible = "arm,armv7-timer-mem"; + reg = <0x0 0x2a810000 0x0 0x10000>; + clock-frequency = <100000000>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + frame@2a830000 { + frame-number = <1>; + interrupts = <0 26 4>; + reg = <0x0 0x2a830000 0x0 0x10000>; + }; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + }; + + smb { + compatible = "simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 0 0 4>, + <0 0 1 &gic 0 0 0 1 4>, + <0 0 2 &gic 0 0 0 2 4>, + <0 0 3 &gic 0 0 0 3 4>, + <0 0 4 &gic 0 0 0 4 4>, + <0 0 5 &gic 0 0 0 5 4>, + <0 0 6 &gic 0 0 0 6 4>, + <0 0 7 &gic 0 0 0 7 4>, + <0 0 8 &gic 0 0 0 8 4>, + <0 0 9 &gic 0 0 0 9 4>, + <0 0 10 &gic 0 0 0 10 4>, + <0 0 11 &gic 0 0 0 11 4>, + <0 0 12 &gic 0 0 0 12 4>, + <0 0 13 &gic 0 0 0 13 4>, + <0 0 14 &gic 0 0 0 14 4>, + <0 0 15 &gic 0 0 0 15 4>, + <0 0 16 &gic 0 0 0 16 4>, + <0 0 17 &gic 0 0 0 17 4>, + <0 0 18 &gic 0 0 0 18 4>, + <0 0 19 &gic 0 0 0 19 4>, + <0 0 20 &gic 0 0 0 20 4>, + <0 0 21 &gic 0 0 0 21 4>, + <0 0 22 &gic 0 0 0 22 4>, + <0 0 23 &gic 0 0 0 23 4>, + <0 0 24 &gic 0 0 0 24 4>, + <0 0 25 &gic 0 0 0 25 4>, + <0 0 26 &gic 0 0 0 26 4>, + <0 0 27 &gic 0 0 0 27 4>, + <0 0 28 &gic 0 0 0 28 4>, + <0 0 29 &gic 0 0 0 29 4>, + <0 0 30 &gic 0 0 0 30 4>, + <0 0 31 &gic 0 0 0 31 4>, + <0 0 32 &gic 0 0 0 32 4>, + <0 0 33 &gic 0 0 0 33 4>, + <0 0 34 &gic 0 0 0 34 4>, + <0 0 35 &gic 0 0 0 35 4>, + <0 0 36 &gic 0 0 0 36 4>, + <0 0 37 &gic 0 0 0 37 4>, + <0 0 38 &gic 0 0 0 38 4>, + <0 0 39 &gic 0 0 0 39 4>, + <0 0 40 &gic 0 0 0 40 4>, + <0 0 41 &gic 0 0 0 41 4>, + <0 0 42 &gic 0 0 0 42 4>; + + /include/ "rtsm_ve-motherboard.dtsi" + }; + + panels { + panel@0 { + compatible = "panel"; + mode = "XVGA"; + refresh = <60>; + xres = <1024>; + yres = <768>; + pixclock = <15748>; + left_margin = <152>; + right_margin = <48>; + upper_margin = <23>; + lower_margin = <3>; + hsync_len = <104>; + vsync_len = <4>; + sync = <0>; + vmode = "FB_VMODE_NONINTERLACED"; + tim2 = "TIM2_BCD", "TIM2_IPC"; + cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)"; + caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888"; + bpp = <16>; + }; + }; +}; diff --git a/fdts/fvp-foundation-gicv2-psci.dtb b/fdts/fvp-foundation-gicv2-psci.dtb Binary files differnew file mode 100644 index 0000000..70175e8 --- /dev/null +++ b/fdts/fvp-foundation-gicv2-psci.dtb diff --git a/fdts/fvp-foundation-gicv2-psci.dts b/fdts/fvp-foundation-gicv2-psci.dts new file mode 100644 index 0000000..8f3de9d --- /dev/null +++ b/fdts/fvp-foundation-gicv2-psci.dts @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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. + */ + +/dts-v1/; + +/memreserve/ 0x80000000 0x00010000; + +/ { +}; + +/ { + model = "FVP Foundation"; + compatible = "arm,fvp-base", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + }; + + psci { + compatible = "arm,psci"; + method = "smc"; + cpu_suspend = <0xc4000001>; + cpu_off = <0x84000002>; + cpu_on = <0xc4000003>; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "psci"; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "psci"; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "psci"; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0 0x7F000000>, + <0x00000008 0x80000000 0 0x80000000>; + }; + + gic: interrupt-controller@2f000000 { + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x0 0x2f000000 0 0x10000>, + <0x0 0x2c000000 0 0x2000>, + <0x0 0x2c010000 0 0x2000>, + <0x0 0x2c02F000 0 0x2000>; + interrupts = <1 9 0xf04>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 0xff01>, + <1 14 0xff01>, + <1 11 0xff01>, + <1 10 0xff01>; + clock-frequency = <100000000>; + }; + + timer@2a810000 { + compatible = "arm,armv7-timer-mem"; + reg = <0x0 0x2a810000 0x0 0x10000>; + clock-frequency = <100000000>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + frame@2a830000 { + frame-number = <1>; + interrupts = <0 26 4>; + reg = <0x0 0x2a830000 0x0 0x10000>; + }; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + }; + + smb { + compatible = "simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + + /include/ "fvp-foundation-motherboard.dtsi" + }; +}; diff --git a/fdts/fvp-foundation-gicv2legacy-psci.dtb b/fdts/fvp-foundation-gicv2legacy-psci.dtb Binary files differnew file mode 100644 index 0000000..564d223 --- /dev/null +++ b/fdts/fvp-foundation-gicv2legacy-psci.dtb diff --git a/fdts/fvp-foundation-gicv2legacy-psci.dts b/fdts/fvp-foundation-gicv2legacy-psci.dts new file mode 100644 index 0000000..951da06 --- /dev/null +++ b/fdts/fvp-foundation-gicv2legacy-psci.dts @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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. + */ + +/dts-v1/; + +/memreserve/ 0x80000000 0x00010000; + +/ { +}; + +/ { + model = "FVP Foundation"; + compatible = "arm,fvp-base", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + }; + + psci { + compatible = "arm,psci"; + method = "smc"; + cpu_suspend = <0xc4000001>; + cpu_off = <0x84000002>; + cpu_on = <0xc4000003>; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "psci"; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "psci"; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "psci"; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0 0x7F000000>, + <0x00000008 0x80000000 0 0x80000000>; + }; + + gic: interrupt-controller@2c001000 { + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x0 0x2c001000 0 0x1000>, + <0x0 0x2c002000 0 0x1000>, + <0x0 0x2c004000 0 0x2000>, + <0x0 0x2c006000 0 0x2000>; + interrupts = <1 9 0xf04>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 0xff01>, + <1 14 0xff01>, + <1 11 0xff01>, + <1 10 0xff01>; + clock-frequency = <100000000>; + }; + + timer@2a810000 { + compatible = "arm,armv7-timer-mem"; + reg = <0x0 0x2a810000 0x0 0x10000>; + clock-frequency = <100000000>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + frame@2a830000 { + frame-number = <1>; + interrupts = <0 26 4>; + reg = <0x0 0x2a830000 0x0 0x10000>; + }; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + }; + + smb { + compatible = "simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + + /include/ "fvp-foundation-motherboard.dtsi" + }; +}; diff --git a/fdts/fvp-foundation-gicv3-psci.dtb b/fdts/fvp-foundation-gicv3-psci.dtb Binary files differnew file mode 100644 index 0000000..26800ba --- /dev/null +++ b/fdts/fvp-foundation-gicv3-psci.dtb diff --git a/fdts/fvp-foundation-gicv3-psci.dts b/fdts/fvp-foundation-gicv3-psci.dts new file mode 100644 index 0000000..7692c61 --- /dev/null +++ b/fdts/fvp-foundation-gicv3-psci.dts @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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. + */ + +/dts-v1/; + +/memreserve/ 0x80000000 0x00010000; + +/ { +}; + +/ { + model = "FVP Foundation"; + compatible = "arm,fvp-base", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + }; + + psci { + compatible = "arm,psci"; + method = "smc"; + cpu_suspend = <0xc4000001>; + cpu_off = <0x84000002>; + cpu_on = <0xc4000003>; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "psci"; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "psci"; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "psci"; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0 0x7F000000>, + <0x00000008 0x80000000 0 0x80000000>; + }; + + gic: interrupt-controller@2f000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + interrupt-controller; + reg = <0x0 0x2f000000 0 0x10000>, // GICD + <0x0 0x2f100000 0 0x200000>, // GICR + <0x0 0x2c000000 0 0x2000>, // GICC + <0x0 0x2c010000 0 0x2000>, // GICH + <0x0 0x2c02f000 0 0x2000>; // GICV + interrupts = <1 9 4>; + + its: its@2f020000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0x2f020000 0x0 0x20000>; // GITS + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 0xff01>, + <1 14 0xff01>, + <1 11 0xff01>, + <1 10 0xff01>; + clock-frequency = <100000000>; + }; + + timer@2a810000 { + compatible = "arm,armv7-timer-mem"; + reg = <0x0 0x2a810000 0x0 0x10000>; + clock-frequency = <100000000>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + frame@2a830000 { + frame-number = <1>; + interrupts = <0 26 4>; + reg = <0x0 0x2a830000 0x0 0x10000>; + }; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + }; + + smb { + compatible = "simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 0 0 4>, + <0 0 1 &gic 0 0 0 1 4>, + <0 0 2 &gic 0 0 0 2 4>, + <0 0 3 &gic 0 0 0 3 4>, + <0 0 4 &gic 0 0 0 4 4>, + <0 0 5 &gic 0 0 0 5 4>, + <0 0 6 &gic 0 0 0 6 4>, + <0 0 7 &gic 0 0 0 7 4>, + <0 0 8 &gic 0 0 0 8 4>, + <0 0 9 &gic 0 0 0 9 4>, + <0 0 10 &gic 0 0 0 10 4>, + <0 0 11 &gic 0 0 0 11 4>, + <0 0 12 &gic 0 0 0 12 4>, + <0 0 13 &gic 0 0 0 13 4>, + <0 0 14 &gic 0 0 0 14 4>, + <0 0 15 &gic 0 0 0 15 4>, + <0 0 16 &gic 0 0 0 16 4>, + <0 0 17 &gic 0 0 0 17 4>, + <0 0 18 &gic 0 0 0 18 4>, + <0 0 19 &gic 0 0 0 19 4>, + <0 0 20 &gic 0 0 0 20 4>, + <0 0 21 &gic 0 0 0 21 4>, + <0 0 22 &gic 0 0 0 22 4>, + <0 0 23 &gic 0 0 0 23 4>, + <0 0 24 &gic 0 0 0 24 4>, + <0 0 25 &gic 0 0 0 25 4>, + <0 0 26 &gic 0 0 0 26 4>, + <0 0 27 &gic 0 0 0 27 4>, + <0 0 28 &gic 0 0 0 28 4>, + <0 0 29 &gic 0 0 0 29 4>, + <0 0 30 &gic 0 0 0 30 4>, + <0 0 31 &gic 0 0 0 31 4>, + <0 0 32 &gic 0 0 0 32 4>, + <0 0 33 &gic 0 0 0 33 4>, + <0 0 34 &gic 0 0 0 34 4>, + <0 0 35 &gic 0 0 0 35 4>, + <0 0 36 &gic 0 0 0 36 4>, + <0 0 37 &gic 0 0 0 37 4>, + <0 0 38 &gic 0 0 0 38 4>, + <0 0 39 &gic 0 0 0 39 4>, + <0 0 40 &gic 0 0 0 40 4>, + <0 0 41 &gic 0 0 0 41 4>, + <0 0 42 &gic 0 0 0 42 4>; + + /include/ "fvp-foundation-motherboard.dtsi" + }; +}; diff --git a/fdts/fvp-foundation-motherboard.dtsi b/fdts/fvp-foundation-motherboard.dtsi new file mode 100644 index 0000000..fd41c8a --- /dev/null +++ b/fdts/fvp-foundation-motherboard.dtsi @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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. + */ + + motherboard { + arm,v2m-memory-map = "rs1"; + compatible = "arm,vexpress,v2m-p1", "simple-bus"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + #interrupt-cells = <1>; + ranges; + + ethernet@2,02000000 { + compatible = "smsc,lan91c111"; + reg = <2 0x02000000 0x10000>; + interrupts = <15>; + }; + + v2m_clk24mhz: clk24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "v2m:clk24mhz"; + }; + + v2m_refclk1mhz: refclk1mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + clock-output-names = "v2m:refclk1mhz"; + }; + + v2m_refclk32khz: refclk32khz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "v2m:refclk32khz"; + }; + + iofpga@3,00000000 { + compatible = "arm,amba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + + v2m_sysreg: sysreg@010000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x010000 0x1000>; + gpio-controller; + #gpio-cells = <2>; + }; + + v2m_sysctl: sysctl@020000 { + compatible = "arm,sp810", "arm,primecell"; + reg = <0x020000 0x1000>; + clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>; + clock-names = "refclk", "timclk", "apb_pclk"; + #clock-cells = <1>; + clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3"; + }; + + v2m_serial0: uart@090000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x090000 0x1000>; + interrupts = <5>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial1: uart@0a0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a0000 0x1000>; + interrupts = <6>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial2: uart@0b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b0000 0x1000>; + interrupts = <7>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial3: uart@0c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c0000 0x1000>; + interrupts = <8>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + wdt@0f0000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x0f0000 0x1000>; + interrupts = <0>; + clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>; + clock-names = "wdogclk", "apb_pclk"; + }; + + v2m_timer01: timer@110000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x110000 0x1000>; + interrupts = <2>; + clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + v2m_timer23: timer@120000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x120000 0x1000>; + interrupts = <3>; + clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + rtc@170000 { + compatible = "arm,pl031", "arm,primecell"; + reg = <0x170000 0x1000>; + interrupts = <4>; + clocks = <&v2m_clk24mhz>; + clock-names = "apb_pclk"; + }; + + virtio_block@0130000 { + compatible = "virtio,mmio"; + reg = <0x130000 0x1000>; + interrupts = <0x2a>; + }; + }; + + v2m_fixed_3v3: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + + mcc { + compatible = "arm,vexpress,config-bus", "simple-bus"; + arm,vexpress,config-bridge = <&v2m_sysreg>; + + reset@0 { + compatible = "arm,vexpress-reset"; + arm,vexpress-sysreg,func = <5 0>; + }; + + muxfpga@0 { + compatible = "arm,vexpress-muxfpga"; + arm,vexpress-sysreg,func = <7 0>; + }; + + shutdown@0 { + compatible = "arm,vexpress-shutdown"; + arm,vexpress-sysreg,func = <8 0>; + }; + + reboot@0 { + compatible = "arm,vexpress-reboot"; + arm,vexpress-sysreg,func = <9 0>; + }; + + dvimode@0 { + compatible = "arm,vexpress-dvimode"; + arm,vexpress-sysreg,func = <11 0>; + }; + }; + }; diff --git a/fdts/rtsm_ve-motherboard.dtsi b/fdts/rtsm_ve-motherboard.dtsi new file mode 100644 index 0000000..7ba575e --- /dev/null +++ b/fdts/rtsm_ve-motherboard.dtsi @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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. + */ + + motherboard { + arm,v2m-memory-map = "rs1"; + compatible = "arm,vexpress,v2m-p1", "simple-bus"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + #interrupt-cells = <1>; + ranges; + + flash@0,00000000 { + compatible = "arm,vexpress-flash", "cfi-flash"; + reg = <0 0x00000000 0x04000000>, + <4 0x00000000 0x04000000>; + bank-width = <4>; + }; + + vram@2,00000000 { + compatible = "arm,vexpress-vram"; + reg = <2 0x00000000 0x00800000>; + }; + + ethernet@2,02000000 { + compatible = "smsc,lan91c111"; + reg = <2 0x02000000 0x10000>; + interrupts = <15>; + }; + + v2m_clk24mhz: clk24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "v2m:clk24mhz"; + }; + + v2m_refclk1mhz: refclk1mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + clock-output-names = "v2m:refclk1mhz"; + }; + + v2m_refclk32khz: refclk32khz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "v2m:refclk32khz"; + }; + + iofpga@3,00000000 { + compatible = "arm,amba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + + v2m_sysreg: sysreg@010000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x010000 0x1000>; + gpio-controller; + #gpio-cells = <2>; + }; + + v2m_sysctl: sysctl@020000 { + compatible = "arm,sp810", "arm,primecell"; + reg = <0x020000 0x1000>; + clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>; + clock-names = "refclk", "timclk", "apb_pclk"; + #clock-cells = <1>; + clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3"; + }; + + aaci@040000 { + compatible = "arm,pl041", "arm,primecell"; + reg = <0x040000 0x1000>; + interrupts = <11>; + clocks = <&v2m_clk24mhz>; + clock-names = "apb_pclk"; + }; + + mmci@050000 { + compatible = "arm,pl180", "arm,primecell"; + reg = <0x050000 0x1000>; + interrupts = <9 10>; + cd-gpios = <&v2m_sysreg 0 0>; + wp-gpios = <&v2m_sysreg 1 0>; + max-frequency = <12000000>; + vmmc-supply = <&v2m_fixed_3v3>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "mclk", "apb_pclk"; + }; + + kmi@060000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x060000 0x1000>; + interrupts = <12>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + kmi@070000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x070000 0x1000>; + interrupts = <13>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + v2m_serial0: uart@090000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x090000 0x1000>; + interrupts = <5>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial1: uart@0a0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a0000 0x1000>; + interrupts = <6>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial2: uart@0b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b0000 0x1000>; + interrupts = <7>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial3: uart@0c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c0000 0x1000>; + interrupts = <8>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + wdt@0f0000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x0f0000 0x1000>; + interrupts = <0>; + clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>; + clock-names = "wdogclk", "apb_pclk"; + }; + + v2m_timer01: timer@110000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x110000 0x1000>; + interrupts = <2>; + clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + v2m_timer23: timer@120000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x120000 0x1000>; + interrupts = <3>; + clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + rtc@170000 { + compatible = "arm,pl031", "arm,primecell"; + reg = <0x170000 0x1000>; + interrupts = <4>; + clocks = <&v2m_clk24mhz>; + clock-names = "apb_pclk"; + }; + + clcd@1f0000 { + compatible = "arm,pl111", "arm,primecell"; + reg = <0x1f0000 0x1000>; + interrupts = <14>; + clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>; + clock-names = "clcdclk", "apb_pclk"; + mode = "XVGA"; + use_dma = <0>; + framebuffer = <0x18000000 0x00180000>; + }; + + virtio_block@0130000 { + compatible = "virtio,mmio"; + reg = <0x130000 0x1000>; + interrupts = <0x2a>; + }; + }; + + v2m_fixed_3v3: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + mcc { + compatible = "arm,vexpress,config-bus", "simple-bus"; + arm,vexpress,config-bridge = <&v2m_sysreg>; + + v2m_oscclk1: osc@1 { + /* CLCD clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 1>; + freq-range = <23750000 63500000>; + #clock-cells = <0>; + clock-output-names = "v2m:oscclk1"; + }; + + reset@0 { + compatible = "arm,vexpress-reset"; + arm,vexpress-sysreg,func = <5 0>; + }; + + muxfpga@0 { + compatible = "arm,vexpress-muxfpga"; + arm,vexpress-sysreg,func = <7 0>; + }; + + shutdown@0 { + compatible = "arm,vexpress-shutdown"; + arm,vexpress-sysreg,func = <8 0>; + }; + + reboot@0 { + compatible = "arm,vexpress-reboot"; + arm,vexpress-sysreg,func = <9 0>; + }; + + dvimode@0 { + compatible = "arm,vexpress-dvimode"; + arm,vexpress-sysreg,func = <11 0>; + }; + }; + }; diff --git a/include/bl31/bl31.h b/include/bl31/bl31.h new file mode 100644 index 0000000..33e4ece --- /dev/null +++ b/include/bl31/bl31.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __BL31_H__ +#define __BL31_H__ + +#include <stdint.h> + +/******************************************************************************* + * Function prototypes + ******************************************************************************/ +void bl31_arch_setup(void); +void bl31_next_el_arch_setup(uint32_t security_state); +void bl31_set_next_image_type(uint32_t type); +uint32_t bl31_get_next_image_type(void); +void bl31_prepare_next_image_entry(); +void bl31_register_bl32_init(int32_t (*)(void)); + +#endif /* __BL31_H__ */ diff --git a/include/bl31/context.h b/include/bl31/context.h new file mode 100644 index 0000000..16cc744 --- /dev/null +++ b/include/bl31/context.h @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __CONTEXT_H__ +#define __CONTEXT_H__ + +/******************************************************************************* + * Constants that allow assembler code to access members of and the 'gp_regs' + * structure at their correct offsets. + ******************************************************************************/ +#define CTX_GPREGS_OFFSET 0x0 +#define CTX_GPREG_X0 0x0 +#define CTX_GPREG_X1 0x8 +#define CTX_GPREG_X2 0x10 +#define CTX_GPREG_X3 0x18 +#define CTX_GPREG_X4 0x20 +#define CTX_GPREG_X5 0x28 +#define CTX_GPREG_X6 0x30 +#define CTX_GPREG_X7 0x38 +#define CTX_GPREG_X8 0x40 +#define CTX_GPREG_X9 0x48 +#define CTX_GPREG_X10 0x50 +#define CTX_GPREG_X11 0x58 +#define CTX_GPREG_X12 0x60 +#define CTX_GPREG_X13 0x68 +#define CTX_GPREG_X14 0x70 +#define CTX_GPREG_X15 0x78 +#define CTX_GPREG_X16 0x80 +#define CTX_GPREG_X17 0x88 +#define CTX_GPREG_X18 0x90 +#define CTX_GPREG_X19 0x98 +#define CTX_GPREG_X20 0xa0 +#define CTX_GPREG_X21 0xa8 +#define CTX_GPREG_X22 0xb0 +#define CTX_GPREG_X23 0xb8 +#define CTX_GPREG_X24 0xc0 +#define CTX_GPREG_X25 0xc8 +#define CTX_GPREG_X26 0xd0 +#define CTX_GPREG_X27 0xd8 +#define CTX_GPREG_X28 0xe0 +#define CTX_GPREG_X29 0xe8 +#define CTX_GPREG_LR 0xf0 +#define CTX_GPREG_SP_EL0 0xf8 +#define CTX_GPREGS_END 0x100 + +/******************************************************************************* + * Constants that allow assembler code to access members of and the 'el3_state' + * structure at their correct offsets. Note that some of the registers are only + * 32-bits wide but are stored as 64-bit values for convenience + ******************************************************************************/ +#define CTX_EL3STATE_OFFSET (CTX_GPREGS_OFFSET + CTX_GPREGS_END) +#define CTX_VBAR_EL3 0x0 /* Currently unused */ +#define CTX_RUNTIME_SP 0x8 +#define CTX_SPSR_EL3 0x10 +#define CTX_ELR_EL3 0x18 +#define CTX_SCR_EL3 0x20 +#define CTX_SCTLR_EL3 0x28 +#define CTX_CPTR_EL3 0x30 +/* Unused space to allow registers to be stored as pairs */ +#define CTX_CNTFRQ_EL0 0x40 +#define CTX_MAIR_EL3 0x48 +#define CTX_TCR_EL3 0x50 +#define CTX_TTBR0_EL3 0x58 +#define CTX_DAIF_EL3 0x60 +/* Unused space to honour alignment requirements */ +#define CTX_EL3STATE_END 0x70 + +/******************************************************************************* + * Constants that allow assembler code to access members of and the + * 'el1_sys_regs' structure at their correct offsets. Note that some of the + * registers are only 32-bits wide but are stored as 64-bit values for + * convenience + ******************************************************************************/ +#define CTX_SYSREGS_OFFSET (CTX_EL3STATE_OFFSET + CTX_EL3STATE_END) +#define CTX_SPSR_EL1 0x0 +#define CTX_ELR_EL1 0x8 +#define CTX_SPSR_ABT 0x10 +#define CTX_SPSR_UND 0x18 +#define CTX_SPSR_IRQ 0x20 +#define CTX_SPSR_FIQ 0x28 +#define CTX_SCTLR_EL1 0x30 +#define CTX_ACTLR_EL1 0x38 +#define CTX_CPACR_EL1 0x40 +#define CTX_CSSELR_EL1 0x48 +#define CTX_SP_EL1 0x50 +#define CTX_ESR_EL1 0x58 +#define CTX_TTBR0_EL1 0x60 +#define CTX_TTBR1_EL1 0x68 +#define CTX_MAIR_EL1 0x70 +#define CTX_AMAIR_EL1 0x78 +#define CTX_TCR_EL1 0x80 +#define CTX_TPIDR_EL1 0x88 +#define CTX_TPIDR_EL0 0x90 +#define CTX_TPIDRRO_EL0 0x98 +#define CTX_DACR32_EL2 0xa0 +#define CTX_IFSR32_EL2 0xa8 +#define CTX_PAR_EL1 0xb0 +#define CTX_FAR_EL1 0xb8 +#define CTX_AFSR0_EL1 0xc0 +#define CTX_AFSR1_EL1 0xc8 +#define CTX_CONTEXTIDR_EL1 0xd0 +#define CTX_VBAR_EL1 0xd8 +/* + * If the timer registers aren't saved and restored, we don't have to reserve + * space for them in the context + */ +#if NS_TIMER_SWITCH +#define CTX_CNTP_CTL_EL0 0xe0 +#define CTX_CNTP_CVAL_EL0 0xe8 +#define CTX_CNTV_CTL_EL0 0xf0 +#define CTX_CNTV_CVAL_EL0 0xf8 +#define CTX_CNTKCTL_EL1 0x100 +#define CTX_FP_FPEXC32_EL2 0x108 +#define CTX_SYSREGS_END 0x110 +#else +#define CTX_FP_FPEXC32_EL2 0xe0 +#define CTX_SYSREGS_END 0xf0 +#endif + +/******************************************************************************* + * Constants that allow assembler code to access members of and the 'fp_regs' + * structure at their correct offsets. + ******************************************************************************/ +#define CTX_FPREGS_OFFSET (CTX_SYSREGS_OFFSET + CTX_SYSREGS_END) +#define CTX_FP_Q0 0x0 +#define CTX_FP_Q1 0x10 +#define CTX_FP_Q2 0x20 +#define CTX_FP_Q3 0x30 +#define CTX_FP_Q4 0x40 +#define CTX_FP_Q5 0x50 +#define CTX_FP_Q6 0x60 +#define CTX_FP_Q7 0x70 +#define CTX_FP_Q8 0x80 +#define CTX_FP_Q9 0x90 +#define CTX_FP_Q10 0xa0 +#define CTX_FP_Q11 0xb0 +#define CTX_FP_Q12 0xc0 +#define CTX_FP_Q13 0xd0 +#define CTX_FP_Q14 0xe0 +#define CTX_FP_Q15 0xf0 +#define CTX_FP_Q16 0x100 +#define CTX_FP_Q17 0x110 +#define CTX_FP_Q18 0x120 +#define CTX_FP_Q19 0x130 +#define CTX_FP_Q20 0x140 +#define CTX_FP_Q21 0x150 +#define CTX_FP_Q22 0x160 +#define CTX_FP_Q23 0x170 +#define CTX_FP_Q24 0x180 +#define CTX_FP_Q25 0x190 +#define CTX_FP_Q26 0x1a0 +#define CTX_FP_Q27 0x1b0 +#define CTX_FP_Q28 0x1c0 +#define CTX_FP_Q29 0x1d0 +#define CTX_FP_Q30 0x1e0 +#define CTX_FP_Q31 0x1f0 +#define CTX_FP_FPSR 0x200 +#define CTX_FP_FPCR 0x208 +#define CTX_FPREGS_END 0x210 + +/****************************************************************************** + * Offsets for the per cpu cache implementation + ******************************************************************************/ +#define PTR_CACHE_CRASH_STACK_OFFSET 0x0 + +#ifndef __ASSEMBLY__ + +#include <cassert.h> +#include <stdint.h> + +/* + * Common constants to help define the 'cpu_context' structure and its + * members below. + */ +#define DWORD_SHIFT 3 +#define DEFINE_REG_STRUCT(name, num_regs) \ + typedef struct name { \ + uint64_t _regs[num_regs]; \ + } __aligned(16) name##_t + +/* Constants to determine the size of individual context structures */ +#define CTX_GPREG_ALL (CTX_GPREGS_END >> DWORD_SHIFT) +#define CTX_SYSREG_ALL (CTX_SYSREGS_END >> DWORD_SHIFT) +#define CTX_FPREG_ALL (CTX_FPREGS_END >> DWORD_SHIFT) +#define CTX_EL3STATE_ALL (CTX_EL3STATE_END >> DWORD_SHIFT) + +/* + * AArch64 general purpose register context structure. Usually x0-x18, + * lr are saved as the compiler is expected to preserve the remaining + * callee saved registers if used by the C runtime and the assembler + * does not touch the remaining. But in case of world switch during + * exception handling, we need to save the callee registers too. + */ +DEFINE_REG_STRUCT(gp_regs, CTX_GPREG_ALL); + +/* + * AArch64 EL1 system register context structure for preserving the + * architectural state during switches from one security state to + * another in EL1. + */ +DEFINE_REG_STRUCT(el1_sys_regs, CTX_SYSREG_ALL); + +/* + * AArch64 floating point register context structure for preserving + * the floating point state during switches from one security state to + * another. + */ +DEFINE_REG_STRUCT(fp_regs, CTX_FPREG_ALL); + +/* + * Miscellaneous registers used by EL3 firmware to maintain its state + * across exception entries and exits + */ +DEFINE_REG_STRUCT(el3_state, CTX_EL3STATE_ALL); + +/* + * Macros to access members of any of the above structures using their + * offsets + */ +#define read_ctx_reg(ctx, offset) ((ctx)->_regs[offset >> DWORD_SHIFT]) +#define write_ctx_reg(ctx, offset, val) (((ctx)->_regs[offset >> DWORD_SHIFT]) \ + = val) + +/* + * Top-level context structure which is used by EL3 firmware to + * preserve the state of a core at EL1 in one of the two security + * states and save enough EL3 meta data to be able to return to that + * EL and security state. The context management library will be used + * to ensure that SP_EL3 always points to an instance of this + * structure at exception entry and exit. Each instance will + * correspond to either the secure or the non-secure state. + */ +typedef struct cpu_context { + gp_regs_t gpregs_ctx; + el3_state_t el3state_ctx; + el1_sys_regs_t sysregs_ctx; + fp_regs_t fpregs_ctx; +} cpu_context_t; + +/* Macros to access members of the 'cpu_context_t' structure */ +#define get_el3state_ctx(h) (&((cpu_context_t *) h)->el3state_ctx) +#define get_fpregs_ctx(h) (&((cpu_context_t *) h)->fpregs_ctx) +#define get_sysregs_ctx(h) (&((cpu_context_t *) h)->sysregs_ctx) +#define get_gpregs_ctx(h) (&((cpu_context_t *) h)->gpregs_ctx) + +/* + * Compile time assertions related to the 'cpu_context' structure to + * ensure that the assembler and the compiler view of the offsets of + * the structure members is the same. + */ +CASSERT(CTX_GPREGS_OFFSET == __builtin_offsetof(cpu_context_t, gpregs_ctx), \ + assert_core_context_gp_offset_mismatch); +CASSERT(CTX_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, sysregs_ctx), \ + assert_core_context_sys_offset_mismatch); +CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context_t, fpregs_ctx), \ + assert_core_context_fp_offset_mismatch); +CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx), \ + assert_core_context_el3state_offset_mismatch); + +/* + * Helper macro to set the general purpose registers that correspond to + * parameters in an aapcs_64 call i.e. x0-x7 + */ +#define set_aapcs_args0(ctx, x0) do { \ + write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0, x0); \ + } while (0); +#define set_aapcs_args1(ctx, x0, x1) do { \ + write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1, x1); \ + set_aapcs_args0(ctx, x0); \ + } while (0); +#define set_aapcs_args2(ctx, x0, x1, x2) do { \ + write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X2, x2); \ + set_aapcs_args1(ctx, x0, x1); \ + } while (0); +#define set_aapcs_args3(ctx, x0, x1, x2, x3) do { \ + write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X3, x3); \ + set_aapcs_args2(ctx, x0, x1, x2); \ + } while (0); +#define set_aapcs_args4(ctx, x0, x1, x2, x3, x4) do { \ + write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X4, x4); \ + set_aapcs_args3(ctx, x0, x1, x2, x3); \ + } while (0); +#define set_aapcs_args5(ctx, x0, x1, x2, x3, x4, x5) do { \ + write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X5, x5); \ + set_aapcs_args4(ctx, x0, x1, x2, x3, x4); \ + } while (0); +#define set_aapcs_args6(ctx, x0, x1, x2, x3, x4, x5, x6) do { \ + write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X6, x6); \ + set_aapcs_args5(ctx, x0, x1, x2, x3, x4, x5); \ + } while (0); +#define set_aapcs_args7(ctx, x0, x1, x2, x3, x4, x5, x6, x7) do { \ + write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X7, x7); \ + set_aapcs_args6(ctx, x0, x1, x2, x3, x4, x5, x6); \ + } while (0); + +/******************************************************************************* + * Function prototypes + ******************************************************************************/ +void el3_sysregs_context_save(el3_state_t *regs); +void el3_sysregs_context_restore(el3_state_t *regs); +void el1_sysregs_context_save(el1_sys_regs_t *regs); +void el1_sysregs_context_restore(el1_sys_regs_t *regs); +void fpregs_context_save(fp_regs_t *regs); +void fpregs_context_restore(fp_regs_t *regs); + + +/* Per-CPU pointer cache of recently used pointers and also the crash stack + * TODO: Add other commonly used variables to this (tf_issues#90) + */ +typedef struct per_cpu_ptr_cache { + uint64_t crash_stack; +} per_cpu_ptr_cache_t; + +CASSERT(PTR_CACHE_CRASH_STACK_OFFSET == __builtin_offsetof\ + (per_cpu_ptr_cache_t, crash_stack), \ + assert_per_cpu_ptr_cache_crash_stack_offset_mismatch); + +#undef CTX_SYSREG_ALL +#undef CTX_FP_ALL +#undef CTX_GPREG_ALL +#undef CTX_EL3STATE_ALL + +#endif /* __ASSEMBLY__ */ + +#endif /* __CONTEXT_H__ */ diff --git a/include/bl31/context_mgmt.h b/include/bl31/context_mgmt.h new file mode 100644 index 0000000..ce4f7a8 --- /dev/null +++ b/include/bl31/context_mgmt.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __CM_H__ +#define __CM_H__ + +#include <stdint.h> + +/******************************************************************************* + * Function & variable prototypes + ******************************************************************************/ +void cm_init(void); +void *cm_get_context(uint64_t mpidr, uint32_t security_state); +void cm_set_context(uint64_t mpidr, + void *context, + uint32_t security_state); +void cm_el3_sysregs_context_save(uint32_t security_state); +void cm_el3_sysregs_context_restore(uint32_t security_state); +void cm_el1_sysregs_context_save(uint32_t security_state); +void cm_el1_sysregs_context_restore(uint32_t security_state); +void cm_set_el3_eret_context(uint32_t security_state, uint64_t entrypoint, + uint32_t spsr, uint32_t scr); +void cm_set_elr_el3(uint32_t security_state, uint64_t entrypoint); +void cm_write_scr_el3_bit(uint32_t security_state, + uint32_t bit_pos, + uint32_t value); +void cm_set_next_eret_context(uint32_t security_state); +void cm_init_pcpu_ptr_cache(); +void cm_set_pcpu_ptr_cache(const void *pcpu_ptr); +void *cm_get_pcpu_ptr_cache(void); +uint32_t cm_get_scr_el3(uint32_t security_state); +#endif /* __CM_H__ */ diff --git a/include/bl31/interrupt_mgmt.h b/include/bl31/interrupt_mgmt.h new file mode 100644 index 0000000..3a2c00c --- /dev/null +++ b/include/bl31/interrupt_mgmt.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __INTERRUPT_MGMT_H__ +#define __INTERRUPT_MGMT_H__ + +#include <arch.h> + +/******************************************************************************* + * Constants for the types of interrupts recognised by the IM framework + ******************************************************************************/ +#define INTR_TYPE_S_EL1 0 +#define INTR_TYPE_EL3 1 +#define INTR_TYPE_NS 2 +#define MAX_INTR_TYPES 3 +#define INTR_TYPE_INVAL MAX_INTR_TYPES +/* + * Constant passed to the interrupt handler in the 'id' field when the + * framework does not read the gic registers to determine the interrupt id. + */ +#define INTR_ID_UNAVAILABLE 0xFFFFFFFF + + +/******************************************************************************* + * Mask for _both_ the routing model bits in the 'flags' parameter and + * constants to define the valid routing models for each supported interrupt + * type + ******************************************************************************/ +#define INTR_RM_FLAGS_SHIFT 0x0 +#define INTR_RM_FLAGS_MASK 0x3 +/* Routed to EL3 from NS. Taken to S-EL1 from Secure */ +#define INTR_SEL1_VALID_RM0 0x2 +/* Routed to EL3 from NS and Secure */ +#define INTR_SEL1_VALID_RM1 0x3 +/* Routed to EL1/EL2 from NS and to S-EL1 from Secure */ +#define INTR_NS_VALID_RM0 0x0 +/* Routed to EL1/EL2 from NS and to EL3 from Secure */ +#define INTR_NS_VALID_RM1 0x1 + + +/******************************************************************************* + * Constants for the _individual_ routing model bits in the 'flags' field for + * each interrupt type and mask to validate the 'flags' parameter while + * registering an interrupt handler + ******************************************************************************/ +#define INTR_TYPE_FLAGS_MASK 0xFFFFFFFC + +#define INTR_RM_FROM_SEC_SHIFT SECURE /* BIT[0] */ +#define INTR_RM_FROM_NS_SHIFT NON_SECURE /* BIT[1] */ +#define INTR_RM_FROM_FLAG_MASK 1 +#define get_interrupt_rm_flag(flag, ss) (((flag >> INTR_RM_FLAGS_SHIFT) >> ss) \ + & INTR_RM_FROM_FLAG_MASK) +#define set_interrupt_rm_flag(flag, ss) (flag |= 1 << ss) +#define clr_interrupt_rm_flag(flag, ss) (flag &= ~(1 << ss)) + + +/******************************************************************************* + * Macros to validate the routing model bits in the 'flags' for a type + * of interrupt. If the model does not match one of the valid masks + * -EINVAL is returned. + ******************************************************************************/ +#define validate_sel1_interrupt_rm(x) (x == INTR_SEL1_VALID_RM0 ? 0 : \ + (x == INTR_SEL1_VALID_RM1 ? 0 :\ + -EINVAL)) + +#define validate_ns_interrupt_rm(x) (x == INTR_NS_VALID_RM0 ? 0 : \ + (x == INTR_NS_VALID_RM1 ? 0 :\ + -EINVAL)) + +/******************************************************************************* + * Macros to set the 'flags' parameter passed to an interrupt type handler. Only + * the flag to indicate the security state when the exception was generated is + * supported. + ******************************************************************************/ +#define INTR_SRC_SS_FLAG_SHIFT 0 /* BIT[0] */ +#define INTR_SRC_SS_FLAG_MASK 1 +#define set_interrupt_src_ss(flag, val) (flag |= val << INTR_SRC_SS_FLAG_SHIFT) +#define clr_interrupt_src_ss(flag) (flag &= ~(1 << INTR_SRC_SS_FLAG_SHIFT)) +#define get_interrupt_src_ss(flag) ((flag >> INTR_SRC_SS_FLAG_SHIFT) & \ + INTR_SRC_SS_FLAG_MASK) + +#ifndef __ASSEMBLY__ + +/* Prototype for defining a handler for an interrupt type */ +typedef uint64_t (*interrupt_type_handler_t)(uint32_t id, + uint32_t flags, + void *handle, + void *cookie); + +/******************************************************************************* + * Function & variable prototypes + ******************************************************************************/ +uint32_t get_scr_el3_from_routing_model(uint32_t security_state); +int32_t set_routing_model(uint32_t type, uint32_t flags); +int32_t register_interrupt_type_handler(uint32_t type, + interrupt_type_handler_t handler, + uint32_t flags); +interrupt_type_handler_t get_interrupt_type_handler(uint32_t interrupt_type); + +#endif /*__ASSEMBLY__*/ +#endif /* __INTERRUPT_MGMT_H__ */ diff --git a/include/bl31/runtime_svc.h b/include/bl31/runtime_svc.h new file mode 100644 index 0000000..d7d88d4 --- /dev/null +++ b/include/bl31/runtime_svc.h @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __RUNTIME_SVC_H__ +#define __RUNTIME_SVC_H__ + +/******************************************************************************* + * Bit definitions inside the function id as per the SMC calling convention + ******************************************************************************/ +#define FUNCID_TYPE_SHIFT 31 +#define FUNCID_CC_SHIFT 30 +#define FUNCID_OEN_SHIFT 24 +#define FUNCID_NUM_SHIFT 0 + +#define FUNCID_TYPE_MASK 0x1 +#define FUNCID_CC_MASK 0x1 +#define FUNCID_OEN_MASK 0x3f +#define FUNCID_NUM_MASK 0xffff + +#define FUNCID_TYPE_WIDTH 1 +#define FUNCID_CC_WIDTH 1 +#define FUNCID_OEN_WIDTH 6 +#define FUNCID_NUM_WIDTH 16 + +#define GET_SMC_CC(id) ((id >> FUNCID_CC_SHIFT) & \ + FUNCID_CC_MASK) +#define GET_SMC_TYPE(id) ((id >> FUNCID_TYPE_SHIFT) & \ + FUNCID_TYPE_MASK) + +#define SMC_64 1 +#define SMC_32 0 +#define SMC_UNK 0xffffffff +#define SMC_TYPE_FAST 1 +#define SMC_TYPE_STD 0 +#define SMC_PREEMPTED 0xfffffffe +/******************************************************************************* + * Owning entity number definitions inside the function id as per the SMC + * calling convention + ******************************************************************************/ +#define OEN_ARM_START 0 +#define OEN_ARM_END 0 +#define OEN_CPU_START 1 +#define OEN_CPU_END 1 +#define OEN_SIP_START 2 +#define OEN_SIP_END 2 +#define OEN_OEM_START 3 +#define OEN_OEM_END 3 +#define OEN_STD_START 4 /* Standard Calls */ +#define OEN_STD_END 4 +#define OEN_TAP_START 48 /* Trusted Applications */ +#define OEN_TAP_END 49 +#define OEN_TOS_START 50 /* Trusted OS */ +#define OEN_TOS_END 63 +#define OEN_LIMIT 64 + +/******************************************************************************* + * Constants to indicate type of exception to the common exception handler. + ******************************************************************************/ +#define SYNC_EXCEPTION_SP_EL0 0x0 +#define IRQ_SP_EL0 0x1 +#define FIQ_SP_EL0 0x2 +#define SERROR_SP_EL0 0x3 +#define SYNC_EXCEPTION_SP_ELX 0x4 +#define IRQ_SP_ELX 0x5 +#define FIQ_SP_ELX 0x6 +#define SERROR_SP_ELX 0x7 +#define SYNC_EXCEPTION_AARCH64 0x8 +#define IRQ_AARCH64 0x9 +#define FIQ_AARCH64 0xa +#define SERROR_AARCH64 0xb +#define SYNC_EXCEPTION_AARCH32 0xc +#define IRQ_AARCH32 0xd +#define FIQ_AARCH32 0xe +#define SERROR_AARCH32 0xf + +/******************************************************************************* + * Structure definition, typedefs & constants for the runtime service framework + ******************************************************************************/ + +/* + * Constants to allow the assembler access a runtime service + * descriptor + */ +#define RT_SVC_SIZE_LOG2 5 +#define SIZEOF_RT_SVC_DESC (1 << RT_SVC_SIZE_LOG2) +#define RT_SVC_DESC_INIT 16 +#define RT_SVC_DESC_HANDLE 24 + +/* + * The function identifier has 6 bits for the owning entity number and + * single bit for the type of smc call. When taken together these + * values limit the maximum number of runtime services to 128. + */ +#define MAX_RT_SVCS 128 + +#ifndef __ASSEMBLY__ + +#include <cassert.h> +#include <context.h> +#include <stdint.h> + +/* Various flags passed to SMC handlers */ +#define SMC_FROM_SECURE (0 << 0) +#define SMC_FROM_NON_SECURE (1 << 0) + +#define is_caller_non_secure(_f) (!!(_f & SMC_FROM_NON_SECURE)) +#define is_caller_secure(_f) (!(is_caller_non_secure(_f))) + +/* Prototype for runtime service initializing function */ +typedef int32_t (*rt_svc_init_t)(void); + +/* Convenience macros to return from SMC handler */ +#define SMC_RET0(_h) { \ + return (uint64_t) (_h); \ +} +#define SMC_RET1(_h, _x0) { \ + write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X0, (_x0)); \ + SMC_RET0(_h); \ +} +#define SMC_RET2(_h, _x0, _x1) { \ + write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X1, (_x1)); \ + SMC_RET1(_h, (_x0)); \ +} +#define SMC_RET3(_h, _x0, _x1, _x2) { \ + write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X2, (_x2)); \ + SMC_RET2(_h, (_x0), (_x1)); \ +} +#define SMC_RET4(_h, _x0, _x1, _x2, _x3) { \ + write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X3, (_x3)); \ + SMC_RET3(_h, (_x0), (_x1), (_x2)); \ +} + + +/* + * Convenience macros to access general purpose registers using handle provided + * to SMC handler. These takes the offset values defined in context.h + */ +#define SMC_GET_GP(_h, _g) \ + read_ctx_reg(get_gpregs_ctx(_h), (_g)); +#define SMC_SET_GP(_h, _g, _v) \ + write_ctx_reg(get_gpregs_ctx(_h), (_g), (_v)); + +/* + * Convenience macros to access EL3 context registers using handle provided to + * SMC handler. These takes the offset values defined in context.h + */ +#define SMC_GET_EL3(_h, _e) \ + read_ctx_reg(get_el3state_ctx(_h), (_e)); +#define SMC_SET_EL3(_h, _e, _v) \ + write_ctx_reg(get_el3state_ctx(_h), (_e), (_v)); + +/* + * Prototype for runtime service SMC handler function. x0 (SMC Function ID) to + * x4 are as passed by the caller. Rest of the arguments to SMC and the context + * can be accessed using the handle pointer. The cookie parameter is reserved + * for future use + */ +typedef uint64_t (*rt_svc_handle_t)(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *cookie, + void *handle, + uint64_t flags); +typedef struct rt_svc_desc { + uint8_t start_oen; + uint8_t end_oen; + uint8_t call_type; + const char *name; + rt_svc_init_t init; + rt_svc_handle_t handle; +} rt_svc_desc_t; + +/* + * Convenience macro to declare a service descriptor + */ +#define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) \ + static const rt_svc_desc_t __svc_desc_ ## _name \ + __attribute__ ((section("rt_svc_descs"), used)) = { \ + _start, \ + _end, \ + _type, \ + #_name, \ + _setup, \ + _smch } + +/* + * Compile time assertions related to the 'rt_svc_desc' structure to: + * 1. ensure that the assembler and the compiler view of the size + * of the structure are the same. + * 2. ensure that the assembler and the compiler see the initialisation + * routine at the same offset. + * 3. ensure that the assembler and the compiler see the handler + * routine at the same offset. + */ +CASSERT((sizeof(rt_svc_desc_t) == SIZEOF_RT_SVC_DESC), \ + assert_sizeof_rt_svc_desc_mismatch); +CASSERT(RT_SVC_DESC_INIT == __builtin_offsetof(rt_svc_desc_t, init), \ + assert_rt_svc_desc_init_offset_mismatch); +CASSERT(RT_SVC_DESC_HANDLE == __builtin_offsetof(rt_svc_desc_t, handle), \ + assert_rt_svc_desc_handle_offset_mismatch); + + +/* + * This macro combines the call type and the owning entity number corresponding + * to a runtime service to generate a unique owning entity number. This unique + * oen is used to access an entry in the 'rt_svc_descs_indices' array. The entry + * contains the index of the service descriptor in the 'rt_svc_descs' array. + */ +#define get_unique_oen(oen, call_type) ((oen & FUNCID_OEN_MASK) | \ + ((call_type & FUNCID_TYPE_MASK) \ + << FUNCID_OEN_WIDTH)) + + +/* + * Macro to define UUID for services. Apart from defining and initializing a + * uuid_t structure, this macro verifies that the first word of the defined UUID + * does not equal SMC_UNK. This is to ensure that the caller won't mistake the + * returned UUID in x0 for an invalid SMC error return + */ +#define DEFINE_SVC_UUID(_name, _tl, _tm, _th, _cl, _ch, \ + _n0, _n1, _n2, _n3, _n4, _n5) \ + CASSERT(_tl != SMC_UNK, invalid_svc_uuid);\ + static const uuid_t _name = { \ + _tl, _tm, _th, _cl, _ch, \ + { _n0, _n1, _n2, _n3, _n4, _n5 } \ + } + +/* Return a UUID in the SMC return registers */ +#define SMC_UUID_RET(_h, _uuid) \ + SMC_RET4(handle, ((const uint32_t *) &(_uuid))[0], \ + ((const uint32_t *) &(_uuid))[1], \ + ((const uint32_t *) &(_uuid))[2], \ + ((const uint32_t *) &(_uuid))[3]) + +/******************************************************************************* + * Function & variable prototypes + ******************************************************************************/ +void runtime_svc_init(); +extern uint64_t __RT_SVC_DESCS_START__; +extern uint64_t __RT_SVC_DESCS_END__; +uint64_t get_crash_stack(uint64_t mpidr); +void runtime_exceptions(void); +#endif /*__ASSEMBLY__*/ +#endif /* __RUNTIME_SVC_H__ */ diff --git a/include/bl31/services/psci.h b/include/bl31/services/psci.h new file mode 100644 index 0000000..887c4ce --- /dev/null +++ b/include/bl31/services/psci.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __PSCI_H__ +#define __PSCI_H__ + + +/******************************************************************************* + * Defines for runtime services func ids + ******************************************************************************/ +#define PSCI_VERSION 0x84000000 +#define PSCI_CPU_SUSPEND_AARCH32 0x84000001 +#define PSCI_CPU_SUSPEND_AARCH64 0xc4000001 +#define PSCI_CPU_OFF 0x84000002 +#define PSCI_CPU_ON_AARCH32 0x84000003 +#define PSCI_CPU_ON_AARCH64 0xc4000003 +#define PSCI_AFFINITY_INFO_AARCH32 0x84000004 +#define PSCI_AFFINITY_INFO_AARCH64 0xc4000004 +#define PSCI_MIG_AARCH32 0x84000005 +#define PSCI_MIG_AARCH64 0xc4000005 +#define PSCI_MIG_INFO_TYPE 0x84000006 +#define PSCI_MIG_INFO_UP_CPU_AARCH32 0x84000007 +#define PSCI_MIG_INFO_UP_CPU_AARCH64 0xc4000007 +#define PSCI_SYSTEM_OFF 0x84000008 +#define PSCI_SYSTEM_RESET 0x84000009 + +/* + * Number of PSCI calls (above) implemented. System off and reset aren't + * implemented as yet + */ +#define PSCI_NUM_CALLS 13 + +/******************************************************************************* + * PSCI Migrate and friends + ******************************************************************************/ +#define PSCI_TOS_UP_MIG_CAP 0 +#define PSCI_TOS_NOT_UP_MIG_CAP 1 +#define PSCI_TOS_NOT_PRESENT_MP 2 + +/******************************************************************************* + * PSCI CPU_SUSPEND 'power_state' parameter specific defines + ******************************************************************************/ +#define PSTATE_ID_SHIFT 0 +#define PSTATE_TYPE_SHIFT 16 +#define PSTATE_AFF_LVL_SHIFT 24 + +#define PSTATE_ID_MASK 0xffff +#define PSTATE_TYPE_MASK 0x1 +#define PSTATE_AFF_LVL_MASK 0x3 +#define PSTATE_VALID_MASK 0xFCFE0000 + +#define PSTATE_TYPE_STANDBY 0x0 +#define PSTATE_TYPE_POWERDOWN 0x1 + +#define psci_get_pstate_id(pstate) (pstate >> PSTATE_ID_SHIFT) & \ + PSTATE_ID_MASK +#define psci_get_pstate_type(pstate) (pstate >> PSTATE_TYPE_SHIFT) & \ + PSTATE_TYPE_MASK +#define psci_get_pstate_afflvl(pstate) (pstate >> PSTATE_AFF_LVL_SHIFT) & \ + PSTATE_AFF_LVL_MASK + +/******************************************************************************* + * PSCI version + ******************************************************************************/ +#define PSCI_MAJOR_VER (0 << 16) +#define PSCI_MINOR_VER 0x2 + +/******************************************************************************* + * PSCI error codes + ******************************************************************************/ +#define PSCI_E_SUCCESS 0 +#define PSCI_E_NOT_SUPPORTED -1 +#define PSCI_E_INVALID_PARAMS -2 +#define PSCI_E_DENIED -3 +#define PSCI_E_ALREADY_ON -4 +#define PSCI_E_ON_PENDING -5 +#define PSCI_E_INTERN_FAIL -6 +#define PSCI_E_NOT_PRESENT -7 +#define PSCI_E_DISABLED -8 + +/******************************************************************************* + * PSCI affinity state related constants. An affinity instance could be present + * or absent physically to cater for asymmetric topologies. If present then it + * could in one of the 4 further defined states. + ******************************************************************************/ +#define PSCI_STATE_SHIFT 1 +#define PSCI_STATE_MASK 0xff + +#define PSCI_AFF_ABSENT 0x0 +#define PSCI_AFF_PRESENT 0x1 +#define PSCI_STATE_ON 0x0 +#define PSCI_STATE_OFF 0x1 +#define PSCI_STATE_ON_PENDING 0x2 +#define PSCI_STATE_SUSPEND 0x3 + +#define PSCI_INVALID_DATA -1 + +#define get_phys_state(x) (x != PSCI_STATE_ON ? \ + PSCI_STATE_OFF : PSCI_STATE_ON) + +#define psci_validate_power_state(pstate) (pstate & PSTATE_VALID_MASK) + + +/* Number of affinity instances whose state this psci imp. can track */ +#define PSCI_NUM_AFFS 32ull + +#ifndef __ASSEMBLY__ + +#include <stdint.h> + + +/******************************************************************************* + * Structure populated by platform specific code to export routines which + * perform common low level pm functions + ******************************************************************************/ +typedef struct plat_pm_ops { + int (*affinst_standby)(unsigned int); + int (*affinst_on)(unsigned long, + unsigned long, + unsigned long, + unsigned int, + unsigned int); + int (*affinst_off)(unsigned long, unsigned int, unsigned int); + int (*affinst_suspend)(unsigned long, + unsigned long, + unsigned long, + unsigned int, + unsigned int); + int (*affinst_on_finish)(unsigned long, unsigned int, unsigned int); + int (*affinst_suspend_finish)(unsigned long, + unsigned int, + unsigned int); +} plat_pm_ops_t; + +/******************************************************************************* + * Optional structure populated by the Secure Payload Dispatcher to be given a + * chance to perform any bookkeeping before PSCI executes a power mgmt. + * operation. It also allows PSCI to determine certain properties of the SP e.g. + * migrate capability etc. + ******************************************************************************/ +typedef struct spd_pm_ops { + void (*svc_on)(uint64_t target_cpu); + int32_t (*svc_off)(uint64_t __unused); + void (*svc_suspend)(uint64_t power_state); + void (*svc_on_finish)(uint64_t __unused); + void (*svc_suspend_finish)(uint64_t suspend_level); + void (*svc_migrate)(uint64_t __unused1, uint64_t __unused2); + int32_t (*svc_migrate_info)(uint64_t *__unused); +} spd_pm_ops_t; + +/******************************************************************************* + * Function & Data prototypes + ******************************************************************************/ +unsigned int psci_version(void); +int __psci_cpu_suspend(unsigned int, unsigned long, unsigned long); +int __psci_cpu_off(void); +int psci_affinity_info(unsigned long, unsigned int); +int psci_migrate(unsigned int); +unsigned int psci_migrate_info_type(void); +unsigned long psci_migrate_info_up_cpu(void); +void psci_system_off(void); +void psci_system_reset(void); +int psci_cpu_on(unsigned long, + unsigned long, + unsigned long); +void __dead2 psci_power_down_wfi(void); +void psci_aff_on_finish_entry(void); +void psci_aff_suspend_finish_entry(void); +void psci_register_spd_pm_hook(const spd_pm_ops_t *); +int psci_get_suspend_stateid(unsigned long mpidr); +int psci_get_suspend_afflvl(unsigned long mpidr); + +uint64_t psci_smc_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *cookie, + void *handle, + uint64_t flags); + +/* PSCI setup function */ +int32_t psci_setup(void); + + +#endif /*__ASSEMBLY__*/ + + +#endif /* __PSCI_H__ */ diff --git a/include/bl31/services/std_svc.h b/include/bl31/services/std_svc.h new file mode 100644 index 0000000..cbd5b62 --- /dev/null +++ b/include/bl31/services/std_svc.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __STD_SVC_H__ +#define __STD_SVC_H__ + +/* SMC function IDs for Standard Service queries */ + +#define ARM_STD_SVC_CALL_COUNT 0x8400ff00 +#define ARM_STD_SVC_UID 0x8400ff01 +/* 0x8400ff02 is reserved */ +#define ARM_STD_SVC_VERSION 0x8400ff03 + +/* ARM Standard Service Calls version numbers */ +#define STD_SVC_VERSION_MAJOR 0x0 +#define STD_SVC_VERSION_MINOR 0x1 + +/* The macros below are used to identify PSCI calls from the SMC function ID */ +#define PSCI_FID_MASK 0xffe0u +#define PSCI_FID_VALUE 0u +#define is_psci_fid(_fid) \ + (((_fid) & PSCI_FID_MASK) == PSCI_FID_VALUE) + +#endif /* __STD_SVC_H__ */ diff --git a/include/common/asm_macros.S b/include/common/asm_macros.S new file mode 100644 index 0000000..ce60fdf --- /dev/null +++ b/include/common/asm_macros.S @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> + + + .macro func_prologue + stp x29, x30, [sp, #-0x10]! + mov x29,sp + .endm + + .macro func_epilogue + ldp x29, x30, [sp], #0x10 + .endm + + + .macro dcache_line_size reg, tmp + mrs \tmp, ctr_el0 + ubfx \tmp, \tmp, #16, #4 + mov \reg, #4 + lsl \reg, \reg, \tmp + .endm + + + .macro icache_line_size reg, tmp + mrs \tmp, ctr_el0 + and \tmp, \tmp, #0xf + mov \reg, #4 + lsl \reg, \reg, \tmp + .endm + + + .macro smc_check label + mrs x0, esr_el3 + ubfx x0, x0, #ESR_EC_SHIFT, #ESR_EC_LENGTH + cmp x0, #EC_AARCH64_SMC + b.ne $label + .endm + + + /* + * This macro verifies that the a given vector doesn't exceed the + * architectural limit of 32 instructions. This is meant to be placed + * immedately after the last instruction in the vector. It takes the + * vector entry as the parameter + */ + .macro check_vector_size since + .if (. - \since) > (32 * 4) + .error "Vector exceeds 32 instructions" + .endif + .endm + + /* + * This macro is used to create a function label and place the + * code into a separate text section based on the function name + * to enable elimination of unused code during linking + */ + .macro func _name + .section .text.\_name, "ax" + .type \_name, %function + \_name: + .endm + + /* --------------------------------------------- + * Find the type of reset and jump to handler + * if present. If the handler is null then it is + * a cold boot. The primary cpu will set up the + * platform while the secondaries wait for + * their turn to be woken up + * --------------------------------------------- + */ + .macro wait_for_entrypoint +wait_for_entrypoint: + mrs x0, mpidr_el1 + bl platform_get_entrypoint + cbnz x0, do_warm_boot + mrs x0, mpidr_el1 + bl platform_is_primary_cpu + cbnz x0, do_cold_boot + + /* --------------------------------------------- + * Perform any platform specific secondary cpu + * actions + * --------------------------------------------- + */ + bl plat_secondary_cold_boot_setup + b wait_for_entrypoint + + do_warm_boot: + /* --------------------------------------------- + * Jump to BL31 for all warm boot init. + * --------------------------------------------- + */ + blr x0 + + do_cold_boot: + .endm + + /* + * This macro declares an array of 1 or more stacks, properly + * aligned and in the requested section + */ +#define STACK_ALIGN 6 + + .macro declare_stack _name, _section, _size, _count + .if ((\_size & ((1 << STACK_ALIGN) - 1)) <> 0) + .error "Stack size not correctly aligned" + .endif + .section \_section, "aw", %nobits + .align STACK_ALIGN + .global \_name + \_name: + .space ((\_count) * (\_size)), 0 + .endm + + /* + * This macro calculates the base address of an MP stack using the + * platform_get_core_pos() index, the name of the stack storage and + * the size of each stack + * In: X0 = MPIDR of CPU whose stack is wanted + * Out: X0 = physical address of stack base + * Clobber: X30, X1, X2 + */ + .macro get_mp_stack _name, _size + bl platform_get_core_pos + ldr x2, =(\_name + \_size) + mov x1, #\_size + madd x0, x0, x1, x2 + .endm + + /* + * This macro calculates the base address of a UP stack using the + * name of the stack storage and the size of the stack + * Out: X0 = physical address of stack base + */ + .macro get_up_stack _name, _size + ldr x0, =(\_name + \_size) + .endm diff --git a/include/common/bl_common.h b/include/common/bl_common.h new file mode 100644 index 0000000..1875284 --- /dev/null +++ b/include/common/bl_common.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __BL_COMMON_H__ +#define __BL_COMMON_H__ + + + +#define SECURE 0x0 +#define NON_SECURE 0x1 +#define PARAM_EP_SECURITY_MASK 0x1 + +#define UP 1 +#define DOWN 0 + +/******************************************************************************* + * Constants for loading images. When BLx wants to load BLy, it looks at a + * meminfo structure to find the extents of free memory. Then depending upon + * how it has been configured, it can either load BLy at the top or bottom of + * the free memory. These constants indicate the choice. + * TODO: Make this configurable while building the trusted firmware. + ******************************************************************************/ +#define TOP_LOAD 0x1 +#define BOT_LOAD !TOP_LOAD +#define LOAD_MASK (1 << 0) + +/****************************************************************************** + * Opcode passed in x0 to tell next EL that we want to run an image. + * Corresponds to the function ID of the only SMC that the BL1 exception + * handlers service. That's why the chosen value is the first function ID of + * the ARM SMC64 range. + *****************************************************************************/ +#define RUN_IMAGE 0xC0000000 + +/******************************************************************************* + * Constants that allow assembler code to access members of and the + * 'entry_point_info' structure at their correct offsets. + ******************************************************************************/ +#define ENTRY_POINT_INFO_PC_OFFSET 0x08 +#define ENTRY_POINT_INFO_ARGS_OFFSET 0x18 + +#define GET_SECURITY_STATE(x) (x & PARAM_EP_SECURITY_MASK) +#define SET_SECURITY_STATE(x, security) \ + ((x) = ((x) & ~PARAM_EP_SECURITY_MASK) | (security)) + +#define PARAM_EP 0x01 +#define PARAM_IMAGE_BINARY 0x02 +#define PARAM_BL31 0x03 + +#define VERSION_1 0x01 + +#define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \ + (_p)->h.type = (uint8_t)(_type); \ + (_p)->h.version = (uint8_t)(_ver); \ + (_p)->h.size = (uint16_t)sizeof(*_p); \ + (_p)->h.attr = (uint32_t)(_attr) ; \ + } while (0) + +#ifndef __ASSEMBLY__ +#include <cdefs.h> /* For __dead2 */ +#include <cassert.h> +#include <stdint.h> + +/******************************************************************************* + * Structure used for telling the next BL how much of a particular type of + * memory is available for its use and how much is already used. + ******************************************************************************/ +typedef struct meminfo { + unsigned long total_base; + long total_size; + unsigned long free_base; + long free_size; + unsigned long attr; + unsigned long next; +} meminfo_t; + +typedef struct aapcs64_params { + unsigned long arg0; + unsigned long arg1; + unsigned long arg2; + unsigned long arg3; + unsigned long arg4; + unsigned long arg5; + unsigned long arg6; + unsigned long arg7; +} aapcs64_params_t; + +/*************************************************************************** + * This structure provides version information and the size of the + * structure, attributes for the structure it represents + ***************************************************************************/ +typedef struct param_header { + uint8_t type; /* type of the structure */ + uint8_t version; /* version of this structure */ + uint16_t size; /* size of this structure in bytes */ + uint32_t attr; /* attributes: unused bits SBZ */ +} param_header_t; + +/***************************************************************************** + * This structure represents the superset of information needed while + * switching exception levels. The only two mechanisms to do so are + * ERET & SMC. Security state is indicated using bit zero of header + * attribute + * NOTE: BL1 expects entrypoint followed by spsr while processing + * SMC to jump to BL31 from the start of entry_point_info + *****************************************************************************/ +typedef struct entry_point_info { + param_header_t h; + uintptr_t pc; + uint32_t spsr; + aapcs64_params_t args; +} entry_point_info_t; + +/***************************************************************************** + * Image info binary provides information from the image loader that + * can be used by the firmware to manage available trusted RAM. + * More advanced firmware image formats can provide additional + * information that enables optimization or greater flexibility in the + * common firmware code + *****************************************************************************/ +typedef struct image_info { + param_header_t h; + uintptr_t image_base; /* physical address of base of image */ + uint32_t image_size; /* bytes read from image file */ +} image_info_t; + +/******************************************************************************* + * This structure represents the superset of information that can be passed to + * BL31 e.g. while passing control to it from BL2. The BL32 parameters will be + * populated only if BL2 detects its presence. A pointer to a structure of this + * type should be passed in X3 to BL31's cold boot entrypoint + * + * Use of this structure and the X3 parameter is not mandatory: the BL3-1 + * platform code can use other mechanisms to provide the necessary information + * about BL3-2 and BL3-3 to the common and SPD code. + * + * BL3-1 image information is mandatory if this structure is used. If either of + * the optional BL3-2 and BL3-3 image information is not provided, this is + * indicated by the respective image_info pointers being zero. + ******************************************************************************/ +typedef struct bl31_params { + param_header_t h; + image_info_t *bl31_image_info; + entry_point_info_t *bl32_ep_info; + image_info_t *bl32_image_info; + entry_point_info_t *bl33_ep_info; + image_info_t *bl33_image_info; +} bl31_params_t; + +/* + * Compile time assertions related to the 'entry_point_info' structure to + * ensure that the assembler and the compiler view of the offsets of + * the structure members is the same. + */ +CASSERT(ENTRY_POINT_INFO_PC_OFFSET == + __builtin_offsetof(entry_point_info_t, pc), \ + assert_BL31_pc_offset_mismatch); + +CASSERT(ENTRY_POINT_INFO_ARGS_OFFSET == \ + __builtin_offsetof(entry_point_info_t, args), \ + assert_BL31_args_offset_mismatch); + +CASSERT(sizeof(unsigned long) == + __builtin_offsetof(entry_point_info_t, spsr) - \ + __builtin_offsetof(entry_point_info_t, pc), \ + assert_entrypoint_and_spsr_should_be_adjacent); + +/******************************************************************************* + * Function & variable prototypes + ******************************************************************************/ +unsigned long page_align(unsigned long, unsigned); +void change_security_state(unsigned int); +unsigned long image_size(const char *); +int load_image(meminfo_t *, + const char *, + unsigned int, + unsigned long, + image_info_t *, + entry_point_info_t *); +extern const char build_message[]; + +#endif /*__ASSEMBLY__*/ + +#endif /* __BL_COMMON_H__ */ diff --git a/include/common/debug.h b/include/common/debug.h new file mode 100644 index 0000000..8abb0b8 --- /dev/null +++ b/include/common/debug.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __DEBUG_H__ +#define __DEBUG_H__ + +#include <stdio.h> + +/* If building the project with DEBUG disabled the INFO and WARN macros + * won't produce any output. The ERROR macro is always enabled. + * The format expected is the same as for printf(). + * INFO("Info %s.\n", "message") -> INFO: Info message. + * WARN("Warning %s.\n", "message") -> WARN: Warning message. + * ERROR("Error %s.\n", "message") -> ERROR: Error message. + * + * TODO : add debug levels. + */ +#if DEBUG + //#define INFO(...) printf("INFO: " __VA_ARGS__) + //#define WARN(...) printf("WARN: " __VA_ARGS__) + #define INFO(...) + #define WARN(...) +#else + #define INFO(...) + #define WARN(...) +#endif + +//#define ERROR(...) printf("ERROR: " __VA_ARGS__) +#define ERROR(...) + + +/* For the moment this Panic function is very basic, Report an error and + * spin. This can be expanded in the future to provide more information. + */ +#if DEBUG +void __dead2 do_panic(const char *file, int line); +#define panic() do_panic(__FILE__, __LINE__) + +#else +void __dead2 do_panic(void); +#define panic() do_panic() + +#endif + +void print_string_value(char *s, unsigned long *mem); + +#endif /* __DEBUG_H__ */ diff --git a/include/common/fip.h b/include/common/fip.h new file mode 100644 index 0000000..19146e2 --- /dev/null +++ b/include/common/fip.h @@ -0,0 +1,141 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/include/common/fip.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <bl_common.h> +#include <stdint.h> +#include <platform_def.h> +#include <storage.h> +#include <config.h> + +#ifndef __BL2_FIP_H_ +#define __BL2_FIP_H_ + +#define NEED_BL32 CONFIG_NEED_BL32 +#define NEED_BL301 CONFIG_NEED_BL301 + +#define TOC_HEADER_NAME (0xAA640001) +#define TOC_HEADER_SERIAL_NUMBER (0x12345678) + +#define _UUID_NODE_LEN 6 + +struct uuid { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint8_t clock_seq_hi_and_reserved; + uint8_t clock_seq_low; + uint8_t node[_UUID_NODE_LEN]; +}; + +typedef struct uuid uuid_t; + +typedef struct fip_toc_header { + uint32_t name; + uint32_t serial_number; + uint64_t flags; +} fip_toc_header_t; + +typedef struct fip_toc_entry { + uuid_t uuid; + uint64_t offset; + uint64_t size; + uint64_t flags; +} fip_toc_entry_t; + +/*amlogic fip structure: bl30+bl31+(bl32)+bl33*/ +typedef struct aml_fip_header { + fip_toc_header_t fip_header; /*16byte*/ + fip_toc_entry_t bl30_entry; /*40byte*/ +#if (NEED_BL301) + fip_toc_entry_t bl301_entry; /*40byte*/ +#endif + fip_toc_entry_t bl31_entry; /*40byte*/ +#if (NEED_BL32) + fip_toc_entry_t bl32_entry; /*40byte*/ +#endif + fip_toc_entry_t bl33_entry; /*40byte*/ +} aml_fip_header_t; + +/*aml defines*/ +#define FIP_HEADER_SIZE_OFFSET 0x20 +#define TPL_LOAD_ADDR CONFIG_SYS_TEXT_BASE +#define TPL_GET_BL_ADDR(offset) (TPL_LOAD_ADDR + (*((volatile unsigned *)(TPL_LOAD_ADDR + (offset))))) +#define TPL_GET_BL_SIZE(offset) (*((volatile unsigned *)(TPL_LOAD_ADDR + offset))) + +/*aml fip.bin doesn't have bl2.bin*/ +//#define FM_BIN_BL2_OFFSET 0x20 +//#define FM_BIN_BL2_SIZE 0x28 +#define FM_BIN_BL30_OFFSET 0x20 //0x48(when have bl2.bin) +#define FM_BIN_BL30_SIZE 0x28 //0x50 +#define FM_BIN_BL31_OFFSET 0x48 //0x70 +#define FM_BIN_BL31_SIZE 0x50 //0x78 +#if (NEED_BL32) +#define FM_BIN_BL32_OFFSET 0x70 //0x98 +#define FM_BIN_BL32_SIZE 0x78 //0xA0 +#define FM_BIN_BL33_OFFSET 0x98 //0xC0 +#define FM_BIN_BL33_SIZE 0xA0 //0xC8 +#else +#define FM_BIN_BL33_OFFSET 0x70 //0x98 +#define FM_BIN_BL33_SIZE 0x78 //0xA0 +#endif + +/* load address assignment */ +#define FM_BL30_LOAD_ADDR CONFIG_SYS_TEXT_BASE +#define FM_BL301_LOAD_ADDR CONFIG_SYS_TEXT_BASE +#define FM_BL31_LOAD_ADDR 0x10100000 //0x05000000 +#define FM_BL32_LOAD_ADDR 0x05200000 +#define FM_BL33_LOAD_ADDR CONFIG_SYS_TEXT_BASE + +/*usb burning func*/ +#define USB_BL2_RETURN_ROM_ADDR 0xd9044504 +#define FM_USB_MODE_LOAD_ADDR 0x0200c000//using u-boot.bin.usb.tpl, not u-boot.bin +#define BL2_RETURN_ROM_USB_ADDR 0xd9043df0 +#define USB_BL2_RUN_CMD_PARA_ADDR (void*)(0XD9000000 + 0XC000)//(BL1_RAM_END)//sram_start + 48K + +#define FM_FIP_HEADER_LOAD_ADDR 0x01400000 /*tmp addr until bl33 load done*/ +#define BL2_MMU_TABLE_BASE 0x01500000 +#define BL2_MMU_TABLE_SIZE (sizeof(uint64_t) * MAX_XLAT_TABLES * XLAT_TABLE_ENTRIES) +#define BL2_MMAP_BASE 0x01600000 +#define BL2_MMAP_NUM (MAX_MMAP_REGIONS + 1) +#define BL2_SEC_BOOT_BUF_BASE 0x01700000 +#define BL2_SEC_BOOT_BUF_SIZE 0x00100000 +#define BL2_NAND_BUF_BASE 0x01800000 +#define BL2_NAND_BUF_SIZE 0x00100000 +#define BL2_SEC_BOOT_SP_BASE (BL2_NAND_BUF_BASE) +#define FM_FIP_BL3X_TEMP_LOAD_ADDR (BL2_SEC_BOOT_BUF_BASE) /*tmp addr for bl3x load & process for secure boot*/ + +/*fip defines*/ +void bl2_load_image(void); + +/*parse blx*/ +void parse_blx(image_info_t *image_data, + entry_point_info_t *entry_point_info, + unsigned int src, + unsigned int dst, + unsigned int length, + unsigned int); +void process_bl30x(image_info_t *image_data, + entry_point_info_t *entry_point_info, + const char * name); +void bl2_to_romcode(uintptr_t entry); +void check_handler(void); + +#endif /*__BL2_FIP_H_*/ diff --git a/include/common/firmware_image_package.h b/include/common/firmware_image_package.h new file mode 100644 index 0000000..f4554ec --- /dev/null +++ b/include/common/firmware_image_package.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __FIRMWARE_IMAGE_PACKAGE_H__ +#define __FIRMWARE_IMAGE_PACKAGE_H__ + +#include <stdint.h> +#include <uuid.h> + +/* This is used as a signature to validate the blob header */ +#define TOC_HEADER_NAME 0xAA640001 + + +/* ToC Entry UUIDs */ +#define UUID_TRUSTED_BOOT_FIRMWARE_BL2 \ + {0x0becf95f, 0x224d, 0x4d3e, 0xa5, 0x44, {0xc3, 0x9d, 0x81, 0xc7, 0x3f, 0x0a} } +#define UUID_SCP_FIRMWARE_BL30 \ + {0x3dfd6697, 0xbe89, 0x49e8, 0xae, 0x5d, {0x78, 0xa1, 0x40, 0x60, 0x82, 0x13} } +#define UUID_EL3_RUNTIME_FIRMWARE_BL31 \ + {0x6d08d447, 0xfe4c, 0x4698, 0x9b, 0x95, {0x29, 0x50, 0xcb, 0xbd, 0x5a, 0x00} } +#define UUID_SECURE_PAYLOAD_BL32 \ + {0x89e1d005, 0xdc53, 0x4713, 0x8d, 0x2b, {0x50, 0x0a, 0x4b, 0x7a, 0x3e, 0x38} } +#define UUID_NON_TRUSTED_FIRMWARE_BL33 \ + {0xa7eed0d6, 0xeafc, 0x4bd5, 0x97, 0x82, {0x99, 0x34, 0xf2, 0x34, 0xb6, 0xe4} } + +typedef struct fip_toc_header { + uint32_t name; + uint32_t serial_number; + uint64_t flags; +} fip_toc_header_t; + +typedef struct fip_toc_entry { + uuid_t uuid; + uint64_t offset_address; + uint64_t size; + uint64_t flags; +} fip_toc_entry_t; + +#endif /* __FIRMWARE_IMAGE_PACKAGE_H__ */ diff --git a/include/common/memtest.h b/include/common/memtest.h new file mode 100644 index 0000000..df05d9b --- /dev/null +++ b/include/common/memtest.h @@ -0,0 +1,41 @@ +/********************************************************************** + * + * Filename: memtest.h + * + * Description: Memory-testing module API. + * + * Notes: The memory tests can be easily ported to systems with + * different data bus widths by redefining 'unsigned int' type. + * + * + * Copyright (c) 2000 by Michael Barr. This software is placed into + * the public domain and may be used for any purpose. However, this + * notice must not be changed or removed and no warranty is either + * expressed or implied by its publication or distribution. + **********************************************************************/ + +#ifndef _memtest_h +#define _memtest_h + + +/* + * Define NULL pointer value. + */ +#ifndef NULL +#define NULL (void *) 0 +#endif + +/* + * Set the data bus width. + */ +//typedef unsigned int unsigned int; + +/* + * Function prototypes. + */ + +unsigned int memTestDataBus(volatile unsigned int * address); +unsigned int memTestAddressBus(volatile unsigned int * baseAddress, unsigned int nBytes); +unsigned int memTestDevice(volatile unsigned int * baseAddress, unsigned int nBytes); + +#endif /* _memtest_h */
\ No newline at end of file diff --git a/include/drivers/arm/cci400.h b/include/drivers/arm/cci400.h new file mode 100644 index 0000000..7222391 --- /dev/null +++ b/include/drivers/arm/cci400.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __CCI_400_H__ +#define __CCI_400_H__ + +/* Slave interface offsets from PERIPHBASE */ +#define SLAVE_IFACE4_OFFSET 0x5000 +#define SLAVE_IFACE3_OFFSET 0x4000 +#define SLAVE_IFACE2_OFFSET 0x3000 +#define SLAVE_IFACE1_OFFSET 0x2000 +#define SLAVE_IFACE0_OFFSET 0x1000 +#define SLAVE_IFACE_OFFSET(index) SLAVE_IFACE0_OFFSET + (0x1000 * index) + +/* Control and ID register offsets */ +#define CTRL_OVERRIDE_REG 0x0 +#define SPEC_CTRL_REG 0x4 +#define SECURE_ACCESS_REG 0x8 +#define STATUS_REG 0xc +#define IMPRECISE_ERR_REG 0x10 +#define PERFMON_CTRL_REG 0x100 + +/* Slave interface register offsets */ +#define SNOOP_CTRL_REG 0x0 +#define SH_OVERRIDE_REG 0x4 +#define READ_CHNL_QOS_VAL_OVERRIDE_REG 0x100 +#define WRITE_CHNL_QOS_VAL_OVERRIDE_REG 0x104 +#define QOS_CTRL_REG 0x10c +#define MAX_OT_REG 0x110 +#define TARGET_LATENCY_REG 0x130 +#define LATENCY_REGULATION_REG 0x134 +#define QOS_RANGE_REG 0x138 + +/* Snoop Control register bit definitions */ +#define DVM_EN_BIT (1 << 1) +#define SNOOP_EN_BIT (1 << 0) + +/* Status register bit definitions */ +#define CHANGE_PENDING_BIT (1 << 0) + +/* Function declarations */ +void cci_enable_coherency(unsigned long mpidr); +void cci_disable_coherency(unsigned long mpidr); + +#endif /* __CCI_400_H__ */ diff --git a/include/drivers/arm/gic_v2.h b/include/drivers/arm/gic_v2.h new file mode 100644 index 0000000..1859a8e --- /dev/null +++ b/include/drivers/arm/gic_v2.h @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __GIC_V2_H__ +#define __GIC_V2_H__ + + +#define GIC400_NUM_SPIS 480 +#define MAX_PPIS 14 +#define MAX_SGIS 16 + +#define GRP0 0 +#define GRP1 1 +#define GIC_PRI_MASK 0xff +#define GIC_HIGHEST_SEC_PRIORITY 0 +#define GIC_LOWEST_SEC_PRIORITY 127 +#define GIC_HIGHEST_NS_PRIORITY 128 +#define GIC_LOWEST_NS_PRIORITY 254 /* 255 would disable an interrupt */ +#define GIC_SPURIOUS_INTERRUPT 1023 + +#define ENABLE_GRP0 (1 << 0) +#define ENABLE_GRP1 (1 << 1) + +/* Distributor interface definitions */ +#define GICD_CTLR 0x0 +#define GICD_TYPER 0x4 +#define GICD_IGROUPR 0x80 +#define GICD_ISENABLER 0x100 +#define GICD_ICENABLER 0x180 +#define GICD_ISPENDR 0x200 +#define GICD_ICPENDR 0x280 +#define GICD_ISACTIVER 0x300 +#define GICD_ICACTIVER 0x380 +#define GICD_IPRIORITYR 0x400 +#define GICD_ITARGETSR 0x800 +#define GICD_ICFGR 0xC00 +#define GICD_SGIR 0xF00 +#define GICD_CPENDSGIR 0xF10 +#define GICD_SPENDSGIR 0xF20 + +#define IGROUPR_SHIFT 5 +#define ISENABLER_SHIFT 5 +#define ICENABLER_SHIFT ISENABLER_SHIFT +#define ISPENDR_SHIFT 5 +#define ICPENDR_SHIFT ISPENDR_SHIFT +#define ISACTIVER_SHIFT 5 +#define ICACTIVER_SHIFT ISACTIVER_SHIFT +#define IPRIORITYR_SHIFT 2 +#define ITARGETSR_SHIFT 2 +#define ICFGR_SHIFT 4 +#define CPENDSGIR_SHIFT 2 +#define SPENDSGIR_SHIFT CPENDSGIR_SHIFT + +/* GICD_TYPER bit definitions */ +#define IT_LINES_NO_MASK 0x1f + +/* Physical CPU Interface registers */ +#define GICC_CTLR 0x0 +#define GICC_PMR 0x4 +#define GICC_BPR 0x8 +#define GICC_IAR 0xC +#define GICC_EOIR 0x10 +#define GICC_RPR 0x14 +#define GICC_HPPIR 0x18 +#define GICC_AHPPIR 0x28 +#define GICC_IIDR 0xFC +#define GICC_DIR 0x1000 +#define GICC_PRIODROP GICC_EOIR + +/* GICC_CTLR bit definitions */ +#define EOI_MODE_NS (1 << 10) +#define EOI_MODE_S (1 << 9) +#define IRQ_BYP_DIS_GRP1 (1 << 8) +#define FIQ_BYP_DIS_GRP1 (1 << 7) +#define IRQ_BYP_DIS_GRP0 (1 << 6) +#define FIQ_BYP_DIS_GRP0 (1 << 5) +#define CBPR (1 << 4) +#define FIQ_EN (1 << 3) +#define ACK_CTL (1 << 2) + +/* GICC_IIDR bit masks and shifts */ +#define GICC_IIDR_PID_SHIFT 20 +#define GICC_IIDR_ARCH_SHIFT 16 +#define GICC_IIDR_REV_SHIFT 12 +#define GICC_IIDR_IMP_SHIFT 0 + +#define GICC_IIDR_PID_MASK 0xfff +#define GICC_IIDR_ARCH_MASK 0xf +#define GICC_IIDR_REV_MASK 0xf +#define GICC_IIDR_IMP_MASK 0xfff + +/* HYP view virtual CPU Interface registers */ +#define GICH_CTL 0x0 +#define GICH_VTR 0x4 +#define GICH_ELRSR0 0x30 +#define GICH_ELRSR1 0x34 +#define GICH_APR0 0xF0 +#define GICH_LR_BASE 0x100 + +/* Virtual CPU Interface registers */ +#define GICV_CTL 0x0 +#define GICV_PRIMASK 0x4 +#define GICV_BP 0x8 +#define GICV_INTACK 0xC +#define GICV_EOI 0x10 +#define GICV_RUNNINGPRI 0x14 +#define GICV_HIGHESTPEND 0x18 +#define GICV_DEACTIVATE 0x1000 + +#ifndef __ASSEMBLY__ + +#include <mmio.h> + + +/******************************************************************************* + * GIC Distributor function prototypes + ******************************************************************************/ + +unsigned int gicd_read_igroupr(unsigned int, unsigned int); +unsigned int gicd_read_isenabler(unsigned int, unsigned int); +unsigned int gicd_read_icenabler(unsigned int, unsigned int); +unsigned int gicd_read_ispendr(unsigned int, unsigned int); +unsigned int gicd_read_icpendr(unsigned int, unsigned int); +unsigned int gicd_read_isactiver(unsigned int, unsigned int); +unsigned int gicd_read_icactiver(unsigned int, unsigned int); +unsigned int gicd_read_ipriorityr(unsigned int, unsigned int); +unsigned int gicd_read_itargetsr(unsigned int, unsigned int); +unsigned int gicd_read_icfgr(unsigned int, unsigned int); +unsigned int gicd_read_cpendsgir(unsigned int, unsigned int); +unsigned int gicd_read_spendsgir(unsigned int, unsigned int); +void gicd_write_igroupr(unsigned int, unsigned int, unsigned int); +void gicd_write_isenabler(unsigned int, unsigned int, unsigned int); +void gicd_write_icenabler(unsigned int, unsigned int, unsigned int); +void gicd_write_ispendr(unsigned int, unsigned int, unsigned int); +void gicd_write_icpendr(unsigned int, unsigned int, unsigned int); +void gicd_write_isactiver(unsigned int, unsigned int, unsigned int); +void gicd_write_icactiver(unsigned int, unsigned int, unsigned int); +void gicd_write_ipriorityr(unsigned int, unsigned int, unsigned int); +void gicd_write_itargetsr(unsigned int, unsigned int, unsigned int); +void gicd_write_icfgr(unsigned int, unsigned int, unsigned int); +void gicd_write_cpendsgir(unsigned int, unsigned int, unsigned int); +void gicd_write_spendsgir(unsigned int, unsigned int, unsigned int); +unsigned int gicd_get_igroupr(unsigned int, unsigned int); +void gicd_set_igroupr(unsigned int, unsigned int); +void gicd_clr_igroupr(unsigned int, unsigned int); +void gicd_set_isenabler(unsigned int, unsigned int); +void gicd_set_icenabler(unsigned int, unsigned int); +void gicd_set_ispendr(unsigned int, unsigned int); +void gicd_set_icpendr(unsigned int, unsigned int); +void gicd_set_isactiver(unsigned int, unsigned int); +void gicd_set_icactiver(unsigned int, unsigned int); +void gicd_set_ipriorityr(unsigned int, unsigned int, unsigned int); +void gicd_set_itargetsr(unsigned int, unsigned int, unsigned int); + + +/******************************************************************************* + * GIC Distributor interface accessors for reading entire registers + ******************************************************************************/ + +static inline unsigned int gicd_read_ctlr(unsigned int base) +{ + return mmio_read_32(base + GICD_CTLR); +} + +static inline unsigned int gicd_read_typer(unsigned int base) +{ + return mmio_read_32(base + GICD_TYPER); +} + +static inline unsigned int gicd_read_sgir(unsigned int base) +{ + return mmio_read_32(base + GICD_SGIR); +} + + +/******************************************************************************* + * GIC Distributor interface accessors for writing entire registers + ******************************************************************************/ + +static inline void gicd_write_ctlr(unsigned int base, unsigned int val) +{ + mmio_write_32(base + GICD_CTLR, val); +} + +static inline void gicd_write_sgir(unsigned int base, unsigned int val) +{ + mmio_write_32(base + GICD_SGIR, val); +} + + +/******************************************************************************* + * GIC CPU interface accessors for reading entire registers + ******************************************************************************/ + +static inline unsigned int gicc_read_ctlr(unsigned int base) +{ + return mmio_read_32(base + GICC_CTLR); +} + +static inline unsigned int gicc_read_pmr(unsigned int base) +{ + return mmio_read_32(base + GICC_PMR); +} + +static inline unsigned int gicc_read_BPR(unsigned int base) +{ + return mmio_read_32(base + GICC_BPR); +} + +static inline unsigned int gicc_read_IAR(unsigned int base) +{ + return mmio_read_32(base + GICC_IAR); +} + +static inline unsigned int gicc_read_EOIR(unsigned int base) +{ + return mmio_read_32(base + GICC_EOIR); +} + +static inline unsigned int gicc_read_hppir(unsigned int base) +{ + return mmio_read_32(base + GICC_HPPIR); +} + +static inline unsigned int gicc_read_ahppir(unsigned int base) +{ + return mmio_read_32(base + GICC_AHPPIR); +} + +static inline unsigned int gicc_read_dir(unsigned int base) +{ + return mmio_read_32(base + GICC_DIR); +} + +static inline unsigned int gicc_read_iidr(unsigned int base) +{ + return mmio_read_32(base + GICC_IIDR); +} + + +/******************************************************************************* + * GIC CPU interface accessors for writing entire registers + ******************************************************************************/ + +static inline void gicc_write_ctlr(unsigned int base, unsigned int val) +{ + mmio_write_32(base + GICC_CTLR, val); +} + +static inline void gicc_write_pmr(unsigned int base, unsigned int val) +{ + mmio_write_32(base + GICC_PMR, val); +} + +static inline void gicc_write_BPR(unsigned int base, unsigned int val) +{ + mmio_write_32(base + GICC_BPR, val); +} + + +static inline void gicc_write_IAR(unsigned int base, unsigned int val) +{ + mmio_write_32(base + GICC_IAR, val); +} + +static inline void gicc_write_EOIR(unsigned int base, unsigned int val) +{ + mmio_write_32(base + GICC_EOIR, val); +} + +static inline void gicc_write_hppir(unsigned int base, unsigned int val) +{ + mmio_write_32(base + GICC_HPPIR, val); +} + +static inline void gicc_write_dir(unsigned int base, unsigned int val) +{ + mmio_write_32(base + GICC_DIR, val); +} + +/******************************************************************************* + * Prototype of function to map an interrupt type to the interrupt line used to + * signal it. + ******************************************************************************/ +uint32_t gicv2_interrupt_type_to_line(uint32_t cpuif_base, uint32_t type); + +#endif /*__ASSEMBLY__*/ + +#endif /* __GIC_V2_H__ */ diff --git a/include/drivers/arm/gic_v3.h b/include/drivers/arm/gic_v3.h new file mode 100644 index 0000000..0f99994 --- /dev/null +++ b/include/drivers/arm/gic_v3.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __GIC_V3_H__ +#define __GIC_V3_H__ + +#include <mmio.h> +#include <stdint.h> + + +/* GICv3 Re-distributor interface registers & shifts */ +#define GICR_PCPUBASE_SHIFT 0x11 +#define GICR_TYPER 0x08 +#define GICR_WAKER 0x14 + +/* GICR_WAKER bit definitions */ +#define WAKER_CA (1UL << 2) +#define WAKER_PS (1UL << 1) + +/* GICR_TYPER bit definitions */ +#define GICR_TYPER_AFF_SHIFT 32 +#define GICR_TYPER_AFF_MASK 0xffffffff +#define GICR_TYPER_LAST (1UL << 4) + +/* GICv3 ICC_SRE register bit definitions*/ +#define ICC_SRE_EN (1UL << 3) +#define ICC_SRE_SRE (1UL << 0) + +/******************************************************************************* + * GICv3 defintions + ******************************************************************************/ +#define GICV3_AFFLVL_MASK 0xff +#define GICV3_AFF0_SHIFT 0 +#define GICV3_AFF1_SHIFT 8 +#define GICV3_AFF2_SHIFT 16 +#define GICV3_AFF3_SHIFT 24 +#define GICV3_AFFINITY_MASK 0xffffffff + +/******************************************************************************* + * Function prototypes + ******************************************************************************/ +uintptr_t gicv3_get_rdist(uintptr_t gicr_base, uint64_t mpidr); + +unsigned int read_icc_sre_el1(void); +unsigned int read_icc_sre_el2(void); +unsigned int read_icc_sre_el3(void); +void write_icc_sre_el1(unsigned int); +void write_icc_sre_el2(unsigned int); +void write_icc_sre_el3(unsigned int); +void write_icc_pmr_el1(unsigned int); + +/******************************************************************************* + * GIC Redistributor interface accessors + ******************************************************************************/ +static inline uint32_t gicr_read_waker(uintptr_t base) +{ + return mmio_read_32(base + GICR_WAKER); +} + +static inline void gicr_write_waker(uintptr_t base, uint32_t val) +{ + mmio_write_32(base + GICR_WAKER, val); +} + +static inline uint64_t gicr_read_typer(uintptr_t base) +{ + return mmio_read_64(base + GICR_TYPER); +} + + +#endif /* __GIC_V3_H__ */ diff --git a/include/drivers/arm/pl011.h b/include/drivers/arm/pl011.h new file mode 100644 index 0000000..281330e --- /dev/null +++ b/include/drivers/arm/pl011.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __PL011_H__ +#define __PL011_H__ + +#include <mmio.h> + + +/* PL011 Registers */ +#define UARTDR 0x000 +#define UARTRSR 0x004 +#define UARTECR 0x004 +#define UARTFR 0x018 +#define UARTILPR 0x020 +#define UARTIBRD 0x024 +#define UARTFBRD 0x028 +#define UARTLCR_H 0x02C +#define UARTCR 0x030 +#define UARTIFLS 0x034 +#define UARTIMSC 0x038 +#define UARTRIS 0x03C +#define UARTMIS 0x040 +#define UARTICR 0x044 +#define UARTDMACR 0x048 + +/* Data status bits */ +#define UART_DATA_ERROR_MASK 0x0F00 + +/* Status reg bits */ +#define UART_STATUS_ERROR_MASK 0x0F + +/* Flag reg bits */ +#define PL011_UARTFR_RI (1 << 8) /* Ring indicator */ +#define PL011_UARTFR_TXFE (1 << 7) /* Transmit FIFO empty */ +#define PL011_UARTFR_RXFF (1 << 6) /* Receive FIFO full */ +#define PL011_UARTFR_TXFF (1 << 5) /* Transmit FIFO full */ +#define PL011_UARTFR_RXFE (1 << 4) /* Receive FIFO empty */ +#define PL011_UARTFR_BUSY (1 << 3) /* UART busy */ +#define PL011_UARTFR_DCD (1 << 2) /* Data carrier detect */ +#define PL011_UARTFR_DSR (1 << 1) /* Data set ready */ +#define PL011_UARTFR_CTS (1 << 0) /* Clear to send */ + +/* Control reg bits */ +#define PL011_UARTCR_CTSEN (1 << 15) /* CTS hardware flow control enable */ +#define PL011_UARTCR_RTSEN (1 << 14) /* RTS hardware flow control enable */ +#define PL011_UARTCR_RTS (1 << 11) /* Request to send */ +#define PL011_UARTCR_DTR (1 << 10) /* Data transmit ready. */ +#define PL011_UARTCR_RXE (1 << 9) /* Receive enable */ +#define PL011_UARTCR_TXE (1 << 8) /* Transmit enable */ +#define PL011_UARTCR_LBE (1 << 7) /* Loopback enable */ +#define PL011_UARTCR_UARTEN (1 << 0) /* UART Enable */ + +#if !defined(PL011_BAUDRATE) +#define PL011_BAUDRATE 115200 +#endif + +#if !defined(PL011_CLK_IN_HZ) +#define PL011_CLK_IN_HZ 24000000 +#endif + +#if !defined(PL011_LINE_CONTROL) +/* FIFO Enabled / No Parity / 8 Data bit / One Stop Bit */ +#define PL011_LINE_CONTROL (PL011_UARTLCR_H_FEN | PL011_UARTLCR_H_WLEN_8) +#endif + +/* Line Control Register Bits */ +#define PL011_UARTLCR_H_SPS (1 << 7) /* Stick parity select */ +#define PL011_UARTLCR_H_WLEN_8 (3 << 5) +#define PL011_UARTLCR_H_WLEN_7 (2 << 5) +#define PL011_UARTLCR_H_WLEN_6 (1 << 5) +#define PL011_UARTLCR_H_WLEN_5 (0 << 5) +#define PL011_UARTLCR_H_FEN (1 << 4) /* FIFOs Enable */ +#define PL011_UARTLCR_H_STP2 (1 << 3) /* Two stop bits select */ +#define PL011_UARTLCR_H_EPS (1 << 2) /* Even parity select */ +#define PL011_UARTLCR_H_PEN (1 << 1) /* Parity Enable */ +#define PL011_UARTLCR_H_BRK (1 << 0) /* Send break */ + +/******************************************************************************* + * Pl011 CPU interface accessors for writing registers + ******************************************************************************/ + +static inline void pl011_write_ibrd(unsigned long base, unsigned int val) +{ + mmio_write_32(base + UARTIBRD, val); +} + +static inline void pl011_write_fbrd(unsigned long base, unsigned int val) +{ + mmio_write_32(base + UARTFBRD, val); +} + +static inline void pl011_write_lcr_h(unsigned long base, unsigned int val) +{ + mmio_write_32(base + UARTLCR_H, val); +} + +static inline void pl011_write_ecr(unsigned long base, unsigned int val) +{ + mmio_write_32(base + UARTECR, val); +} + +static inline void pl011_write_cr(unsigned long base, unsigned int val) +{ + mmio_write_32(base + UARTCR, val); +} + +static inline void pl011_write_dr(unsigned long base, unsigned int val) +{ + mmio_write_32(base + UARTDR, val); +} + +/******************************************************************************* + * Pl011 CPU interface accessors for reading registers + ******************************************************************************/ + +static inline unsigned int pl011_read_fr(unsigned long base) +{ + return mmio_read_32(base + UARTFR); +} + +static inline unsigned int pl011_read_dr(unsigned long base) +{ + return mmio_read_32(base + UARTDR); +} + +/******************************************************************************* + * Function prototypes + ******************************************************************************/ + +void pl011_setbaudrate(unsigned long base_addr, unsigned int baudrate); + +#endif /* __PL011_H__ */ diff --git a/include/drivers/arm/tzc400.h b/include/drivers/arm/tzc400.h new file mode 100644 index 0000000..b4aa3ba --- /dev/null +++ b/include/drivers/arm/tzc400.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __TZC400_H__ +#define __TZC400_H__ + +#include <stdint.h> + +#define BUILD_CONFIG_OFF 0x000 +#define ACTION_OFF 0x004 +#define GATE_KEEPER_OFF 0x008 +#define SPECULATION_CTRL_OFF 0x00c +#define INT_STATUS 0x010 +#define INT_CLEAR 0x014 + +#define FAIL_ADDRESS_LOW_OFF 0x020 +#define FAIL_ADDRESS_HIGH_OFF 0x024 +#define FAIL_CONTROL_OFF 0x028 +#define FAIL_ID 0x02c + +#define REGION_BASE_LOW_OFF 0x100 +#define REGION_BASE_HIGH_OFF 0x104 +#define REGION_TOP_LOW_OFF 0x108 +#define REGION_TOP_HIGH_OFF 0x10c +#define REGION_ATTRIBUTES_OFF 0x110 +#define REGION_ID_ACCESS_OFF 0x114 +#define REGION_NUM_OFF(region) (0x20 * region) + +/* ID Registers */ +#define PID0_OFF 0xfe0 +#define PID1_OFF 0xfe4 +#define PID2_OFF 0xfe8 +#define PID3_OFF 0xfec +#define PID4_OFF 0xfd0 +#define PID5_OFF 0xfd4 +#define PID6_OFF 0xfd8 +#define PID7_OFF 0xfdc +#define CID0_OFF 0xff0 +#define CID1_OFF 0xff4 +#define CID2_OFF 0xff8 +#define CID3_OFF 0xffc + +#define BUILD_CONFIG_NF_SHIFT 24 +#define BUILD_CONFIG_NF_MASK 0x3 +#define BUILD_CONFIG_AW_SHIFT 8 +#define BUILD_CONFIG_AW_MASK 0x3f +#define BUILD_CONFIG_NR_SHIFT 0 +#define BUILD_CONFIG_NR_MASK 0x1f + +/* Not describing the case where regions 1 to 8 overlap */ +#define ACTION_RV_SHIFT 0 +#define ACTION_RV_MASK 0x3 +#define ACTION_RV_LOWOK 0x0 +#define ACTION_RV_LOWERR 0x1 +#define ACTION_RV_HIGHOK 0x2 +#define ACTION_RV_HIGHERR 0x3 + +/* + * Number of gate keepers is implementation defined. But we know the max for + * this device is 4. Get implementation details from BUILD_CONFIG. + */ +#define GATE_KEEPER_OS_SHIFT 16 +#define GATE_KEEPER_OS_MASK 0xf +#define GATE_KEEPER_OR_SHIFT 0 +#define GATE_KEEPER_OR_MASK 0xf + +/* Speculation is enabled by default. */ +#define SPECULATION_CTRL_WRITE_DISABLE (1 << 1) +#define SPECULATION_CTRL_READ_DISABLE (1 << 0) + +/* Max number of filters allowed is 4. */ +#define INT_STATUS_OVERLAP_SHIFT 16 +#define INT_STATUS_OVERLAP_MASK 0xf +#define INT_STATUS_OVERRUN_SHIFT 8 +#define INT_STATUS_OVERRUN_MASK 0xf +#define INT_STATUS_STATUS_SHIFT 0 +#define INT_STATUS_STATUS_MASK 0xf + +#define INT_CLEAR_CLEAR_SHIFT 0 +#define INT_CLEAR_CLEAR_MASK 0xf + +#define FAIL_CONTROL_DIR_SHIFT (1 << 24) +#define FAIL_CONTROL_DIR_READ 0x0 +#define FAIL_CONTROL_DIR_WRITE 0x1 +#define FAIL_CONTROL_NS_SHIFT (1 << 21) +#define FAIL_CONTROL_NS_SECURE 0x0 +#define FAIL_CONTROL_NS_NONSECURE 0x1 +#define FAIL_CONTROL_PRIV_SHIFT (1 << 20) +#define FAIL_CONTROL_PRIV_PRIV 0x0 +#define FAIL_CONTROL_PRIV_UNPRIV 0x1 + +/* + * FAIL_ID_ID_MASK depends on AID_WIDTH which is platform specific. + * Platform should provide the value on initialisation. + */ +#define FAIL_ID_VNET_SHIFT 24 +#define FAIL_ID_VNET_MASK 0xf +#define FAIL_ID_ID_SHIFT 0 + +/* Used along with 'tzc_region_attributes_t' below */ +#define REGION_ATTRIBUTES_SEC_SHIFT 30 +#define REGION_ATTRIBUTES_F_EN_SHIFT 0 +#define REGION_ATTRIBUTES_F_EN_MASK 0xf + +#define REGION_ID_ACCESS_NSAID_WR_EN_SHIFT 16 +#define REGION_ID_ACCESS_NSAID_RD_EN_SHIFT 0 +#define REGION_ID_ACCESS_NSAID_ID_MASK 0xf + + +/* Macros for setting Region ID access permissions based on NSAID */ +#define TZC_REGION_ACCESS_RD(id) \ + ((1 << (id & REGION_ID_ACCESS_NSAID_ID_MASK)) << \ + REGION_ID_ACCESS_NSAID_RD_EN_SHIFT) +#define TZC_REGION_ACCESS_WR(id) \ + ((1 << (id & REGION_ID_ACCESS_NSAID_ID_MASK)) << \ + REGION_ID_ACCESS_NSAID_WR_EN_SHIFT) +#define TZC_REGION_ACCESS_RDWR(id) \ + (TZC_REGION_ACCESS_RD(id) | TZC_REGION_ACCESS_WR(id)) + +/* Filters are bit mapped 0 to 3. */ +#define TZC400_COMPONENT_ID 0xb105f00d + +/******************************************************************************* + * Function & variable prototypes + ******************************************************************************/ + +/* + * What type of action is expected when an access violation occurs. + * The memory requested is zeroed. But we can also raise and event to + * let the system know it happened. + * We can raise an interrupt(INT) and/or cause an exception(ERR). + * TZC_ACTION_NONE - No interrupt, no Exception + * TZC_ACTION_ERR - No interrupt, raise exception -> sync external + * data abort + * TZC_ACTION_INT - Raise interrupt, no exception + * TZC_ACTION_ERR_INT - Raise interrupt, raise exception -> sync + * external data abort + */ +typedef enum { + TZC_ACTION_NONE = 0, + TZC_ACTION_ERR = 1, + TZC_ACTION_INT = 2, + TZC_ACTION_ERR_INT = (TZC_ACTION_ERR | TZC_ACTION_INT) +} tzc_action_t; + +/* + * Controls secure access to a region. If not enabled secure access is not + * allowed to region. + */ +typedef enum { + TZC_REGION_S_NONE = 0, + TZC_REGION_S_RD = 1, + TZC_REGION_S_WR = 2, + TZC_REGION_S_RDWR = (TZC_REGION_S_RD | TZC_REGION_S_WR) +} tzc_region_attributes_t; + +/* + * Implementation defined values used to validate inputs later. + * Filters : max of 4 ; 0 to 3 + * Regions : max of 9 ; 0 to 8 + * Address width : Values between 32 to 64 + */ +typedef struct tzc_instance { + uint64_t base; + uint32_t aid_width; + uint8_t addr_width; + uint8_t num_filters; + uint8_t num_regions; +} tzc_instance_t ; + +void tzc_init(tzc_instance_t *controller); +void tzc_configure_region(const tzc_instance_t *controller, uint32_t filters, + uint8_t region, uint64_t region_base, uint64_t region_top, + tzc_region_attributes_t sec_attr, uint32_t ns_device_access); +void tzc_enable_filters(const tzc_instance_t *controller); +void tzc_disable_filters(const tzc_instance_t *controller); +void tzc_set_action(const tzc_instance_t *controller, tzc_action_t action); + + +#endif /* __TZC400__ */ diff --git a/include/drivers/io_driver.h b/include/drivers/io_driver.h new file mode 100644 index 0000000..867abbf --- /dev/null +++ b/include/drivers/io_driver.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __IO_DRIVER_H__ +#define __IO_DRIVER_H__ + +#include <io_storage.h> +#include <platform_def.h> /* For MAX_IO_DEVICES */ +#include <stdint.h> + + +/* Generic IO entity structure,representing an accessible IO construct on the + * device, such as a file */ +typedef struct io_entity { + struct io_dev_info *dev_handle; + uintptr_t info; +} io_entity_t; + + +/* Device info structure, providing device-specific functions and a means of + * adding driver-specific state */ +typedef struct io_dev_info { + const struct io_dev_funcs *funcs; + uintptr_t info; +} io_dev_info_t; + + +/* Structure used to create a connection to a type of device */ +typedef struct io_dev_connector { + /* dev_open opens a connection to a particular device driver */ + int (*dev_open)(const uintptr_t dev_spec, io_dev_info_t **dev_info); +} io_dev_connector_t; + + +/* Structure to hold device driver function pointers */ +typedef struct io_dev_funcs { + io_type_t (*type)(void); + int (*open)(io_dev_info_t *dev_info, const uintptr_t spec, + io_entity_t *entity); + int (*seek)(io_entity_t *entity, int mode, ssize_t offset); + int (*size)(io_entity_t *entity, size_t *length); + int (*read)(io_entity_t *entity, uintptr_t buffer, size_t length, + size_t *length_read); + int (*write)(io_entity_t *entity, const uintptr_t buffer, + size_t length, size_t *length_written); + int (*close)(io_entity_t *entity); + int (*dev_init)(io_dev_info_t *dev_info, const uintptr_t init_params); + int (*dev_close)(io_dev_info_t *dev_info); +} io_dev_funcs_t; + + +/* IO platform data - used to track devices registered for a specific + * platform */ +typedef struct io_plat_data { + const io_dev_info_t *devices[MAX_IO_DEVICES]; + unsigned int dev_count; +} io_plat_data_t; + + +/* Operations intended to be performed during platform initialisation */ + +/* Initialise the IO layer */ +void io_init(io_plat_data_t *data); + +/* Register a device driver */ +int io_register_device(const io_dev_info_t *dev_info); + +#endif /* __IO_DRIVER_H__ */ diff --git a/include/drivers/io_fip.h b/include/drivers/io_fip.h new file mode 100644 index 0000000..90b2fd0 --- /dev/null +++ b/include/drivers/io_fip.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014 ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __IO_FIP_H__ +#define __IO_FIP_H__ + +struct io_dev_connector; + +int register_io_dev_fip(const struct io_dev_connector **dev_con); + +#endif /* __IO_FIP_H__ */ diff --git a/include/drivers/io_memmap.h b/include/drivers/io_memmap.h new file mode 100644 index 0000000..7ee60fe --- /dev/null +++ b/include/drivers/io_memmap.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __IO_MEMMAP_H__ +#define __IO_MEMMAP_H__ + +struct io_dev_connector; + +int register_io_dev_memmap(const struct io_dev_connector **dev_con); + +#endif /* __IO_MEMMAP_H__ */ diff --git a/include/drivers/io_semihosting.h b/include/drivers/io_semihosting.h new file mode 100644 index 0000000..8902a6f --- /dev/null +++ b/include/drivers/io_semihosting.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __IO_SH_H__ +#define __IO_SH_H__ + +struct io_dev_connector; + +int register_io_dev_sh(const struct io_dev_connector **dev_con); + +#endif /* __IO_SH_H__ */ diff --git a/include/drivers/serial.h b/include/drivers/serial.h new file mode 100644 index 0000000..a189287 --- /dev/null +++ b/include/drivers/serial.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __SERIAL_H__ +#define __SERIAL_H__ + + +//#define P_AO_UART_WFIFO (0xc81004c0) +//#define P_AO_RTI_PIN_MUX_REG (0xc8100014) +#define UART_WFIFO (0<<2) +#define UART_RFIFO (1<<2) +#define UART_CONTROL (2<<2) +#define UART_STATUS (3<<2) +#define UART_MISC (4<<2) +#define UART_PORT_CONS AO_UART_WFIFO +//#define UART_CLK_SRC CLK_CLK81 + +#define P_UART(uart_base,reg) (uart_base+reg) +#define P_UART_WFIFO(uart_base) P_UART(uart_base,UART_WFIFO) +#define P_UART_RFIFO(uart_base) P_UART(uart_base,UART_RFIFO) + +#define P_UART_CONTROL(uart_base) P_UART(uart_base,UART_CONTROL) + #define UART_CNTL_MASK_BAUD_RATE (0xfff) + #define UART_CNTL_MASK_TX_EN (1<<12) + #define UART_CNTL_MASK_RX_EN (1<<13) + #define UART_CNTL_MASK_2WIRE (1<<15) + #define UART_CNTL_MASK_STP_BITS (3<<16) + #define UART_CNTL_MASK_STP_1BIT (0<<16) + #define UART_CNTL_MASK_STP_2BIT (1<<16) + #define UART_CNTL_MASK_PRTY_EVEN (0<<18) + #define UART_CNTL_MASK_PRTY_ODD (1<<18) + #define UART_CNTL_MASK_PRTY_TYPE (1<<18) + #define UART_CNTL_MASK_PRTY_EN (1<<19) + #define UART_CNTL_MASK_CHAR_LEN (3<<20) + #define UART_CNTL_MASK_CHAR_8BIT (0<<20) + #define UART_CNTL_MASK_CHAR_7BIT (1<<20) + #define UART_CNTL_MASK_CHAR_6BIT (2<<20) + #define UART_CNTL_MASK_CHAR_5BIT (3<<20) + #define UART_CNTL_MASK_RST_TX (1<<22) + #define UART_CNTL_MASK_RST_RX (1<<23) + #define UART_CNTL_MASK_CLR_ERR (1<<24) + #define UART_CNTL_MASK_INV_RX (1<<25) + #define UART_CNTL_MASK_INV_TX (1<<26) + #define UART_CNTL_MASK_RINT_EN (1<<27) + #define UART_CNTL_MASK_TINT_EN (1<<28) + #define UART_CNTL_MASK_INV_CTS (1<<29) + #define UART_CNTL_MASK_MASK_ERR (1<<30) + #define UART_CNTL_MASK_INV_RTS (1<<31) +#define P_UART_STATUS(uart_base) P_UART(uart_base,UART_STATUS ) + #define UART_STAT_MASK_RFIFO_CNT (0x3f<<0) + #define UART_STAT_MASK_TFIFO_CNT (0x3f<<8) + #define UART_STAT_MASK_PRTY_ERR (1<<16) + #define UART_STAT_MASK_FRAM_ERR (1<<17) + #define UART_STAT_MASK_WFULL_ERR (1<<18) + #define UART_STAT_MASK_RFIFO_FULL (1<<19) + #define UART_STAT_MASK_RFIFO_EMPTY (1<<20) + #define UART_STAT_MASK_TFIFO_FULL (1<<21) + #define UART_STAT_MASK_TFIFO_EMPTY (1<<22) +#define P_UART_MISC(uart_base) P_UART(uart_base,UART_MISC) + +void serial_init(unsigned set); +int serial_putc(int c); +int serial_getc(void); +int serial_puts(const char *s); +void serial_put_hex(unsigned long data,unsigned int bitlen); +void serial_put_dec(unsigned long data); + +#endif /* __SERIAL_H__ */ diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h new file mode 100644 index 0000000..01eb155 --- /dev/null +++ b/include/lib/aarch64/arch.h @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __ARCH_H__ +#define __ARCH_H__ + + +/******************************************************************************* + * MIDR bit definitions + ******************************************************************************/ +#define MIDR_VAR_MASK 0xf +#define MIDR_REV_MASK 0xf +#define MIDR_PN_MASK 0xfff +#define MIDR_VAR_SHIFT 20 +#define MIDR_REV_SHIFT 0 +#define MIDR_PN_SHIFT 4 +#define MIDR_PN_AEM 0xd0f +#define MIDR_PN_A57 0xd07 +#define MIDR_PN_A53 0xd03 + +/******************************************************************************* + * MPIDR macros + ******************************************************************************/ +#define MPIDR_CPU_MASK MPIDR_AFFLVL_MASK +#define MPIDR_CLUSTER_MASK MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS +#define MPIDR_AFFINITY_BITS 8 +#define MPIDR_AFFLVL_MASK 0xff +#define MPIDR_AFF0_SHIFT 0 +#define MPIDR_AFF1_SHIFT 8 +#define MPIDR_AFF2_SHIFT 16 +#define MPIDR_AFF3_SHIFT 32 +#define MPIDR_AFFINITY_MASK 0xff00ffffff +#define MPIDR_AFFLVL_SHIFT 3 +#define MPIDR_AFFLVL0 0 +#define MPIDR_AFFLVL1 1 +#define MPIDR_AFFLVL2 2 +#define MPIDR_AFFLVL3 3 +/* TODO: Support only the first 3 affinity levels for now */ +#define MPIDR_MAX_AFFLVL 2 + +/* Constant to highlight the assumption that MPIDR allocation starts from 0 */ +#define FIRST_MPIDR 0 + +/******************************************************************************* + * Implementation defined sysreg encodings + ******************************************************************************/ +#define CPUECTLR_EL1 S3_1_C15_C2_1 +#define CPUACTLR_EL1 S3_1_C15_C2_0 + +/******************************************************************************* + * Generic timer memory mapped registers & offsets + ******************************************************************************/ +#define CNTCR_OFF 0x000 +#define CNTFID_OFF 0x020 + +#define CNTCR_EN (1 << 0) +#define CNTCR_HDBG (1 << 1) +#define CNTCR_FCREQ(x) ((x) << 8) + +/******************************************************************************* + * System register bit definitions + ******************************************************************************/ +/* CLIDR definitions */ +#define LOUIS_SHIFT 21 +#define LOC_SHIFT 24 +#define CLIDR_FIELD_WIDTH 3 + +/* CSSELR definitions */ +#define LEVEL_SHIFT 1 + +/* D$ set/way op type defines */ +#define DCISW 0x0 +#define DCCISW 0x1 +#define DCCSW 0x2 + +/* ID_AA64PFR0_EL1 definitions */ +#define ID_AA64PFR0_EL0_SHIFT 0 +#define ID_AA64PFR0_EL1_SHIFT 4 +#define ID_AA64PFR0_EL2_SHIFT 8 +#define ID_AA64PFR0_EL3_SHIFT 12 +#define ID_AA64PFR0_ELX_MASK 0xf + +/* ID_PFR1_EL1 definitions */ +#define ID_PFR1_VIRTEXT_SHIFT 12 +#define ID_PFR1_VIRTEXT_MASK 0xf +#define GET_VIRT_EXT(id) ((id >> ID_PFR1_VIRTEXT_SHIFT) \ + & ID_PFR1_VIRTEXT_MASK) + +/* SCTLR definitions */ +#define SCTLR_EL2_RES1 ((1 << 29) | (1 << 28) | (1 << 23) | (1 << 22) | \ + (1 << 18) | (1 << 16) | (1 << 11) | (1 << 5) | \ + (1 << 4)) + +#define SCTLR_EL1_RES1 ((1 << 29) | (1 << 28) | (1 << 23) | (1 << 22) | \ + (1 << 11)) +#define SCTLR_M_BIT (1 << 0) +#define SCTLR_A_BIT (1 << 1) +#define SCTLR_C_BIT (1 << 2) +#define SCTLR_SA_BIT (1 << 3) +#define SCTLR_B_BIT (1 << 7) +#define SCTLR_Z_BIT (1 << 11) +#define SCTLR_I_BIT (1 << 12) +#define SCTLR_WXN_BIT (1 << 19) +#define SCTLR_EXCEPTION_BITS (0x3 << 6) +#define SCTLR_EE_BIT (1 << 25) + +/* CPACR_El1 definitions */ +#define CPACR_EL1_FPEN(x) (x << 20) +#define CPACR_EL1_FP_TRAP_EL0 0x1 +#define CPACR_EL1_FP_TRAP_ALL 0x2 +#define CPACR_EL1_FP_TRAP_NONE 0x3 + +/* SCR definitions */ +#define SCR_RES1_BITS ((1 << 4) | (1 << 5)) +#define SCR_TWE_BIT (1 << 13) +#define SCR_TWI_BIT (1 << 12) +#define SCR_ST_BIT (1 << 11) +#define SCR_RW_BIT (1 << 10) +#define SCR_SIF_BIT (1 << 9) +#define SCR_HCE_BIT (1 << 8) +#define SCR_SMD_BIT (1 << 7) +#define SCR_EA_BIT (1 << 3) +#define SCR_FIQ_BIT (1 << 2) +#define SCR_IRQ_BIT (1 << 1) +#define SCR_NS_BIT (1 << 0) +#define SCR_VALID_BIT_MASK 0x2f8f + +/* HCR definitions */ +#define HCR_RW_BIT (1ull << 31) +#define HCR_AMO_BIT (1 << 5) +#define HCR_IMO_BIT (1 << 4) +#define HCR_FMO_BIT (1 << 3) + +/* CNTHCTL_EL2 definitions */ +#define EL1PCEN_BIT (1 << 1) +#define EL1PCTEN_BIT (1 << 0) + +/* CNTKCTL_EL1 definitions */ +#define EL0PTEN_BIT (1 << 9) +#define EL0VTEN_BIT (1 << 8) +#define EL0PCTEN_BIT (1 << 0) +#define EL0VCTEN_BIT (1 << 1) + +/* CPTR_EL3 definitions */ +#define TCPAC_BIT (1 << 31) +#define TTA_BIT (1 << 20) +#define TFP_BIT (1 << 10) + +/* CPSR/SPSR definitions */ +#define DAIF_FIQ_BIT (1 << 0) +#define DAIF_IRQ_BIT (1 << 1) +#define DAIF_ABT_BIT (1 << 2) +#define DAIF_DBG_BIT (1 << 3) +#define SPSR_DAIF_SHIFT 6 +#define SPSR_DAIF_MASK 0xf + +#define SPSR_AIF_SHIFT 6 +#define SPSR_AIF_MASK 0x7 + +#define SPSR_E_SHIFT 9 +#define SPSR_E_MASK 0x1 +#define SPSR_E_LITTLE 0x0 +#define SPSR_E_BIG 0x1 + +#define SPSR_T_SHIFT 5 +#define SPSR_T_MASK 0x1 +#define SPSR_T_ARM 0x0 +#define SPSR_T_THUMB 0x1 + +#define DISABLE_ALL_EXCEPTIONS \ + (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT) + + +/* + * TCR defintions + */ +#define TCR_EL3_RES1 ((1UL << 31) | (1UL << 23)) + +#define TCR_T0SZ_4GB 32 + +#define TCR_RGN_INNER_NC (0x0 << 8) +#define TCR_RGN_INNER_WBA (0x1 << 8) +#define TCR_RGN_INNER_WT (0x2 << 8) +#define TCR_RGN_INNER_WBNA (0x3 << 8) + +#define TCR_RGN_OUTER_NC (0x0 << 10) +#define TCR_RGN_OUTER_WBA (0x1 << 10) +#define TCR_RGN_OUTER_WT (0x2 << 10) +#define TCR_RGN_OUTER_WBNA (0x3 << 10) + +#define TCR_SH_NON_SHAREABLE (0x0 << 12) +#define TCR_SH_OUTER_SHAREABLE (0x2 << 12) +#define TCR_SH_INNER_SHAREABLE (0x3 << 12) + +#define MODE_SP_SHIFT 0x0 +#define MODE_SP_MASK 0x1 +#define MODE_SP_EL0 0x0 +#define MODE_SP_ELX 0x1 + +#define MODE_RW_SHIFT 0x4 +#define MODE_RW_MASK 0x1 +#define MODE_RW_64 0x0 +#define MODE_RW_32 0x1 + +#define MODE_EL_SHIFT 0x2 +#define MODE_EL_MASK 0x3 +#define MODE_EL3 0x3 +#define MODE_EL2 0x2 +#define MODE_EL1 0x1 +#define MODE_EL0 0x0 + +#define MODE32_SHIFT 0 +#define MODE32_MASK 0xf +#define MODE32_usr 0x0 +#define MODE32_fiq 0x1 +#define MODE32_irq 0x2 +#define MODE32_svc 0x3 +#define MODE32_mon 0x6 +#define MODE32_abt 0x7 +#define MODE32_hyp 0xa +#define MODE32_und 0xb +#define MODE32_sys 0xf + +#define GET_RW(mode) (((mode) >> MODE_RW_SHIFT) & MODE_RW_MASK) +#define GET_EL(mode) (((mode) >> MODE_EL_SHIFT) & MODE_EL_MASK) +#define GET_SP(mode) (((mode) >> MODE_SP_SHIFT) & MODE_SP_MASK) +#define GET_M32(mode) (((mode) >> MODE32_SHIFT) & MODE32_MASK) + +#define SPSR_64(el, sp, daif) \ + (MODE_RW_64 << MODE_RW_SHIFT | \ + ((el) & MODE_EL_MASK) << MODE_EL_SHIFT | \ + ((sp) & MODE_SP_MASK) << MODE_SP_SHIFT | \ + ((daif) & SPSR_DAIF_MASK) << SPSR_DAIF_SHIFT) + +#define SPSR_MODE32(mode, isa, endian, aif) \ + (MODE_RW_32 << MODE_RW_SHIFT | \ + ((mode) & MODE32_MASK) << MODE32_SHIFT | \ + ((isa) & SPSR_T_MASK) << SPSR_T_SHIFT | \ + ((endian) & SPSR_E_MASK) << SPSR_E_SHIFT | \ + ((aif) & SPSR_AIF_MASK) << SPSR_AIF_SHIFT) + + +/* Physical timer control register bit fields shifts and masks */ +#define CNTP_CTL_ENABLE_SHIFT 0 +#define CNTP_CTL_IMASK_SHIFT 1 +#define CNTP_CTL_ISTATUS_SHIFT 2 + +#define CNTP_CTL_ENABLE_MASK 1 +#define CNTP_CTL_IMASK_MASK 1 +#define CNTP_CTL_ISTATUS_MASK 1 + +#define get_cntp_ctl_enable(x) ((x >> CNTP_CTL_ENABLE_SHIFT) & \ + CNTP_CTL_ENABLE_MASK) +#define get_cntp_ctl_imask(x) ((x >> CNTP_CTL_IMASK_SHIFT) & \ + CNTP_CTL_IMASK_MASK) +#define get_cntp_ctl_istatus(x) ((x >> CNTP_CTL_ISTATUS_SHIFT) & \ + CNTP_CTL_ISTATUS_MASK) + +#define set_cntp_ctl_enable(x) (x |= 1 << CNTP_CTL_ENABLE_SHIFT) +#define set_cntp_ctl_imask(x) (x |= 1 << CNTP_CTL_IMASK_SHIFT) + +#define clr_cntp_ctl_enable(x) (x &= ~(1 << CNTP_CTL_ENABLE_SHIFT)) +#define clr_cntp_ctl_imask(x) (x &= ~(1 << CNTP_CTL_IMASK_SHIFT)) + +/* Miscellaneous MMU related constants */ +#define NUM_2MB_IN_GB (1 << 9) +#define NUM_4K_IN_2MB (1 << 9) +#define NUM_GB_IN_4GB (1 << 2) + +#define TWO_MB_SHIFT 21 +#define ONE_GB_SHIFT 30 +#define FOUR_KB_SHIFT 12 + +#define ONE_GB_INDEX(x) ((x) >> ONE_GB_SHIFT) +#define TWO_MB_INDEX(x) ((x) >> TWO_MB_SHIFT) +#define FOUR_KB_INDEX(x) ((x) >> FOUR_KB_SHIFT) + +#define INVALID_DESC 0x0 +#define BLOCK_DESC 0x1 +#define TABLE_DESC 0x3 + +#define FIRST_LEVEL_DESC_N ONE_GB_SHIFT +#define SECOND_LEVEL_DESC_N TWO_MB_SHIFT +#define THIRD_LEVEL_DESC_N FOUR_KB_SHIFT + +#define LEVEL1 1 +#define LEVEL2 2 +#define LEVEL3 3 + +#define XN (1ull << 2) +#define PXN (1ull << 1) +#define CONT_HINT (1ull << 0) + +#define UPPER_ATTRS(x) (x & 0x7) << 52 +#define NON_GLOBAL (1 << 9) +#define ACCESS_FLAG (1 << 8) +#define NSH (0x0 << 6) +#define OSH (0x2 << 6) +#define ISH (0x3 << 6) + +#define PAGE_SIZE_SHIFT FOUR_KB_SHIFT +#define PAGE_SIZE (1 << PAGE_SIZE_SHIFT) +#define PAGE_SIZE_MASK (PAGE_SIZE - 1) +#define IS_PAGE_ALIGNED(addr) (((addr) & PAGE_SIZE_MASK) == 0) + +#define XLAT_ENTRY_SIZE_SHIFT 3 /* Each MMU table entry is 8 bytes (1 << 3) */ +#define XLAT_ENTRY_SIZE (1 << XLAT_ENTRY_SIZE_SHIFT) + +#define XLAT_TABLE_SIZE_SHIFT PAGE_SIZE_SHIFT +#define XLAT_TABLE_SIZE (1 << XLAT_TABLE_SIZE_SHIFT) + +/* Values for number of entries in each MMU translation table */ +#define XLAT_TABLE_ENTRIES_SHIFT (XLAT_TABLE_SIZE_SHIFT - XLAT_ENTRY_SIZE_SHIFT) +#define XLAT_TABLE_ENTRIES (1 << XLAT_TABLE_ENTRIES_SHIFT) +#define XLAT_TABLE_ENTRIES_MASK (XLAT_TABLE_ENTRIES - 1) + +/* Values to convert a memory address to an index into a translation table */ +#define L3_XLAT_ADDRESS_SHIFT PAGE_SIZE_SHIFT +#define L2_XLAT_ADDRESS_SHIFT (L3_XLAT_ADDRESS_SHIFT + XLAT_TABLE_ENTRIES_SHIFT) +#define L1_XLAT_ADDRESS_SHIFT (L2_XLAT_ADDRESS_SHIFT + XLAT_TABLE_ENTRIES_SHIFT) + +/* + * AP[1] bit is ignored by hardware and is + * treated as if it is One in EL2/EL3 + */ +#define AP_RO (0x1 << 5) +#define AP_RW (0x0 << 5) + +#define NS (0x1 << 3) +#define ATTR_SO_INDEX 0x2 +#define ATTR_DEVICE_INDEX 0x1 +#define ATTR_IWBWA_OWBWA_NTR_INDEX 0x0 +#define LOWER_ATTRS(x) (((x) & 0xfff) << 2) +#define ATTR_SO (0x0) +#define ATTR_DEVICE (0x4) +#define ATTR_IWBWA_OWBWA_NTR (0xff) +#define MAIR_ATTR_SET(attr, index) (attr << (index << 3)) + +/* Exception Syndrome register bits and bobs */ +#define ESR_EC_SHIFT 26 +#define ESR_EC_MASK 0x3f +#define ESR_EC_LENGTH 6 +#define EC_UNKNOWN 0x0 +#define EC_WFE_WFI 0x1 +#define EC_AARCH32_CP15_MRC_MCR 0x3 +#define EC_AARCH32_CP15_MRRC_MCRR 0x4 +#define EC_AARCH32_CP14_MRC_MCR 0x5 +#define EC_AARCH32_CP14_LDC_STC 0x6 +#define EC_FP_SIMD 0x7 +#define EC_AARCH32_CP10_MRC 0x8 +#define EC_AARCH32_CP14_MRRC_MCRR 0xc +#define EC_ILLEGAL 0xe +#define EC_AARCH32_SVC 0x11 +#define EC_AARCH32_HVC 0x12 +#define EC_AARCH32_SMC 0x13 +#define EC_AARCH64_SVC 0x15 +#define EC_AARCH64_HVC 0x16 +#define EC_AARCH64_SMC 0x17 +#define EC_AARCH64_SYS 0x18 +#define EC_IABORT_LOWER_EL 0x20 +#define EC_IABORT_CUR_EL 0x21 +#define EC_PC_ALIGN 0x22 +#define EC_DABORT_LOWER_EL 0x24 +#define EC_DABORT_CUR_EL 0x25 +#define EC_SP_ALIGN 0x26 +#define EC_AARCH32_FP 0x28 +#define EC_AARCH64_FP 0x2c +#define EC_SERROR 0x2f + +#define EC_BITS(x) (x >> ESR_EC_SHIFT) & ESR_EC_MASK + +/******************************************************************************* + * Imp. Def. register defines. + ******************************************************************************/ +/* CPUECTLR definitions */ +#define CPUECTLR_SMP_BIT (1 << 6) + +/* A57 CPUACTLR definitions */ +#define CPUACTLR_NO_ALLOC_WBWA (1 << 49) +#define CPUACTLR_DIS_DMB_NULL (1 << 58) +#define CPUACTLR_DCC_AS_DCCI (1 << 44) + +/******************************************************************************* + * Definitions of register offsets and fields in the CNTCTLBase Frame of the + * system level implementation of the Generic Timer. + ******************************************************************************/ +#define CNTNSAR 0x4 +#define CNTNSAR_NS_SHIFT(x) x + +#define CNTACR_BASE(x) (0x40 + (x << 2)) +#define CNTACR_RPCT_SHIFT 0x0 +#define CNTACR_RVCT_SHIFT 0x1 +#define CNTACR_RFRQ_SHIFT 0x2 +#define CNTACR_RVOFF_SHIFT 0x3 +#define CNTACR_RWVT_SHIFT 0x4 +#define CNTACR_RWPT_SHIFT 0x5 + +#endif /* __ARCH_H__ */ diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h new file mode 100644 index 0000000..b3d2c53 --- /dev/null +++ b/include/lib/aarch64/arch_helpers.h @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __ARCH_HELPERS_H__ +#define __ARCH_HELPERS_H__ + +#include <cdefs.h> /* For __dead2 */ + + +/******************************************************************************* + * Aarch64 translation tables manipulation helper prototypes + ******************************************************************************/ +unsigned long create_table_desc(unsigned long *next_table_ptr); +unsigned long create_block_desc(unsigned long desc, + unsigned long addr, + unsigned int level); +unsigned long create_device_block(unsigned long output_addr, + unsigned int level, + unsigned int ns); +unsigned long create_romem_block(unsigned long output_addr, + unsigned int level, + unsigned int ns); +unsigned long create_rwmem_block(unsigned long output_addr, + unsigned int level, + unsigned int ns); + +/******************************************************************************* + * TLB maintenance accessor prototypes + ******************************************************************************/ +void tlbialle1(void); +void tlbialle1is(void); +void tlbialle2(void); +void tlbialle2is(void); +void tlbialle3(void); +void tlbialle3is(void); +void tlbivmalle1(void); + +/******************************************************************************* + * Cache maintenance accessor prototypes + ******************************************************************************/ +void dcisw(unsigned long); +void dccisw(unsigned long); +void dccsw(unsigned long); +void dccvac(unsigned long); +void dcivac(unsigned long); +void dccivac(unsigned long); +void dccvau(unsigned long); +void dczva(unsigned long); +void flush_dcache_range(unsigned long, unsigned long); +void inv_dcache_range(unsigned long, unsigned long); +void dcsw_op_louis(unsigned int); +void dcsw_op_all(unsigned int); + +void disable_mmu_el3(void); +void disable_mmu_icache_el3(void); + + +void _clean_dcache_addr(unsigned long); +void _clean_invd_dcache_addr(unsigned long); + + +/******************************************************************************* + * Misc. accessor prototypes + ******************************************************************************/ +void enable_irq(void); +void enable_fiq(void); +void enable_serror(void); +void enable_debug_exceptions(void); + +void disable_irq(void); +void disable_fiq(void); +void disable_serror(void); +void disable_debug_exceptions(void); + +unsigned long read_id_pfr1_el1(void); +unsigned long read_id_aa64pfr0_el1(void); +unsigned long read_current_el(void); +unsigned long read_daif(void); +unsigned long read_spsr_el1(void); +unsigned long read_spsr_el2(void); +unsigned long read_spsr_el3(void); +unsigned long read_elr_el1(void); +unsigned long read_elr_el2(void); +unsigned long read_elr_el3(void); + +void write_daif(unsigned long); +void write_spsr_el1(unsigned long); +void write_spsr_el2(unsigned long); +void write_spsr_el3(unsigned long); +void write_elr_el1(unsigned long); +void write_elr_el2(unsigned long); +void write_elr_el3(unsigned long); + +void wfi(void); +void wfe(void); +void rfe(void); +void sev(void); +void dsb(void); +void isb(void); + +unsigned int get_afflvl_shift(unsigned int); +unsigned int mpidr_mask_lower_afflvls(unsigned long, unsigned int); + +void __dead2 eret(unsigned long, unsigned long, + unsigned long, unsigned long, + unsigned long, unsigned long, + unsigned long, unsigned long); + +void __dead2 smc(unsigned long, unsigned long, + unsigned long, unsigned long, + unsigned long, unsigned long, + unsigned long, unsigned long); + +/******************************************************************************* + * System register accessor prototypes + ******************************************************************************/ +unsigned long read_midr(void); +unsigned long read_mpidr(void); + +unsigned long read_scr(void); +unsigned long read_hcr(void); + +unsigned long read_vbar_el1(void); +unsigned long read_vbar_el2(void); +unsigned long read_vbar_el3(void); + +unsigned long read_sctlr_el1(void); +unsigned long read_sctlr_el2(void); +unsigned long read_sctlr_el3(void); + +unsigned long read_actlr_el1(void); +unsigned long read_actlr_el2(void); +unsigned long read_actlr_el3(void); + +unsigned long read_esr_el1(void); +unsigned long read_esr_el2(void); +unsigned long read_esr_el3(void); + +unsigned long read_afsr0_el1(void); +unsigned long read_afsr0_el2(void); +unsigned long read_afsr0_el3(void); + +unsigned long read_afsr1_el1(void); +unsigned long read_afsr1_el2(void); +unsigned long read_afsr1_el3(void); + +unsigned long read_far_el1(void); +unsigned long read_far_el2(void); +unsigned long read_far_el3(void); + +unsigned long read_mair_el1(void); +unsigned long read_mair_el2(void); +unsigned long read_mair_el3(void); + +unsigned long read_amair_el1(void); +unsigned long read_amair_el2(void); +unsigned long read_amair_el3(void); + +unsigned long read_rvbar_el1(void); +unsigned long read_rvbar_el2(void); +unsigned long read_rvbar_el3(void); + +unsigned long read_rmr_el1(void); +unsigned long read_rmr_el2(void); +unsigned long read_rmr_el3(void); + +unsigned long read_tcr_el1(void); +unsigned long read_tcr_el2(void); +unsigned long read_tcr_el3(void); + +unsigned long read_ttbr0_el1(void); +unsigned long read_ttbr0_el2(void); +unsigned long read_ttbr0_el3(void); + +unsigned long read_ttbr1_el1(void); + +unsigned long read_cptr_el2(void); +unsigned long read_cptr_el3(void); + +unsigned long read_cpacr(void); +unsigned long read_cpuectlr(void); +unsigned int read_cntfrq_el0(void); +unsigned int read_cntps_ctl_el1(void); +unsigned int read_cntps_tval_el1(void); +unsigned long read_cntps_cval_el1(void); +unsigned long read_cntpct_el0(void); +unsigned long read_cnthctl_el2(void); + +unsigned long read_tpidr_el3(void); + +void write_scr(unsigned long); +void write_hcr(unsigned long); +void write_cpacr(unsigned long); +void write_cntfrq_el0(unsigned int); +void write_cntps_ctl_el1(unsigned int); +void write_cntps_tval_el1(unsigned int); +void write_cntps_cval_el1(unsigned long); +void write_cnthctl_el2(unsigned long); + +void write_vbar_el1(unsigned long); +void write_vbar_el2(unsigned long); +void write_vbar_el3(unsigned long); + +void write_sctlr_el1(unsigned long); +void write_sctlr_el2(unsigned long); +void write_sctlr_el3(unsigned long); + +void write_actlr_el1(unsigned long); +void write_actlr_el2(unsigned long); +void write_actlr_el3(unsigned long); + +void write_esr_el1(unsigned long); +void write_esr_el2(unsigned long); +void write_esr_el3(unsigned long); + +void write_afsr0_el1(unsigned long); +void write_afsr0_el2(unsigned long); +void write_afsr0_el3(unsigned long); + +void write_afsr1_el1(unsigned long); +void write_afsr1_el2(unsigned long); +void write_afsr1_el3(unsigned long); + +void write_far_el1(unsigned long); +void write_far_el2(unsigned long); +void write_far_el3(unsigned long); + +void write_mair_el1(unsigned long); +void write_mair_el2(unsigned long); +void write_mair_el3(unsigned long); + +void write_amair_el1(unsigned long); +void write_amair_el2(unsigned long); +void write_amair_el3(unsigned long); + +void write_rmr_el1(unsigned long); +void write_rmr_el2(unsigned long); +void write_rmr_el3(unsigned long); + +void write_tcr_el1(unsigned long); +void write_tcr_el2(unsigned long); +void write_tcr_el3(unsigned long); + +void write_ttbr0_el1(unsigned long); +void write_ttbr0_el2(unsigned long); +void write_ttbr0_el3(unsigned long); + +void write_ttbr1_el1(unsigned long); + +void write_cpuectlr(unsigned long); +void write_cptr_el2(unsigned long); +void write_cptr_el3(unsigned long); + +void write_tpidr_el3(unsigned long); + +void remap_zero_address(void); + +#define IS_IN_EL(x) \ + (GET_EL(read_current_el()) == MODE_EL##x) + +#define IS_IN_EL1() IS_IN_EL(1) +#define IS_IN_EL3() IS_IN_EL(3) + + +#endif /* __ARCH_HELPERS_H__ */ diff --git a/include/lib/aarch64/xlat_tables.h b/include/lib/aarch64/xlat_tables.h new file mode 100644 index 0000000..5df655b --- /dev/null +++ b/include/lib/aarch64/xlat_tables.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __XLAT_TABLES_H__ +#define __XLAT_TABLES_H__ + +#include <stdint.h> + +/* + * Flags for building up memory mapping attributes. + * These are organised so that a clear bit gives a more restrictive mapping + * that a set bit, that way a bitwise-and two sets of attributes will never give + * an attribute which has greater access rights that any of the original + * attributes. + */ +typedef enum { + MT_DEVICE = 0 << 0, + MT_MEMORY = 1 << 0, + + MT_RO = 0 << 1, + MT_RW = 1 << 1, + + MT_SECURE = 0 << 2, + MT_NS = 1 << 2 +} mmap_attr_t; + +/* + * Structure for specifying a single region of memory. + */ +typedef struct mmap_region { + unsigned long base; + unsigned long size; + mmap_attr_t attr; +} mmap_region_t; + +void mmap_add_region(unsigned long base, unsigned long size, + unsigned attr); +void mmap_add(const mmap_region_t *mm); + +void init_xlat_tables(void); + +void enable_mmu_el1(void); +void enable_mmu_el3(void); + +#endif /* __XLAT_TABLES_H__ */ diff --git a/include/lib/bakery_lock.h b/include/lib/bakery_lock.h new file mode 100644 index 0000000..037fa7d --- /dev/null +++ b/include/lib/bakery_lock.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __BAKERY_LOCK_H__ +#define __BAKERY_LOCK_H__ + +#include <platform_def.h> + +#define BAKERY_LOCK_MAX_CPUS PLATFORM_CORE_COUNT + +typedef struct bakery_lock { + int owner; + volatile char entering[BAKERY_LOCK_MAX_CPUS]; + volatile unsigned number[BAKERY_LOCK_MAX_CPUS]; +} bakery_lock_t; + +#define NO_OWNER (-1) + +void bakery_lock_init(bakery_lock_t *bakery); +void bakery_lock_get(unsigned long mpidr, bakery_lock_t *bakery); +void bakery_lock_release(unsigned long mpidr, bakery_lock_t *bakery); +int bakery_lock_try(unsigned long mpidr, bakery_lock_t *bakery); + +#endif /* __BAKERY_LOCK_H__ */ diff --git a/include/lib/cassert.h b/include/lib/cassert.h new file mode 100644 index 0000000..0e5529d --- /dev/null +++ b/include/lib/cassert.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __CASSERT_H__ +#define __CASSERT_H__ + +/******************************************************************************* + * Macro to flag a compile time assertion. It uses the preprocessor to generate + * an invalid C construct if 'cond' evaluates to false. + * The following compilation error is triggered if the assertion fails: + * "error: size of array 'msg' is negative" + ******************************************************************************/ +#define CASSERT(cond, msg) typedef char msg[(cond) ? 1 : -1] + +#endif /* __CASSERT_H__ */ diff --git a/include/lib/io.h b/include/lib/io.h new file mode 100644 index 0000000..43b7eda --- /dev/null +++ b/include/lib/io.h @@ -0,0 +1,12 @@ +/*aml basic io module*/ + +#ifndef __BL2_IO_H_ +#define __BL2_IO_H_ + +#define writel(val,reg) (*((volatile unsigned *)(reg)))=(val) +#define readl(reg) (*((volatile unsigned *)(reg))) +#define setbits_le32(reg,val) (*((volatile unsigned *)(reg)))|=(val) +#define clrbits_le32(reg,val) (*((volatile unsigned *)(reg)))&=(~(val)) +#define clrsetbits_le32(reg,clr,set) {unsigned __v=readl(reg);__v&=(~(clr));__v|=(set);writel(__v,reg);} + +#endif /*__BL2_IO_H_*/
\ No newline at end of file diff --git a/include/lib/io_storage.h b/include/lib/io_storage.h new file mode 100644 index 0000000..ae1158c --- /dev/null +++ b/include/lib/io_storage.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __IO_H__ +#define __IO_H__ + +#include <stdint.h> +#include <stdio.h> /* For ssize_t */ + + +/* Device type which can be used to enable policy decisions about which device + * to access */ +typedef enum { + IO_TYPE_INVALID, + IO_TYPE_SEMIHOSTING, + IO_TYPE_MEMMAP, + IO_TYPE_FIRMWARE_IMAGE_PACKAGE, + IO_TYPE_MAX +} io_type_t; + + +/* Modes used when seeking data on a supported device */ +typedef enum { + IO_SEEK_INVALID, + IO_SEEK_SET, + IO_SEEK_END, + IO_SEEK_CUR, + IO_SEEK_MAX +} io_seek_mode_t; + + +/* Connector type, providing a means of identifying a device to open */ +struct io_dev_connector; + + +/* File specification - used to refer to data on a device supporting file-like + * entities */ +typedef struct io_file_spec { + const char *path; + unsigned int mode; +} io_file_spec_t; + + +/* Block specification - used to refer to data on a device supporting + * block-like entities */ +typedef struct io_block_spec { + size_t offset; + size_t length; +} io_block_spec_t; + + +/* Access modes used when accessing data on a device */ +#define IO_MODE_INVALID (0) +#define IO_MODE_RO (1 << 0) +#define IO_MODE_RW (1 << 1) + + +/* Return codes reported by 'io_*' APIs */ +#define IO_SUCCESS (0) +#define IO_FAIL (-1) +#define IO_NOT_SUPPORTED (-2) +#define IO_RESOURCES_EXHAUSTED (-3) + + +/* Open a connection to a device */ +int io_dev_open(const struct io_dev_connector *dev_con, + const uintptr_t dev_spec, + uintptr_t *dev_handle); + + +/* Initialise a device explicitly - to permit lazy initialisation or + * re-initialisation */ +int io_dev_init(uintptr_t dev_handle, const uintptr_t init_params); + +/* TODO: Consider whether an explicit "shutdown" API should be included */ + +/* Close a connection to a device */ +int io_dev_close(uintptr_t dev_handle); + + +/* Synchronous operations */ +int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle); + +int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset); + +int io_size(uintptr_t handle, size_t *length); + +int io_read(uintptr_t handle, uintptr_t buffer, size_t length, + size_t *length_read); + +int io_write(uintptr_t handle, const uintptr_t buffer, size_t length, + size_t *length_written); + +int io_close(uintptr_t handle); + + +#endif /* __IO_H__ */ diff --git a/include/lib/mmio.h b/include/lib/mmio.h new file mode 100644 index 0000000..5d33c59 --- /dev/null +++ b/include/lib/mmio.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __MMIO_H__ +#define __MMIO_H__ + +#include <stdint.h> + +void mmio_write_8(uintptr_t addr, uint8_t value); +uint8_t mmio_read_8(uintptr_t addr); + +void mmio_write_32(uintptr_t addr, uint32_t value); +uint32_t mmio_read_32(uintptr_t addr); + +void mmio_write_64(uintptr_t addr, uint64_t value); +uint64_t mmio_read_64(uintptr_t addr); + +#endif /* __MMIO_H__ */ diff --git a/include/lib/semihosting.h b/include/lib/semihosting.h new file mode 100644 index 0000000..b4eecc5 --- /dev/null +++ b/include/lib/semihosting.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __SEMIHOSTING_H__ +#define __SEMIHOSTING_H__ + +#include <stdint.h> +#include <stdio.h> /* For ssize_t */ + + +#define SEMIHOSTING_SYS_OPEN 0x01 +#define SEMIHOSTING_SYS_CLOSE 0x02 +#define SEMIHOSTING_SYS_WRITE0 0x04 +#define SEMIHOSTING_SYS_WRITEC 0x03 +#define SEMIHOSTING_SYS_WRITE 0x05 +#define SEMIHOSTING_SYS_READ 0x06 +#define SEMIHOSTING_SYS_READC 0x07 +#define SEMIHOSTING_SYS_SEEK 0x0A +#define SEMIHOSTING_SYS_FLEN 0x0C +#define SEMIHOSTING_SYS_REMOVE 0x0E +#define SEMIHOSTING_SYS_SYSTEM 0x12 +#define SEMIHOSTING_SYS_ERRNO 0x13 + +#define FOPEN_MODE_R 0x0 +#define FOPEN_MODE_RB 0x1 +#define FOPEN_MODE_RPLUS 0x2 +#define FOPEN_MODE_RPLUSB 0x3 +#define FOPEN_MODE_W 0x4 +#define FOPEN_MODE_WB 0x5 +#define FOPEN_MODE_WPLUS 0x6 +#define FOPEN_MODE_WPLUSB 0x7 +#define FOPEN_MODE_A 0x8 +#define FOPEN_MODE_AB 0x9 +#define FOPEN_MODE_APLUS 0xa +#define FOPEN_MODE_APLUSB 0xb + +long semihosting_connection_supported(void); +long semihosting_file_open(const char *file_name, size_t mode); +long semihosting_file_seek(long file_handle, ssize_t offset); +long semihosting_file_read(long file_handle, size_t *length, uintptr_t buffer); +long semihosting_file_write(long file_handle, + size_t *length, + const uintptr_t buffer); +long semihosting_file_close(long file_handle); +long semihosting_file_length(long file_handle); +long semihosting_system(char *command_line); +long semihosting_get_flen(const char *file_name); +long semihosting_download_file(const char *file_name, + size_t buf_size, + uintptr_t buf); +void semihosting_write_char(char character); +void semihosting_write_string(char *string); +char semihosting_read_char(void); + +#endif /* __SEMIHOSTING_H__ */ diff --git a/include/lib/spinlock.h b/include/lib/spinlock.h new file mode 100644 index 0000000..cb0bc3e --- /dev/null +++ b/include/lib/spinlock.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __SPINLOCK_H__ +#define __SPINLOCK_H__ + +typedef struct spinlock { + volatile unsigned int lock; +} spinlock_t; + +void spin_lock(spinlock_t *lock); +void spin_unlock(spinlock_t *lock); + +#endif /* __SPINLOCK_H__ */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h new file mode 100644 index 0000000..1095a0e --- /dev/null +++ b/include/plat/common/platform.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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__ + +#include <stdint.h> +#include <asm/arch/cpu.h> +#include <bl_common.h> + +/******************************************************************************* + * Forward declarations + ******************************************************************************/ +struct plat_pm_ops; +struct meminfo; +struct image_info; +struct entry_point_info; +struct bl31_params; + +/******************************************************************************* + * Function declarations + ******************************************************************************/ +/******************************************************************************* + * Mandatory common functions + ******************************************************************************/ +uint64_t plat_get_syscnt_freq(void); +int plat_get_image_source(const char *image_name, + uintptr_t *dev_handle, + uintptr_t *image_spec); +unsigned long plat_get_ns_image_entrypoint(void); + +/******************************************************************************* + * Mandatory interrupt management functions + ******************************************************************************/ +uint32_t plat_ic_get_pending_interrupt_id(void); +uint32_t plat_ic_get_pending_interrupt_type(void); +uint32_t plat_ic_acknowledge_interrupt(void); +uint32_t plat_ic_get_interrupt_type(uint32_t id); +void plat_ic_end_of_interrupt(uint32_t id); +uint32_t plat_interrupt_type_to_line(uint32_t type, + uint32_t security_state); + +/******************************************************************************* + * Optional common functions (may be overridden) + ******************************************************************************/ +unsigned int platform_get_core_pos(unsigned long mpidr); +unsigned long platform_get_stack(unsigned long mpidr); +//void plat_report_exception(unsigned long); + +/******************************************************************************* + * Mandatory BL1 functions + ******************************************************************************/ +void bl1_plat_arch_setup(void); +void bl1_platform_setup(void); +struct meminfo *bl1_plat_sec_mem_layout(void); + +/* + * This function allows the platform to change the entrypoint information for + * BL2, after BL1 has loaded BL2 into memory but before BL2 is executed. + */ +void bl1_plat_set_bl2_ep_info(struct image_info *image, + struct entry_point_info *ep); + +/******************************************************************************* + * Optional BL1 functions (may be overridden) + ******************************************************************************/ +void init_bl2_mem_layout(struct meminfo *, + struct meminfo *, + unsigned int, + unsigned long); + +/******************************************************************************* + * Mandatory BL2 functions + ******************************************************************************/ +void bl2_plat_arch_setup(void); +void bl2_platform_setup(void); +struct meminfo *bl2_plat_sec_mem_layout(void); + +/* + * This function returns a pointer to the shared memory that the platform has + * kept aside to pass trusted firmware related information that BL3-1 + * could need + */ +struct bl31_params *bl2_plat_get_bl31_params(void); + +/* + * This function returns a pointer to the shared memory that the platform + * has kept to point to entry point information of BL31 to BL2 + */ +struct entry_point_info *bl2_plat_get_bl31_ep_info(void); + +/* + * This function flushes to main memory all the params that are + * passed to BL3-1 + */ +void bl2_plat_flush_bl31_params(void); + +/* + * The next 3 functions allow the platform to change the entrypoint + * information for the 3rd level BL images, after BL2 has loaded the 3rd + * level BL images into memory but before BL3-1 is executed. + */ +void bl2_plat_set_bl31_ep_info(struct image_info *image, + struct entry_point_info *ep); + +void bl2_plat_set_bl32_ep_info(struct image_info *image, + struct entry_point_info *ep); + +void bl2_plat_set_bl33_ep_info(struct image_info *image, + struct entry_point_info *ep); + +/* Gets the memory layout for BL32 */ +void bl2_plat_get_bl32_meminfo(struct meminfo *mem_info); + +/* Gets the memory layout for BL33 */ +void bl2_plat_get_bl33_meminfo(struct meminfo *mem_info); + +/******************************************************************************* + * Optional BL2 functions (may be overridden) + ******************************************************************************/ + +/******************************************************************************* + * Mandatory BL3-1 functions + ******************************************************************************/ +void bl31_early_platform_setup(struct bl31_params *from_bl2, + void *plat_params_from_bl2); +void bl31_plat_arch_setup(void); +void bl31_platform_setup(void); +struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type); + +/******************************************************************************* + * Mandatory PSCI functions (BL3-1) + ******************************************************************************/ +int platform_setup_pm(const struct plat_pm_ops **); +int plat_get_max_afflvl(void); +unsigned int plat_get_aff_count(unsigned int, unsigned long); +unsigned int plat_get_aff_state(unsigned int, unsigned long); + +/******************************************************************************* + * Optional BL3-1 functions (may be overridden) + ******************************************************************************/ +void bl31_plat_enable_mmu(); + +/******************************************************************************* + * Mandatory BL3-2 functions (only if platform contains a BL3-2) + ******************************************************************************/ +void bl32_platform_setup(void); + +/******************************************************************************* + * Optional BL3-2 functions (may be overridden) + ******************************************************************************/ +void bl32_plat_enable_mmu(); + +#endif /* __PLATFORM_H__ */ diff --git a/include/stdlib/assert.h b/include/stdlib/assert.h new file mode 100644 index 0000000..5621f8c --- /dev/null +++ b/include/stdlib/assert.h @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)assert.h 8.2 (Berkeley) 1/21/94 + * $FreeBSD$ + */ + +#include <sys/cdefs.h> + +/* + * Unlike other ANSI header files, <assert.h> may usefully be included + * multiple times, with and without NDEBUG defined. + */ + +#undef assert +#undef _assert + +#ifdef NDEBUG +#define assert(e) ((void)0) +#define _assert(e) ((void)0) +#else +#define _assert(e) assert(e) + +#define assert(e) ((e) ? (void)0 : __assert(__func__, __FILE__, \ + __LINE__, #e)) +#endif /* NDEBUG */ + +#ifndef _ASSERT_H_ +#define _ASSERT_H_ +__BEGIN_DECLS +void __assert(const char *, const char *, int, const char *) __dead2; +__END_DECLS +#endif /* !_ASSERT_H_ */ diff --git a/include/stdlib/machine/_limits.h b/include/stdlib/machine/_limits.h new file mode 100644 index 0000000..49a768b --- /dev/null +++ b/include/stdlib/machine/_limits.h @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. 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 REGENTS 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 REGENTS 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. + * + * @(#)limits.h 8.3 (Berkeley) 1/4/94 + * $FreeBSD$ + */ + +#ifndef _MACHINE__LIMITS_H_ +#define _MACHINE__LIMITS_H_ + +/* + * According to ANSI (section 2.2.4.2), the values below must be usable by + * #if preprocessing directives. Additionally, the expression must have the + * same type as would an expression that is an object of the corresponding + * type converted according to the integral promotions. The subtraction for + * INT_MIN, etc., is so the value is not unsigned; e.g., 0x80000000 is an + * unsigned int for 32-bit two's complement ANSI compilers (section 3.1.3.2). + */ + +#define __CHAR_BIT 8 /* number of bits in a char */ + +#define __SCHAR_MAX 0x7f /* max value for a signed char */ +#define __SCHAR_MIN (-0x7f-1) /* min value for a signed char */ + +#define __UCHAR_MAX 0xff /* max value for an unsigned char */ + +#define __USHRT_MAX 0xffff /* max value for an unsigned short */ +#define __SHRT_MAX 0x7fff /* max value for a short */ +#define __SHRT_MIN (-0x7fff-1) /* min value for a short */ + +#define __UINT_MAX 0xffffffff /* max value for an unsigned int */ +#define __INT_MAX 0x7fffffff /* max value for an int */ +#define __INT_MIN (-0x7fffffff-1) /* min value for an int */ + +#define __ULONG_MAX 0xffffffffffffffff /* max for an unsigned long */ +#define __LONG_MAX 0x7fffffffffffffff /* max for a long */ +#define __LONG_MIN (-0x7fffffffffffffff-1) /* min for a long */ + +/* Long longs have the same size but not the same type as longs. */ + /* max for an unsigned long long */ +#define __ULLONG_MAX 0xffffffffffffffffULL +#define __LLONG_MAX 0x7fffffffffffffffLL /* max for a long long */ +#define __LLONG_MIN (-0x7fffffffffffffffLL-1) /* min for a long long */ + +#define __SSIZE_MAX __LONG_MAX /* max value for a ssize_t */ + +#define __SIZE_T_MAX __ULONG_MAX /* max value for a size_t */ + +#define __OFF_MAX __LONG_MAX /* max value for an off_t */ +#define __OFF_MIN __LONG_MIN /* min value for an off_t */ + +/* Quads and longs are the same size. Ensure they stay in sync. */ +#define __UQUAD_MAX (__ULONG_MAX) /* max value for a uquad_t */ +#define __QUAD_MAX (__LONG_MAX) /* max value for a quad_t */ +#define __QUAD_MIN (__LONG_MIN) /* min value for a quad_t */ + +#define __LONG_BIT 64 +#define __WORD_BIT 32 + +/* Minimum signal stack size. */ +#define __MINSIGSTKSZ (1024 * 4) + +#endif /* !_MACHINE__LIMITS_H_ */ diff --git a/include/stdlib/machine/_stdint.h b/include/stdlib/machine/_stdint.h new file mode 100644 index 0000000..3fb9723 --- /dev/null +++ b/include/stdlib/machine/_stdint.h @@ -0,0 +1,164 @@ +/*- + * Copyright (c) 2001, 2002 Mike Barcroft <mike@FreeBSD.org> + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Klaus Klein. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE__STDINT_H_ +#define _MACHINE__STDINT_H_ + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) + +#define INT8_C(c) (c) +#define INT16_C(c) (c) +#define INT32_C(c) (c) +#define INT64_C(c) (c ## L) + +#define UINT8_C(c) (c) +#define UINT16_C(c) (c) +#define UINT32_C(c) (c ## U) +#define UINT64_C(c) (c ## UL) + +#define INTMAX_C(c) INT64_C(c) +#define UINTMAX_C(c) UINT64_C(c) + +#endif /* !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) */ + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) + +/* + * ISO/IEC 9899:1999 + * 7.18.2.1 Limits of exact-width integer types + */ +/* Minimum values of exact-width signed integer types. */ +#define INT8_MIN (-0x7f-1) +#define INT16_MIN (-0x7fff-1) +#define INT32_MIN (-0x7fffffff-1) +#define INT64_MIN (-0x7fffffffffffffffL-1) + +/* Maximum values of exact-width signed integer types. */ +#define INT8_MAX 0x7f +#define INT16_MAX 0x7fff +#define INT32_MAX 0x7fffffff +#define INT64_MAX 0x7fffffffffffffffL + +/* Maximum values of exact-width unsigned integer types. */ +#define UINT8_MAX 0xff +#define UINT16_MAX 0xffff +#define UINT32_MAX 0xffffffffU +#define UINT64_MAX 0xffffffffffffffffUL + +/* + * ISO/IEC 9899:1999 + * 7.18.2.2 Limits of minimum-width integer types + */ +/* Minimum values of minimum-width signed integer types. */ +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST64_MIN INT64_MIN + +/* Maximum values of minimum-width signed integer types. */ +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MAX INT64_MAX + +/* Maximum values of minimum-width unsigned integer types. */ +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +/* + * ISO/IEC 9899:1999 + * 7.18.2.3 Limits of fastest minimum-width integer types + */ +/* Minimum values of fastest minimum-width signed integer types. */ +#define INT_FAST8_MIN INT32_MIN +#define INT_FAST16_MIN INT32_MIN +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST64_MIN INT64_MIN + +/* Maximum values of fastest minimum-width signed integer types. */ +#define INT_FAST8_MAX INT32_MAX +#define INT_FAST16_MAX INT32_MAX +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MAX INT64_MAX + +/* Maximum values of fastest minimum-width unsigned integer types. */ +#define UINT_FAST8_MAX UINT32_MAX +#define UINT_FAST16_MAX UINT32_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +/* + * ISO/IEC 9899:1999 + * 7.18.2.4 Limits of integer types capable of holding object pointers + */ +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#define UINTPTR_MAX UINT64_MAX + +/* + * ISO/IEC 9899:1999 + * 7.18.2.5 Limits of greatest-width integer types + */ +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +/* + * ISO/IEC 9899:1999 + * 7.18.3 Limits of other integer types + */ +/* Limits of ptrdiff_t. */ +#define PTRDIFF_MIN INT64_MIN +#define PTRDIFF_MAX INT64_MAX + +/* Limits of sig_atomic_t. */ +#define SIG_ATOMIC_MIN INT32_MIN +#define SIG_ATOMIC_MAX INT32_MAX + +/* Limit of size_t. */ +#define SIZE_MAX UINT64_MAX + +#ifndef WCHAR_MIN /* Also possibly defined in <wchar.h> */ +/* Limits of wchar_t. */ +#define WCHAR_MIN INT32_MIN +#define WCHAR_MAX INT32_MAX +#endif + +/* Limits of wint_t. */ +#define WINT_MIN INT32_MIN +#define WINT_MAX INT32_MAX + +#endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */ + +#endif /* !_MACHINE__STDINT_H_ */ diff --git a/include/stdlib/machine/_types.h b/include/stdlib/machine/_types.h new file mode 100644 index 0000000..7e993c4 --- /dev/null +++ b/include/stdlib/machine/_types.h @@ -0,0 +1,110 @@ +/*- + * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org> + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * From: @(#)ansi.h 8.2 (Berkeley) 1/4/94 + * From: @(#)types.h 8.3 (Berkeley) 1/5/94 + * $FreeBSD$ + */ + +#ifndef _MACHINE__TYPES_H_ +#define _MACHINE__TYPES_H_ + +#ifndef _SYS_CDEFS_H_ +#error this file needs sys/cdefs.h as a prerequisite +#endif + +/* + * Basic types upon which most other types are built. + */ +typedef __signed char __int8_t; +typedef unsigned char __uint8_t; +typedef short __int16_t; +typedef unsigned short __uint16_t; +typedef int __int32_t; +typedef unsigned int __uint32_t; +typedef long __int64_t; +typedef unsigned long __uint64_t; + +/* + * Standard type definitions. + */ +typedef __int32_t __clock_t; /* clock()... */ +typedef __int64_t __critical_t; +typedef double __double_t; +typedef float __float_t; +typedef __int64_t __intfptr_t; +typedef __int64_t __intmax_t; +typedef __int64_t __intptr_t; +typedef __int32_t __int_fast8_t; +typedef __int32_t __int_fast16_t; +typedef __int32_t __int_fast32_t; +typedef __int64_t __int_fast64_t; +typedef __int8_t __int_least8_t; +typedef __int16_t __int_least16_t; +typedef __int32_t __int_least32_t; +typedef __int64_t __int_least64_t; +typedef __int64_t __ptrdiff_t; /* ptr1 - ptr2 */ +typedef __int64_t __register_t; +typedef __int64_t __segsz_t; /* segment size (in pages) */ +typedef __uint64_t __size_t; /* sizeof() */ +typedef __int64_t __ssize_t; /* byte count or error */ +typedef __int64_t __time_t; /* time()... */ +typedef __uint64_t __uintfptr_t; +typedef __uint64_t __uintmax_t; +typedef __uint64_t __uintptr_t; +typedef __uint32_t __uint_fast8_t; +typedef __uint32_t __uint_fast16_t; +typedef __uint32_t __uint_fast32_t; +typedef __uint64_t __uint_fast64_t; +typedef __uint8_t __uint_least8_t; +typedef __uint16_t __uint_least16_t; +typedef __uint32_t __uint_least32_t; +typedef __uint64_t __uint_least64_t; +typedef __uint64_t __u_register_t; +typedef __uint64_t __vm_offset_t; +typedef __int64_t __vm_ooffset_t; +typedef __uint64_t __vm_paddr_t; +typedef __uint64_t __vm_pindex_t; +typedef __uint64_t __vm_size_t; + +/* + * Unusual type definitions. + */ +#ifdef __GNUCLIKE_BUILTIN_VARARGS +typedef __builtin_va_list __va_list; /* internally known to gcc */ +#else +typedef char * __va_list; +#endif /* __GNUCLIKE_BUILTIN_VARARGS */ +#if defined(__GNUCLIKE_BUILTIN_VAALIST) && !defined(__GNUC_VA_LIST) \ + && !defined(__NO_GNUC_VA_LIST) +#define __GNUC_VA_LIST +typedef __va_list __gnuc_va_list; /* compatibility w/GNU headers*/ +#endif + +#endif /* !_MACHINE__TYPES_H_ */ diff --git a/include/stdlib/stddef.h b/include/stdlib/stddef.h new file mode 100644 index 0000000..ea88214 --- /dev/null +++ b/include/stdlib/stddef.h @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)stddef.h 8.1 (Berkeley) 6/2/93 + * + * $FreeBSD$ + */ + +#ifndef _STDDEF_H_ +#define _STDDEF_H_ + +#include <sys/cdefs.h> +#include <sys/_null.h> +#include <sys/_types.h> + +typedef __ptrdiff_t ptrdiff_t; + +#if __BSD_VISIBLE +#ifndef _RUNE_T_DECLARED +typedef __rune_t rune_t; +#define _RUNE_T_DECLARED +#endif +#endif + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +#ifndef __cplusplus +#ifndef _WCHAR_T_DECLARED +typedef __wchar_t wchar_t; +#define _WCHAR_T_DECLARED +#endif +#endif + +#define offsetof(type, member) __offsetof(type, member) + +#endif /* _STDDEF_H_ */ diff --git a/include/stdlib/stdio.h b/include/stdlib/stdio.h new file mode 100644 index 0000000..ee3d241 --- /dev/null +++ b/include/stdlib/stdio.h @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)stdio.h 8.5 (Berkeley) 4/29/95 + * $FreeBSD$ + */ + +/* + * Portions copyright (c) 2013-2014, ARM Limited and Contributors. + * All rights reserved. + */ + + +#ifndef _STDIO_H_ +#define _STDIO_H_ + +#include <sys/cdefs.h> +#include <sys/_null.h> +#include <sys/_types.h> +#include <serial.h> + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +#ifndef _SSIZE_T_DECLARED +#define _SSIZE_T_DECLARED +typedef __ssize_t ssize_t; +#endif + +#define EOF (-1) + + +#ifdef ENABLE_PRINTF +int printf(const char * __restrict, ...); +int putchar(int); +int puts(const char *); +int sprintf(char * __restrict, const char * __restrict, ...); +int vsprintf(char * __restrict, const char * __restrict, + __va_list); + +#if __ISO_C_VISIBLE >= 1999 +int snprintf(char * __restrict, size_t, const char * __restrict, + ...) __printflike(3, 4); +int vsnprintf(char * __restrict, size_t, const char * __restrict, + __va_list) __printflike(3, 0); +#endif +#endif + +#endif /* !_STDIO_H_ */ diff --git a/include/stdlib/string.h b/include/stdlib/string.h new file mode 100644 index 0000000..00a5dcd --- /dev/null +++ b/include/stdlib/string.h @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)string.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD$ + */ + +/* + * Portions copyright (c) 2013-2014, ARM Limited and Contributors. + * All rights reserved. + */ + +#ifndef _STRING_H_ +#define _STRING_H_ + +#include <sys/cdefs.h> +#include <sys/_null.h> +#include <sys/_types.h> + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +__BEGIN_DECLS + +void *memchr(const void *, int, size_t) __pure; +int memcmp(const void *, const void *, size_t) __pure; +void *memcpy(void * __restrict, const void * __restrict, size_t); +void *memmove(void *, const void *, size_t); +void *memset(void *, int, size_t); + +char *strchr(const char *, int) __pure; +int strcmp(const char *, const char *) __pure; +size_t strlen(const char *) __pure; +int strncmp(const char *, const char *, size_t) __pure; + +__END_DECLS + +#endif /* _STRING_H_ */ diff --git a/include/stdlib/sys/_null.h b/include/stdlib/sys/_null.h new file mode 100644 index 0000000..92706c6 --- /dev/null +++ b/include/stdlib/sys/_null.h @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2003 Marcel Moolenaar + * 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 AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef NULL + +#if !defined(__cplusplus) +#define NULL ((void *)0) +#else +#if __cplusplus >= 201103L +#define NULL nullptr +#elif defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 4 +#define NULL __null +#else +#if defined(__LP64__) +#define NULL (0L) +#else +#define NULL 0 +#endif /* __LP64__ */ +#endif /* __GNUG__ */ +#endif /* !__cplusplus */ + +#endif diff --git a/include/stdlib/sys/_stdint.h b/include/stdlib/sys/_stdint.h new file mode 100644 index 0000000..d0f9249 --- /dev/null +++ b/include/stdlib/sys/_stdint.h @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2011 David E. O'Brien <obrien@FreeBSD.org> + * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org> + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _SYS__STDINT_H_ +#define _SYS__STDINT_H_ + +#ifndef _INT8_T_DECLARED +typedef __int8_t int8_t; +#define _INT8_T_DECLARED +#endif + +#ifndef _INT16_T_DECLARED +typedef __int16_t int16_t; +#define _INT16_T_DECLARED +#endif + +#ifndef _INT32_T_DECLARED +typedef __int32_t int32_t; +#define _INT32_T_DECLARED +#endif + +#ifndef _INT64_T_DECLARED +typedef __int64_t int64_t; +#define _INT64_T_DECLARED +#endif + +#ifndef _UINT8_T_DECLARED +typedef __uint8_t uint8_t; +#define _UINT8_T_DECLARED +#endif + +#ifndef _UINT16_T_DECLARED +typedef __uint16_t uint16_t; +#define _UINT16_T_DECLARED +#endif + +#ifndef _UINT32_T_DECLARED +typedef __uint32_t uint32_t; +#define _UINT32_T_DECLARED +#endif + +#ifndef _UINT64_T_DECLARED +typedef __uint64_t uint64_t; +#define _UINT64_T_DECLARED +#endif + +#ifndef _INTPTR_T_DECLARED +typedef __intptr_t intptr_t; +#define _INTPTR_T_DECLARED +#endif +#ifndef _UINTPTR_T_DECLARED +typedef __uintptr_t uintptr_t; +#define _UINTPTR_T_DECLARED +#endif + +#endif /* !_SYS__STDINT_H_ */ diff --git a/include/stdlib/sys/_types.h b/include/stdlib/sys/_types.h new file mode 100644 index 0000000..c59afd3 --- /dev/null +++ b/include/stdlib/sys/_types.h @@ -0,0 +1,106 @@ +/*- + * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org> + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _SYS__TYPES_H_ +#define _SYS__TYPES_H_ + +#include <sys/cdefs.h> +#include <machine/_types.h> + +/* + * Standard type definitions. + */ +typedef __uint32_t __blksize_t; /* file block size */ +typedef __int64_t __blkcnt_t; /* file block count */ +typedef __int32_t __clockid_t; /* clock_gettime()... */ +typedef __uint64_t __cap_rights_t; /* capability rights */ +typedef __uint32_t __fflags_t; /* file flags */ +typedef __uint64_t __fsblkcnt_t; +typedef __uint64_t __fsfilcnt_t; +typedef __uint32_t __gid_t; +typedef __int64_t __id_t; /* can hold a gid_t, pid_t, or uid_t */ +typedef __uint32_t __ino_t; /* inode number */ +typedef long __key_t; /* IPC key (for Sys V IPC) */ +typedef __int32_t __lwpid_t; /* Thread ID (a.k.a. LWP) */ +typedef __uint16_t __mode_t; /* permissions */ +typedef int __accmode_t; /* access permissions */ +typedef int __nl_item; +typedef __uint16_t __nlink_t; /* link count */ +typedef __int64_t __off_t; /* file offset */ +typedef __int32_t __pid_t; /* process [group] */ +typedef __int64_t __rlim_t; /* resource limit - intentionally */ + /* signed, because of legacy code */ + /* that uses -1 for RLIM_INFINITY */ +typedef __uint8_t __sa_family_t; +typedef __uint32_t __socklen_t; +typedef long __suseconds_t; /* microseconds (signed) */ +typedef struct __timer *__timer_t; /* timer_gettime()... */ +typedef struct __mq *__mqd_t; /* mq_open()... */ +typedef __uint32_t __uid_t; +typedef unsigned int __useconds_t; /* microseconds (unsigned) */ +typedef int __cpuwhich_t; /* which parameter for cpuset. */ +typedef int __cpulevel_t; /* level parameter for cpuset. */ +typedef int __cpusetid_t; /* cpuset identifier. */ + +/* + * Unusual type definitions. + */ +/* + * rune_t is declared to be an ``int'' instead of the more natural + * ``unsigned long'' or ``long''. Two things are happening here. It is not + * unsigned so that EOF (-1) can be naturally assigned to it and used. Also, + * it looks like 10646 will be a 31 bit standard. This means that if your + * ints cannot hold 32 bits, you will be in trouble. The reason an int was + * chosen over a long is that the is*() and to*() routines take ints (says + * ANSI C), but they use __ct_rune_t instead of int. + * + * NOTE: rune_t is not covered by ANSI nor other standards, and should not + * be instantiated outside of lib/libc/locale. Use wchar_t. wchar_t and + * rune_t must be the same type. Also, wint_t must be no narrower than + * wchar_t, and should be able to hold all members of the largest + * character set plus one extra value (WEOF), and must be at least 16 bits. + */ +typedef int __ct_rune_t; /* arg type for ctype funcs */ +typedef __ct_rune_t __rune_t; /* rune_t (see above) */ +typedef __ct_rune_t __wchar_t; /* wchar_t (see above) */ +typedef __ct_rune_t __wint_t; /* wint_t (see above) */ + +typedef __uint32_t __dev_t; /* device number */ + +typedef __uint32_t __fixpt_t; /* fixed point number */ + +/* + * mbstate_t is an opaque object to keep conversion state during multibyte + * stream conversions. + */ +typedef union { + char __mbstate8[128]; + __int64_t _mbstateL; /* for alignment */ +} __mbstate_t; + +#endif /* !_SYS__TYPES_H_ */ diff --git a/include/stdlib/sys/cdefs.h b/include/stdlib/sys/cdefs.h new file mode 100644 index 0000000..16fb151 --- /dev/null +++ b/include/stdlib/sys/cdefs.h @@ -0,0 +1,686 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Berkeley Software Design, Inc. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)cdefs.h 8.8 (Berkeley) 1/9/95 + * $FreeBSD$ + */ + +#ifndef _SYS_CDEFS_H_ +#define _SYS_CDEFS_H_ + +#if defined(__cplusplus) +#define __BEGIN_DECLS extern "C" { +#define __END_DECLS } +#else +#define __BEGIN_DECLS +#define __END_DECLS +#endif + +/* + * This code has been put in place to help reduce the addition of + * compiler specific defines in FreeBSD code. It helps to aid in + * having a compiler-agnostic source tree. + */ + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) + +#if __GNUC__ >= 3 || defined(__INTEL_COMPILER) +#define __GNUCLIKE_ASM 3 +#define __GNUCLIKE_MATH_BUILTIN_CONSTANTS +#else +#define __GNUCLIKE_ASM 2 +#endif +#define __GNUCLIKE___TYPEOF 1 +#define __GNUCLIKE___OFFSETOF 1 +#define __GNUCLIKE___SECTION 1 + +#ifndef __INTEL_COMPILER +# define __GNUCLIKE_CTOR_SECTION_HANDLING 1 +#endif + +#define __GNUCLIKE_BUILTIN_CONSTANT_P 1 +# if defined(__INTEL_COMPILER) && defined(__cplusplus) \ + && __INTEL_COMPILER < 800 +# undef __GNUCLIKE_BUILTIN_CONSTANT_P +# endif + +#if (__GNUC_MINOR__ > 95 || __GNUC__ >= 3) && !defined(__INTEL_COMPILER) +# define __GNUCLIKE_BUILTIN_VARARGS 1 +# define __GNUCLIKE_BUILTIN_STDARG 1 +# define __GNUCLIKE_BUILTIN_VAALIST 1 +#endif + +#if defined(__GNUC__) +# define __GNUC_VA_LIST_COMPATIBILITY 1 +#endif + +#ifndef __INTEL_COMPILER +# define __GNUCLIKE_BUILTIN_NEXT_ARG 1 +# define __GNUCLIKE_MATH_BUILTIN_RELOPS +#endif + +#define __GNUCLIKE_BUILTIN_MEMCPY 1 + +/* XXX: if __GNUC__ >= 2: not tested everywhere originally, where replaced */ +#define __CC_SUPPORTS_INLINE 1 +#define __CC_SUPPORTS___INLINE 1 +#define __CC_SUPPORTS___INLINE__ 1 + +#define __CC_SUPPORTS___FUNC__ 1 +#define __CC_SUPPORTS_WARNING 1 + +#define __CC_SUPPORTS_VARADIC_XXX 1 /* see varargs.h */ + +#define __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 1 + +#endif /* __GNUC__ || __INTEL_COMPILER */ + +/* + * Macro to test if we're using a specific version of gcc or later. + */ +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) +#define __GNUC_PREREQ__(ma, mi) \ + (__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)) +#else +#define __GNUC_PREREQ__(ma, mi) 0 +#endif + +/* + * The __CONCAT macro is used to concatenate parts of symbol names, e.g. + * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo. + * The __CONCAT macro is a bit tricky to use if it must work in non-ANSI + * mode -- there must be no spaces between its arguments, and for nested + * __CONCAT's, all the __CONCAT's must be at the left. __CONCAT can also + * concatenate double-quoted strings produced by the __STRING macro, but + * this only works with ANSI C. + * + * __XSTRING is like __STRING, but it expands any macros in its argument + * first. It is only available with ANSI C. + */ +#if defined(__STDC__) || defined(__cplusplus) +#define __P(protos) protos /* full-blown ANSI C */ +#define __CONCAT1(x,y) x ## y +#define __CONCAT(x,y) __CONCAT1(x,y) +#define __STRING(x) #x /* stringify without expanding x */ +#define __XSTRING(x) __STRING(x) /* expand x, then stringify */ + +#define __const const /* define reserved names to standard */ +#define __signed signed +#define __volatile volatile +#if defined(__cplusplus) +#define __inline inline /* convert to C++ keyword */ +#else +#if !(defined(__CC_SUPPORTS___INLINE)) +#define __inline /* delete GCC keyword */ +#endif /* ! __CC_SUPPORTS___INLINE */ +#endif /* !__cplusplus */ + +#else /* !(__STDC__ || __cplusplus) */ +#define __P(protos) () /* traditional C preprocessor */ +#define __CONCAT(x,y) x/**/y +#define __STRING(x) "x" + +#if !defined(__CC_SUPPORTS___INLINE) +#define __const /* delete pseudo-ANSI C keywords */ +#define __inline +#define __signed +#define __volatile +/* + * In non-ANSI C environments, new programs will want ANSI-only C keywords + * deleted from the program and old programs will want them left alone. + * When using a compiler other than gcc, programs using the ANSI C keywords + * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS. + * When using "gcc -traditional", we assume that this is the intent; if + * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone. + */ +#ifndef NO_ANSI_KEYWORDS +#define const /* delete ANSI C keywords */ +#define inline +#define signed +#define volatile +#endif /* !NO_ANSI_KEYWORDS */ +#endif /* !__CC_SUPPORTS___INLINE */ +#endif /* !(__STDC__ || __cplusplus) */ + +/* + * Compiler-dependent macros to help declare dead (non-returning) and + * pure (no side effects) functions, and unused variables. They are + * null except for versions of gcc that are known to support the features + * properly (old versions of gcc-2 supported the dead and pure features + * in a different (wrong) way). If we do not provide an implementation + * for a given compiler, let the compile fail if it is told to use + * a feature that we cannot live without. + */ +#ifdef lint +#define __dead2 +#define __pure2 +#define __unused +#define __packed +#define __aligned(x) +#define __section(x) +#else +#if !__GNUC_PREREQ__(2, 5) && !defined(__INTEL_COMPILER) +#define __dead2 +#define __pure2 +#define __unused +#endif +#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 && !defined(__INTEL_COMPILER) +#define __dead2 __attribute__((__noreturn__)) +#define __pure2 __attribute__((__const__)) +#define __unused +/* XXX Find out what to do for __packed, __aligned and __section */ +#endif +#if __GNUC_PREREQ__(2, 7) +#define __dead2 __attribute__((__noreturn__)) +#define __pure2 __attribute__((__const__)) +#define __unused __attribute__((__unused__)) +#define __used __attribute__((__used__)) +#define __packed __attribute__((__packed__)) +#define __aligned(x) __attribute__((__aligned__(x))) +#define __section(x) __attribute__((__section__(x))) +#endif +#if defined(__INTEL_COMPILER) +#define __dead2 __attribute__((__noreturn__)) +#define __pure2 __attribute__((__const__)) +#define __unused __attribute__((__unused__)) +#define __used __attribute__((__used__)) +#define __packed __attribute__((__packed__)) +#define __aligned(x) __attribute__((__aligned__(x))) +#define __section(x) __attribute__((__section__(x))) +#endif +#endif + +#if !__GNUC_PREREQ__(2, 95) +#define __alignof(x) __offsetof(struct { char __a; x __b; }, __b) +#endif + +/* + * Keywords added in C11. + */ +#if defined(__cplusplus) && __cplusplus >= 201103L +#define _Alignas(e) alignas(e) +#define _Alignof(e) alignof(e) +#define _Noreturn [[noreturn]] +#define _Static_assert(e, s) static_assert(e, s) +/* FIXME: change this to thread_local when clang in base supports it */ +#define _Thread_local __thread +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +/* Do nothing. They are language keywords. */ +#else +/* Not supported. Implement them using our versions. */ +#define _Alignas(x) __aligned(x) +#define _Alignof(x) __alignof(x) +#define _Noreturn __dead2 +#define _Thread_local __thread +#ifdef __COUNTER__ +#define _Static_assert(x, y) __Static_assert(x, __COUNTER__) +#define __Static_assert(x, y) ___Static_assert(x, y) +#define ___Static_assert(x, y) typedef char __assert_ ## y[(x) ? 1 : -1] +#else +#define _Static_assert(x, y) struct __hack +#endif +#endif + +/* + * Emulation of C11 _Generic(). Unlike the previously defined C11 + * keywords, it is not possible to implement this using exactly the same + * syntax. Therefore implement something similar under the name + * __generic(). Unlike _Generic(), this macro can only distinguish + * between a single type, so it requires nested invocations to + * distinguish multiple cases. + */ + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#define __generic(expr, t, yes, no) \ + _Generic(expr, t: yes, default: no) +#elif __GNUC_PREREQ__(3, 1) && !defined(__cplusplus) +#define __generic(expr, t, yes, no) \ + __builtin_choose_expr( \ + __builtin_types_compatible_p(__typeof(expr), t), yes, no) +#endif + +#if __GNUC_PREREQ__(2, 96) +#define __malloc_like __attribute__((__malloc__)) +#define __pure __attribute__((__pure__)) +#else +#define __malloc_like +#define __pure +#endif + +#if __GNUC_PREREQ__(3, 1) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800) +#define __always_inline __attribute__((__always_inline__)) +#else +#define __always_inline +#endif + +#if __GNUC_PREREQ__(3, 1) +#define __noinline __attribute__ ((__noinline__)) +#else +#define __noinline +#endif + +#if __GNUC_PREREQ__(3, 3) +#define __nonnull(x) __attribute__((__nonnull__(x))) +#else +#define __nonnull(x) +#endif + +#if __GNUC_PREREQ__(3, 4) +#define __fastcall __attribute__((__fastcall__)) +#else +#define __fastcall +#endif + +#if __GNUC_PREREQ__(4, 1) +#define __returns_twice __attribute__((__returns_twice__)) +#else +#define __returns_twice +#endif + +/* XXX: should use `#if __STDC_VERSION__ < 199901'. */ +#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER) +#define __func__ NULL +#endif + +#if (defined(__INTEL_COMPILER) || (defined(__GNUC__) && __GNUC__ >= 2)) && !defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901 +#define __LONG_LONG_SUPPORTED +#endif + +/* C++11 exposes a load of C99 stuff */ +#if defined(__cplusplus) && __cplusplus >= 201103L +#define __LONG_LONG_SUPPORTED +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS +#endif +#ifndef __STDC_CONSTANT_MACROS +#define __STDC_CONSTANT_MACROS +#endif +#endif + +/* + * GCC 2.95 provides `__restrict' as an extension to C90 to support the + * C99-specific `restrict' type qualifier. We happen to use `__restrict' as + * a way to define the `restrict' type qualifier without disturbing older + * software that is unaware of C99 keywords. + */ +#if !(__GNUC__ == 2 && __GNUC_MINOR__ == 95) +#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901 || defined(lint) +#define __restrict +#else +#define __restrict restrict +#endif +#endif + +/* + * GNU C version 2.96 adds explicit branch prediction so that + * the CPU back-end can hint the processor and also so that + * code blocks can be reordered such that the predicted path + * sees a more linear flow, thus improving cache behavior, etc. + * + * The following two macros provide us with a way to utilize this + * compiler feature. Use __predict_true() if you expect the expression + * to evaluate to true, and __predict_false() if you expect the + * expression to evaluate to false. + * + * A few notes about usage: + * + * * Generally, __predict_false() error condition checks (unless + * you have some _strong_ reason to do otherwise, in which case + * document it), and/or __predict_true() `no-error' condition + * checks, assuming you want to optimize for the no-error case. + * + * * Other than that, if you don't know the likelihood of a test + * succeeding from empirical or other `hard' evidence, don't + * make predictions. + * + * * These are meant to be used in places that are run `a lot'. + * It is wasteful to make predictions in code that is run + * seldomly (e.g. at subsystem initialization time) as the + * basic block reordering that this affects can often generate + * larger code. + */ +#if __GNUC_PREREQ__(2, 96) +#define __predict_true(exp) __builtin_expect((exp), 1) +#define __predict_false(exp) __builtin_expect((exp), 0) +#else +#define __predict_true(exp) (exp) +#define __predict_false(exp) (exp) +#endif + +#if __GNUC_PREREQ__(4, 2) +#define __hidden __attribute__((__visibility__("hidden"))) +#define __exported __attribute__((__visibility__("default"))) +#else +#define __hidden +#define __exported +#endif + +/* + * We define this here since <stddef.h>, <sys/queue.h>, and <sys/types.h> + * require it. + */ +#if __GNUC_PREREQ__(4, 1) +#define __offsetof(type, field) __builtin_offsetof(type, field) +#else +#ifndef __cplusplus +#define __offsetof(type, field) \ + ((__size_t)(__uintptr_t)((const volatile void *)&((type *)0)->field)) +#else +#define __offsetof(type, field) \ + (__offsetof__ (reinterpret_cast <__size_t> \ + (&reinterpret_cast <const volatile char &> \ + (static_cast<type *> (0)->field)))) +#endif +#endif +#define __rangeof(type, start, end) \ + (__offsetof(type, end) - __offsetof(type, start)) + +/* + * Given the pointer x to the member m of the struct s, return + * a pointer to the containing structure. When using GCC, we first + * assign pointer x to a local variable, to check that its type is + * compatible with member m. + */ +#if __GNUC_PREREQ__(3, 1) +#define __containerof(x, s, m) ({ \ + const volatile __typeof(((s *)0)->m) *__x = (x); \ + __DEQUALIFY(s *, (const volatile char *)__x - __offsetof(s, m));\ +}) +#else +#define __containerof(x, s, m) \ + __DEQUALIFY(s *, (const volatile char *)(x) - __offsetof(s, m)) +#endif + +/* + * Compiler-dependent macros to declare that functions take printf-like + * or scanf-like arguments. They are null except for versions of gcc + * that are known to support the features properly (old versions of gcc-2 + * didn't permit keeping the keywords out of the application namespace). + */ +#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER) +#define __printflike(fmtarg, firstvararg) +#define __scanflike(fmtarg, firstvararg) +#define __format_arg(fmtarg) +#define __strfmonlike(fmtarg, firstvararg) +#define __strftimelike(fmtarg, firstvararg) +#else +#define __printflike(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf__, fmtarg, firstvararg))) +#define __scanflike(fmtarg, firstvararg) \ + __attribute__((__format__ (__scanf__, fmtarg, firstvararg))) +#define __format_arg(fmtarg) __attribute__((__format_arg__ (fmtarg))) +#define __strfmonlike(fmtarg, firstvararg) \ + __attribute__((__format__ (__strfmon__, fmtarg, firstvararg))) +#define __strftimelike(fmtarg, firstvararg) \ + __attribute__((__format__ (__strftime__, fmtarg, firstvararg))) +#endif + +/* Compiler-dependent macros that rely on FreeBSD-specific extensions. */ +#if __FreeBSD_cc_version >= 300001 && defined(__GNUC__) && !defined(__INTEL_COMPILER) +#define __printf0like(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf0__, fmtarg, firstvararg))) +#else +#define __printf0like(fmtarg, firstvararg) +#endif + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) +#ifndef __INTEL_COMPILER +#define __strong_reference(sym,aliassym) \ + extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym))) +#endif +#ifdef __STDC__ +#define __weak_reference(sym,alias) \ + __asm__(".weak " #alias); \ + __asm__(".equ " #alias ", " #sym) +#define __warn_references(sym,msg) \ + __asm__(".section .gnu.warning." #sym); \ + __asm__(".asciz \"" msg "\""); \ + __asm__(".previous") +#define __sym_compat(sym,impl,verid) \ + __asm__(".symver " #impl ", " #sym "@" #verid) +#define __sym_default(sym,impl,verid) \ + __asm__(".symver " #impl ", " #sym "@@" #verid) +#else +#define __weak_reference(sym,alias) \ + __asm__(".weak alias"); \ + __asm__(".equ alias, sym") +#define __warn_references(sym,msg) \ + __asm__(".section .gnu.warning.sym"); \ + __asm__(".asciz \"msg\""); \ + __asm__(".previous") +#define __sym_compat(sym,impl,verid) \ + __asm__(".symver impl, sym@verid") +#define __sym_default(impl,sym,verid) \ + __asm__(".symver impl, sym@@verid") +#endif /* __STDC__ */ +#endif /* __GNUC__ || __INTEL_COMPILER */ + +#define __GLOBL1(sym) __asm__(".globl " #sym) +#define __GLOBL(sym) __GLOBL1(sym) + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) +#define __IDSTRING(name,string) __asm__(".ident\t\"" string "\"") +#else +/* + * The following definition might not work well if used in header files, + * but it should be better than nothing. If you want a "do nothing" + * version, then it should generate some harmless declaration, such as: + * #define __IDSTRING(name,string) struct __hack + */ +#define __IDSTRING(name,string) static const char name[] __unused = string +#endif + +/* + * Embed the rcs id of a source file in the resulting library. Note that in + * more recent ELF binutils, we use .ident allowing the ID to be stripped. + * Usage: + * __FBSDID("$FreeBSD$"); + */ +#ifndef __FBSDID +#if !defined(lint) && !defined(STRIP_FBSDID) +#define __FBSDID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s) +#else +#define __FBSDID(s) struct __hack +#endif +#endif + +#ifndef __RCSID +#ifndef NO__RCSID +#define __RCSID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s) +#else +#define __RCSID(s) struct __hack +#endif +#endif + +#ifndef __RCSID_SOURCE +#ifndef NO__RCSID_SOURCE +#define __RCSID_SOURCE(s) __IDSTRING(__CONCAT(__rcsid_source_,__LINE__),s) +#else +#define __RCSID_SOURCE(s) struct __hack +#endif +#endif + +#ifndef __SCCSID +#ifndef NO__SCCSID +#define __SCCSID(s) __IDSTRING(__CONCAT(__sccsid_,__LINE__),s) +#else +#define __SCCSID(s) struct __hack +#endif +#endif + +#ifndef __COPYRIGHT +#ifndef NO__COPYRIGHT +#define __COPYRIGHT(s) __IDSTRING(__CONCAT(__copyright_,__LINE__),s) +#else +#define __COPYRIGHT(s) struct __hack +#endif +#endif + +#ifndef __DECONST +#define __DECONST(type, var) ((type)(__uintptr_t)(const void *)(var)) +#endif + +#ifndef __DEVOLATILE +#define __DEVOLATILE(type, var) ((type)(__uintptr_t)(volatile void *)(var)) +#endif + +#ifndef __DEQUALIFY +#define __DEQUALIFY(type, var) ((type)(__uintptr_t)(const volatile void *)(var)) +#endif + +/*- + * The following definitions are an extension of the behavior originally + * implemented in <sys/_posix.h>, but with a different level of granularity. + * POSIX.1 requires that the macros we test be defined before any standard + * header file is included. + * + * Here's a quick run-down of the versions: + * defined(_POSIX_SOURCE) 1003.1-1988 + * _POSIX_C_SOURCE == 1 1003.1-1990 + * _POSIX_C_SOURCE == 2 1003.2-1992 C Language Binding Option + * _POSIX_C_SOURCE == 199309 1003.1b-1993 + * _POSIX_C_SOURCE == 199506 1003.1c-1995, 1003.1i-1995, + * and the omnibus ISO/IEC 9945-1: 1996 + * _POSIX_C_SOURCE == 200112 1003.1-2001 + * _POSIX_C_SOURCE == 200809 1003.1-2008 + * + * In addition, the X/Open Portability Guide, which is now the Single UNIX + * Specification, defines a feature-test macro which indicates the version of + * that specification, and which subsumes _POSIX_C_SOURCE. + * + * Our macros begin with two underscores to avoid namespace screwage. + */ + +/* Deal with IEEE Std. 1003.1-1990, in which _POSIX_C_SOURCE == 1. */ +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 1 +#undef _POSIX_C_SOURCE /* Probably illegal, but beyond caring now. */ +#define _POSIX_C_SOURCE 199009 +#endif + +/* Deal with IEEE Std. 1003.2-1992, in which _POSIX_C_SOURCE == 2. */ +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 2 +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 199209 +#endif + +/* Deal with various X/Open Portability Guides and Single UNIX Spec. */ +#ifdef _XOPEN_SOURCE +#if _XOPEN_SOURCE - 0 >= 700 +#define __XSI_VISIBLE 700 +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200809 +#elif _XOPEN_SOURCE - 0 >= 600 +#define __XSI_VISIBLE 600 +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112 +#elif _XOPEN_SOURCE - 0 >= 500 +#define __XSI_VISIBLE 500 +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 199506 +#endif +#endif + +/* + * Deal with all versions of POSIX. The ordering relative to the tests above is + * important. + */ +#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 198808 +#endif +#ifdef _POSIX_C_SOURCE +#if _POSIX_C_SOURCE >= 200809 +#define __POSIX_VISIBLE 200809 +#define __ISO_C_VISIBLE 1999 +#elif _POSIX_C_SOURCE >= 200112 +#define __POSIX_VISIBLE 200112 +#define __ISO_C_VISIBLE 1999 +#elif _POSIX_C_SOURCE >= 199506 +#define __POSIX_VISIBLE 199506 +#define __ISO_C_VISIBLE 1990 +#elif _POSIX_C_SOURCE >= 199309 +#define __POSIX_VISIBLE 199309 +#define __ISO_C_VISIBLE 1990 +#elif _POSIX_C_SOURCE >= 199209 +#define __POSIX_VISIBLE 199209 +#define __ISO_C_VISIBLE 1990 +#elif _POSIX_C_SOURCE >= 199009 +#define __POSIX_VISIBLE 199009 +#define __ISO_C_VISIBLE 1990 +#else +#define __POSIX_VISIBLE 198808 +#define __ISO_C_VISIBLE 0 +#endif /* _POSIX_C_SOURCE */ +#else +/*- + * Deal with _ANSI_SOURCE: + * If it is defined, and no other compilation environment is explicitly + * requested, then define our internal feature-test macros to zero. This + * makes no difference to the preprocessor (undefined symbols in preprocessing + * expressions are defined to have value zero), but makes it more convenient for + * a test program to print out the values. + * + * If a program mistakenly defines _ANSI_SOURCE and some other macro such as + * _POSIX_C_SOURCE, we will assume that it wants the broader compilation + * environment (and in fact we will never get here). + */ +#if defined(_ANSI_SOURCE) /* Hide almost everything. */ +#define __POSIX_VISIBLE 0 +#define __XSI_VISIBLE 0 +#define __BSD_VISIBLE 0 +#define __ISO_C_VISIBLE 1990 +#elif defined(_C99_SOURCE) /* Localism to specify strict C99 env. */ +#define __POSIX_VISIBLE 0 +#define __XSI_VISIBLE 0 +#define __BSD_VISIBLE 0 +#define __ISO_C_VISIBLE 1999 +#else /* Default environment: show everything. */ +#define __POSIX_VISIBLE 200809 +#define __XSI_VISIBLE 700 +#define __BSD_VISIBLE 1 +#define __ISO_C_VISIBLE 1999 +#endif +#endif + +#ifndef __has_feature +#define __has_feature(x) 0 +#endif +#ifndef __has_include +#define __has_include(x) 0 +#endif +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + +#if defined(__mips) || defined(__powerpc64__) || defined(__arm__) +#define __NO_TLS 1 +#endif + +#endif /* !_SYS_CDEFS_H_ */ diff --git a/include/stdlib/sys/ctype.h b/include/stdlib/sys/ctype.h new file mode 100644 index 0000000..f2758b7 --- /dev/null +++ b/include/stdlib/sys/ctype.h @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 1982, 1988, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * $FreeBSD$ + */ + +/* + * Portions copyright (c) 2009-2014, ARM Limited and Contributors. + * All rights reserved. + */ + +#ifndef _SYS_CTYPE_H_ +#define _SYS_CTYPE_H_ + +#define isspace(c) ((c) == ' ' || ((c) >= '\t' && (c) <= '\r')) +#define isascii(c) (((c) & ~0x7f) == 0) +#define isupper(c) ((c) >= 'A' && (c) <= 'Z') +#define islower(c) ((c) >= 'a' && (c) <= 'z') +#define isalpha(c) (isupper(c) || islower(c)) +#define isdigit(c) ((c) >= '0' && (c) <= '9') +#define isxdigit(c) (isdigit(c) \ + || ((c) >= 'A' && (c) <= 'F') \ + || ((c) >= 'a' && (c) <= 'f')) +#define isprint(c) ((c) >= ' ' && (c) <= '~') + +#define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z'))) +#define tolower(c) ((c) + 0x20 * (((c) >= 'A') && ((c) <= 'Z'))) + +#endif /* !_SYS_CTYPE_H_ */ diff --git a/include/stdlib/sys/errno.h b/include/stdlib/sys/errno.h new file mode 100644 index 0000000..f595514 --- /dev/null +++ b/include/stdlib/sys/errno.h @@ -0,0 +1,193 @@ +/*- + * Copyright (c) 1982, 1986, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)errno.h 8.5 (Berkeley) 1/21/94 + * $FreeBSD$ + */ + +#ifndef _SYS_ERRNO_H_ +#define _SYS_ERRNO_H_ + +#ifndef _KERNEL +#include <sys/cdefs.h> +__BEGIN_DECLS +int * __error(void); +__END_DECLS +#define errno (* __error()) +#endif + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* Input/output error */ +#define ENXIO 6 /* Device not configured */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file descriptor */ +#define ECHILD 10 /* No child processes */ +#define EDEADLK 11 /* Resource deadlock avoided */ + /* 11 was EAGAIN */ +#define ENOMEM 12 /* Cannot allocate memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#ifndef _POSIX_SOURCE +#define ENOTBLK 15 /* Block device required */ +#endif +#define EBUSY 16 /* Device busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* Operation not supported by device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* Too many open files in system */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Inappropriate ioctl for device */ +#ifndef _POSIX_SOURCE +#define ETXTBSY 26 /* Text file busy */ +#endif +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only filesystem */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ + +/* math software */ +#define EDOM 33 /* Numerical argument out of domain */ +#define ERANGE 34 /* Result too large */ + +/* non-blocking and interrupt i/o */ +#define EAGAIN 35 /* Resource temporarily unavailable */ +#ifndef _POSIX_SOURCE +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define EINPROGRESS 36 /* Operation now in progress */ +#define EALREADY 37 /* Operation already in progress */ + +/* ipc/network software -- argument errors */ +#define ENOTSOCK 38 /* Socket operation on non-socket */ +#define EDESTADDRREQ 39 /* Destination address required */ +#define EMSGSIZE 40 /* Message too long */ +#define EPROTOTYPE 41 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 42 /* Protocol not available */ +#define EPROTONOSUPPORT 43 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 44 /* Socket type not supported */ +#define EOPNOTSUPP 45 /* Operation not supported */ +#define ENOTSUP EOPNOTSUPP /* Operation not supported */ +#define EPFNOSUPPORT 46 /* Protocol family not supported */ +#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */ +#define EADDRINUSE 48 /* Address already in use */ +#define EADDRNOTAVAIL 49 /* Can't assign requested address */ + +/* ipc/network software -- operational errors */ +#define ENETDOWN 50 /* Network is down */ +#define ENETUNREACH 51 /* Network is unreachable */ +#define ENETRESET 52 /* Network dropped connection on reset */ +#define ECONNABORTED 53 /* Software caused connection abort */ +#define ECONNRESET 54 /* Connection reset by peer */ +#define ENOBUFS 55 /* No buffer space available */ +#define EISCONN 56 /* Socket is already connected */ +#define ENOTCONN 57 /* Socket is not connected */ +#define ESHUTDOWN 58 /* Can't send after socket shutdown */ +#define ETOOMANYREFS 59 /* Too many references: can't splice */ +#define ETIMEDOUT 60 /* Operation timed out */ +#define ECONNREFUSED 61 /* Connection refused */ + +#define ELOOP 62 /* Too many levels of symbolic links */ +#endif /* _POSIX_SOURCE */ +#define ENAMETOOLONG 63 /* File name too long */ + +/* should be rearranged */ +#ifndef _POSIX_SOURCE +#define EHOSTDOWN 64 /* Host is down */ +#define EHOSTUNREACH 65 /* No route to host */ +#endif /* _POSIX_SOURCE */ +#define ENOTEMPTY 66 /* Directory not empty */ + +/* quotas & mush */ +#ifndef _POSIX_SOURCE +#define EPROCLIM 67 /* Too many processes */ +#define EUSERS 68 /* Too many users */ +#define EDQUOT 69 /* Disc quota exceeded */ + +/* Network File System */ +#define ESTALE 70 /* Stale NFS file handle */ +#define EREMOTE 71 /* Too many levels of remote in path */ +#define EBADRPC 72 /* RPC struct is bad */ +#define ERPCMISMATCH 73 /* RPC version wrong */ +#define EPROGUNAVAIL 74 /* RPC prog. not avail */ +#define EPROGMISMATCH 75 /* Program version wrong */ +#define EPROCUNAVAIL 76 /* Bad procedure for program */ +#endif /* _POSIX_SOURCE */ + +#define ENOLCK 77 /* No locks available */ +#define ENOSYS 78 /* Function not implemented */ + +#ifndef _POSIX_SOURCE +#define EFTYPE 79 /* Inappropriate file type or format */ +#define EAUTH 80 /* Authentication error */ +#define ENEEDAUTH 81 /* Need authenticator */ +#define EIDRM 82 /* Identifier removed */ +#define ENOMSG 83 /* No message of desired type */ +#define EOVERFLOW 84 /* Value too large to be stored in data type */ +#define ECANCELED 85 /* Operation canceled */ +#define EILSEQ 86 /* Illegal byte sequence */ +#define ENOATTR 87 /* Attribute not found */ + +#define EDOOFUS 88 /* Programming error */ +#endif /* _POSIX_SOURCE */ + +#define EBADMSG 89 /* Bad message */ +#define EMULTIHOP 90 /* Multihop attempted */ +#define ENOLINK 91 /* Link has been severed */ +#define EPROTO 92 /* Protocol error */ + +#ifndef _POSIX_SOURCE +#define ENOTCAPABLE 93 /* Capabilities insufficient */ +#define ECAPMODE 94 /* Not permitted in capability mode */ +#endif /* _POSIX_SOURCE */ + +#ifndef _POSIX_SOURCE +#define ELAST 94 /* Must be equal largest errno */ +#endif /* _POSIX_SOURCE */ + +#ifdef _KERNEL +/* pseudo-errors returned inside kernel to modify return to process */ +#define ERESTART (-1) /* restart syscall */ +#define EJUSTRETURN (-2) /* don't modify regs, just return */ +#define ENOIOCTL (-3) /* ioctl not handled by this layer */ +#define EDIRIOCTL (-4) /* do direct ioctl in GEOM */ +#endif + +#endif diff --git a/include/stdlib/sys/limits.h b/include/stdlib/sys/limits.h new file mode 100644 index 0000000..c56a337 --- /dev/null +++ b/include/stdlib/sys/limits.h @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * $FreeBSD$ + */ + +#ifndef _SYS_LIMITS_H_ +#define _SYS_LIMITS_H_ + +#include <sys/cdefs.h> +#include <machine/_limits.h> + +#define CHAR_BIT __CHAR_BIT /* number of bits in a char */ + +#define SCHAR_MAX __SCHAR_MAX /* max value for a signed char */ +#define SCHAR_MIN __SCHAR_MIN /* min value for a signed char */ + +#define UCHAR_MAX __UCHAR_MAX /* max value for an unsigned char */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MAX UCHAR_MAX /* max value for a char */ +#define CHAR_MIN 0 /* min value for a char */ +#else +#define CHAR_MAX SCHAR_MAX +#define CHAR_MIN SCHAR_MIN +#endif + +#define USHRT_MAX __USHRT_MAX /* max value for an unsigned short */ +#define SHRT_MAX __SHRT_MAX /* max value for a short */ +#define SHRT_MIN __SHRT_MIN /* min value for a short */ + +#define UINT_MAX __UINT_MAX /* max value for an unsigned int */ +#define INT_MAX __INT_MAX /* max value for an int */ +#define INT_MIN __INT_MIN /* min value for an int */ + +#define ULONG_MAX __ULONG_MAX /* max for an unsigned long */ +#define LONG_MAX __LONG_MAX /* max for a long */ +#define LONG_MIN __LONG_MIN /* min for a long */ + +#ifdef __LONG_LONG_SUPPORTED +#define ULLONG_MAX __ULLONG_MAX /* max for an unsigned long long */ +#define LLONG_MAX __LLONG_MAX /* max for a long long */ +#define LLONG_MIN __LLONG_MIN /* min for a long long */ +#endif + +#if __POSIX_VISIBLE || __XSI_VISIBLE +#define SSIZE_MAX __SSIZE_MAX /* max value for an ssize_t */ +#endif + +#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE +#define SIZE_T_MAX __SIZE_T_MAX /* max value for a size_t */ + +#define OFF_MAX __OFF_MAX /* max value for an off_t */ +#define OFF_MIN __OFF_MIN /* min value for an off_t */ +#endif + +#if __BSD_VISIBLE +#define GID_MAX UINT_MAX /* max value for a gid_t */ +#define UID_MAX UINT_MAX /* max value for a uid_t */ + +#define UQUAD_MAX (__UQUAD_MAX) /* max value for a uquad_t */ +#define QUAD_MAX (__QUAD_MAX) /* max value for a quad_t */ +#define QUAD_MIN (__QUAD_MIN) /* min value for a quad_t */ +#endif + +#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809 +#define LONG_BIT __LONG_BIT +#define WORD_BIT __WORD_BIT +#endif + +#if __POSIX_VISIBLE +#define MQ_PRIO_MAX 64 +#endif + +#endif /* !_SYS_LIMITS_H_ */ diff --git a/include/stdlib/sys/stdarg.h b/include/stdlib/sys/stdarg.h new file mode 100644 index 0000000..c315dfc --- /dev/null +++ b/include/stdlib/sys/stdarg.h @@ -0,0 +1,75 @@ +/*- + * Copyright (c) 2002 David E. O'Brien. 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_STDARG_H_ +#define _MACHINE_STDARG_H_ + +#include <sys/cdefs.h> +#include <sys/_types.h> + +#ifndef _VA_LIST_DECLARED +#define _VA_LIST_DECLARED +typedef __va_list va_list; +#endif + +#ifdef __GNUCLIKE_BUILTIN_STDARG + +#define va_start(ap, last) \ + __builtin_va_start((ap), (last)) + +#define va_arg(ap, type) \ + __builtin_va_arg((ap), type) + +#define __va_copy(dest, src) \ + __builtin_va_copy((dest), (src)) + +#if __ISO_C_VISIBLE >= 1999 +#define va_copy(dest, src) \ + __va_copy(dest, src) +#endif + +#define va_end(ap) \ + __builtin_va_end(ap) + +#elif defined(lint) +/* Provide a fake implementation for lint's benefit */ +#define __va_size(type) \ + (((sizeof(type) + sizeof(long) - 1) / sizeof(long)) * sizeof(long)) +#define va_start(ap, last) \ + ((ap) = (va_list)&(last) + __va_size(last)) +#define va_arg(ap, type) \ + (*(type *)((ap) += __va_size(type), (ap) - __va_size(type))) +#define va_end(ap) + +#else +#error this file needs to be ported to your compiler +#endif + +#endif /* !_MACHINE_STDARG_H_ */ diff --git a/include/stdlib/sys/stdint.h b/include/stdlib/sys/stdint.h new file mode 100644 index 0000000..aa5ac81 --- /dev/null +++ b/include/stdlib/sys/stdint.h @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org> + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _SYS_STDINT_H_ +#define _SYS_STDINT_H_ + +#include <sys/cdefs.h> +#include <sys/_types.h> + +#include <machine/_stdint.h> +#include <sys/_stdint.h> + +typedef __int_least8_t int_least8_t; +typedef __int_least16_t int_least16_t; +typedef __int_least32_t int_least32_t; +typedef __int_least64_t int_least64_t; + +typedef __uint_least8_t uint_least8_t; +typedef __uint_least16_t uint_least16_t; +typedef __uint_least32_t uint_least32_t; +typedef __uint_least64_t uint_least64_t; + +typedef __int_fast8_t int_fast8_t; +typedef __int_fast16_t int_fast16_t; +typedef __int_fast32_t int_fast32_t; +typedef __int_fast64_t int_fast64_t; + +typedef __uint_fast8_t uint_fast8_t; +typedef __uint_fast16_t uint_fast16_t; +typedef __uint_fast32_t uint_fast32_t; +typedef __uint_fast64_t uint_fast64_t; + +#ifndef _INTMAX_T_DECLARED +typedef __intmax_t intmax_t; +#define _INTMAX_T_DECLARED +#endif +#ifndef _UINTMAX_T_DECLARED +typedef __uintmax_t uintmax_t; +#define _UINTMAX_T_DECLARED +#endif + +/* GNU and Darwin define this and people seem to think it's portable */ +#if defined(UINTPTR_MAX) && defined(UINT64_MAX) && (UINTPTR_MAX == UINT64_MAX) +#define __WORDSIZE 64 +#else +#define __WORDSIZE 32 +#endif + +#endif /* !_SYS_STDINT_H_ */ diff --git a/include/stdlib/sys/uuid.h b/include/stdlib/sys/uuid.h new file mode 100644 index 0000000..5c4767b --- /dev/null +++ b/include/stdlib/sys/uuid.h @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2002 Marcel Moolenaar + * 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 AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD$ + */ + +/* + * Portions copyright (c) 2014, ARM Limited and Contributors. + * All rights reserved. + */ + +#ifndef _SYS_UUID_H_ +#define _SYS_UUID_H_ + +#include <sys/cdefs.h> + +/* Length of a node address (an IEEE 802 address). */ +#define _UUID_NODE_LEN 6 + +/* + * See also: + * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt + * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm + * + * A DCE 1.1 compatible source representation of UUIDs. + */ +struct uuid { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint8_t clock_seq_hi_and_reserved; + uint8_t clock_seq_low; + uint8_t node[_UUID_NODE_LEN]; +}; + +/* XXX namespace pollution? */ +typedef struct uuid uuid_t; + +#endif /* _SYS_UUID_H_ */ diff --git a/lib/aarch64/cache_helpers.S b/lib/aarch64/cache_helpers.S new file mode 100644 index 0000000..04caac4 --- /dev/null +++ b/lib/aarch64/cache_helpers.S @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> + + .globl dcisw + .globl dccisw + .globl dccsw + .globl dccvac + .globl dcivac + .globl dccivac + .globl dccvau + .globl dczva + .globl flush_dcache_range + .globl inv_dcache_range + .globl dcsw_op_louis + .globl dcsw_op_all + + .global _clean_dcache_addr + .global _clean_invd_dcache_addr + .globl platform_stack_set_bl2 + + .type platform_stack_set_bl2, @function +platform_stack_set_bl2: + mov x9, x30 //lr + mov sp, x0 + ret x9 + +func dcisw + dc isw, x0 + ret + + +func dccisw + dc cisw, x0 + ret + + +func dccsw + dc csw, x0 + ret + + +func dccvac + dc cvac, x0 + ret + + +func dcivac + dc ivac, x0 + ret + + +func dccivac + dc civac, x0 + ret + + +func dccvau + dc cvau, x0 + ret + + +func dczva + dc zva, x0 + ret + + + /* ------------------------------------------ + * Clean+Invalidate from base address till + * size. 'x0' = addr, 'x1' = size + * ------------------------------------------ + */ +func flush_dcache_range + dcache_line_size x2, x3 + add x1, x0, x1 + sub x3, x2, #1 + bic x0, x0, x3 +flush_loop: + dc civac, x0 + add x0, x0, x2 + cmp x0, x1 + b.lo flush_loop + dsb sy + ret + + + /* ------------------------------------------ + * Invalidate from base address till + * size. 'x0' = addr, 'x1' = size + * ------------------------------------------ + */ +func inv_dcache_range + dcache_line_size x2, x3 + add x1, x0, x1 + sub x3, x2, #1 + bic x0, x0, x3 +inv_loop: + dc ivac, x0 + add x0, x0, x2 + cmp x0, x1 + b.lo inv_loop + dsb sy + ret + + + /* --------------------------------------------------------------- + * Data cache operations by set/way to the level specified + * + * The main function, do_dcsw_op requires: + * x0: The operation type (0-2), as defined in arch.h + * x3: The last cache level to operate on + * x9: clidr_el1 + * and will carry out the operation on each data cache from level 0 + * to the level in x3 in sequence + * + * The dcsw_op macro sets up the x3 and x9 parameters based on + * clidr_el1 cache information before invoking the main function + * --------------------------------------------------------------- + */ + + .macro dcsw_op shift, fw, ls + mrs x9, clidr_el1 + ubfx x3, x9, \shift, \fw + lsl x3, x3, \ls + b do_dcsw_op + .endm + +func do_dcsw_op + cbz x3, exit + mov x10, xzr + adr x14, dcsw_loop_table // compute inner loop address + add x14, x14, x0, lsl #5 // inner loop is 8x32-bit instructions + mov x0, x9 + mov w8, #1 +loop1: + add x2, x10, x10, lsr #1 // work out 3x current cache level + lsr x1, x0, x2 // extract cache type bits from clidr + and x1, x1, #7 // mask the bits for current cache only + cmp x1, #2 // see what cache we have at this level + b.lt level_done // nothing to do if no cache or icache + + msr csselr_el1, x10 // select current cache level in csselr + isb // isb to sych the new cssr&csidr + mrs x1, ccsidr_el1 // read the new ccsidr + and x2, x1, #7 // extract the length of the cache lines + add x2, x2, #4 // add 4 (line length offset) + ubfx x4, x1, #3, #10 // maximum way number + clz w5, w4 // bit position of way size increment + lsl w9, w4, w5 // w9 = aligned max way number + lsl w16, w8, w5 // w16 = way number loop decrement + orr w9, w10, w9 // w9 = combine way and cache number + ubfx w6, w1, #13, #15 // w6 = max set number + lsl w17, w8, w2 // w17 = set number loop decrement + dsb sy // barrier before we start this level + br x14 // jump to DC operation specific loop + + .macro dcsw_loop _op +loop2_\_op: + lsl w7, w6, w2 // w7 = aligned max set number + +loop3_\_op: + orr w11, w9, w7 // combine cache, way and set number + dc \_op, x11 + subs w7, w7, w17 // decrement set number + b.ge loop3_\_op + + subs x9, x9, x16 // decrement way number + b.ge loop2_\_op + + b level_done + .endm + +level_done: + add x10, x10, #2 // increment cache number + cmp x3, x10 + b.gt loop1 + msr csselr_el1, xzr // select cache level 0 in csselr + dsb sy // barrier to complete final cache operation + isb +exit: + ret + +dcsw_loop_table: + dcsw_loop isw + dcsw_loop cisw + dcsw_loop csw + + +func dcsw_op_louis + dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT + + +func dcsw_op_all + dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT + + +#if 0 +//============================================== +// void _clean_dcache_addr(unsigned long addr) +// clean dcache by VA +//============================================== + .type _clean_dcache_addr, @function +_clean_dcache_addr: + dc cvac, x0 + dsb sy + ret +//============================================== +// void _clean_invd_dcache_addr(unsigned long addr) +// clean&invalid dcache by VA +//============================================== + .type _clean_invd_dcache_addr, @function +_clean_invd_dcache_addr: + dc civac, x0 + dsb sy + ret +#endif diff --git a/lib/aarch64/cpu_helpers.S b/lib/aarch64/cpu_helpers.S new file mode 100644 index 0000000..008d39d --- /dev/null +++ b/lib/aarch64/cpu_helpers.S @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> + + .weak cpu_reset_handler + + +func cpu_reset_handler + /* --------------------------------------------- + * As a bare minimal enable the SMP bit. + * --------------------------------------------- + */ + mrs x0, midr_el1 + lsr x1, x0, #MIDR_PN_SHIFT + and x1, x1, #MIDR_PN_MASK + cmp x1, #MIDR_PN_A57 + b.eq a57_setup_begin + cmp x1, #MIDR_PN_A53 + b.eq smp_setup_begin + b smp_setup_end + +a57_setup_begin: + ubfx x1, x0, #MIDR_VAR_SHIFT, #4 + cmp x1, #0 // Major Revision 0 + b.ne smp_setup_begin + ubfx x1, x0, #MIDR_REV_SHIFT, #4 + cmp x1, #0 // Minor Revision 0 + b.ne smp_setup_begin + mov x1, #CPUACTLR_NO_ALLOC_WBWA + orr x1, x1, #CPUACTLR_DIS_DMB_NULL + orr x1, x1, #CPUACTLR_DCC_AS_DCCI + mrs x0, CPUACTLR_EL1 + orr x0, x0, x1 + msr CPUACTLR_EL1, x0 + mov x0, #0x082 + msr s3_1_c11_c0_2, x0 + +smp_setup_begin: + mrs x0, CPUECTLR_EL1 + orr x0, x0, #CPUECTLR_SMP_BIT + msr CPUECTLR_EL1, x0 + isb + +smp_setup_end: + ret diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S new file mode 100644 index 0000000..e15c243 --- /dev/null +++ b/lib/aarch64/misc_helpers.S @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> + + .globl enable_irq + .globl disable_irq + + .globl enable_fiq + .globl disable_fiq + + .globl enable_serror + .globl disable_serror + + .globl enable_debug_exceptions + .globl disable_debug_exceptions + + .globl read_daif + .globl write_daif + + .globl read_spsr_el1 + .globl read_spsr_el2 + .globl read_spsr_el3 + + .globl write_spsr_el1 + .globl write_spsr_el2 + .globl write_spsr_el3 + + .globl read_elr_el1 + .globl read_elr_el2 + .globl read_elr_el3 + + .globl write_elr_el1 + .globl write_elr_el2 + .globl write_elr_el3 + + .globl get_afflvl_shift + .globl mpidr_mask_lower_afflvls + .globl dsb + .globl isb + .globl sev + .globl wfe + .globl wfi + .globl eret + .globl smc + + .globl zeromem16 + .globl memcpy16 + + .globl disable_mmu_el3 + .globl disable_mmu_icache_el3 + .globl remap_zero_address + + +func get_afflvl_shift + cmp x0, #3 + cinc x0, x0, eq + mov x1, #MPIDR_AFFLVL_SHIFT + lsl x0, x0, x1 + ret + +func mpidr_mask_lower_afflvls + cmp x1, #3 + cinc x1, x1, eq + mov x2, #MPIDR_AFFLVL_SHIFT + lsl x2, x1, x2 + lsr x0, x0, x2 + lsl x0, x0, x2 + ret + + /* ----------------------------------------------------- + * Asynchronous exception manipulation accessors + * ----------------------------------------------------- + */ +func enable_irq + msr daifclr, #DAIF_IRQ_BIT + ret + + +func enable_fiq + msr daifclr, #DAIF_FIQ_BIT + ret + + +func enable_serror + msr daifclr, #DAIF_ABT_BIT + ret + + +func enable_debug_exceptions + msr daifclr, #DAIF_DBG_BIT + ret + + +func disable_irq + msr daifset, #DAIF_IRQ_BIT + ret + + +func disable_fiq + msr daifset, #DAIF_FIQ_BIT + ret + + +func disable_serror + msr daifset, #DAIF_ABT_BIT + ret + + +func disable_debug_exceptions + msr daifset, #DAIF_DBG_BIT + ret + + +func read_daif + mrs x0, daif + ret + + +func write_daif + msr daif, x0 + ret + + +func read_spsr_el1 + mrs x0, spsr_el1 + ret + + +func read_spsr_el2 + mrs x0, spsr_el2 + ret + + +func read_spsr_el3 + mrs x0, spsr_el3 + ret + + +func write_spsr_el1 + msr spsr_el1, x0 + ret + + +func write_spsr_el2 + msr spsr_el2, x0 + ret + + +func write_spsr_el3 + msr spsr_el3, x0 + ret + + +func read_elr_el1 + mrs x0, elr_el1 + ret + + +func read_elr_el2 + mrs x0, elr_el2 + ret + + +func read_elr_el3 + mrs x0, elr_el3 + ret + + +func write_elr_el1 + msr elr_el1, x0 + ret + + +func write_elr_el2 + msr elr_el2, x0 + ret + + +func write_elr_el3 + msr elr_el3, x0 + ret + + +func dsb + dsb sy + ret + + +func isb + isb + ret + + +func sev + sev + ret + + +func wfe + wfe + ret + + +func wfi + wfi + ret + + +func eret + eret + + +func smc + smc #0 + +/* ----------------------------------------------------------------------- + * void zeromem16(void *mem, unsigned int length); + * + * Initialise a memory region to 0. + * The memory address must be 16-byte aligned. + * ----------------------------------------------------------------------- + */ +func zeromem16 + add x2, x0, x1 +/* zero 16 bytes at a time */ +z_loop16: + sub x3, x2, x0 + cmp x3, #16 + b.lt z_loop1 + stp xzr, xzr, [x0], #16 + b z_loop16 +/* zero byte per byte */ +z_loop1: + cmp x0, x2 + b.eq z_end + strb wzr, [x0], #1 + b z_loop1 +z_end: ret + + +/* -------------------------------------------------------------------------- + * void memcpy16(void *dest, const void *src, unsigned int length) + * + * Copy length bytes from memory area src to memory area dest. + * The memory areas should not overlap. + * Destination and source addresses must be 16-byte aligned. + * -------------------------------------------------------------------------- + */ +func memcpy16 +/* copy 16 bytes at a time */ +m_loop16: + cmp x2, #16 + b.lt m_loop1 + ldp x3, x4, [x1], #16 + stp x3, x4, [x0], #16 + sub x2, x2, #16 + b m_loop16 +/* copy byte per byte */ +m_loop1: + cbz x2, m_end + ldrb w3, [x1], #1 + strb w3, [x0], #1 + subs x2, x2, #1 + b.ne m_loop1 +m_end: ret + +/* --------------------------------------------------------------------------- + * Disable the MMU at EL3 + * This is implemented in assembler to ensure that the data cache is cleaned + * and invalidated after the MMU is disabled without any intervening cacheable + * data accesses + * --------------------------------------------------------------------------- + */ + +func disable_mmu_el3 + mov x1, #(SCTLR_M_BIT | SCTLR_C_BIT) +do_disable_mmu: + mrs x0, sctlr_el3 + bic x0, x0, x1 + msr sctlr_el3, x0 + isb // ensure MMU is off + mov x0, #DCCISW // DCache clean and invalidate + b dcsw_op_all + + +func disable_mmu_icache_el3 + mov x1, #(SCTLR_M_BIT | SCTLR_C_BIT | SCTLR_I_BIT) + b do_disable_mmu + +func remap_zero_address + ldr x1, =0xc1300000 + ldr w0, =0x00000001 + str w0, [x1] + isb + dmb sy diff --git a/lib/aarch64/sysreg_helpers.S b/lib/aarch64/sysreg_helpers.S new file mode 100644 index 0000000..925e93e --- /dev/null +++ b/lib/aarch64/sysreg_helpers.S @@ -0,0 +1,782 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> + + .globl read_vbar_el1 + .globl read_vbar_el2 + .globl read_vbar_el3 + .globl write_vbar_el1 + .globl write_vbar_el2 + .globl write_vbar_el3 + + .globl read_sctlr_el1 + .globl read_sctlr_el2 + .globl read_sctlr_el3 + .globl write_sctlr_el1 + .globl write_sctlr_el2 + .globl write_sctlr_el3 + + .globl read_actlr_el1 + .globl read_actlr_el2 + .globl read_actlr_el3 + .globl write_actlr_el1 + .globl write_actlr_el2 + .globl write_actlr_el3 + + .globl read_esr_el1 + .globl read_esr_el2 + .globl read_esr_el3 + .globl write_esr_el1 + .globl write_esr_el2 + .globl write_esr_el3 + + .globl read_afsr0_el1 + .globl read_afsr0_el2 + .globl read_afsr0_el3 + .globl write_afsr0_el1 + .globl write_afsr0_el2 + .globl write_afsr0_el3 + + .globl read_afsr1_el1 + .globl read_afsr1_el2 + .globl read_afsr1_el3 + .globl write_afsr1_el1 + .globl write_afsr1_el2 + .globl write_afsr1_el3 + + .globl read_far_el1 + .globl read_far_el2 + .globl read_far_el3 + .globl write_far_el1 + .globl write_far_el2 + .globl write_far_el3 + + .globl read_mair_el1 + .globl read_mair_el2 + .globl read_mair_el3 + .globl write_mair_el1 + .globl write_mair_el2 + .globl write_mair_el3 + + .globl read_amair_el1 + .globl read_amair_el2 + .globl read_amair_el3 + .globl write_amair_el1 + .globl write_amair_el2 + .globl write_amair_el3 + + .globl read_rvbar_el1 + .globl read_rvbar_el2 + .globl read_rvbar_el3 + + .globl read_rmr_el1 + .globl read_rmr_el2 + .globl read_rmr_el3 + .globl write_rmr_el1 + .globl write_rmr_el2 + .globl write_rmr_el3 + + .globl read_tcr_el1 + .globl read_tcr_el2 + .globl read_tcr_el3 + .globl write_tcr_el1 + .globl write_tcr_el2 + .globl write_tcr_el3 + + .globl read_cptr_el2 + .globl read_cptr_el3 + .globl write_cptr_el2 + .globl write_cptr_el3 + + .globl read_ttbr0_el1 + .globl read_ttbr0_el2 + .globl read_ttbr0_el3 + .globl write_ttbr0_el1 + .globl write_ttbr0_el2 + .globl write_ttbr0_el3 + + .globl read_ttbr1_el1 + .globl write_ttbr1_el1 + + .globl read_cpacr + .globl write_cpacr + + .globl read_cntfrq + .globl write_cntfrq + + .globl read_cpuectlr + .globl write_cpuectlr + + .globl read_cnthctl_el2 + .globl write_cnthctl_el2 + + .globl read_cntfrq_el0 + .globl write_cntfrq_el0 + + .globl read_cntps_ctl_el1 + .globl write_cntps_ctl_el1 + + .globl read_cntps_cval_el1 + .globl write_cntps_cval_el1 + + .globl read_cntps_tval_el1 + .globl write_cntps_tval_el1 + + .globl read_scr + .globl write_scr + + .globl read_hcr + .globl write_hcr + + .globl read_midr + .globl read_mpidr + + .globl read_cntpct_el0 + .globl read_current_el + .globl read_id_pfr1_el1 + .globl read_id_aa64pfr0_el1 + + .globl write_tpidr_el3 + .globl read_tpidr_el3 + +#if SUPPORT_VFP + .globl enable_vfp +#endif + + +func read_current_el + mrs x0, CurrentEl + ret + + +func read_id_pfr1_el1 + mrs x0, id_pfr1_el1 + ret + + +func read_id_aa64pfr0_el1 + mrs x0, id_aa64pfr0_el1 + ret + + + /* ----------------------------------------------------- + * VBAR accessors + * ----------------------------------------------------- + */ +func read_vbar_el1 + mrs x0, vbar_el1 + ret + + +func read_vbar_el2 + mrs x0, vbar_el2 + ret + + +func read_vbar_el3 + mrs x0, vbar_el3 + ret + + +func write_vbar_el1 + msr vbar_el1, x0 + ret + + +func write_vbar_el2 + msr vbar_el2, x0 + ret + + +func write_vbar_el3 + msr vbar_el3, x0 + ret + + + /* ----------------------------------------------------- + * AFSR0 accessors + * ----------------------------------------------------- + */ +func read_afsr0_el1 + mrs x0, afsr0_el1 + ret + + +func read_afsr0_el2 + mrs x0, afsr0_el2 + ret + + +func read_afsr0_el3 + mrs x0, afsr0_el3 + ret + + +func write_afsr0_el1 + msr afsr0_el1, x0 + ret + + +func write_afsr0_el2 + msr afsr0_el2, x0 + ret + + +func write_afsr0_el3 + msr afsr0_el3, x0 + ret + + + /* ----------------------------------------------------- + * FAR accessors + * ----------------------------------------------------- + */ +func read_far_el1 + mrs x0, far_el1 + ret + + +func read_far_el2 + mrs x0, far_el2 + ret + + +func read_far_el3 + mrs x0, far_el3 + ret + + +func write_far_el1 + msr far_el1, x0 + ret + + +func write_far_el2 + msr far_el2, x0 + ret + + +func write_far_el3 + msr far_el3, x0 + ret + + + /* ----------------------------------------------------- + * MAIR accessors + * ----------------------------------------------------- + */ +func read_mair_el1 + mrs x0, mair_el1 + ret + + +func read_mair_el2 + mrs x0, mair_el2 + ret + + +func read_mair_el3 + mrs x0, mair_el3 + ret + + +func write_mair_el1 + msr mair_el1, x0 + ret + + +func write_mair_el2 + msr mair_el2, x0 + ret + + +func write_mair_el3 + msr mair_el3, x0 + ret + + + /* ----------------------------------------------------- + * AMAIR accessors + * ----------------------------------------------------- + */ +func read_amair_el1 + mrs x0, amair_el1 + ret + + +func read_amair_el2 + mrs x0, amair_el2 + ret + + +func read_amair_el3 + mrs x0, amair_el3 + ret + + +func write_amair_el1 + msr amair_el1, x0 + ret + + +func write_amair_el2 + msr amair_el2, x0 + ret + + +func write_amair_el3 + msr amair_el3, x0 + ret + + + /* ----------------------------------------------------- + * RVBAR accessors + * ----------------------------------------------------- + */ +func read_rvbar_el1 + mrs x0, rvbar_el1 + ret + + +func read_rvbar_el2 + mrs x0, rvbar_el2 + ret + + +func read_rvbar_el3 + mrs x0, rvbar_el3 + ret + + + /* ----------------------------------------------------- + * RMR accessors + * ----------------------------------------------------- + */ +func read_rmr_el1 + mrs x0, rmr_el1 + ret + + +func read_rmr_el2 + mrs x0, rmr_el2 + ret + + +func read_rmr_el3 + mrs x0, rmr_el3 + ret + + +func write_rmr_el1 + msr rmr_el1, x0 + ret + + +func write_rmr_el2 + msr rmr_el2, x0 + ret + + +func write_rmr_el3 + msr rmr_el3, x0 + ret + + + /* ----------------------------------------------------- + * AFSR1 accessors + * ----------------------------------------------------- + */ +func read_afsr1_el1 + mrs x0, afsr1_el1 + ret + + +func read_afsr1_el2 + mrs x0, afsr1_el2 + ret + + +func read_afsr1_el3 + mrs x0, afsr1_el3 + ret + + +func write_afsr1_el1 + msr afsr1_el1, x0 + ret + + +func write_afsr1_el2 + msr afsr1_el2, x0 + ret + + +func write_afsr1_el3 + msr afsr1_el3, x0 + ret + + + /* ----------------------------------------------------- + * SCTLR accessors + * ----------------------------------------------------- + */ +func read_sctlr_el1 + mrs x0, sctlr_el1 + ret + + +func read_sctlr_el2 + mrs x0, sctlr_el2 + ret + + +func read_sctlr_el3 + mrs x0, sctlr_el3 + ret + + +func write_sctlr_el1 + msr sctlr_el1, x0 + ret + + +func write_sctlr_el2 + msr sctlr_el2, x0 + ret + + +func write_sctlr_el3 + msr sctlr_el3, x0 + ret + + + /* ----------------------------------------------------- + * ACTLR accessors + * ----------------------------------------------------- + */ +func read_actlr_el1 + mrs x0, actlr_el1 + ret + + +func read_actlr_el2 + mrs x0, actlr_el2 + ret + + +func read_actlr_el3 + mrs x0, actlr_el3 + ret + + +func write_actlr_el1 + msr actlr_el1, x0 + ret + + +func write_actlr_el2 + msr actlr_el2, x0 + ret + + +func write_actlr_el3 + msr actlr_el3, x0 + ret + + + /* ----------------------------------------------------- + * ESR accessors + * ----------------------------------------------------- + */ +func read_esr_el1 + mrs x0, esr_el1 + ret + + +func read_esr_el2 + mrs x0, esr_el2 + ret + + +func read_esr_el3 + mrs x0, esr_el3 + ret + + +func write_esr_el1 + msr esr_el1, x0 + ret + + +func write_esr_el2 + msr esr_el2, x0 + ret + + +func write_esr_el3 + msr esr_el3, x0 + ret + + + /* ----------------------------------------------------- + * TCR accessors + * ----------------------------------------------------- + */ +func read_tcr_el1 + mrs x0, tcr_el1 + ret + + +func read_tcr_el2 + mrs x0, tcr_el2 + ret + + +func read_tcr_el3 + mrs x0, tcr_el3 + ret + + +func write_tcr_el1 + msr tcr_el1, x0 + ret + + +func write_tcr_el2 + msr tcr_el2, x0 + ret + + +func write_tcr_el3 + msr tcr_el3, x0 + ret + + + /* ----------------------------------------------------- + * CPTR accessors + * ----------------------------------------------------- + */ +func read_cptr_el2 + mrs x0, cptr_el2 + ret + + +func read_cptr_el3 + mrs x0, cptr_el3 + ret + + +func write_cptr_el2 + msr cptr_el2, x0 + ret + + +func write_cptr_el3 + msr cptr_el3, x0 + ret + + + /* ----------------------------------------------------- + * TTBR0 accessors + * ----------------------------------------------------- + */ +func read_ttbr0_el1 + mrs x0, ttbr0_el1 + ret + + +func read_ttbr0_el2 + mrs x0, ttbr0_el2 + ret + + +func read_ttbr0_el3 + mrs x0, ttbr0_el3 + ret + + +func write_ttbr0_el1 + msr ttbr0_el1, x0 + ret + + +func write_ttbr0_el2 + msr ttbr0_el2, x0 + ret + + +func write_ttbr0_el3 + msr ttbr0_el3, x0 + ret + + + /* ----------------------------------------------------- + * TTBR1 accessors + * ----------------------------------------------------- + */ +func read_ttbr1_el1 + mrs x0, ttbr1_el1 + ret + + +func write_ttbr1_el1 + msr ttbr1_el1, x0 + ret + + +func read_hcr + mrs x0, hcr_el2 + ret + + +func write_hcr + msr hcr_el2, x0 + ret + + +func read_cpacr + mrs x0, cpacr_el1 + ret + + +func write_cpacr + msr cpacr_el1, x0 + ret + + +func read_cntfrq_el0 + mrs x0, cntfrq_el0 + ret + + +func write_cntfrq_el0 + msr cntfrq_el0, x0 + ret + +func read_cntps_ctl_el1 + mrs x0, cntps_ctl_el1 + ret + +func write_cntps_ctl_el1 + msr cntps_ctl_el1, x0 + ret + +func read_cntps_cval_el1 + mrs x0, cntps_cval_el1 + ret + +func write_cntps_cval_el1 + msr cntps_cval_el1, x0 + ret + +func read_cntps_tval_el1 + mrs x0, cntps_tval_el1 + ret + +func write_cntps_tval_el1 + msr cntps_tval_el1, x0 + ret + +func read_cntpct_el0 + mrs x0, cntpct_el0 + ret + +func read_cpuectlr + mrs x0, CPUECTLR_EL1 + ret + + +func write_cpuectlr + msr CPUECTLR_EL1, x0 + ret + + +func read_cnthctl_el2 + mrs x0, cnthctl_el2 + ret + + +func write_cnthctl_el2 + msr cnthctl_el2, x0 + ret + + +func read_cntfrq + mrs x0, cntfrq_el0 + ret + + +func write_cntfrq + msr cntfrq_el0, x0 + ret + + +func write_scr + msr scr_el3, x0 + ret + + +func read_scr + mrs x0, scr_el3 + ret + + +func read_midr + mrs x0, midr_el1 + ret + + +func read_mpidr + mrs x0, mpidr_el1 + ret + +func write_tpidr_el3 + msr tpidr_el3, x0 + ret + +func read_tpidr_el3 + mrs x0, tpidr_el3 + ret + +#if SUPPORT_VFP +func enable_vfp + mrs x0, cpacr_el1 + orr x0, x0, #CPACR_VFP_BITS + msr cpacr_el1, x0 + mrs x0, cptr_el3 + mov x1, #AARCH64_CPTR_TFP + bic x0, x0, x1 + msr cptr_el3, x0 + isb + ret + +#endif diff --git a/lib/aarch64/tlb_helpers.S b/lib/aarch64/tlb_helpers.S new file mode 100644 index 0000000..8dfae12 --- /dev/null +++ b/lib/aarch64/tlb_helpers.S @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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_macros.S> + + .globl tlbialle1 + .globl tlbialle1is + .globl tlbialle2 + .globl tlbialle2is + .globl tlbialle3 + .globl tlbialle3is + .globl tlbivmalle1 + + +func tlbialle1 + tlbi alle1 + ret + + +func tlbialle1is + tlbi alle1is + ret + + +func tlbialle2 + tlbi alle2 + ret + + +func tlbialle2is + tlbi alle2is + ret + + +func tlbialle3 + tlbi alle3 + ret + + +func tlbialle3is + tlbi alle3is + ret + +func tlbivmalle1 + tlbi vmalle1 + ret diff --git a/lib/aarch64/xlat_helpers.c b/lib/aarch64/xlat_helpers.c new file mode 100644 index 0000000..d401ffc --- /dev/null +++ b/lib/aarch64/xlat_helpers.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <assert.h> + +/******************************************************************************* + * Helper to create a level 1/2 table descriptor which points to a level 2/3 + * table. + ******************************************************************************/ +unsigned long create_table_desc(unsigned long *next_table_ptr) +{ + unsigned long desc = (unsigned long) next_table_ptr; + + /* Clear the last 12 bits */ + desc >>= FOUR_KB_SHIFT; + desc <<= FOUR_KB_SHIFT; + + desc |= TABLE_DESC; + + return desc; +} + +/******************************************************************************* + * Helper to create a level 1/2/3 block descriptor which maps the va to addr + ******************************************************************************/ +unsigned long create_block_desc(unsigned long desc, + unsigned long addr, + unsigned int level) +{ + switch (level) { + case LEVEL1: + desc |= (addr << FIRST_LEVEL_DESC_N) | BLOCK_DESC; + break; + case LEVEL2: + desc |= (addr << SECOND_LEVEL_DESC_N) | BLOCK_DESC; + break; + case LEVEL3: + desc |= (addr << THIRD_LEVEL_DESC_N) | TABLE_DESC; + break; + default: + assert(0); + } + + return desc; +} + +/******************************************************************************* + * Helper to create a level 1/2/3 block descriptor which maps the va to output_ + * addr with Device nGnRE attributes. + ******************************************************************************/ +unsigned long create_device_block(unsigned long output_addr, + unsigned int level, + unsigned int ns) +{ + unsigned long upper_attrs, lower_attrs, desc; + + lower_attrs = LOWER_ATTRS(ACCESS_FLAG | OSH | AP_RW); + lower_attrs |= LOWER_ATTRS(ns | ATTR_DEVICE_INDEX); + upper_attrs = UPPER_ATTRS(XN); + desc = upper_attrs | lower_attrs; + + return create_block_desc(desc, output_addr, level); +} + +/******************************************************************************* + * Helper to create a level 1/2/3 block descriptor which maps the va to output_ + * addr with inner-shareable normal wbwa read-only memory attributes. + ******************************************************************************/ +unsigned long create_romem_block(unsigned long output_addr, + unsigned int level, + unsigned int ns) +{ + unsigned long upper_attrs, lower_attrs, desc; + + lower_attrs = LOWER_ATTRS(ACCESS_FLAG | ISH | AP_RO); + lower_attrs |= LOWER_ATTRS(ns | ATTR_IWBWA_OWBWA_NTR_INDEX); + upper_attrs = UPPER_ATTRS(0ull); + desc = upper_attrs | lower_attrs; + + return create_block_desc(desc, output_addr, level); +} + +/******************************************************************************* + * Helper to create a level 1/2/3 block descriptor which maps the va to output_ + * addr with inner-shareable normal wbwa read-write memory attributes. + ******************************************************************************/ +unsigned long create_rwmem_block(unsigned long output_addr, + unsigned int level, + unsigned int ns) +{ + unsigned long upper_attrs, lower_attrs, desc; + + lower_attrs = LOWER_ATTRS(ACCESS_FLAG | ISH | AP_RW); + lower_attrs |= LOWER_ATTRS(ns | ATTR_IWBWA_OWBWA_NTR_INDEX); + upper_attrs = UPPER_ATTRS(XN); + desc = upper_attrs | lower_attrs; + + return create_block_desc(desc, output_addr, level); +} diff --git a/lib/aarch64/xlat_tables.c b/lib/aarch64/xlat_tables.c new file mode 100644 index 0000000..6e8df59 --- /dev/null +++ b/lib/aarch64/xlat_tables.c @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <platform_def.h> +#include <string.h> +#include <xlat_tables.h> +#include <stdio.h> +#include <fip.h> + +#ifndef DEBUG_XLAT_TABLE +#define DEBUG_XLAT_TABLE 0 +#endif + +#if DEBUG_XLAT_TABLE +#define debug_print(...) printf(__VA_ARGS__) +#else +#define debug_print(...) ((void)0) +#endif + + +#define UNSET_DESC ~0ul + +#define NUM_L1_ENTRIES (ADDR_SPACE_SIZE >> L1_XLAT_ADDRESS_SHIFT) + +static uint64_t l1_xlation_table[NUM_L1_ENTRIES] +__aligned(NUM_L1_ENTRIES * sizeof(uint64_t)); + +static uint64_t **xlat_tables; +//__aligned(XLAT_TABLE_SIZE) __attribute__((section("xlat_table"))); + +static unsigned next_xlat; + +/* + * Array of all memory regions stored in order of ascending base address. + * The list is terminated by the first entry with size == 0. + */ +static mmap_region_t mmap[MAX_MMAP_REGIONS + 1]; + +static void print_mmap(void) +{ +#if DEBUG_XLAT_TABLE + debug_print("mmap:\n"); + mmap_region_t *mm = mmap; + while (mm->size) { + debug_print(" %010lx %10lx %x\n", mm->base, mm->size, mm->attr); + ++mm; + }; + debug_print("\n"); +#endif +} + +void mmap_add_region(unsigned long base, unsigned long size, unsigned attr) +{ + mmap_region_t *mm = mmap; + mmap_region_t *mm_last = mm + sizeof(mmap) / sizeof(mmap[0]) - 1; + + assert(IS_PAGE_ALIGNED(base)); + assert(IS_PAGE_ALIGNED(size)); + + if (!size) + return; + + /* Find correct place in mmap to insert new region */ + while (mm->base < base && mm->size) + ++mm; + + /* Make room for new region by moving other regions up by one place */ + memmove(mm + 1, mm, (uintptr_t)mm_last - (uintptr_t)mm); + + /* Check we haven't lost the empty sentinal from the end of the array */ + assert(mm_last->size == 0); + + mm->base = base; + mm->size = size; + mm->attr = attr; +} + +void mmap_add(const mmap_region_t *mm) +{ + while (mm->size) { + mmap_add_region(mm->base, mm->size, mm->attr); + ++mm; + } +} + +static unsigned long mmap_desc(unsigned attr, unsigned long addr, + unsigned level) +{ + unsigned long desc = addr; + + desc |= level == 3 ? TABLE_DESC : BLOCK_DESC; + + desc |= attr & MT_NS ? LOWER_ATTRS(NS) : 0; + + desc |= attr & MT_RW ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO); + + desc |= LOWER_ATTRS(ACCESS_FLAG); + + if (attr & MT_MEMORY) { + desc |= LOWER_ATTRS(ATTR_IWBWA_OWBWA_NTR_INDEX | ISH); + if (attr & MT_RW) + desc |= UPPER_ATTRS(XN); + } else { + desc |= LOWER_ATTRS(ATTR_DEVICE_INDEX | OSH); + desc |= UPPER_ATTRS(XN); + } + + debug_print(attr & MT_MEMORY ? "MEM" : "DEV"); + debug_print(attr & MT_RW ? "-RW" : "-RO"); + debug_print(attr & MT_NS ? "-NS" : "-S"); + + return desc; +} + +static int mmap_region_attr(mmap_region_t *mm, unsigned long base, + unsigned long size) +{ + int attr = mm->attr; + + for (;;) { + ++mm; + + if (!mm->size) + return attr; /* Reached end of list */ + + if (mm->base >= base + size) + return attr; /* Next region is after area so end */ + + if (mm->base + mm->size <= base) + continue; /* Next region has already been overtaken */ + + if ((mm->attr & attr) == attr) + continue; /* Region doesn't override attribs so skip */ + + attr &= mm->attr; + + if (mm->base > base || mm->base + mm->size < base + size) + return -1; /* Region doesn't fully cover our area */ + } +} + +static mmap_region_t *init_xlation_table(mmap_region_t *mm, unsigned long base, + unsigned long *table, unsigned level) +{ + unsigned level_size_shift = L1_XLAT_ADDRESS_SHIFT - (level - 1) * + XLAT_TABLE_ENTRIES_SHIFT; + unsigned level_size = 1 << level_size_shift; + unsigned long level_index_mask = XLAT_TABLE_ENTRIES_MASK << level_size_shift; + + assert(level <= 3); + + debug_print("New xlat table:\n"); + + do { + unsigned long desc = UNSET_DESC; + + if (mm->base + mm->size <= base) { + /* Area now after the region so skip it */ + ++mm; + continue; + } + + debug_print(" %010lx %8lx " + 6 - 2 * level, base, level_size); + + if (mm->base >= base + level_size) { + /* Next region is after area so nothing to map yet */ + desc = INVALID_DESC; + } else if (mm->base <= base && + mm->base + mm->size >= base + level_size) { + /* Next region covers all of area */ + int attr = mmap_region_attr(mm, base, level_size); + if (attr >= 0) + desc = mmap_desc(attr, base, level); + } + /* else Next region only partially covers area, so need */ + + if (desc == UNSET_DESC) { + /* Area not covered by a region so need finer table */ + unsigned long *new_table = xlat_tables[next_xlat++]; + assert(next_xlat <= MAX_XLAT_TABLES); + desc = TABLE_DESC | (unsigned long)new_table; + + /* Recurse to fill in new table */ + mm = init_xlation_table(mm, base, new_table, level+1); + } + + debug_print("\n"); + + *table++ = desc; + base += level_size; + } while (mm->size && (base & level_index_mask)); + + return mm; +} + +void init_xlat_tables(void) +{ + /* move mmu table to ddr*/ + memset((void *)MMU_TABLE_BASE, 0, MMU_TABLE_SIZE); + uint64_t * xlat_tables_x[MAX_XLAT_TABLES] = {0}; + uint32_t loop = 0; + for (loop=0; loop<MAX_XLAT_TABLES; loop++) { + xlat_tables_x[loop] = (uint64_t *)(uint64_t)(MMU_TABLE_BASE + loop * MMU_TABLE_SIZE); + } + xlat_tables = xlat_tables_x; + + print_mmap(); + init_xlation_table(mmap, 0, l1_xlation_table, 1); +} + +/******************************************************************************* + * Macro generating the code for the function enabling the MMU in the given + * exception level, assuming that the pagetables have already been created. + * + * _el: Exception level at which the function will run + * _tcr_extra: Extra bits to set in the TCR register. This mask will + * be OR'ed with the default TCR value. + * _tlbi_fct: Function to invalidate the TLBs at the current + * exception level + ******************************************************************************/ +#define DEFINE_ENABLE_MMU_EL(_el, _tcr_extra, _tlbi_fct) \ + void enable_mmu_el##_el(void) \ + { \ + uint64_t mair, tcr, ttbr; \ + uint32_t sctlr; \ + \ + assert(IS_IN_EL(_el)); \ + assert((read_sctlr_el##_el() & SCTLR_M_BIT) == 0); \ + \ + /* Set attributes in the right indices of the MAIR */ \ + mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); \ + mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, \ + ATTR_IWBWA_OWBWA_NTR_INDEX); \ + write_mair_el##_el(mair); \ + \ + /* Invalidate TLBs at the current exception level */ \ + _tlbi_fct(); \ + \ + /* Set TCR bits as well. */ \ + /* Inner & outer WBWA & shareable + T0SZ = 32 */ \ + tcr = TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA | \ + TCR_RGN_INNER_WBA | TCR_T0SZ_4GB; \ + tcr |= _tcr_extra; \ + write_tcr_el##_el(tcr); \ + \ + /* Set TTBR bits as well */ \ + ttbr = (uint64_t) l1_xlation_table; \ + write_ttbr0_el##_el(ttbr); \ + \ + /* Ensure all translation table writes have drained */ \ + /* into memory, the TLB invalidation is complete, */ \ + /* and translation register writes are committed */ \ + /* before enabling the MMU */ \ + dsb(); \ + isb(); \ + \ + sctlr = read_sctlr_el##_el(); \ + sctlr |= SCTLR_WXN_BIT | SCTLR_I_BIT; \ + sctlr |= SCTLR_A_BIT | SCTLR_C_BIT; \ + write_sctlr_el##_el(sctlr); \ + \ + /* Ensure the MMU enable takes effect immediately */ \ + isb(); \ + } + +/* Define EL1 and EL3 variants of the function enabling the MMU */ +DEFINE_ENABLE_MMU_EL(1, 0, tlbivmalle1) +DEFINE_ENABLE_MMU_EL(3, TCR_EL3_RES1, tlbialle3) diff --git a/lib/io_storage.c b/lib/io_storage.c new file mode 100644 index 0000000..204310a --- /dev/null +++ b/lib/io_storage.c @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <io_driver.h> +#include <io_storage.h> +#include <stddef.h> + + +#define MAX_DEVICES(plat_data) \ + (sizeof((plat_data)->devices)/sizeof((plat_data)->devices[0])) + + +/* Storage for a fixed maximum number of IO entities, definable by platform */ +static io_entity_t entity_pool[MAX_IO_HANDLES]; + +/* Simple way of tracking used storage - each entry is NULL or a pointer to an + * entity */ +static io_entity_t *entity_map[MAX_IO_HANDLES]; + +/* Track number of allocated entities */ +static unsigned int entity_count; + + +/* Used to keep a reference to platform-specific data */ +static io_plat_data_t *platform_data; + + +#if DEBUG /* Extra validation functions only used in debug builds */ + +/* Return a boolean value indicating whether a device connector is valid */ +static int is_valid_dev_connector(const io_dev_connector_t *dev_con) +{ + int result = (dev_con != NULL) && (dev_con->dev_open != NULL); + return result; +} + + +/* Return a boolean value indicating whether a device handle is valid */ +static int is_valid_dev(const uintptr_t dev_handle) +{ + const io_dev_info_t *dev = (io_dev_info_t *)dev_handle; + int result = (dev != NULL) && (dev->funcs != NULL) && + (dev->funcs->type != NULL) && + (dev->funcs->type() < IO_TYPE_MAX); + return result; +} + + +/* Return a boolean value indicating whether an IO entity is valid */ +static int is_valid_entity(const uintptr_t handle) +{ + const io_entity_t *entity = (io_entity_t *)handle; + int result = (entity != NULL) && + (is_valid_dev((uintptr_t)entity->dev_handle)); + return result; +} + + +/* Return a boolean value indicating whether a seek mode is valid */ +static int is_valid_seek_mode(io_seek_mode_t mode) +{ + return ((mode != IO_SEEK_INVALID) && (mode < IO_SEEK_MAX)); +} + +#endif /* End of debug-only validation functions */ + + +/* Open a connection to a specific device */ +static int dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec, + io_dev_info_t **dev_info) +{ + int result = IO_FAIL; + assert(dev_info != NULL); + assert(is_valid_dev_connector(dev_con)); + + result = dev_con->dev_open(dev_spec, dev_info); + return result; +} + + +/* Set a handle to track an entity */ +static void set_handle(uintptr_t *handle, io_entity_t *entity) +{ + assert(handle != NULL); + *handle = (uintptr_t)entity; +} + + +/* Locate an entity in the pool, specified by address */ +static int find_first_entity(const io_entity_t *entity, unsigned int *index_out) +{ + int result = IO_FAIL; + for (int index = 0; index < MAX_IO_HANDLES; ++index) { + if (entity_map[index] == entity) { + result = IO_SUCCESS; + *index_out = index; + break; + } + } + return result; +} + + +/* Allocate an entity from the pool and return a pointer to it */ +static int allocate_entity(io_entity_t **entity) +{ + int result = IO_FAIL; + assert(entity != NULL); + + if (entity_count < MAX_IO_HANDLES) { + unsigned int index = 0; + result = find_first_entity(NULL, &index); + assert(result == IO_SUCCESS); + *entity = entity_map[index] = &entity_pool[index]; + ++entity_count; + } else + result = IO_RESOURCES_EXHAUSTED; + + return result; +} + + +/* Release an entity back to the pool */ +static int free_entity(const io_entity_t *entity) +{ + int result = IO_FAIL; + unsigned int index = 0; + assert(entity != NULL); + + result = find_first_entity(entity, &index); + if (result == IO_SUCCESS) { + entity_map[index] = NULL; + --entity_count; + } + + return result; +} + + +/* Exported API */ + + +/* Initialise the IO layer */ +void io_init(io_plat_data_t *data) +{ + assert(data != NULL); + platform_data = data; +} + + +/* Register a device driver */ +int io_register_device(const io_dev_info_t *dev_info) +{ + int result = IO_FAIL; + assert(dev_info != NULL); + assert(platform_data != NULL); + + unsigned int dev_count = platform_data->dev_count; + + if (dev_count < MAX_DEVICES(platform_data)) { + platform_data->devices[dev_count] = dev_info; + platform_data->dev_count++; + result = IO_SUCCESS; + } else { + result = IO_RESOURCES_EXHAUSTED; + } + + return result; +} + + +/* Open a connection to an IO device */ +int io_dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec, + uintptr_t *handle) +{ + int result = IO_FAIL; + assert(handle != NULL); + + result = dev_open(dev_con, dev_spec, (io_dev_info_t **)handle); + return result; +} + + +/* Initialise an IO device explicitly - to permit lazy initialisation or + * re-initialisation */ +int io_dev_init(uintptr_t dev_handle, const uintptr_t init_params) +{ + int result = IO_FAIL; + assert(dev_handle != (uintptr_t)NULL); + assert(is_valid_dev(dev_handle)); + + io_dev_info_t *dev = (io_dev_info_t *)dev_handle; + + if (dev->funcs->dev_init != NULL) { + result = dev->funcs->dev_init(dev, init_params); + } else { + /* Absence of registered function implies NOP here */ + result = IO_SUCCESS; + } + return result; +} + + +/* TODO: Consider whether an explicit "shutdown" API should be included */ + +/* Close a connection to a device */ +int io_dev_close(uintptr_t dev_handle) +{ + int result = IO_FAIL; + assert(dev_handle != (uintptr_t)NULL); + assert(is_valid_dev(dev_handle)); + + io_dev_info_t *dev = (io_dev_info_t *)dev_handle; + + if (dev->funcs->dev_close != NULL) { + result = dev->funcs->dev_close(dev); + } else { + /* Absence of registered function implies NOP here */ + result = IO_SUCCESS; + } + + return result; +} + + +/* Synchronous operations */ + + +/* Open an IO entity */ +int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle) +{ + int result = IO_FAIL; + assert((spec != (uintptr_t)NULL) && (handle != NULL)); + assert(is_valid_dev(dev_handle)); + + io_dev_info_t *dev = (io_dev_info_t *)dev_handle; + io_entity_t *entity; + + result = allocate_entity(&entity); + + if (result == IO_SUCCESS) { + assert(dev->funcs->open != NULL); + result = dev->funcs->open(dev, spec, entity); + + if (result == IO_SUCCESS) { + entity->dev_handle = dev; + set_handle(handle, entity); + } else + free_entity(entity); + } + return result; +} + + +/* Seek to a specific position in an IO entity */ +int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle) && is_valid_seek_mode(mode)); + + io_entity_t *entity = (io_entity_t *)handle; + + io_dev_info_t *dev = entity->dev_handle; + + if (dev->funcs->seek != NULL) + result = dev->funcs->seek(entity, mode, offset); + else + result = IO_NOT_SUPPORTED; + + return result; +} + + +/* Determine the length of an IO entity */ +int io_size(uintptr_t handle, size_t *length) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle) && (length != NULL)); + + io_entity_t *entity = (io_entity_t *)handle; + + io_dev_info_t *dev = entity->dev_handle; + + if (dev->funcs->size != NULL) + result = dev->funcs->size(entity, length); + else + result = IO_NOT_SUPPORTED; + + return result; +} + + +/* Read data from an IO entity */ +int io_read(uintptr_t handle, + uintptr_t buffer, + size_t length, + size_t *length_read) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle) && (buffer != (uintptr_t)NULL)); + + io_entity_t *entity = (io_entity_t *)handle; + + io_dev_info_t *dev = entity->dev_handle; + + if (dev->funcs->read != NULL) + result = dev->funcs->read(entity, buffer, length, length_read); + else + result = IO_NOT_SUPPORTED; + + return result; +} + + +/* Write data to an IO entity */ +int io_write(uintptr_t handle, + const uintptr_t buffer, + size_t length, + size_t *length_written) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle) && (buffer != (uintptr_t)NULL)); + + io_entity_t *entity = (io_entity_t *)handle; + + io_dev_info_t *dev = entity->dev_handle; + + if (dev->funcs->write != NULL) { + result = dev->funcs->write(entity, buffer, length, + length_written); + } else + result = IO_NOT_SUPPORTED; + + return result; +} + + +/* Close an IO entity */ +int io_close(uintptr_t handle) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle)); + + io_entity_t *entity = (io_entity_t *)handle; + + io_dev_info_t *dev = entity->dev_handle; + + if (dev->funcs->close != NULL) + result = dev->funcs->close(entity); + else { + /* Absence of registered function implies NOP here */ + result = IO_SUCCESS; + } + /* Ignore improbable free_entity failure */ + (void)free_entity(entity); + + return result; +} diff --git a/lib/locks/bakery/bakery_lock.c b/lib/locks/bakery/bakery_lock.c new file mode 100644 index 0000000..4e148b5 --- /dev/null +++ b/lib/locks/bakery/bakery_lock.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bakery_lock.h> +#include <platform.h> +#include <string.h> + +/* + * Functions in this file implement Bakery Algorithm for mutual exclusion. + * + * ARM architecture offers a family of exclusive access instructions to + * efficiently implement mutual exclusion with hardware support. However, as + * well as depending on external hardware, the these instructions have defined + * behavior only on certain memory types (cacheable and Normal memory in + * particular; see ARMv8 Architecture Reference Manual section B2.10). Use cases + * in trusted firmware are such that mutual exclusion implementation cannot + * expect that accesses to the lock have the specific type required by the + * architecture for these primitives to function (for example, not all + * contenders may have address translation enabled). + * + * This implementation does not use mutual exclusion primitives. It expects + * memory regions where the locks reside to be fully ordered and coherent + * (either by disabling address translation, or by assigning proper attributes + * when translation is enabled). + * + * Note that the ARM architecture guarantees single-copy atomicity for aligned + * accesses regardless of status of address translation. + */ + +#define assert_bakery_entry_valid(entry, bakery) do { \ + assert(bakery); \ + assert(entry < BAKERY_LOCK_MAX_CPUS); \ +} while (0) + +/* Convert a ticket to priority */ +#define PRIORITY(t, pos) (((t) << 8) | (pos)) + + +/* Initialize Bakery Lock to reset ownership and all ticket values */ +void bakery_lock_init(bakery_lock_t *bakery) +{ + assert(bakery); + + /* All ticket values need to be 0 */ + memset(bakery, 0, sizeof(*bakery)); + bakery->owner = NO_OWNER; +} + + +/* Obtain a ticket for a given CPU */ +static unsigned int bakery_get_ticket(bakery_lock_t *bakery, unsigned int me) +{ + unsigned int my_ticket, their_ticket; + unsigned int they; + + /* + * Flag that we're busy getting our ticket. All CPUs are iterated in the + * order of their ordinal position to decide the maximum ticket value + * observed so far. Our priority is set to be greater than the maximum + * observed priority + * + * Note that it's possible that more than one contender gets the same + * ticket value. That's OK as the lock is acquired based on the priority + * value, not the ticket value alone. + */ + my_ticket = 0; + bakery->entering[me] = 1; + for (they = 0; they < BAKERY_LOCK_MAX_CPUS; they++) { + their_ticket = bakery->number[they]; + if (their_ticket > my_ticket) + my_ticket = their_ticket; + } + + /* + * Compute ticket; then signal to other contenders waiting for us to + * finish calculating our ticket value that we're done + */ + ++my_ticket; + bakery->number[me] = my_ticket; + bakery->entering[me] = 0; + sev(); + + return my_ticket; +} + + +/* + * Acquire bakery lock + * + * Contending CPUs need first obtain a non-zero ticket and then calculate + * priority value. A contending CPU iterate over all other CPUs in the platform, + * which may be contending for the same lock, in the order of their ordinal + * position (CPU0, CPU1 and so on). A non-contending CPU will have its ticket + * (and priority) value as 0. The contending CPU compares its priority with that + * of others'. The CPU with the highest priority (lowest numerical value) + * acquires the lock + */ +void bakery_lock_get(unsigned long mpidr, bakery_lock_t *bakery) +{ + unsigned int they, me; + unsigned int my_ticket, my_prio, their_ticket; + + me = platform_get_core_pos(mpidr); + + assert_bakery_entry_valid(me, bakery); + + /* Prevent recursive acquisition */ + assert(bakery->owner != me); + + /* Get a ticket */ + my_ticket = bakery_get_ticket(bakery, me); + + /* + * Now that we got our ticket, compute our priority value, then compare + * with that of others, and proceed to acquire the lock + */ + my_prio = PRIORITY(my_ticket, me); + for (they = 0; they < BAKERY_LOCK_MAX_CPUS; they++) { + if (me == they) + continue; + + /* Wait for the contender to get their ticket */ + while (bakery->entering[they]) + wfe(); + + /* + * If the other party is a contender, they'll have non-zero + * (valid) ticket value. If they do, compare priorities + */ + their_ticket = bakery->number[they]; + if (their_ticket && (PRIORITY(their_ticket, they) < my_prio)) { + /* + * They have higher priority (lower value). Wait for + * their ticket value to change (either release the lock + * to have it dropped to 0; or drop and probably content + * again for the same lock to have an even higher value) + */ + do { + wfe(); + } while (their_ticket == bakery->number[they]); + } + } + + /* Lock acquired */ + bakery->owner = me; +} + + +/* Release the lock and signal contenders */ +void bakery_lock_release(unsigned long mpidr, bakery_lock_t *bakery) +{ + unsigned int me = platform_get_core_pos(mpidr); + + assert_bakery_entry_valid(me, bakery); + assert(bakery->owner == me); + + /* + * Release lock by resetting ownership and ticket. Then signal other + * waiting contenders + */ + bakery->owner = NO_OWNER; + bakery->number[me] = 0; + sev(); +} diff --git a/lib/locks/exclusive/spinlock.S b/lib/locks/exclusive/spinlock.S new file mode 100644 index 0000000..5eae2b0 --- /dev/null +++ b/lib/locks/exclusive/spinlock.S @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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_macros.S> + + .globl spin_lock + .globl spin_unlock + + +func spin_lock + mov w2, #1 + sevl +l1: wfe +l2: ldaxr w1, [x0] + cbnz w1, l1 + stxr w1, w2, [x0] + cbnz w1, l2 + ret + + +func spin_unlock + stlr wzr, [x0] + ret diff --git a/lib/mmio.c b/lib/mmio.c new file mode 100644 index 0000000..1350609 --- /dev/null +++ b/lib/mmio.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdint.h> + +void mmio_write_8(uintptr_t addr, uint8_t value) +{ + *(volatile uint8_t*)addr = value; +} + +uint8_t mmio_read_8(uintptr_t addr) +{ + return *(volatile uint8_t*)addr; +} + +void mmio_write_32(uintptr_t addr, uint32_t value) +{ + *(volatile uint32_t*)addr = value; +} + +uint32_t mmio_read_32(uintptr_t addr) +{ + return *(volatile uint32_t*)addr; +} + +void mmio_write_64(uintptr_t addr, uint64_t value) +{ + *(volatile uint64_t*)addr = value; +} + +uint64_t mmio_read_64(uintptr_t addr) +{ + return *(volatile uint64_t*)addr; +} diff --git a/lib/semihosting/aarch64/semihosting_call.S b/lib/semihosting/aarch64/semihosting_call.S new file mode 100644 index 0000000..e6a9675 --- /dev/null +++ b/lib/semihosting/aarch64/semihosting_call.S @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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_macros.S> + + .globl semihosting_call + +func semihosting_call + hlt #0xf000 + ret diff --git a/lib/semihosting/semihosting.c b/lib/semihosting/semihosting.c new file mode 100644 index 0000000..849ec12 --- /dev/null +++ b/lib/semihosting/semihosting.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <errno.h> +#include <semihosting.h> +#include <string.h> + +#ifndef SEMIHOSTING_SUPPORTED +#define SEMIHOSTING_SUPPORTED 1 +#endif + +long semihosting_call(unsigned long operation, + void *system_block_address); + +typedef struct { + const char *file_name; + unsigned long mode; + size_t name_length; +} smh_file_open_block_t; + +typedef struct { + long handle; + uintptr_t buffer; + size_t length; +} smh_file_read_write_block_t; + +typedef struct { + long handle; + ssize_t location; +} smh_file_seek_block_t; + +typedef struct { + char *command_line; + size_t command_length; +} smh_system_block_t; + +long semihosting_connection_supported(void) +{ + return SEMIHOSTING_SUPPORTED; +} + +long semihosting_file_open(const char *file_name, size_t mode) +{ + smh_file_open_block_t open_block; + + open_block.file_name = file_name; + open_block.mode = mode; + open_block.name_length = strlen(file_name); + + return semihosting_call(SEMIHOSTING_SYS_OPEN, + (void *) &open_block); +} + +long semihosting_file_seek(long file_handle, ssize_t offset) +{ + smh_file_seek_block_t seek_block; + long result; + + seek_block.handle = file_handle; + seek_block.location = offset; + + result = semihosting_call(SEMIHOSTING_SYS_SEEK, + (void *) &seek_block); + + if (result) + result = semihosting_call(SEMIHOSTING_SYS_ERRNO, 0); + + return result; +} + +long semihosting_file_read(long file_handle, size_t *length, uintptr_t buffer) +{ + smh_file_read_write_block_t read_block; + long result = -EINVAL; + + if ((length == NULL) || (buffer == (uintptr_t)NULL)) + return result; + + read_block.handle = file_handle; + read_block.buffer = buffer; + read_block.length = *length; + + result = semihosting_call(SEMIHOSTING_SYS_READ, + (void *) &read_block); + + if (result == *length) { + return -EINVAL; + } else if (result < *length) { + *length -= result; + return 0; + } else + return result; +} + +long semihosting_file_write(long file_handle, + size_t *length, + const uintptr_t buffer) +{ + smh_file_read_write_block_t write_block; + + if ((length == NULL) || (buffer == (uintptr_t)NULL)) + return -EINVAL; + + write_block.handle = file_handle; + write_block.buffer = (uintptr_t)buffer; /* cast away const */ + write_block.length = *length; + + *length = semihosting_call(SEMIHOSTING_SYS_WRITE, + (void *) &write_block); + + return *length; +} + +long semihosting_file_close(long file_handle) +{ + return semihosting_call(SEMIHOSTING_SYS_CLOSE, + (void *) &file_handle); +} + +long semihosting_file_length(long file_handle) +{ + return semihosting_call(SEMIHOSTING_SYS_FLEN, + (void *) &file_handle); +} + +char semihosting_read_char(void) +{ + return semihosting_call(SEMIHOSTING_SYS_READC, NULL); +} + +void semihosting_write_char(char character) +{ + semihosting_call(SEMIHOSTING_SYS_WRITEC, (void *) &character); +} + +void semihosting_write_string(char *string) +{ + semihosting_call(SEMIHOSTING_SYS_WRITE0, (void *) string); +} + +long semihosting_system(char *command_line) +{ + smh_system_block_t system_block; + + system_block.command_line = command_line; + system_block.command_length = strlen(command_line); + + return semihosting_call(SEMIHOSTING_SYS_SYSTEM, + (void *) &system_block); +} + +long semihosting_get_flen(const char *file_name) +{ + long file_handle; + size_t length; + + assert(semihosting_connection_supported()); + + file_handle = semihosting_file_open(file_name, FOPEN_MODE_RB); + if (file_handle == -1) + return file_handle; + + /* Find the length of the file */ + length = semihosting_file_length(file_handle); + + return semihosting_file_close(file_handle) ? -1 : length; +} + +long semihosting_download_file(const char *file_name, + size_t buf_size, + uintptr_t buf) +{ + long ret = -EINVAL; + size_t length; + long file_handle; + + /* Null pointer check */ + if (!buf) + return ret; + + assert(semihosting_connection_supported()); + + file_handle = semihosting_file_open(file_name, FOPEN_MODE_RB); + if (file_handle == -1) + return ret; + + /* Find the actual length of the file */ + length = semihosting_file_length(file_handle); + if (length == -1) + goto semihosting_fail; + + /* Signal error if we do not have enough space for the file */ + if (length > buf_size) + goto semihosting_fail; + + /* + * A successful read will return 0 in which case we pass back + * the actual number of bytes read. Else we pass a negative + * value indicating an error. + */ + ret = semihosting_file_read(file_handle, &length, buf); + if (ret) + goto semihosting_fail; + else + ret = length; + +semihosting_fail: + semihosting_file_close(file_handle); + return ret; +} diff --git a/lib/stdlib/abort.c b/lib/stdlib/abort.c new file mode 100644 index 0000000..1b06132 --- /dev/null +++ b/lib/stdlib/abort.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <stdio.h> + +/* + * This is a basic implementation. This could be improved. + */ +void abort (void) +{ + serial_puts("ABORT\n\r"); + while (1) ; +} diff --git a/lib/stdlib/assert.c b/lib/stdlib/assert.c new file mode 100644 index 0000000..0a5ae43 --- /dev/null +++ b/lib/stdlib/assert.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <stdio.h> + +/* + * This is a basic implementation. This could be improved. + */ +void __assert (const char *function, const char *file, unsigned int line, + const char *assertion) +{ + serial_puts("ASSERT: "); + serial_puts(function); + serial_puts(" <"); + serial_put_dec(line); + serial_puts("> : "); + serial_puts(assertion); + serial_puts("\n\r"); + while (1) ; +} diff --git a/lib/stdlib/mem.c b/lib/stdlib/mem.c new file mode 100644 index 0000000..f1f335a --- /dev/null +++ b/lib/stdlib/mem.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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> /* size_t */ + +/* + * Fill @count bytes of memory pointed to by @dst with @val + */ +void *memset(void *dst, int val, size_t count) +{ + char *ptr = dst; + + while (count--) + *ptr++ = val; + + return dst; +} + +/* + * Compare @len bytes of @s1 and @s2 + */ +int memcmp(const void *s1, const void *s2, size_t len) +{ + const char *s = s1; + const char *d = s2; + char dc; + char sc; + + while (len--) { + sc = *s++; + dc = *d++; + if (sc - dc) + return (sc - dc); + } + + return 0; +} + +/* + * Copy @len bytes from @src to @dst + */ +void *memcpy(void *dst, const void *src, size_t len) +{ + const char *s = src; + char *d = dst; + + while (len--) + *d++ = *s++; + + return dst; +} + +/* + * Move @len bytes from @src to @dst + */ +void *memmove(void *dst, const void *src, size_t len) +{ + /* + * The following test makes use of unsigned arithmetic overflow to + * more efficiently test the condition !(src <= dst && dst < str+len). + * It also avoids the situation where the more explicit test would give + * incorrect results were the calculation str+len to overflow (though + * that issue is probably moot as such usage is probably undefined + * behaviour and a bug anyway. + */ + if ((size_t)dst - (size_t)src >= len) { + /* destination not in source data, so can safely use memcpy */ + return memcpy(dst, src, len); + } else { + /* copy backwards... */ + const char *end = dst; + const char *s = (const char *)src + len; + char *d = (char *)dst + len; + while (d != end) + *--d = *--s; + } + return dst; +} + +/* + * Scan @len bytes of @src for value @c + */ +void *memchr(const void *src, int c, size_t len) +{ + const char *s = src; + + while (len--) { + if (*s == c) + return (void *) s; + s++; + } + + return NULL; +} diff --git a/lib/stdlib/printf.c b/lib/stdlib/printf.c new file mode 100644 index 0000000..d339668 --- /dev/null +++ b/lib/stdlib/printf.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <stdio.h> +#include <stdarg.h> + +#ifdef ENABLE_PRINTF +/* Choose max of 128 chars for now. */ +#define PRINT_BUFFER_SIZE 128 +int printf(const char *fmt, ...) +{ + va_list args; + char buf[PRINT_BUFFER_SIZE]; + int count; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf) - 1, fmt, args); + va_end(args); + + /* Use putchar directly as 'puts()' adds a newline. */ + buf[PRINT_BUFFER_SIZE - 1] = '\0'; + count = 0; + while (buf[count]) + { + if (putchar(buf[count]) != EOF) { + count++; + } else { + count = EOF; + break; + } + } + + return count; +} +#endif
\ No newline at end of file diff --git a/lib/stdlib/putchar.c b/lib/stdlib/putchar.c new file mode 100644 index 0000000..81375bb --- /dev/null +++ b/lib/stdlib/putchar.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <stdio.h> +#include <serial.h> + +/* Putchar() should either return the character printed or EOF in case of error. + * Our current console_putc() function assumes success and returns the + * character. Write all other printing functions in terms of putchar(), if + * possible, so they all benefit when this is improved. + */ +int putchar(int c) +{ + int res; + if (serial_putc((unsigned char)c) >= 0) + res = c; + else + res = EOF; + + return res; +} diff --git a/lib/stdlib/puts.c b/lib/stdlib/puts.c new file mode 100644 index 0000000..542902e --- /dev/null +++ b/lib/stdlib/puts.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <stdio.h> + +int puts(const char *s) +{ + int count = 0; + while (*s) + { + if (putchar(*s++) != EOF) { + count++; + } else { + count = EOF; + break; + } + } + + /* According to the puts(3) manpage, the function should write a + * trailing newline. + */ + if ((count != EOF) && (putchar('\n') != EOF)) + count++; + else + count = EOF; + + return count; +} diff --git a/lib/stdlib/std.c b/lib/stdlib/std.c new file mode 100644 index 0000000..4608754 --- /dev/null +++ b/lib/stdlib/std.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 the various implemented functions */ +#include "abort.c" +#include "assert.c" +#include "mem.c" +#include "printf.c" +#include "putchar.c" +#include "puts.c" +#include "strchr.c" +#include "strcmp.c" +#include "strlen.c" +#include "strncmp.c" +#include "subr_prf.c" diff --git a/lib/stdlib/strchr.c b/lib/stdlib/strchr.c new file mode 100644 index 0000000..4247dcd --- /dev/null +++ b/lib/stdlib/strchr.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +/* + * Portions copyright (c) 2013-2014, ARM Limited and Contributors. + * All rights reserved. + */ + +#include <sys/cdefs.h> +#include <stddef.h> +#include <string.h> + +char * +strchr(const char *p, int ch) +{ + char c; + + c = ch; + for (;; ++p) { + if (*p == c) + return ((char *)p); + if (*p == '\0') + return (NULL); + } + /* NOTREACHED */ +} diff --git a/lib/stdlib/strcmp.c b/lib/stdlib/strcmp.c new file mode 100644 index 0000000..1d26f2b --- /dev/null +++ b/lib/stdlib/strcmp.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +/* + * Portions copyright (c) 2014, ARM Limited and Contributors. + * All rights reserved. + */ + +#include <sys/cdefs.h> +#include <string.h> + +/* + * Compare strings. + */ +int +strcmp(const char *s1, const char *s2) +{ + while (*s1 == *s2++) + if (*s1++ == '\0') + return 0; + return *(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1); +} diff --git a/lib/stdlib/strlen.c b/lib/stdlib/strlen.c new file mode 100644 index 0000000..23c3d39 --- /dev/null +++ b/lib/stdlib/strlen.c @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +/* + * Portions copyright (c) 2009-2014, ARM Limited and Contributors. All rights reserved. + */ + +#include <stddef.h> + +size_t +strlen(str) + const char *str; +{ + register const char *s; + + for (s = str; *s; ++s); + return(s - str); +} diff --git a/lib/stdlib/strncmp.c b/lib/stdlib/strncmp.c new file mode 100644 index 0000000..f45f4a2 --- /dev/null +++ b/lib/stdlib/strncmp.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +/* + * Portions copyright (c) 2014, ARM Limited and Contributors. + * All rights reserved. + */ + +#include <sys/cdefs.h> +#include <string.h> + +int +strncmp(const char *s1, const char *s2, size_t n) +{ + + if (n == 0) + return 0; + do { + if (*s1 != *s2++) + return (*(const unsigned char *)s1 - + *(const unsigned char *)(s2 - 1)); + if (*s1++ == '\0') + break; + } while (--n != 0); + return 0; +} diff --git a/lib/stdlib/subr_prf.c b/lib/stdlib/subr_prf.c new file mode 100644 index 0000000..97d6fad --- /dev/null +++ b/lib/stdlib/subr_prf.c @@ -0,0 +1,552 @@ +/*- + * Copyright (c) 1986, 1988, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 + */ + +/* + * Portions copyright (c) 2009-2014, ARM Limited and Contributors. + * All rights reserved. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdarg.h> +#include <stddef.h> +#include <string.h> +#include <ctype.h> + +typedef unsigned char u_char; +typedef unsigned int u_int; +typedef int64_t quad_t; +typedef uint64_t u_quad_t; +typedef unsigned long u_long; +typedef unsigned short u_short; + +static inline int imax(int a, int b) { return (a > b ? a : b); } + +/* + * Note that stdarg.h and the ANSI style va_start macro is used for both + * ANSI and traditional C compilers. + */ + +#define TOCONS 0x01 +#define TOTTY 0x02 +#define TOLOG 0x04 + +/* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */ +#define MAXNBUF (sizeof(intmax_t) * 8 + 1) + +struct putchar_arg { + int flags; + int pri; + struct tty *tty; + char *p_bufr; + size_t n_bufr; + char *p_next; + size_t remain; +}; + +struct snprintf_arg { + char *str; + size_t remain; +}; + +extern int log_open; + +#ifdef ENABLE_PRINTF + +static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len, int upper); +static void snprintf_func(int ch, void *arg); +static int kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap); + +int vsnprintf(char *str, size_t size, const char *format, va_list ap); + +static char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz"; +#define hex2ascii(hex) (hex2ascii_data[hex]) + +/* + * Scaled down version of sprintf(3). + */ +int +sprintf(char *buf, const char *cfmt, ...) +{ + int retval; + va_list ap; + + va_start(ap, cfmt); + retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap); + buf[retval] = '\0'; + va_end(ap); + return (retval); +} + +/* + * Scaled down version of vsprintf(3). + */ +int +vsprintf(char *buf, const char *cfmt, va_list ap) +{ + int retval; + + retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap); + buf[retval] = '\0'; + return (retval); +} + +/* + * Scaled down version of snprintf(3). + */ +int +snprintf(char *str, size_t size, const char *format, ...) +{ + int retval; + va_list ap; + + va_start(ap, format); + retval = vsnprintf(str, size, format, ap); + va_end(ap); + return(retval); +} + +/* + * Scaled down version of vsnprintf(3). + */ +int +vsnprintf(char *str, size_t size, const char *format, va_list ap) +{ + struct snprintf_arg info; + int retval; + + info.str = str; + info.remain = size; + retval = kvprintf(format, snprintf_func, &info, 10, ap); + if (info.remain >= 1) + *info.str++ = '\0'; + return (retval); +} + +static void +snprintf_func(int ch, void *arg) +{ + struct snprintf_arg *const info = arg; + + if (info->remain >= 2) { + *info->str++ = ch; + info->remain--; + } +} + + +/* + * Kernel version which takes radix argument vsnprintf(3). + */ +int +vsnrprintf(char *str, size_t size, int radix, const char *format, va_list ap) +{ + struct snprintf_arg info; + int retval; + + info.str = str; + info.remain = size; + retval = kvprintf(format, snprintf_func, &info, radix, ap); + if (info.remain >= 1) + *info.str++ = '\0'; + return (retval); +} + + +/* + * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse + * order; return an optional length and a pointer to the last character + * written in the buffer (i.e., the first character of the string). + * The buffer pointed to by `nbuf' must have length >= MAXNBUF. + */ +static char * +ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper) +{ + char *p, c; + + p = nbuf; + *p = '\0'; + do { + c = hex2ascii(num % base); + *++p = upper ? toupper(c) : c; + } while (num /= base); + if (lenp) + *lenp = p - nbuf; + return (p); +} + +/* + * Scaled down version of printf(3). + * + * Two additional formats: + * + * The format %b is supported to decode error registers. + * Its usage is: + * + * printf("reg=%b\n", regval, "<base><arg>*"); + * + * where <base> is the output base expressed as a control character, e.g. + * \10 gives octal; \20 gives hex. Each arg is a sequence of characters, + * the first of which gives the bit number to be inspected (origin 1), and + * the next characters (up to a control character, i.e. a character <= 32), + * give the name of the register. Thus: + * + * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); + * + * would produce output: + * + * reg=3<BITTWO,BITONE> + * + * XXX: %D -- Hexdump, takes pointer and separator string: + * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX + * ("%*D", len, ptr, " " -> XX XX XX XX ... + */ +int +kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap) +{ +#define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; } + char nbuf[MAXNBUF]; + char *d; + const char *p, *percent, *q; + u_char *up; + int ch, n; + uintmax_t num; + int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; + int cflag, hflag, jflag, tflag, zflag; + int dwidth, upper; + char padc; + int stop = 0, retval = 0; + + num = 0; + if (!func) + d = (char *) arg; + else + d = NULL; + + if (fmt == NULL) + fmt = "(fmt null)\n"; + + if (radix < 2 || radix > 36) + radix = 10; + + for (;;) { + padc = ' '; + width = 0; + while ((ch = (u_char)*fmt++) != '%' || stop) { + if (ch == '\0') + return (retval); + PCHAR(ch); + } + percent = fmt - 1; + qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; + sign = 0; dot = 0; dwidth = 0; upper = 0; + cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0; +reswitch: switch (ch = (u_char)*fmt++) { + case '.': + dot = 1; + goto reswitch; + case '#': + sharpflag = 1; + goto reswitch; + case '+': + sign = 1; + goto reswitch; + case '-': + ladjust = 1; + goto reswitch; + case '%': + PCHAR(ch); + break; + case '*': + if (!dot) { + width = va_arg(ap, int); + if (width < 0) { + ladjust = !ladjust; + width = -width; + } + } else { + dwidth = va_arg(ap, int); + } + goto reswitch; + case '0': + if (!dot) { + padc = '0'; + goto reswitch; + } + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + for (n = 0;; ++fmt) { + n = n * 10 + ch - '0'; + ch = *fmt; + if (ch < '0' || ch > '9') + break; + } + if (dot) + dwidth = n; + else + width = n; + goto reswitch; + case 'b': + num = (u_int)va_arg(ap, int); + p = va_arg(ap, char *); + for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;) + PCHAR(*q--); + + if (num == 0) + break; + + for (tmp = 0; *p;) { + n = *p++; + if (num & (1 << (n - 1))) { + PCHAR(tmp ? ',' : '<'); + for (; (n = *p) > ' '; ++p) + PCHAR(n); + tmp = 1; + } else + for (; *p > ' '; ++p) + continue; + } + if (tmp) + PCHAR('>'); + break; + case 'c': + PCHAR(va_arg(ap, int)); + break; + case 'D': + up = va_arg(ap, u_char *); + p = va_arg(ap, char *); + if (!width) + width = 16; + while (width--) { + PCHAR(hex2ascii(*up >> 4)); + PCHAR(hex2ascii(*up & 0x0f)); + up++; + if (width) + for (q=p;*q;q++) + PCHAR(*q); + } + break; + case 'd': + case 'i': + base = 10; + sign = 1; + goto handle_sign; + case 'h': + if (hflag) { + hflag = 0; + cflag = 1; + } else + hflag = 1; + goto reswitch; + case 'j': + jflag = 1; + goto reswitch; + case 'l': + if (lflag) { + lflag = 0; + qflag = 1; + } else + lflag = 1; + goto reswitch; + case 'n': + if (jflag) + *(va_arg(ap, intmax_t *)) = retval; + else if (qflag) + *(va_arg(ap, quad_t *)) = retval; + else if (lflag) + *(va_arg(ap, long *)) = retval; + else if (zflag) + *(va_arg(ap, size_t *)) = retval; + else if (hflag) + *(va_arg(ap, short *)) = retval; + else if (cflag) + *(va_arg(ap, char *)) = retval; + else + *(va_arg(ap, int *)) = retval; + break; + case 'o': + base = 8; + goto handle_nosign; + case 'p': + base = 16; + sharpflag = (width == 0); + sign = 0; + num = (uintptr_t)va_arg(ap, void *); + goto number; + case 'q': + qflag = 1; + goto reswitch; + case 'r': + base = radix; + if (sign) + goto handle_sign; + goto handle_nosign; + case 's': + p = va_arg(ap, char *); + if (p == NULL) + p = "(null)"; + if (!dot) + n = strlen (p); + else + for (n = 0; n < dwidth && p[n]; n++) + continue; + + width -= n; + + if (!ladjust && width > 0) + while (width--) + PCHAR(padc); + while (n--) + PCHAR(*p++); + if (ladjust && width > 0) + while (width--) + PCHAR(padc); + break; + case 't': + tflag = 1; + goto reswitch; + case 'u': + base = 10; + goto handle_nosign; + case 'X': + upper = 1; + case 'x': + base = 16; + goto handle_nosign; + case 'y': + base = 16; + sign = 1; + goto handle_sign; + case 'z': + zflag = 1; + goto reswitch; +handle_nosign: + sign = 0; + if (jflag) + num = va_arg(ap, uintmax_t); + else if (qflag) + num = va_arg(ap, u_quad_t); + else if (tflag) + num = va_arg(ap, ptrdiff_t); + else if (lflag) + num = va_arg(ap, u_long); + else if (zflag) + num = va_arg(ap, size_t); + else if (hflag) + num = (u_short)va_arg(ap, int); + else if (cflag) + num = (u_char)va_arg(ap, int); + else + num = va_arg(ap, u_int); + goto number; +handle_sign: + if (jflag) + num = va_arg(ap, intmax_t); + else if (qflag) + num = va_arg(ap, quad_t); + else if (tflag) + num = va_arg(ap, ptrdiff_t); + else if (lflag) + num = va_arg(ap, long); + else if (zflag) + num = va_arg(ap, ssize_t); + else if (hflag) + num = (short)va_arg(ap, int); + else if (cflag) + num = (char)va_arg(ap, int); + else + num = va_arg(ap, int); +number: + if (sign && (intmax_t)num < 0) { + neg = 1; + num = -(intmax_t)num; + } + p = ksprintn(nbuf, num, base, &n, upper); + tmp = 0; + if (sharpflag && num != 0) { + if (base == 8) + tmp++; + else if (base == 16) + tmp += 2; + } + if (neg) + tmp++; + + if (!ladjust && padc == '0') + dwidth = width - tmp; + width -= tmp + imax(dwidth, n); + dwidth -= n; + if (!ladjust) + while (width-- > 0) + PCHAR(' '); + if (neg) + PCHAR('-'); + if (sharpflag && num != 0) { + if (base == 8) { + PCHAR('0'); + } else if (base == 16) { + PCHAR('0'); + PCHAR('x'); + } + } + while (dwidth-- > 0) + PCHAR('0'); + + while (*p) + PCHAR(*p--); + + if (ladjust) + while (width-- > 0) + PCHAR(' '); + + break; + default: + while (percent < fmt) + PCHAR(*percent++); + /* + * Since we ignore an formatting argument it is no + * longer safe to obey the remaining formatting + * arguments as the arguments will no longer match + * the format specs. + */ + stop = 1; + break; + } + } +#undef PCHAR +} + +#endif
\ No newline at end of file diff --git a/license.md b/license.md new file mode 100644 index 0000000..941b741 --- /dev/null +++ b/license.md @@ -0,0 +1,26 @@ +Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* 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. + +* Neither the name of ARM nor the names of its contributors may be used to + endorse or promote products derived from this software without specific prior + written permission. + +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. @@ -0,0 +1,5316 @@ + REALCLEAN + DEPS build/juno/debug/bl31/bl31.ld.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/bl31.ld -MF build/juno/debug/bl31/bl31.ld.d bl31/bl31.ld.S + DEPS build/juno/debug/bl31/sysreg_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/sysreg_helpers.o -MF build/juno/debug/bl31/sysreg_helpers.d lib/aarch64/sysreg_helpers.S + DEPS build/juno/debug/bl31/platform_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/platform_helpers.o -MF build/juno/debug/bl31/platform_helpers.d plat/common/aarch64/platform_helpers.S + DEPS build/juno/debug/bl31/tlb_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/tlb_helpers.o -MF build/juno/debug/bl31/tlb_helpers.d lib/aarch64/tlb_helpers.S + DEPS build/juno/debug/bl31/misc_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/misc_helpers.o -MF build/juno/debug/bl31/misc_helpers.d lib/aarch64/misc_helpers.S + DEPS build/juno/debug/bl31/cache_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/cache_helpers.o -MF build/juno/debug/bl31/cache_helpers.d lib/aarch64/cache_helpers.S + DEPS build/juno/debug/bl31/psci_entry.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/psci_entry.o -MF build/juno/debug/bl31/psci_entry.d services/std_svc/psci/psci_entry.S + DEPS build/juno/debug/bl31/spinlock.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/spinlock.o -MF build/juno/debug/bl31/spinlock.d lib/locks/exclusive/spinlock.S + DEPS build/juno/debug/bl31/cpu_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/cpu_helpers.o -MF build/juno/debug/bl31/cpu_helpers.d lib/aarch64/cpu_helpers.S + DEPS build/juno/debug/bl31/early_exceptions.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/early_exceptions.o -MF build/juno/debug/bl31/early_exceptions.d common/aarch64/early_exceptions.S + DEPS build/juno/debug/bl31/crash_reporting.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/crash_reporting.o -MF build/juno/debug/bl31/crash_reporting.d bl31/aarch64/crash_reporting.S + DEPS build/juno/debug/bl31/runtime_exceptions.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/runtime_exceptions.o -MF build/juno/debug/bl31/runtime_exceptions.d bl31/aarch64/runtime_exceptions.S + DEPS build/juno/debug/bl31/context.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/context.o -MF build/juno/debug/bl31/context.d bl31/aarch64/context.S + DEPS build/juno/debug/bl31/bl31_entrypoint.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/bl31_entrypoint.o -MF build/juno/debug/bl31/bl31_entrypoint.d bl31/aarch64/bl31_entrypoint.S + DEPS build/juno/debug/bl31/plat_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/plat_helpers.o -MF build/juno/debug/bl31/plat_helpers.d plat/juno/aarch64/plat_helpers.S + DEPS build/juno/debug/bl31/platform_mp_stack.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl31/platform_mp_stack.o -MF build/juno/debug/bl31/platform_mp_stack.d plat/common/aarch64/platform_mp_stack.S + DEPS build/juno/debug/bl31/plat_io_storage.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/plat_io_storage.o -MF build/juno/debug/bl31/plat_io_storage.d plat/juno/plat_io_storage.c + DEPS build/juno/debug/bl31/plat_common.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/plat_common.o -MF build/juno/debug/bl31/plat_common.d plat/common/aarch64/plat_common.c + DEPS build/juno/debug/bl31/xlat_tables.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/xlat_tables.o -MF build/juno/debug/bl31/xlat_tables.d lib/aarch64/xlat_tables.c + DEPS build/juno/debug/bl31/mmio.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/mmio.o -MF build/juno/debug/bl31/mmio.d lib/mmio.c + DEPS build/juno/debug/bl31/io_memmap.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/io_memmap.o -MF build/juno/debug/bl31/io_memmap.d drivers/io/io_memmap.c + DEPS build/juno/debug/bl31/io_fip.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/io_fip.o -MF build/juno/debug/bl31/io_fip.d drivers/io/io_fip.c + DEPS build/juno/debug/bl31/serial.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/serial.o -MF build/juno/debug/bl31/serial.d drivers/arm/serial/serial.c + DEPS build/juno/debug/bl31/io_storage.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/io_storage.o -MF build/juno/debug/bl31/io_storage.d lib/io_storage.c + DEPS build/juno/debug/bl31/std.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/std.o -MF build/juno/debug/bl31/std.d lib/stdlib/std.c + DEPS build/juno/debug/bl31/xlat_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/xlat_helpers.o -MF build/juno/debug/bl31/xlat_helpers.d lib/aarch64/xlat_helpers.c + DEPS build/juno/debug/bl31/debug.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/debug.o -MF build/juno/debug/bl31/debug.d common/debug.c + DEPS build/juno/debug/bl31/bl_common.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/bl_common.o -MF build/juno/debug/bl31/bl_common.d common/bl_common.c + DEPS build/juno/debug/bl31/psci_setup.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/psci_setup.o -MF build/juno/debug/bl31/psci_setup.d services/std_svc/psci/psci_setup.c + DEPS build/juno/debug/bl31/psci_main.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/psci_main.o -MF build/juno/debug/bl31/psci_main.d services/std_svc/psci/psci_main.c + DEPS build/juno/debug/bl31/psci_common.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/psci_common.o -MF build/juno/debug/bl31/psci_common.d services/std_svc/psci/psci_common.c + DEPS build/juno/debug/bl31/psci_afflvl_suspend.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/psci_afflvl_suspend.o -MF build/juno/debug/bl31/psci_afflvl_suspend.d services/std_svc/psci/psci_afflvl_suspend.c + DEPS build/juno/debug/bl31/psci_afflvl_on.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/psci_afflvl_on.o -MF build/juno/debug/bl31/psci_afflvl_on.d services/std_svc/psci/psci_afflvl_on.c + DEPS build/juno/debug/bl31/psci_afflvl_off.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/psci_afflvl_off.o -MF build/juno/debug/bl31/psci_afflvl_off.d services/std_svc/psci/psci_afflvl_off.c + DEPS build/juno/debug/bl31/std_svc_setup.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/std_svc_setup.o -MF build/juno/debug/bl31/std_svc_setup.d services/std_svc/std_svc_setup.c + DEPS build/juno/debug/bl31/bakery_lock.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/bakery_lock.o -MF build/juno/debug/bl31/bakery_lock.d lib/locks/bakery/bakery_lock.c + DEPS build/juno/debug/bl31/bl31_arch_setup.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/bl31_arch_setup.o -MF build/juno/debug/bl31/bl31_arch_setup.d bl31/aarch64/bl31_arch_setup.c + DEPS build/juno/debug/bl31/interrupt_mgmt.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/interrupt_mgmt.o -MF build/juno/debug/bl31/interrupt_mgmt.d bl31/interrupt_mgmt.c + DEPS build/juno/debug/bl31/runtime_svc.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/runtime_svc.o -MF build/juno/debug/bl31/runtime_svc.d bl31/runtime_svc.c + DEPS build/juno/debug/bl31/context_mgmt.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/context_mgmt.o -MF build/juno/debug/bl31/context_mgmt.d bl31/context_mgmt.c + DEPS build/juno/debug/bl31/bl31_main.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/bl31_main.o -MF build/juno/debug/bl31/bl31_main.d bl31/bl31_main.c + DEPS build/juno/debug/bl31/smc_arm.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/smc_arm.o -MF build/juno/debug/bl31/smc_arm.d plat/juno/smc_arm.c + DEPS build/juno/debug/bl31/scpi.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/scpi.o -MF build/juno/debug/bl31/scpi.d plat/juno/scpi.c + DEPS build/juno/debug/bl31/plat_gic.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/plat_gic.o -MF build/juno/debug/bl31/plat_gic.d plat/juno/plat_gic.c + DEPS build/juno/debug/bl31/plat_topology.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/plat_topology.o -MF build/juno/debug/bl31/plat_topology.d plat/juno/plat_topology.c + DEPS build/juno/debug/bl31/plat_pm.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/plat_pm.o -MF build/juno/debug/bl31/plat_pm.d plat/juno/plat_pm.c + DEPS build/juno/debug/bl31/juno_common.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/juno_common.o -MF build/juno/debug/bl31/juno_common.d plat/juno/aarch64/juno_common.c + DEPS build/juno/debug/bl31/mhu.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/mhu.o -MF build/juno/debug/bl31/mhu.d plat/juno/mhu.c + DEPS build/juno/debug/bl31/bl31_plat_setup.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/bl31_plat_setup.o -MF build/juno/debug/bl31/bl31_plat_setup.d plat/juno/bl31_plat_setup.c + DEPS build/juno/debug/bl31/gic_v2.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/gic_v2.o -MF build/juno/debug/bl31/gic_v2.d drivers/arm/gic/gic_v2.c + DEPS build/juno/debug/bl31/cci400.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl31/cci400.o -MF build/juno/debug/bl31/cci400.d drivers/arm/cci400/cci400.c + DEPS build/juno/debug/bl2/bl2.ld.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl2/bl2.ld -MF build/juno/debug/bl2/bl2.ld.d bl2/bl2.ld.S + DEPS build/juno/debug/bl2/sysreg_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl2/sysreg_helpers.o -MF build/juno/debug/bl2/sysreg_helpers.d lib/aarch64/sysreg_helpers.S + DEPS build/juno/debug/bl2/platform_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl2/platform_helpers.o -MF build/juno/debug/bl2/platform_helpers.d plat/common/aarch64/platform_helpers.S + DEPS build/juno/debug/bl2/tlb_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl2/tlb_helpers.o -MF build/juno/debug/bl2/tlb_helpers.d lib/aarch64/tlb_helpers.S + DEPS build/juno/debug/bl2/misc_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl2/misc_helpers.o -MF build/juno/debug/bl2/misc_helpers.d lib/aarch64/misc_helpers.S + DEPS build/juno/debug/bl2/cache_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl2/cache_helpers.o -MF build/juno/debug/bl2/cache_helpers.d lib/aarch64/cache_helpers.S + DEPS build/juno/debug/bl2/spinlock.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl2/spinlock.o -MF build/juno/debug/bl2/spinlock.d lib/locks/exclusive/spinlock.S + DEPS build/juno/debug/bl2/early_exceptions.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl2/early_exceptions.o -MF build/juno/debug/bl2/early_exceptions.d common/aarch64/early_exceptions.S + DEPS build/juno/debug/bl2/bl2_entrypoint.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl2/bl2_entrypoint.o -MF build/juno/debug/bl2/bl2_entrypoint.d bl2/aarch64/bl2_entrypoint.S + DEPS build/juno/debug/bl2/plat_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl2/plat_helpers.o -MF build/juno/debug/bl2/plat_helpers.d plat/juno/aarch64/plat_helpers.S + DEPS build/juno/debug/bl2/platform_up_stack.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl2/platform_up_stack.o -MF build/juno/debug/bl2/platform_up_stack.d plat/common/aarch64/platform_up_stack.S + DEPS build/juno/debug/bl2/plat_io_storage.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/plat_io_storage.o -MF build/juno/debug/bl2/plat_io_storage.d plat/juno/plat_io_storage.c + DEPS build/juno/debug/bl2/plat_common.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/plat_common.o -MF build/juno/debug/bl2/plat_common.d plat/common/aarch64/plat_common.c + DEPS build/juno/debug/bl2/xlat_tables.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/xlat_tables.o -MF build/juno/debug/bl2/xlat_tables.d lib/aarch64/xlat_tables.c + DEPS build/juno/debug/bl2/mmio.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/mmio.o -MF build/juno/debug/bl2/mmio.d lib/mmio.c + DEPS build/juno/debug/bl2/io_memmap.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/io_memmap.o -MF build/juno/debug/bl2/io_memmap.d drivers/io/io_memmap.c + DEPS build/juno/debug/bl2/io_fip.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/io_fip.o -MF build/juno/debug/bl2/io_fip.d drivers/io/io_fip.c + DEPS build/juno/debug/bl2/serial.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/serial.o -MF build/juno/debug/bl2/serial.d drivers/arm/serial/serial.c + DEPS build/juno/debug/bl2/io_storage.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/io_storage.o -MF build/juno/debug/bl2/io_storage.d lib/io_storage.c + DEPS build/juno/debug/bl2/std.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/std.o -MF build/juno/debug/bl2/std.d lib/stdlib/std.c + DEPS build/juno/debug/bl2/xlat_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/xlat_helpers.o -MF build/juno/debug/bl2/xlat_helpers.d lib/aarch64/xlat_helpers.c + DEPS build/juno/debug/bl2/debug.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/debug.o -MF build/juno/debug/bl2/debug.d common/debug.c + DEPS build/juno/debug/bl2/bl_common.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/bl_common.o -MF build/juno/debug/bl2/bl_common.d common/bl_common.c + DEPS build/juno/debug/bl2/bl2_arch_setup.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/bl2_arch_setup.o -MF build/juno/debug/bl2/bl2_arch_setup.d bl2/aarch64/bl2_arch_setup.c + DEPS build/juno/debug/bl2/bl2_main.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/bl2_main.o -MF build/juno/debug/bl2/bl2_main.d bl2/bl2_main.c + DEPS build/juno/debug/bl2/scpi.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/scpi.o -MF build/juno/debug/bl2/scpi.d plat/juno/scpi.c + DEPS build/juno/debug/bl2/scp_bootloader.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/scp_bootloader.o -MF build/juno/debug/bl2/scp_bootloader.d plat/juno/scp_bootloader.c + DEPS build/juno/debug/bl2/juno_common.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/juno_common.o -MF build/juno/debug/bl2/juno_common.d plat/juno/aarch64/juno_common.c + DEPS build/juno/debug/bl2/mhu.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/mhu.o -MF build/juno/debug/bl2/mhu.d plat/juno/mhu.c + DEPS build/juno/debug/bl2/bl2_plat_setup.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/bl2_plat_setup.o -MF build/juno/debug/bl2/bl2_plat_setup.d plat/juno/bl2_plat_setup.c + DEPS build/juno/debug/bl2/bakery_lock.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl2/bakery_lock.o -MF build/juno/debug/bl2/bakery_lock.d lib/locks/bakery/bakery_lock.c + DEPS build/juno/debug/bl1/bl1.ld.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl1/bl1.ld -MF build/juno/debug/bl1/bl1.ld.d bl1/bl1.ld.S + DEPS build/juno/debug/bl1/sysreg_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl1/sysreg_helpers.o -MF build/juno/debug/bl1/sysreg_helpers.d lib/aarch64/sysreg_helpers.S + DEPS build/juno/debug/bl1/platform_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl1/platform_helpers.o -MF build/juno/debug/bl1/platform_helpers.d plat/common/aarch64/platform_helpers.S + DEPS build/juno/debug/bl1/tlb_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl1/tlb_helpers.o -MF build/juno/debug/bl1/tlb_helpers.d lib/aarch64/tlb_helpers.S + DEPS build/juno/debug/bl1/misc_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl1/misc_helpers.o -MF build/juno/debug/bl1/misc_helpers.d lib/aarch64/misc_helpers.S + DEPS build/juno/debug/bl1/cache_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl1/cache_helpers.o -MF build/juno/debug/bl1/cache_helpers.d lib/aarch64/cache_helpers.S + DEPS build/juno/debug/bl1/cpu_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl1/cpu_helpers.o -MF build/juno/debug/bl1/cpu_helpers.d lib/aarch64/cpu_helpers.S + DEPS build/juno/debug/bl1/bl1_exceptions.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl1/bl1_exceptions.o -MF build/juno/debug/bl1/bl1_exceptions.d bl1/aarch64/bl1_exceptions.S + DEPS build/juno/debug/bl1/bl1_entrypoint.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl1/bl1_entrypoint.o -MF build/juno/debug/bl1/bl1_entrypoint.d bl1/aarch64/bl1_entrypoint.S + DEPS build/juno/debug/bl1/plat_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl1/plat_helpers.o -MF build/juno/debug/bl1/plat_helpers.d plat/juno/aarch64/plat_helpers.S + DEPS build/juno/debug/bl1/bl1_plat_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl1/bl1_plat_helpers.o -MF build/juno/debug/bl1/bl1_plat_helpers.d plat/juno/aarch64/bl1_plat_helpers.S + DEPS build/juno/debug/bl1/platform_up_stack.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -Wa,--gdwarf-2 -nostdinc -ffreestanding -Wa,--fatal-warnings -mgeneral-regs-only -D__ASSEMBLY__ -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -M -MT ./build/juno/debug/bl1/platform_up_stack.o -MF build/juno/debug/bl1/platform_up_stack.d plat/common/aarch64/platform_up_stack.S + DEPS build/juno/debug/bl1/plat_io_storage.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/plat_io_storage.o -MF build/juno/debug/bl1/plat_io_storage.d plat/juno/plat_io_storage.c + DEPS build/juno/debug/bl1/plat_common.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/plat_common.o -MF build/juno/debug/bl1/plat_common.d plat/common/aarch64/plat_common.c + DEPS build/juno/debug/bl1/xlat_tables.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/xlat_tables.o -MF build/juno/debug/bl1/xlat_tables.d lib/aarch64/xlat_tables.c + DEPS build/juno/debug/bl1/mmio.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/mmio.o -MF build/juno/debug/bl1/mmio.d lib/mmio.c + DEPS build/juno/debug/bl1/io_memmap.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/io_memmap.o -MF build/juno/debug/bl1/io_memmap.d drivers/io/io_memmap.c + DEPS build/juno/debug/bl1/io_fip.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/io_fip.o -MF build/juno/debug/bl1/io_fip.d drivers/io/io_fip.c + DEPS build/juno/debug/bl1/serial.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/serial.o -MF build/juno/debug/bl1/serial.d drivers/arm/serial/serial.c + DEPS build/juno/debug/bl1/io_storage.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/io_storage.o -MF build/juno/debug/bl1/io_storage.d lib/io_storage.c + DEPS build/juno/debug/bl1/std.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/std.o -MF build/juno/debug/bl1/std.d lib/stdlib/std.c + DEPS build/juno/debug/bl1/xlat_helpers.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/xlat_helpers.o -MF build/juno/debug/bl1/xlat_helpers.d lib/aarch64/xlat_helpers.c + DEPS build/juno/debug/bl1/debug.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/debug.o -MF build/juno/debug/bl1/debug.d common/debug.c + DEPS build/juno/debug/bl1/bl_common.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/bl_common.o -MF build/juno/debug/bl1/bl_common.d common/bl_common.c + DEPS build/juno/debug/bl1/bl1_arch_setup.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/bl1_arch_setup.o -MF build/juno/debug/bl1/bl1_arch_setup.d bl1/aarch64/bl1_arch_setup.c + DEPS build/juno/debug/bl1/bl1_main.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/bl1_main.o -MF build/juno/debug/bl1/bl1_main.d bl1/bl1_main.c + DEPS build/juno/debug/bl1/juno_common.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/juno_common.o -MF build/juno/debug/bl1/juno_common.d plat/juno/aarch64/juno_common.c + DEPS build/juno/debug/bl1/bl1_plat_setup.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/bl1_plat_setup.o -MF build/juno/debug/bl1/bl1_plat_setup.d plat/juno/bl1_plat_setup.c + DEPS build/juno/debug/bl1/cci400.d +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -M -MT ./build/juno/debug/bl1/cci400.o -MF build/juno/debug/bl1/cci400.d drivers/arm/cci400/cci400.c + CC lib/locks/bakery/bakery_lock.c +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -c lib/locks/bakery/bakery_lock.c -o build/juno/debug/bl2/bakery_lock.o + CC plat/juno/bl2_plat_setup.c +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -c plat/juno/bl2_plat_setup.c -o build/juno/debug/bl2/bl2_plat_setup.o + CC plat/juno/mhu.c +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -c plat/juno/mhu.c -o build/juno/debug/bl2/mhu.o + CC plat/juno/aarch64/juno_common.c +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -c plat/juno/aarch64/juno_common.c -o build/juno/debug/bl2/juno_common.o + CC plat/juno/scp_bootloader.c +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -c plat/juno/scp_bootloader.c -o build/juno/debug/bl2/scp_bootloader.o + CC plat/juno/scpi.c +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -c plat/juno/scpi.c -o build/juno/debug/bl2/scpi.o + CC bl2/bl2_main.c +/mnt/fileroot/xiaobo.gu/work/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-gcc -g -nostdinc -pedantic -ffreestanding -Wall -mgeneral-regs-only -std=c99 -c -Os -DIMF_READ_INTERRUPT_ID=0 -DDEBUG=1 -DNS_TIMER_SWITCH=0 -DRESET_TO_BL31=0 -Iinclude/bl1 -Iinclude/bl2 -Iinclude/bl31 -Iinclude/bl31/services -Iinclude/bl32 -Iinclude/bl32/payloads -Iinclude/common -Iinclude/drivers -Iinclude/drivers/arm -Iinclude/drivers/serial -Iinclude/lib -Iinclude/lib/aarch64 -Iinclude/plat/common -Iinclude/stdlib -Iinclude/stdlib/sys -Iplat/juno/include/ -ffunction-sections -fdata-sections -c bl2/bl2_main.c -o build/juno/debug/bl2/bl2_main.o +In file included from bl2/firmware/spl.c:4:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_eth_pinmux.h:29:0: warning: "ETH_BANK0_GPIOY1_Y9" redefined [enabled by default] + #define ETH_BANK0_GPIOY1_Y9 (0) + ^ +In file included from bl2/firmware/spl.c:3:0, + from bl2/bl2_main.c:43: +bl2/firmware/am_eth_pinmux.h:17:0: note: this is the location of the previous definition + #define ETH_BANK0_GPIOY1_Y9 0 + ^ +In file included from bl2/firmware/spl.c:4:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_eth_pinmux.h:30:0: warning: "ETH_BANK0_REG1" redefined [enabled by default] + #define ETH_BANK0_REG1 (6) + ^ +In file included from bl2/firmware/spl.c:3:0, + from bl2/bl2_main.c:43: +bl2/firmware/am_eth_pinmux.h:18:0: note: this is the location of the previous definition + #define ETH_BANK0_REG1 6 + ^ +In file included from bl2/firmware/spl.c:4:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_eth_pinmux.h:33:0: warning: "ETH_CLK_IN_GPIOY0_REG6_18" redefined [enabled by default] + #define ETH_CLK_IN_GPIOY0_REG6_18 (0) + ^ +In file included from bl2/firmware/spl.c:3:0, + from bl2/bl2_main.c:43: +bl2/firmware/am_eth_pinmux.h:21:0: note: this is the location of the previous definition + #define ETH_CLK_IN_GPIOY0_REG6_18 0 + ^ +In file included from bl2/firmware/spl.c:4:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_eth_pinmux.h:34:0: warning: "ETH_CLK_OUT_GPIOY0_REG6_17" redefined [enabled by default] + #define ETH_CLK_OUT_GPIOY0_REG6_17 (1) + ^ +In file included from bl2/firmware/spl.c:3:0, + from bl2/bl2_main.c:43: +bl2/firmware/am_eth_pinmux.h:22:0: note: this is the location of the previous definition + #define ETH_CLK_OUT_GPIOY0_REG6_17 1 + ^ +In file included from bl2/firmware/mtd.h:11:0, + from bl2/firmware/aml_nand.h:4, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/div64.h: In function ‘lldiv’: +bl2/firmware/div64.h:45:2: warning: implicit declaration of function ‘typeof’ [-Wimplicit-function-declaration] + do_div(__res, divisor); + ^ +bl2/firmware/div64.h:30:22: error: expected expression before ‘)’ token + (void)(((typeof(n) *)0) == ((uint64_t *)0)); \ + ^ +bl2/firmware/div64.h:45:2: note: in expansion of macro ‘do_div’ + do_div(__res, divisor); + ^ +bl2/firmware/div64.h:27:25: warning: ISO C forbids braced-groups within expressions [-Wpedantic] + # define do_div(n,base) ({ \ + ^ +bl2/firmware/div64.h:45:2: note: in expansion of macro ‘do_div’ + do_div(__res, divisor); + ^ +In file included from bl2/firmware/mtd-abi.h:11:0, + from bl2/firmware/mtd.h:12, + from bl2/firmware/aml_nand.h:4, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/compat.h: At top level: +bl2/firmware/compat.h:51:0: warning: "PAGE_SIZE" redefined [enabled by default] + #define PAGE_SIZE 4096 + ^ +In file included from bl2/bl2_main.c:31:0: +include/lib/aarch64/arch.h:329:0: note: this is the location of the previous definition + #define PAGE_SIZE (1 << PAGE_SIZE_SHIFT) + ^ +In file included from bl2/firmware/aml_nand.h:4:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/mtd.h:50:2: error: unknown type name ‘u_long’ + u_long time; + ^ +bl2/firmware/mtd.h:51:2: error: unknown type name ‘u_long’ + u_long retries; + ^ +bl2/firmware/mtd.h:52:2: error: unknown type name ‘u_int’ + u_int dev; + ^ +bl2/firmware/mtd.h:53:2: error: unknown type name ‘u_int’ + u_int cell; + ^ +bl2/firmware/mtd.h:55:2: error: unknown type name ‘u_long’ + u_long priv; + ^ +bl2/firmware/mtd.h:56:2: error: unknown type name ‘u_char’ + u_char state; + ^ +bl2/firmware/mtd.h:62:2: error: unknown type name ‘u_int32_t’ + u_int32_t erasesize; /* For this region */ + ^ +bl2/firmware/mtd.h:63:2: error: unknown type name ‘u_int32_t’ + u_int32_t numblocks; /* Number of blocks of erasesize in this region */ + ^ +bl2/firmware/mtd.h:114:2: error: unknown type name ‘u_char’ + u_char type; + ^ +bl2/firmware/mtd.h:115:2: error: unknown type name ‘u_int32_t’ + u_int32_t flags; + ^ +bl2/firmware/mtd.h:122:2: error: unknown type name ‘u_int32_t’ + u_int32_t erasesize; + ^ +bl2/firmware/mtd.h:130:2: error: unknown type name ‘u_int32_t’ + u_int32_t writesize; + ^ +bl2/firmware/mtd.h:132:2: error: unknown type name ‘u_int32_t’ + u_int32_t oobsize; /* Amount of OOB data per block (e.g. 16) */ + ^ +bl2/firmware/mtd.h:133:2: error: unknown type name ‘u_int32_t’ + u_int32_t oobavail; /* Available OOB bytes per block */ + ^ +bl2/firmware/mtd.h:162:38: error: unknown type name ‘loff_t’ + int (*point) (struct mtd_info *mtd, loff_t from, size_t len, + ^ +bl2/firmware/mtd.h:163:33: error: unknown type name ‘phys_addr_t’ + size_t *retlen, void **virt, phys_addr_t *phys); + ^ +bl2/firmware/mtd.h:166:41: error: unknown type name ‘loff_t’ + void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len); + ^ +bl2/firmware/mtd.h:169:37: error: unknown type name ‘loff_t’ + int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + ^ +bl2/firmware/mtd.h:169:78: error: unknown type name ‘u_char’ + int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + ^ +bl2/firmware/mtd.h:170:38: error: unknown type name ‘loff_t’ + int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); + ^ +bl2/firmware/mtd.h:170:38: error: unknown type name ‘u_char’ +bl2/firmware/mtd.h:179:44: error: unknown type name ‘loff_t’ + int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); + ^ +bl2/firmware/mtd.h:179:44: error: unknown type name ‘u_char’ +bl2/firmware/mtd.h:181:41: error: unknown type name ‘loff_t’ + int (*read_oob) (struct mtd_info *mtd, loff_t from, + ^ +bl2/firmware/mtd.h:183:42: error: unknown type name ‘loff_t’ + int (*write_oob) (struct mtd_info *mtd, loff_t to, + ^ +bl2/firmware/mtd.h:192:51: error: unknown type name ‘loff_t’ + int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + ^ +bl2/firmware/mtd.h:192:92: error: unknown type name ‘u_char’ + int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + ^ +bl2/firmware/mtd.h:194:51: error: unknown type name ‘loff_t’ + int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + ^ +bl2/firmware/mtd.h:194:92: error: unknown type name ‘u_char’ + int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + ^ +bl2/firmware/mtd.h:195:52: error: unknown type name ‘loff_t’ + int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + ^ +bl2/firmware/mtd.h:195:93: error: unknown type name ‘u_char’ + int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + ^ +bl2/firmware/mtd.h:196:51: error: unknown type name ‘loff_t’ + int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len); + ^ +bl2/firmware/mtd.h:211:37: error: unknown type name ‘loff_t’ + int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); + ^ +bl2/firmware/mtd.h:212:39: error: unknown type name ‘loff_t’ + int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); + ^ +bl2/firmware/mtd.h:215:44: error: unknown type name ‘loff_t’ + int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); + ^ +bl2/firmware/mtd.h:216:46: error: unknown type name ‘loff_t’ + int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); + ^ +In file included from bl2/firmware/mtd.h:11:0, + from bl2/firmware/aml_nand.h:4, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/mtd.h: In function ‘mtd_div_by_eb’: +bl2/firmware/div64.h:30:22: error: expected expression before ‘)’ token + (void)(((typeof(n) *)0) == ((uint64_t *)0)); \ + ^ +bl2/firmware/mtd.h:243:2: note: in expansion of macro ‘do_div’ + do_div(sz, mtd->erasesize); + ^ +bl2/firmware/div64.h:27:25: warning: ISO C forbids braced-groups within expressions [-Wpedantic] + # define do_div(n,base) ({ \ + ^ +bl2/firmware/mtd.h:243:2: note: in expansion of macro ‘do_div’ + do_div(sz, mtd->erasesize); + ^ +bl2/firmware/mtd.h: In function ‘mtd_mod_by_eb’: +bl2/firmware/div64.h:30:22: error: expected expression before ‘)’ token + (void)(((typeof(n) *)0) == ((uint64_t *)0)); \ + ^ +bl2/firmware/mtd.h:249:9: note: in expansion of macro ‘do_div’ + return do_div(sz, mtd->erasesize); + ^ +bl2/firmware/div64.h:27:25: warning: ISO C forbids braced-groups within expressions [-Wpedantic] + # define do_div(n,base) ({ \ + ^ +bl2/firmware/mtd.h:249:9: note: in expansion of macro ‘do_div’ + return do_div(sz, mtd->erasesize); + ^ +In file included from bl2/firmware/aml_nand.h:4:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/mtd.h: At top level: +bl2/firmware/mtd.h:307:25: warning: ISO C does not permit named variadic macros [-Wvariadic-macros] + #define MTDDEBUG(n, args...) \ + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:450:2: error: unknown type name ‘u8’ + u8 id[MAX_ID_LEN]; + ^ +bl2/firmware/nand.h:458:2: error: unknown type name ‘u8’ + u8 onfi_mode; + ^ +bl2/firmware/nand.h:467:2: error: unknown type name ‘u_int32_t’ + u_int32_t mask_flags; + ^ +bl2/firmware/nand.h:480:10: error: unknown type name ‘u_char’ + u_char env_valid; + ^ +bl2/firmware/nand.h:481:10: error: unknown type name ‘u_char’ + u_char env_init; + ^ +bl2/firmware/nand.h:482:10: error: unknown type name ‘u_char’ + u_char part_num_before_sys; + ^ +bl2/firmware/nand.h:530:2: error: unknown type name ‘u_char’ + u_char env_valid; + ^ +bl2/firmware/nand.h:531:2: error: unknown type name ‘u_char’ + u_char env_init; + ^ +bl2/firmware/nand.h:532:2: error: unknown type name ‘u_char’ + u_char part_num_before_sys; + ^ +bl2/firmware/nand.h:639:2: error: unknown type name ‘u8’ + u8 flag; + ^ +bl2/firmware/nand.h:640:2: error: unknown type name ‘u8’ + u8 reg_cnt; + ^ +bl2/firmware/nand.h:641:2: error: unknown type name ‘u8’ + u8 retry_cnt; + ^ +bl2/firmware/nand.h:642:2: error: unknown type name ‘u8’ + u8 default_flag; + ^ +bl2/firmware/nand.h:643:2: error: unknown type name ‘u8’ + u8 cur_cnt[MAX_CHIP_NUM]; + ^ +bl2/firmware/nand.h:644:2: error: unknown type name ‘u8’ + u8 reg_addr[READ_RETRY_REG_NUM]; + ^ +bl2/firmware/nand.h:645:2: error: unknown type name ‘u8’ + u8 reg_default_value[MAX_CHIP_NUM][READ_RETRY_REG_NUM]; + ^ +bl2/firmware/nand.h:655:2: error: unknown type name ‘u8’ + u8 flag; + ^ +bl2/firmware/nand.h:656:2: error: unknown type name ‘u8’ + u8 reg_cnt; + ^ +bl2/firmware/nand.h:657:2: error: unknown type name ‘u8’ + u8 reg_addr[ENHANCE_SLC_REG_NUM]; + ^ +bl2/firmware/nand.h:658:2: error: unknown type name ‘u8’ + u8 reg_default_value[MAX_CHIP_NUM][ENHANCE_SLC_REG_NUM]; + ^ +bl2/firmware/nand.h:667:2: error: unknown type name ‘u8’ + u8 slc_flag; + ^ +bl2/firmware/nand.h:668:2: error: unknown type name ‘u8’ + u8 dynamic_read_flag; + ^ +bl2/firmware/nand.h:669:2: error: unknown type name ‘u8’ + u8 read_case_num_max_lower_page;//Nmax _lower_page + ^ +bl2/firmware/nand.h:670:2: error: unknown type name ‘u8’ + u8 read_case_num_max_upper_page;//Nmax_upper_page + ^ +bl2/firmware/nand.h:671:2: error: unknown type name ‘u8’ + u8 cur_case_num_lower_page[MAX_CHIP_NUM];//N_lower_page + ^ +bl2/firmware/nand.h:672:2: error: unknown type name ‘u8’ + u8 cur_case_num_upper_page[MAX_CHIP_NUM];//N_upper_page + ^ +bl2/firmware/nand.h:673:2: error: unknown type name ‘u8’ + u8 reg_addr_init[DYNAMIC_REG_INIT_NUM]; + ^ +bl2/firmware/nand.h:674:2: error: unknown type name ‘u8’ + u8 reg_addr_lower_page[DYNAMIC_REG_NUM]; + ^ +bl2/firmware/nand.h:675:2: error: unknown type name ‘u8’ + u8 reg_addr_upper_page[DYNAMIC_REG_NUM]; + ^ +bl2/firmware/nand.h:686:5: error: unknown type name ‘u8’ + u8 type; + ^ +bl2/firmware/nand.h:702:2: error: unknown type name ‘u8’ + u8 mfr_type; + ^ +bl2/firmware/nand.h:712:2: error: unknown type name ‘u8’ + u8 plane_num; + ^ +bl2/firmware/nand.h:713:2: error: unknown type name ‘u8’ + u8 chip_num; + ^ +bl2/firmware/nand.h:714:2: error: unknown type name ‘u8’ + u8 internal_chipnr; + ^ +bl2/firmware/nand.h:724:2: error: unknown type name ‘u8’ + u8 user_byte_mode; + ^ +bl2/firmware/nand.h:725:2: error: unknown type name ‘u8’ + u8 ops_mode; + ^ +bl2/firmware/nand.h:726:2: error: unknown type name ‘u8’ + u8 cached_prog_status; + ^ +bl2/firmware/nand.h:727:2: error: unknown type name ‘u8’ + u8 max_bch_mode; + ^ +bl2/firmware/nand.h:738:2: error: unknown type name ‘u8’ + u8 ecc_cnt_limit; + ^ +bl2/firmware/nand.h:739:2: error: unknown type name ‘u8’ + u8 ecc_cnt_cur; + ^ +bl2/firmware/nand.h:740:2: error: unknown type name ‘u8’ + u8 ecc_max; + ^ +bl2/firmware/nand.h:749:20: error: field ‘chip’ has incomplete type + struct nand_chip chip; + ^ +bl2/firmware/nand.h:750:2: error: unknown type name ‘u8’ + u8 key_protect; + ^ +bl2/firmware/nand.h:803:36: error: field ‘platform_nand_data’ has incomplete type + struct platform_nand_data platform_nand_data; + ^ +bl2/firmware/nand.h:808:2: error: unknown type name ‘u8’ + u8 dev_num; + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h: In function ‘mtd_to_nand_chip’: +bl2/firmware/nand.h:79:16: error: expected declaration specifiers or ‘...’ before ‘(’ token + const typeof( ((type *)0)->member ) *__mptr = (const typeof( ((type *)0)->member ) *)(ptr); \ + ^ +bl2/firmware/nand.h:813:9: note: in expansion of macro ‘container_of’ + return container_of(mtd, struct aml_nand_chip, mtd); + ^ +bl2/firmware/nand.h:80:20: error: ‘__mptr’ undeclared (first use in this function) + (type *)( (char *)__mptr - offsetof(type,member) );}) + ^ +bl2/firmware/nand.h:813:9: note: in expansion of macro ‘container_of’ + return container_of(mtd, struct aml_nand_chip, mtd); + ^ +bl2/firmware/nand.h:80:20: note: each undeclared identifier is reported only once for each function it appears in + (type *)( (char *)__mptr - offsetof(type,member) );}) + ^ +bl2/firmware/nand.h:813:9: note: in expansion of macro ‘container_of’ + return container_of(mtd, struct aml_nand_chip, mtd); + ^ +bl2/firmware/nand.h:813:34: warning: implicit declaration of function ‘offsetof’ [-Wimplicit-function-declaration] + return container_of(mtd, struct aml_nand_chip, mtd); + ^ +bl2/firmware/nand.h:80:3: note: in definition of macro ‘container_of’ + (type *)( (char *)__mptr - offsetof(type,member) );}) + ^ +bl2/firmware/nand.h:813:27: error: expected expression before ‘struct’ + return container_of(mtd, struct aml_nand_chip, mtd); + ^ +bl2/firmware/nand.h:80:38: note: in definition of macro ‘container_of’ + (type *)( (char *)__mptr - offsetof(type,member) );}) + ^ +bl2/firmware/nand.h:78:41: warning: ISO C forbids braced-groups within expressions [-Wpedantic] + #define container_of(ptr, type, member) ({ \ + ^ +bl2/firmware/nand.h:813:9: note: in expansion of macro ‘container_of’ + return container_of(mtd, struct aml_nand_chip, mtd); + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h: In function ‘nand_get_chip’: +bl2/firmware/nand.h:819:2: warning: implicit declaration of function ‘SET_CBUS_REG_MASK’ [-Wimplicit-function-declaration] + SET_CBUS_REG_MASK(P_PAD_PULL_UP_EN_REG2, 0x84ff); + ^ +bl2/firmware/nand.h:819:20: error: ‘P_PAD_PULL_UP_EN_REG2’ undeclared (first use in this function) + SET_CBUS_REG_MASK(P_PAD_PULL_UP_EN_REG2, 0x84ff); + ^ +bl2/firmware/nand.h:822:20: error: ‘P_PAD_PULL_UP_REG2’ undeclared (first use in this function) + SET_CBUS_REG_MASK(P_PAD_PULL_UP_REG2, 0x0400); + ^ +bl2/firmware/nand.h:824:20: error: ‘P_PERIPHS_PIN_MUX_2’ undeclared (first use in this function) + SET_CBUS_REG_MASK(P_PERIPHS_PIN_MUX_2, ((0x3ff<<18) | (1<<17))); + ^ +bl2/firmware/nand.h: In function ‘nand_release_chip’: +bl2/firmware/nand.h:829:2: warning: implicit declaration of function ‘CLEAR_CBUS_REG_MASK’ [-Wimplicit-function-declaration] + CLEAR_CBUS_REG_MASK(P_PAD_PULL_UP_REG2, 0x0400); + ^ +bl2/firmware/nand.h:829:22: error: ‘P_PAD_PULL_UP_REG2’ undeclared (first use in this function) + CLEAR_CBUS_REG_MASK(P_PAD_PULL_UP_REG2, 0x0400); + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h: At top level: +bl2/firmware/aml_nand.h:8:0: warning: "NAND_CMD" redefined [enabled by default] + #define NAND_CMD ((0xc1108600-IO_CBUS_BASE)>>2) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:84:0: note: this is the location of the previous definition + #define NAND_CMD P_NAND_BASE+0x0 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:9:0: warning: "NAND_CFG" redefined [enabled by default] + #define NAND_CFG ((0xc1108604-IO_CBUS_BASE)>>2) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:85:0: note: this is the location of the previous definition + #define NAND_CFG P_NAND_BASE+0x1 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:10:0: warning: "NAND_DADR" redefined [enabled by default] + #define NAND_DADR ((0xc1108608-IO_CBUS_BASE)>>2) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:86:0: note: this is the location of the previous definition + #define NAND_DADR P_NAND_BASE+0x2 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:11:0: warning: "NAND_IADR" redefined [enabled by default] + #define NAND_IADR ((0xc110860c-IO_CBUS_BASE)>>2) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:87:0: note: this is the location of the previous definition + #define NAND_IADR P_NAND_BASE+0x3 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:12:0: warning: "NAND_BUF" redefined [enabled by default] + #define NAND_BUF ((0xc1108610-IO_CBUS_BASE)>>2) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:88:0: note: this is the location of the previous definition + #define NAND_BUF P_NAND_BASE+0x4 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:13:0: warning: "NAND_INFO" redefined [enabled by default] + #define NAND_INFO ((0xc1108614-IO_CBUS_BASE)>>2) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:89:0: note: this is the location of the previous definition + #define NAND_INFO P_NAND_BASE+0x5 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:14:0: warning: "NAND_DC" redefined [enabled by default] + #define NAND_DC ((0xc1108618-IO_CBUS_BASE)>>2) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:90:0: note: this is the location of the previous definition + #define NAND_DC P_NAND_BASE+0x6 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:15:0: warning: "NAND_ADR" redefined [enabled by default] + #define NAND_ADR ((0xc110861c-IO_CBUS_BASE)>>2) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:91:0: note: this is the location of the previous definition + #define NAND_ADR P_NAND_BASE+0x7 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:16:0: warning: "NAND_DL" redefined [enabled by default] + #define NAND_DL ((0xc1108620-IO_CBUS_BASE)>>2) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:92:0: note: this is the location of the previous definition + #define NAND_DL P_NAND_BASE+0x8 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:17:0: warning: "NAND_DH" redefined [enabled by default] + #define NAND_DH ((0xc1108624-IO_CBUS_BASE)>>2) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:93:0: note: this is the location of the previous definition + #define NAND_DH P_NAND_BASE+0x9 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:22:0: warning: "NAND_CYCLE_DELAY" redefined [enabled by default] + #define NAND_CYCLE_DELAY 90 + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:97:0: note: this is the location of the previous definition + #define NAND_CYCLE_DELAY 100 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:23:0: warning: "NAND_BOOT_NAME" redefined [enabled by default] + #define NAND_BOOT_NAME "nand0" + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:98:0: note: this is the location of the previous definition + #define NAND_BOOT_NAME "nandboot" + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:24:0: warning: "NAND_NORMAL_NAME" redefined [enabled by default] + #define NAND_NORMAL_NAME "nand1" + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:99:0: note: this is the location of the previous definition + #define NAND_NORMAL_NAME "nandnormal" + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:25:0: warning: "NAND_MULTI_NAME" redefined [enabled by default] + #define NAND_MULTI_NAME "nand2" + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:100:0: note: this is the location of the previous definition + #define NAND_MULTI_NAME "nandmulti" + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:79:0: warning: "DWR_SYNC" redefined [enabled by default] + #define DWR_SYNC DWR + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:163:0: note: this is the location of the previous definition + #define DWR_SYNC (0x7<<14) + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:80:0: warning: "DRD_SYNC" redefined [enabled by default] + #define DRD_SYNC DRD + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:164:0: note: this is the location of the previous definition + #define DRD_SYNC (0x3<<14) + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:138:0: warning: "NFC_CMD_SEED" redefined [enabled by default] + #define NFC_CMD_SEED(seed) (SEED|(seed&0x7fff)) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:224:0: note: this is the location of the previous definition + #define NFC_CMD_SEED(seed) (SEED|(0xc2 + seed&0x7fff)) + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:160:0: warning: "NAND_ECC_NONE" redefined [enabled by default] + #define NAND_ECC_NONE (0x0) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:249:0: note: this is the location of the previous definition + #define NAND_ECC_NONE (0x0<<14) + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:163:0: warning: "NAND_ECC_BCH16" redefined [enabled by default] + #define NAND_ECC_BCH16 (0x3) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:255:0: note: this is the location of the previous definition + #define NAND_ECC_BCH16 (0x7<<14) + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:198:0: warning: "NFC_SEND_CMD_IDLE" redefined [enabled by default] + #define NFC_SEND_CMD_IDLE(ce,time) NFC_SEND_CMD(NFC_CMD_IDLE(ce,time)) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:306:0: note: this is the location of the previous definition + #define NFC_SEND_CMD_IDLE(ce,time) {while(NFC_CMDFIFO_SIZE()>0);NFC_SEND_CMD(NFC_CMD_IDLE(ce,time));} + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:238:0: warning: "NAND_DEFAULT_OPTIONS" redefined [enabled by default] + #define NAND_DEFAULT_OPTIONS (NAND_TIMING_MODE5 | NAND_ECC_BCH8_512_MODE) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:404:0: note: this is the location of the previous definition + #define NAND_DEFAULT_OPTIONS (NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE) + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:244:0: warning: "AML_INTERLEAVING_MODE" redefined [enabled by default] + #define AML_INTERLEAVING_MODE 4 + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:351:0: note: this is the location of the previous definition + #define AML_INTERLEAVING_MODE 8 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:259:0: warning: "NAND_BCH16_ECC_SIZE" redefined [enabled by default] + #define NAND_BCH16_ECC_SIZE 28 + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:366:0: note: this is the location of the previous definition + #define NAND_BCH16_ECC_SIZE 26 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:274:0: warning: "NAND_ECC_BCH8_1K_MODE" redefined [enabled by default] + #define NAND_ECC_BCH8_1K_MODE 0x00000002 + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:386:0: note: this is the location of the previous definition + #define NAND_ECC_BCH8_1K_MODE 0x00000006 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:275:0: warning: "NAND_ECC_BCH16_MODE" redefined [enabled by default] + #define NAND_ECC_BCH16_MODE 0x00000003 + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:385:0: note: this is the location of the previous definition + #define NAND_ECC_BCH16_MODE 0x00000005 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:280:0: warning: "NAND_ECC_SHORT_MODE" redefined [enabled by default] + #define NAND_ECC_SHORT_MODE 0x00000008 + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:381:0: note: this is the location of the previous definition + #define NAND_ECC_SHORT_MODE 0x00000001 + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:320:8: error: redefinition of ‘struct aml_nand_flash_dev’ + struct aml_nand_flash_dev { + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:448:8: note: originally defined here + struct aml_nand_flash_dev { + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:322:2: error: unknown type name ‘u8’ + u8 id[MAX_ID_LEN]; + ^ +bl2/firmware/aml_nand.h:339:8: error: redefinition of ‘struct aml_nand_chip’ + struct aml_nand_chip { + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:700:8: note: originally defined here + struct aml_nand_chip { + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:341:2: error: unknown type name ‘u8’ + u8 mfr_type; + ^ +bl2/firmware/aml_nand.h:348:2: error: unknown type name ‘u8’ + u8 plane_num; + ^ +bl2/firmware/aml_nand.h:349:2: error: unknown type name ‘u8’ + u8 chip_num; + ^ +bl2/firmware/aml_nand.h:350:2: error: unknown type name ‘u8’ + u8 internal_chipnr; + ^ +bl2/firmware/aml_nand.h:359:2: error: unknown type name ‘u8’ + u8 user_byte_mode; + ^ +bl2/firmware/aml_nand.h:360:2: error: unknown type name ‘u8’ + u8 ops_mode; + ^ +bl2/firmware/aml_nand.h:361:2: error: unknown type name ‘u8’ + u8 cached_prog_status; + ^ +bl2/firmware/aml_nand.h:372:20: error: field ‘chip’ has incomplete type + struct nand_chip chip; + ^ +bl2/firmware/aml_nand.h:400:8: error: redefinition of ‘struct aml_nand_platform’ + struct aml_nand_platform { + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:758:9: note: originally defined here + struct aml_nand_platform *platform; + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:414:36: error: field ‘platform_nand_data’ has incomplete type + struct platform_nand_data platform_nand_data; + ^ +bl2/firmware/aml_nand.h:417:8: error: redefinition of ‘struct aml_nand_device’ + struct aml_nand_device { + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:806:8: note: originally defined here + struct aml_nand_device { + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h:419:2: error: unknown type name ‘u8’ + u8 dev_num; + ^ +bl2/firmware/aml_nand.h:424:21: error: redefinition of ‘nand_get_chip’ + static void inline nand_get_chip(void ) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:816:21: note: previous definition of ‘nand_get_chip’ was here + static void inline nand_get_chip(void ) + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/aml_nand.h: In function ‘nand_get_chip’: +bl2/firmware/aml_nand.h:426:15: error: ‘P_PREG_PAD_GPIO3_EN_N’ undeclared (first use in this function) + setbits_le32(P_PREG_PAD_GPIO3_EN_N,0x3ffff); //disable gpio output + ^ +include/drivers/serial/serial.h:59:55: note: in definition of macro ‘setbits_le32’ + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/aml_nand.h:428:15: error: ‘P_PERIPHS_PIN_MUX_5’ undeclared (first use in this function) + setbits_le32(P_PERIPHS_PIN_MUX_5,0x7<<7); + ^ +include/drivers/serial/serial.h:59:55: note: in definition of macro ‘setbits_le32’ + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/aml_nand.h:433:15: error: ‘P_PERIPHS_PIN_MUX_2’ undeclared (first use in this function) + setbits_le32(P_PERIPHS_PIN_MUX_2, (1<<27) | (1<<26) | (1<<25) | (0xf<<18)); + ^ +include/drivers/serial/serial.h:59:55: note: in definition of macro ‘setbits_le32’ + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h: At top level: +bl2/firmware/aml_nand.h:437:20: error: redefinition of ‘nand_release_chip’ + static void inline nand_release_chip(void) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:827:20: note: previous definition of ‘nand_release_chip’ was here + static void inline nand_release_chip(void) + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/aml_nand.h: In function ‘nand_release_chip’: +bl2/firmware/aml_nand.h:439:16: error: ‘P_PREG_PAD_GPIO3_O’ undeclared (first use in this function) + setbits_le32 (P_PREG_PAD_GPIO3_O,0x3ffff); + ^ +include/drivers/serial/serial.h:59:55: note: in definition of macro ‘setbits_le32’ + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/aml_nand.h:440:15: error: ‘P_PREG_PAD_GPIO3_EN_N’ undeclared (first use in this function) + clrbits_le32(P_PREG_PAD_GPIO3_EN_N,0x3ffff); //enable gpio output + ^ +include/drivers/serial/serial.h:60:55: note: in definition of macro ‘clrbits_le32’ + #define clrbits_le32(reg,val) (*((volatile unsigned *)reg))&=(~val) + ^ +bl2/firmware/aml_nand.h:444:15: error: ‘P_PERIPHS_PIN_MUX_2’ undeclared (first use in this function) + clrbits_le32(P_PERIPHS_PIN_MUX_2, (1<<27) | (1<<26) | (1<<25) | (0xf<<18)); + ^ +include/drivers/serial/serial.h:60:55: note: in definition of macro ‘clrbits_le32’ + #define clrbits_le32(reg,val) (*((volatile unsigned *)reg))&=(~val) + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h: At top level: +bl2/firmware/aml_nand.h:461:37: error: conflicting types for ‘mtd_to_nand_chip’ + static inline struct aml_nand_chip *mtd_to_nand_chip(struct mtd_info *mtd) + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:811:37: note: previous definition of ‘mtd_to_nand_chip’ was here + static inline struct aml_nand_chip *mtd_to_nand_chip(struct mtd_info *mtd) + ^ +In file included from bl2/firmware/spl.c:7:0, + from bl2/bl2_main.c:43: +bl2/firmware/aml_nand.h: In function ‘mtd_to_nand_chip’: +bl2/firmware/aml_nand.h:464:13: error: dereferencing pointer to incomplete type + return chip->priv; + ^ +bl2/firmware/aml_nand.h: At top level: +bl2/firmware/aml_nand.h:467:12: error: conflicting types for ‘aml_nand_init’ + extern int aml_nand_init(struct aml_nand_chip *aml_chip); + ^ +In file included from bl2/firmware/aml_nand.h:5:0, + from bl2/firmware/spl.c:7, + from bl2/bl2_main.c:43: +bl2/firmware/nand.h:833:12: note: previous declaration of ‘aml_nand_init’ was here + extern int aml_nand_init(struct aml_nand_chip *aml_chip); + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:35:0: warning: "P_AO_RTI_PIN_MUX_REG" redefined [enabled by default] + #define P_AO_RTI_PIN_MUX_REG AOBUS_REG_ADDR(AO_RTI_PIN_MUX_REG) + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:5:0: note: this is the location of the previous definition + #define P_AO_RTI_PIN_MUX_REG (0xc8100014) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:125:0: warning: "P_AO_UART_WFIFO" redefined [enabled by default] + #define P_AO_UART_WFIFO AOBUS_REG_ADDR(AO_UART_WFIFO) + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:4:0: note: this is the location of the previous definition + #define P_AO_UART_WFIFO (0xc81004c0) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:6:4: warning: #warning is a GCC extension [enabled by default] + #warning(Please check the IO_AOBUS_BASE!) + ^ +bl2/firmware/c_always_on_pointer.h:6:4: warning: #warning (Please check the IO_AOBUS_BASE!) [-Wcpp] +bl2/firmware/c_always_on_pointer.h:17:0: warning: "P_AO_RTI_STATUS_REG0" redefined [enabled by default] + #define P_AO_RTI_STATUS_REG0 (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x00 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:25:0: note: this is the location of the previous definition + #define P_AO_RTI_STATUS_REG0 AOBUS_REG_ADDR(AO_RTI_STATUS_REG0) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:18:0: warning: "P_AO_RTI_STATUS_REG1" redefined [enabled by default] + #define P_AO_RTI_STATUS_REG1 (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x01 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:27:0: note: this is the location of the previous definition + #define P_AO_RTI_STATUS_REG1 AOBUS_REG_ADDR(AO_RTI_STATUS_REG1) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:19:0: warning: "P_AO_RTI_STATUS_REG2" redefined [enabled by default] + #define P_AO_RTI_STATUS_REG2 (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x02 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:29:0: note: this is the location of the previous definition + #define P_AO_RTI_STATUS_REG2 AOBUS_REG_ADDR(AO_RTI_STATUS_REG2) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:21:0: warning: "P_AO_RTI_PWR_CNTL_REG0" redefined [enabled by default] + #define P_AO_RTI_PWR_CNTL_REG0 (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x04 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:33:0: note: this is the location of the previous definition + #define P_AO_RTI_PWR_CNTL_REG0 AOBUS_REG_ADDR(AO_RTI_PWR_CNTL_REG0) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:22:0: warning: "P_AO_RTI_PIN_MUX_REG" redefined [enabled by default] + #define P_AO_RTI_PIN_MUX_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x05 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:35:0: note: this is the location of the previous definition + #define P_AO_RTI_PIN_MUX_REG AOBUS_REG_ADDR(AO_RTI_PIN_MUX_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:24:0: warning: "P_AO_WD_GPIO_REG" redefined [enabled by default] + #define P_AO_WD_GPIO_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x06 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:37:0: note: this is the location of the previous definition + #define P_AO_WD_GPIO_REG AOBUS_REG_ADDR(AO_WD_GPIO_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:26:0: warning: "P_AO_REMAP_REG0" redefined [enabled by default] + #define P_AO_REMAP_REG0 (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x07 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:39:0: note: this is the location of the previous definition + #define P_AO_REMAP_REG0 AOBUS_REG_ADDR(AO_REMAP_REG0) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:27:0: warning: "P_AO_REMAP_REG1" redefined [enabled by default] + #define P_AO_REMAP_REG1 (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x08 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:41:0: note: this is the location of the previous definition + #define P_AO_REMAP_REG1 AOBUS_REG_ADDR(AO_REMAP_REG1) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:28:0: warning: "P_AO_GPIO_O_EN_N" redefined [enabled by default] + #define P_AO_GPIO_O_EN_N (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x09 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:43:0: note: this is the location of the previous definition + #define P_AO_GPIO_O_EN_N AOBUS_REG_ADDR(AO_GPIO_O_EN_N) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:29:0: warning: "P_AO_GPIO_I" redefined [enabled by default] + #define P_AO_GPIO_I (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x0A << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:45:0: note: this is the location of the previous definition + #define P_AO_GPIO_I AOBUS_REG_ADDR(AO_GPIO_I) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:31:0: warning: "P_AO_RTI_PULL_UP_REG" redefined [enabled by default] + #define P_AO_RTI_PULL_UP_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x0B << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:47:0: note: this is the location of the previous definition + #define P_AO_RTI_PULL_UP_REG AOBUS_REG_ADDR(AO_RTI_PULL_UP_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:34:0: warning: "P_AO_RTI_WD_MARK" redefined [enabled by default] + #define P_AO_RTI_WD_MARK (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x0D << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:49:0: note: this is the location of the previous definition + #define P_AO_RTI_WD_MARK AOBUS_REG_ADDR(AO_RTI_WD_MARK) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:36:0: warning: "P_AO_RTI_GEN_CNTL_REG0" redefined [enabled by default] + #define P_AO_RTI_GEN_CNTL_REG0 (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x10 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:55:0: note: this is the location of the previous definition + #define P_AO_RTI_GEN_CNTL_REG0 AOBUS_REG_ADDR(AO_RTI_GEN_CNTL_REG0) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:37:0: warning: "P_AO_WATCHDOG_REG" redefined [enabled by default] + #define P_AO_WATCHDOG_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x11 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:57:0: note: this is the location of the previous definition + #define P_AO_WATCHDOG_REG AOBUS_REG_ADDR(AO_WATCHDOG_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:38:0: warning: "P_AO_WATCHDOG_RESET" redefined [enabled by default] + #define P_AO_WATCHDOG_RESET (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x12 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:59:0: note: this is the location of the previous definition + #define P_AO_WATCHDOG_RESET AOBUS_REG_ADDR(AO_WATCHDOG_RESET) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:40:0: warning: "P_AO_TIMER_REG" redefined [enabled by default] + #define P_AO_TIMER_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x13 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:61:0: note: this is the location of the previous definition + #define P_AO_TIMER_REG AOBUS_REG_ADDR(AO_TIMER_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:41:0: warning: "P_AO_TIMERA_REG" redefined [enabled by default] + #define P_AO_TIMERA_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x14 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:63:0: note: this is the location of the previous definition + #define P_AO_TIMERA_REG AOBUS_REG_ADDR(AO_TIMERA_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:42:0: warning: "P_AO_TIMERE_REG" redefined [enabled by default] + #define P_AO_TIMERE_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x15 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:65:0: note: this is the location of the previous definition + #define P_AO_TIMERE_REG AOBUS_REG_ADDR(AO_TIMERE_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:44:0: warning: "P_AO_AHB2DDR_CNTL" redefined [enabled by default] + #define P_AO_AHB2DDR_CNTL (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x18 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:67:0: note: this is the location of the previous definition + #define P_AO_AHB2DDR_CNTL AOBUS_REG_ADDR(AO_AHB2DDR_CNTL) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:46:0: warning: "P_AO_IRQ_MASK_FIQ_SEL" redefined [enabled by default] + #define P_AO_IRQ_MASK_FIQ_SEL (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x20 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:69:0: note: this is the location of the previous definition + #define P_AO_IRQ_MASK_FIQ_SEL AOBUS_REG_ADDR(AO_IRQ_MASK_FIQ_SEL) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:47:0: warning: "P_AO_IRQ_GPIO_REG" redefined [enabled by default] + #define P_AO_IRQ_GPIO_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x21 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:71:0: note: this is the location of the previous definition + #define P_AO_IRQ_GPIO_REG AOBUS_REG_ADDR(AO_IRQ_GPIO_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:48:0: warning: "P_AO_IRQ_STAT" redefined [enabled by default] + #define P_AO_IRQ_STAT (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x22 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:73:0: note: this is the location of the previous definition + #define P_AO_IRQ_STAT AOBUS_REG_ADDR(AO_IRQ_STAT) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:49:0: warning: "P_AO_IRQ_STAT_CLR" redefined [enabled by default] + #define P_AO_IRQ_STAT_CLR (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x23 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:75:0: note: this is the location of the previous definition + #define P_AO_IRQ_STAT_CLR AOBUS_REG_ADDR(AO_IRQ_STAT_CLR) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:51:0: warning: "P_AO_DEBUG_REG0" redefined [enabled by default] + #define P_AO_DEBUG_REG0 (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x28 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:77:0: note: this is the location of the previous definition + #define P_AO_DEBUG_REG0 AOBUS_REG_ADDR(AO_DEBUG_REG0) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:52:0: warning: "P_AO_DEBUG_REG1" redefined [enabled by default] + #define P_AO_DEBUG_REG1 (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x29 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:79:0: note: this is the location of the previous definition + #define P_AO_DEBUG_REG1 AOBUS_REG_ADDR(AO_DEBUG_REG1) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:53:0: warning: "P_AO_DEBUG_REG2" redefined [enabled by default] + #define P_AO_DEBUG_REG2 (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x2a << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:81:0: note: this is the location of the previous definition + #define P_AO_DEBUG_REG2 AOBUS_REG_ADDR(AO_DEBUG_REG2) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:54:0: warning: "P_AO_DEBUG_REG3" redefined [enabled by default] + #define P_AO_DEBUG_REG3 (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x2b << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:83:0: note: this is the location of the previous definition + #define P_AO_DEBUG_REG3 AOBUS_REG_ADDR(AO_DEBUG_REG3) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:56:0: warning: "AO_IR_BLASTER_ADDR0" redefined [enabled by default] + #define AO_IR_BLASTER_ADDR0 0x30 + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:84:0: note: this is the location of the previous definition + #define AO_IR_BLASTER_ADDR0 ((0x00 << 10) | (0x30 << 2)) ///../ucode/c_always_on_pointer.h:58 + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:57:0: warning: "AO_IR_BLASTER_ADDR1" redefined [enabled by default] + #define AO_IR_BLASTER_ADDR1 0x31 + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:86:0: note: this is the location of the previous definition + #define AO_IR_BLASTER_ADDR1 ((0x00 << 10) | (0x31 << 2)) ///../ucode/c_always_on_pointer.h:59 + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:58:0: warning: "AO_IR_BLASTER_ADDR2" redefined [enabled by default] + #define AO_IR_BLASTER_ADDR2 0x32 + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:88:0: note: this is the location of the previous definition + #define AO_IR_BLASTER_ADDR2 ((0x00 << 10) | (0x32 << 2)) ///../ucode/c_always_on_pointer.h:60 + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:60:0: warning: "P_AO_CEC_GEN_CNTL" redefined [enabled by default] + #define P_AO_CEC_GEN_CNTL (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x40 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:99:0: note: this is the location of the previous definition + #define P_AO_CEC_GEN_CNTL AOBUS_REG_ADDR(AO_CEC_GEN_CNTL) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:61:0: warning: "P_AO_CEC_RW_REG" redefined [enabled by default] + #define P_AO_CEC_RW_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x41 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:101:0: note: this is the location of the previous definition + #define P_AO_CEC_RW_REG AOBUS_REG_ADDR(AO_CEC_RW_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:62:0: warning: "P_AO_CEC_INTR_MASKN" redefined [enabled by default] + #define P_AO_CEC_INTR_MASKN (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x42 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:103:0: note: this is the location of the previous definition + #define P_AO_CEC_INTR_MASKN AOBUS_REG_ADDR(AO_CEC_INTR_MASKN) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:63:0: warning: "P_AO_CEC_INTR_CLR" redefined [enabled by default] + #define P_AO_CEC_INTR_CLR (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x43 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:105:0: note: this is the location of the previous definition + #define P_AO_CEC_INTR_CLR AOBUS_REG_ADDR(AO_CEC_INTR_CLR) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:64:0: warning: "P_AO_CEC_INTR_STAT" redefined [enabled by default] + #define P_AO_CEC_INTR_STAT (volatile unsigned long *)(IO_AOBUS_BASE | (0x00 << 10) | (0x44 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:107:0: note: this is the location of the previous definition + #define P_AO_CEC_INTR_STAT AOBUS_REG_ADDR(AO_CEC_INTR_STAT) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:69:0: warning: "P_AO_IR_DEC_LDR_ACTIVE" redefined [enabled by default] + #define P_AO_IR_DEC_LDR_ACTIVE (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x20 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:109:0: note: this is the location of the previous definition + #define P_AO_IR_DEC_LDR_ACTIVE AOBUS_REG_ADDR(AO_IR_DEC_LDR_ACTIVE) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:70:0: warning: "P_AO_IR_DEC_LDR_IDLE" redefined [enabled by default] + #define P_AO_IR_DEC_LDR_IDLE (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x21 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:111:0: note: this is the location of the previous definition + #define P_AO_IR_DEC_LDR_IDLE AOBUS_REG_ADDR(AO_IR_DEC_LDR_IDLE) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:71:0: warning: "P_AO_IR_DEC_LDR_REPEAT" redefined [enabled by default] + #define P_AO_IR_DEC_LDR_REPEAT (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x22 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:113:0: note: this is the location of the previous definition + #define P_AO_IR_DEC_LDR_REPEAT AOBUS_REG_ADDR(AO_IR_DEC_LDR_REPEAT) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:72:0: warning: "P_AO_IR_DEC_BIT_0" redefined [enabled by default] + #define P_AO_IR_DEC_BIT_0 (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x23 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:115:0: note: this is the location of the previous definition + #define P_AO_IR_DEC_BIT_0 AOBUS_REG_ADDR(AO_IR_DEC_BIT_0) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:73:0: warning: "P_AO_IR_DEC_REG0" redefined [enabled by default] + #define P_AO_IR_DEC_REG0 (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x24 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:117:0: note: this is the location of the previous definition + #define P_AO_IR_DEC_REG0 AOBUS_REG_ADDR(AO_IR_DEC_REG0) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:74:0: warning: "P_AO_IR_DEC_FRAME" redefined [enabled by default] + #define P_AO_IR_DEC_FRAME (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x25 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:119:0: note: this is the location of the previous definition + #define P_AO_IR_DEC_FRAME AOBUS_REG_ADDR(AO_IR_DEC_FRAME) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:75:0: warning: "P_AO_IR_DEC_STATUS" redefined [enabled by default] + #define P_AO_IR_DEC_STATUS (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x26 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:121:0: note: this is the location of the previous definition + #define P_AO_IR_DEC_STATUS AOBUS_REG_ADDR(AO_IR_DEC_STATUS) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:76:0: warning: "P_AO_IR_DEC_REG1" redefined [enabled by default] + #define P_AO_IR_DEC_REG1 (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x27 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:123:0: note: this is the location of the previous definition + #define P_AO_IR_DEC_REG1 AOBUS_REG_ADDR(AO_IR_DEC_REG1) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:81:0: warning: "P_AO_UART_WFIFO" redefined [enabled by default] + #define P_AO_UART_WFIFO (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x30 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:125:0: note: this is the location of the previous definition + #define P_AO_UART_WFIFO AOBUS_REG_ADDR(AO_UART_WFIFO) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:82:0: warning: "P_AO_UART_RFIFO" redefined [enabled by default] + #define P_AO_UART_RFIFO (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x31 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:127:0: note: this is the location of the previous definition + #define P_AO_UART_RFIFO AOBUS_REG_ADDR(AO_UART_RFIFO) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:83:0: warning: "P_AO_UART_CONTROL" redefined [enabled by default] + #define P_AO_UART_CONTROL (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x32 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:129:0: note: this is the location of the previous definition + #define P_AO_UART_CONTROL AOBUS_REG_ADDR(AO_UART_CONTROL) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:84:0: warning: "P_AO_UART_STATUS" redefined [enabled by default] + #define P_AO_UART_STATUS (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x33 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:131:0: note: this is the location of the previous definition + #define P_AO_UART_STATUS AOBUS_REG_ADDR(AO_UART_STATUS) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:85:0: warning: "P_AO_UART_MISC" redefined [enabled by default] + #define P_AO_UART_MISC (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x34 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:133:0: note: this is the location of the previous definition + #define P_AO_UART_MISC AOBUS_REG_ADDR(AO_UART_MISC) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:86:0: warning: "P_AO_UART_REG5" redefined [enabled by default] + #define P_AO_UART_REG5 (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x35 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:135:0: note: this is the location of the previous definition + #define P_AO_UART_REG5 AOBUS_REG_ADDR(AO_UART_REG5) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:91:0: warning: "P_AO_UART2_WFIFO" redefined [enabled by default] + #define P_AO_UART2_WFIFO (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x38 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:137:0: note: this is the location of the previous definition + #define P_AO_UART2_WFIFO AOBUS_REG_ADDR(AO_UART2_WFIFO) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:92:0: warning: "P_AO_UART2_RFIFO" redefined [enabled by default] + #define P_AO_UART2_RFIFO (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x39 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:139:0: note: this is the location of the previous definition + #define P_AO_UART2_RFIFO AOBUS_REG_ADDR(AO_UART2_RFIFO) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:93:0: warning: "P_AO_UART2_CONTROL" redefined [enabled by default] + #define P_AO_UART2_CONTROL (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x3a << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:141:0: note: this is the location of the previous definition + #define P_AO_UART2_CONTROL AOBUS_REG_ADDR(AO_UART2_CONTROL) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:94:0: warning: "P_AO_UART2_STATUS" redefined [enabled by default] + #define P_AO_UART2_STATUS (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x3b << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:143:0: note: this is the location of the previous definition + #define P_AO_UART2_STATUS AOBUS_REG_ADDR(AO_UART2_STATUS) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:95:0: warning: "P_AO_UART2_MISC" redefined [enabled by default] + #define P_AO_UART2_MISC (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x3c << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:145:0: note: this is the location of the previous definition + #define P_AO_UART2_MISC AOBUS_REG_ADDR(AO_UART2_MISC) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:96:0: warning: "P_AO_UART2_REG5" redefined [enabled by default] + #define P_AO_UART2_REG5 (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x3d << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:147:0: note: this is the location of the previous definition + #define P_AO_UART2_REG5 AOBUS_REG_ADDR(AO_UART2_REG5) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:101:0: warning: "P_AO_I2C_M_0_CONTROL_REG" redefined [enabled by default] + #define P_AO_I2C_M_0_CONTROL_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x40 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:149:0: note: this is the location of the previous definition + #define P_AO_I2C_M_0_CONTROL_REG AOBUS_REG_ADDR(AO_I2C_M_0_CONTROL_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:102:0: warning: "P_AO_I2C_M_0_SLAVE_ADDR" redefined [enabled by default] + #define P_AO_I2C_M_0_SLAVE_ADDR (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x41 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:151:0: note: this is the location of the previous definition + #define P_AO_I2C_M_0_SLAVE_ADDR AOBUS_REG_ADDR(AO_I2C_M_0_SLAVE_ADDR) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:103:0: warning: "P_AO_I2C_M_0_TOKEN_LIST0" redefined [enabled by default] + #define P_AO_I2C_M_0_TOKEN_LIST0 (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x42 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:153:0: note: this is the location of the previous definition + #define P_AO_I2C_M_0_TOKEN_LIST0 AOBUS_REG_ADDR(AO_I2C_M_0_TOKEN_LIST0) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:104:0: warning: "P_AO_I2C_M_0_TOKEN_LIST1" redefined [enabled by default] + #define P_AO_I2C_M_0_TOKEN_LIST1 (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x43 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:155:0: note: this is the location of the previous definition + #define P_AO_I2C_M_0_TOKEN_LIST1 AOBUS_REG_ADDR(AO_I2C_M_0_TOKEN_LIST1) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:105:0: warning: "P_AO_I2C_M_0_WDATA_REG0" redefined [enabled by default] + #define P_AO_I2C_M_0_WDATA_REG0 (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x44 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:157:0: note: this is the location of the previous definition + #define P_AO_I2C_M_0_WDATA_REG0 AOBUS_REG_ADDR(AO_I2C_M_0_WDATA_REG0) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:106:0: warning: "P_AO_I2C_M_0_WDATA_REG1" redefined [enabled by default] + #define P_AO_I2C_M_0_WDATA_REG1 (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x45 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:159:0: note: this is the location of the previous definition + #define P_AO_I2C_M_0_WDATA_REG1 AOBUS_REG_ADDR(AO_I2C_M_0_WDATA_REG1) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:107:0: warning: "P_AO_I2C_M_0_RDATA_REG0" redefined [enabled by default] + #define P_AO_I2C_M_0_RDATA_REG0 (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x46 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:161:0: note: this is the location of the previous definition + #define P_AO_I2C_M_0_RDATA_REG0 AOBUS_REG_ADDR(AO_I2C_M_0_RDATA_REG0) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:108:0: warning: "P_AO_I2C_M_0_RDATA_REG1" redefined [enabled by default] + #define P_AO_I2C_M_0_RDATA_REG1 (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x47 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:163:0: note: this is the location of the previous definition + #define P_AO_I2C_M_0_RDATA_REG1 AOBUS_REG_ADDR(AO_I2C_M_0_RDATA_REG1) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:112:0: warning: "P_AO_I2C_S_CONTROL_REG" redefined [enabled by default] + #define P_AO_I2C_S_CONTROL_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x50 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:165:0: note: this is the location of the previous definition + #define P_AO_I2C_S_CONTROL_REG AOBUS_REG_ADDR(AO_I2C_S_CONTROL_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:113:0: warning: "P_AO_I2C_S_SEND_REG" redefined [enabled by default] + #define P_AO_I2C_S_SEND_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x51 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:167:0: note: this is the location of the previous definition + #define P_AO_I2C_S_SEND_REG AOBUS_REG_ADDR(AO_I2C_S_SEND_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:114:0: warning: "P_AO_I2C_S_RECV_REG" redefined [enabled by default] + #define P_AO_I2C_S_RECV_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x52 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:169:0: note: this is the location of the previous definition + #define P_AO_I2C_S_RECV_REG AOBUS_REG_ADDR(AO_I2C_S_RECV_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:115:0: warning: "P_AO_I2C_S_CNTL1_REG" redefined [enabled by default] + #define P_AO_I2C_S_CNTL1_REG (volatile unsigned long *)(IO_AOBUS_BASE | (0x01 << 10) | (0x53 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:171:0: note: this is the location of the previous definition + #define P_AO_I2C_S_CNTL1_REG AOBUS_REG_ADDR(AO_I2C_S_CNTL1_REG) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:122:0: warning: "P_AO_RTC_ADDR0" redefined [enabled by default] + #define P_AO_RTC_ADDR0 (volatile unsigned long *)(0xDA004000 | (0xd0 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:173:0: note: this is the location of the previous definition + #define P_AO_RTC_ADDR0 AOBUS_REG_ADDR(AO_RTC_ADDR0) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:123:0: warning: "P_AO_RTC_ADDR1" redefined [enabled by default] + #define P_AO_RTC_ADDR1 (volatile unsigned long *)(0xDA004000 | (0xd1 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:175:0: note: this is the location of the previous definition + #define P_AO_RTC_ADDR1 AOBUS_REG_ADDR(AO_RTC_ADDR1) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:124:0: warning: "P_AO_RTC_ADDR2" redefined [enabled by default] + #define P_AO_RTC_ADDR2 (volatile unsigned long *)(0xDA004000 | (0xd2 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:177:0: note: this is the location of the previous definition + #define P_AO_RTC_ADDR2 AOBUS_REG_ADDR(AO_RTC_ADDR2) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:125:0: warning: "P_AO_RTC_ADDR3" redefined [enabled by default] + #define P_AO_RTC_ADDR3 (volatile unsigned long *)(0xDA004000 | (0xd3 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:179:0: note: this is the location of the previous definition + #define P_AO_RTC_ADDR3 AOBUS_REG_ADDR(AO_RTC_ADDR3) + ^ +In file included from bl2/firmware/spl.c:9:0, + from bl2/bl2_main.c:43: +bl2/firmware/c_always_on_pointer.h:126:0: warning: "P_AO_RTC_ADDR4" redefined [enabled by default] + #define P_AO_RTC_ADDR4 (volatile unsigned long *)(0xDA004000 | (0xd4 << 2)) + ^ +In file included from bl2/firmware/spl.c:8:0, + from bl2/bl2_main.c:43: +bl2/firmware/ao_reg.h:181:0: note: this is the location of the previous definition + #define P_AO_RTC_ADDR4 AOBUS_REG_ADDR(AO_RTC_ADDR4) + ^ +In file included from bl2/firmware/spl.c:10:0, + from bl2/bl2_main.c:43: +bl2/firmware/cache.h: In function ‘invalidate_l2_cache’: +bl2/firmware/cache.h:37:2: error: ‘asm’ undeclared (first use in this function) + asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache" + ^ +bl2/firmware/cache.h:37:6: error: expected ‘;’ before ‘volatile’ + asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache" + ^ +bl2/firmware/cache.h:35:15: warning: unused variable ‘val’ [-Wunused-variable] + unsigned int val=0; + ^ +In file included from bl2/firmware/spl.c:12:0, + from bl2/bl2_main.c:43: +bl2/firmware/canvas.h: At top level: +bl2/firmware/canvas.h:26:2: error: unknown type name ‘ulong’ + ulong addr; + ^ +bl2/firmware/canvas.h:27:2: error: unknown type name ‘u32’ + u32 width; + ^ +bl2/firmware/canvas.h:28:2: error: unknown type name ‘u32’ + u32 height; + ^ +bl2/firmware/canvas.h:29:2: error: unknown type name ‘u32’ + u32 wrap; + ^ +bl2/firmware/canvas.h:30:2: error: unknown type name ‘u32’ + u32 blkmode; + ^ +bl2/firmware/canvas.h:51:27: error: unknown type name ‘u32’ + extern void canvas_config(u32 index, ulong addr, u32 width, + ^ +bl2/firmware/canvas.h:51:38: error: unknown type name ‘ulong’ + extern void canvas_config(u32 index, ulong addr, u32 width, + ^ +bl2/firmware/canvas.h:51:50: error: unknown type name ‘u32’ + extern void canvas_config(u32 index, ulong addr, u32 width, + ^ +bl2/firmware/canvas.h:52:27: error: unknown type name ‘u32’ + u32 height, u32 wrap, u32 blkmode); + ^ +bl2/firmware/canvas.h:52:39: error: unknown type name ‘u32’ + u32 height, u32 wrap, u32 blkmode); + ^ +bl2/firmware/canvas.h:52:49: error: unknown type name ‘u32’ + u32 height, u32 wrap, u32 blkmode); + ^ +bl2/firmware/canvas.h:54:25: error: unknown type name ‘u32’ + extern void canvas_read(u32 index, canvas_t *p); + ^ +bl2/firmware/canvas.h:58:32: error: unknown type name ‘u32’ + extern void canvas_update_addr(u32 index, u32 addr); + ^ +bl2/firmware/canvas.h:58:43: error: unknown type name ‘u32’ + extern void canvas_update_addr(u32 index, u32 addr); + ^ +bl2/firmware/canvas.h:60:37: error: unknown type name ‘u32’ + extern unsigned int canvas_get_addr(u32 index); + ^ +In file included from bl2/firmware/spl.c:15:0, + from bl2/bl2_main.c:43: +bl2/firmware/reg_addr.h:102:0: warning: "P_AM_ANALOG_TOP_REG1" redefined [enabled by default] + #define P_AM_ANALOG_TOP_REG1 CBUS_REG_ADDR(AM_ANALOG_TOP_REG1) + ^ +In file included from bl2/bl2_main.c:42:0: +bl2/ddr/ddr.c:30:0: note: this is the location of the previous definition + #define P_AM_ANALOG_TOP_REG1 0xC11081BC + ^ +In file included from bl2/firmware/spl.c:15:0, + from bl2/bl2_main.c:43: +bl2/firmware/reg_addr.h:595:0: warning: "P_HHI_MPLL_CNTL5" redefined [enabled by default] + #define P_HHI_MPLL_CNTL5 CBUS_REG_ADDR(HHI_MPLL_CNTL5) + ^ +In file included from bl2/bl2_main.c:42:0: +bl2/ddr/ddr.c:31:0: note: this is the location of the previous definition + #define P_HHI_MPLL_CNTL5 0xC883C290 + ^ +In file included from bl2/firmware/spl.c:15:0, + from bl2/bl2_main.c:43: +bl2/firmware/reg_addr.h:614:0: warning: "P_HHI_SYS_PLL_CNTL" redefined [enabled by default] + #define P_HHI_SYS_PLL_CNTL CBUS_REG_ADDR(HHI_SYS_PLL_CNTL) + ^ +In file included from bl2/bl2_main.c:42:0: +bl2/ddr/ddr.c:32:0: note: this is the location of the previous definition + #define P_HHI_SYS_PLL_CNTL 0xC883C300 + ^ +In file included from bl2/firmware/spl.c:19:0, + from bl2/bl2_main.c:43: +bl2/firmware/string.h:20:44: error: unknown type name ‘__kernel_size_t’ + extern void * memcpy(void *, const void *, __kernel_size_t); + ^ +bl2/firmware/string.h:27:45: error: unknown type name ‘__kernel_size_t’ + extern void * memmove(void *, const void *, __kernel_size_t); + ^ +bl2/firmware/string.h:30:41: error: unknown type name ‘__kernel_size_t’ + extern void * memchr(const void *, int, __kernel_size_t); + ^ +bl2/firmware/string.h:39:35: error: unknown type name ‘__kernel_size_t’ + extern void * memset(void *, int, __kernel_size_t); + ^ +bl2/firmware/string.h:57:32: error: unknown type name ‘__kernel_size_t’ + extern void memzero(void *ptr, __kernel_size_t n); + ^ +In file included from bl2/firmware/spl.c:22:0, + from bl2/bl2_main.c:43: +bl2/firmware/timer.c:4:0: warning: "PREG_CTLREG0_ADDR" redefined [enabled by default] + #define PREG_CTLREG0_ADDR 0x1233333 + ^ +In file included from bl2/firmware/aml_eth_reg.h:474:0, + from bl2/firmware/spl.c:5, + from bl2/bl2_main.c:43: +bl2/firmware/register.h:372:0: note: this is the location of the previous definition + #define PREG_CTLREG0_ADDR 0x2000 + ^ +In file included from bl2/firmware/spl.c:22:0, + from bl2/bl2_main.c:43: +bl2/firmware/timer.c:5:0: warning: "P_ISA_TIMER_MUX" redefined [enabled by default] + #define P_ISA_TIMER_MUX 0x1233333 + ^ +In file included from bl2/firmware/spl.c:15:0, + from bl2/bl2_main.c:43: +bl2/firmware/reg_addr.h:446:0: note: this is the location of the previous definition + #define P_ISA_TIMER_MUX CBUS_REG_ADDR(ISA_TIMER_MUX) + ^ +In file included from bl2/firmware/spl.c:22:0, + from bl2/bl2_main.c:43: +bl2/firmware/timer.c: In function ‘timer_init’: +bl2/firmware/timer.c:8:5: warning: implicit declaration of function ‘WRITE_CBUS_REG_BITS’ [-Wimplicit-function-declaration] + WRITE_CBUS_REG_BITS(PREG_CTLREG0_ADDR,CONFIG_CRYSTAL_MHZ,4,5); + ^ +bl2/firmware/timer.c: In function ‘get_utimer’: +bl2/firmware/timer.c:15:5: warning: implicit declaration of function ‘READ_CBUS_REG’ [-Wimplicit-function-declaration] + return TIMERE_SUB(TIMERE_GET(),base); + ^ +In file included from bl2/firmware/timming.c:5:0, + from bl2/firmware/spl.c:23, + from bl2/bl2_main.c:43: +bl2/firmware/uart.h: At top level: +bl2/firmware/uart.h:27:0: warning: "UART_PORT_CONS" redefined [enabled by default] + #define UART_PORT_CONS UART_PORT_AO + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:11:0: note: this is the location of the previous definition + #define UART_PORT_CONS P_AO_UART_WFIFO + ^ +In file included from bl2/firmware/timming.c:5:0, + from bl2/firmware/spl.c:23, + from bl2/bl2_main.c:43: +bl2/firmware/uart.h:51:0: warning: "UART_WFIFO" redefined [enabled by default] + #define UART_WFIFO 0 + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:6:0: note: this is the location of the previous definition + #define UART_WFIFO (0<<2) + ^ +In file included from bl2/firmware/timming.c:5:0, + from bl2/firmware/spl.c:23, + from bl2/bl2_main.c:43: +bl2/firmware/uart.h:52:0: warning: "UART_RFIFO" redefined [enabled by default] + #define UART_RFIFO 1 + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:7:0: note: this is the location of the previous definition + #define UART_RFIFO (1<<2) + ^ +In file included from bl2/firmware/timming.c:5:0, + from bl2/firmware/spl.c:23, + from bl2/bl2_main.c:43: +bl2/firmware/uart.h:53:0: warning: "UART_CONTROL" redefined [enabled by default] + #define UART_CONTROL 2 + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:8:0: note: this is the location of the previous definition + #define UART_CONTROL (2<<2) + ^ +In file included from bl2/firmware/timming.c:5:0, + from bl2/firmware/spl.c:23, + from bl2/bl2_main.c:43: +bl2/firmware/uart.h:54:0: warning: "UART_STATUS" redefined [enabled by default] + #define UART_STATUS 3 + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:9:0: note: this is the location of the previous definition + #define UART_STATUS (3<<2) + ^ +In file included from bl2/firmware/timming.c:5:0, + from bl2/firmware/spl.c:23, + from bl2/bl2_main.c:43: +bl2/firmware/uart.h:55:0: warning: "UART_MISC" redefined [enabled by default] + #define UART_MISC 4 + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:10:0: note: this is the location of the previous definition + #define UART_MISC (4<<2) + ^ +In file included from bl2/firmware/timming.c:5:0, + from bl2/firmware/spl.c:23, + from bl2/bl2_main.c:43: +bl2/firmware/uart.h:58:0: warning: "P_UART" redefined [enabled by default] + #define P_UART(uart_base,reg) (uart_base + (reg<<2)) + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:14:0: note: this is the location of the previous definition + #define P_UART(uart_base,reg) (uart_base+reg) + ^ +In file included from bl2/firmware/timming.c:5:0, + from bl2/firmware/spl.c:23, + from bl2/bl2_main.c:43: +bl2/firmware/uart.h:93:0: warning: "UART_STAT_MASK_RFIFO_CNT" redefined [enabled by default] + #define UART_STAT_MASK_RFIFO_CNT (0x7f<<0) + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:46:0: note: this is the location of the previous definition + #define UART_STAT_MASK_RFIFO_CNT (0x3f<<0) + ^ +In file included from bl2/firmware/timming.c:5:0, + from bl2/firmware/spl.c:23, + from bl2/bl2_main.c:43: +bl2/firmware/uart.h:94:0: warning: "UART_STAT_MASK_TFIFO_CNT" redefined [enabled by default] + #define UART_STAT_MASK_TFIFO_CNT (0x7f<<8) + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:47:0: note: this is the location of the previous definition + #define UART_STAT_MASK_TFIFO_CNT (0x3f<<8) + ^ +In file included from bl2/firmware/timming.c:5:0, + from bl2/firmware/spl.c:23, + from bl2/bl2_main.c:43: +bl2/firmware/uart.h:104:0: warning: "P_UART_MISC" redefined [enabled by default] + #define P_UART_MISC(uart_base) P_UART(uart_base,UART_MISC ) + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:55:0: note: this is the location of the previous definition + #define P_UART_MISC(uart_base) P_UART(uart_base,UART_MISC) + ^ +In file included from bl2/firmware/spl.c:25:0, + from bl2/bl2_main.c:43: +bl2/firmware/serial.c: In function ‘serial_init’: +bl2/firmware/serial.c:39:5: warning: passing argument 1 of ‘serial_set_pin_port’ makes integer from pointer without a cast [enabled by default] + serial_set_pin_port(UART_PORT_CONS); + ^ +In file included from bl2/firmware/spl.c:24:0, + from bl2/bl2_main.c:43: +bl2/firmware/uartpin.c:5:21: note: expected ‘unsigned int’ but argument is of type ‘volatile long unsigned int *’ + SPL_STATIC_FUNC int serial_set_pin_port(unsigned port_base) + ^ +In file included from bl2/firmware/spl.c:27:0, + from bl2/bl2_main.c:43: +bl2/firmware/sdpinmux.c: In function ‘disable_sdio’: +bl2/firmware/sdpinmux.c:21:5: warning: implicit declaration of function ‘CBUS_REG_ADDR’ [-Wimplicit-function-declaration] + setbits_le32(P_PREG_PAD_GPIO5_O,(1<<31)); + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/sdpinmux.c:21:5: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_PREG_PAD_GPIO5_O,(1<<31)); + ^ +include/drivers/serial/serial.h:60:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define clrbits_le32(reg,val) (*((volatile unsigned *)reg))&=(~val) + ^ +bl2/firmware/sdpinmux.c:22:5: note: in expansion of macro ‘clrbits_le32’ + clrbits_le32(P_PREG_PAD_GPIO5_EN_N,(1<<31)); + ^ +include/drivers/serial/serial.h:60:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define clrbits_le32(reg,val) (*((volatile unsigned *)reg))&=(~val) + ^ +bl2/firmware/sdpinmux.c:27:13: note: in expansion of macro ‘clrbits_le32’ + clrbits_le32(P_PERIPHS_PIN_MUX_8,0x3f); + ^ +include/drivers/serial/serial.h:60:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define clrbits_le32(reg,val) (*((volatile unsigned *)reg))&=(~val) + ^ +bl2/firmware/sdpinmux.c:30:13: note: in expansion of macro ‘clrbits_le32’ + clrbits_le32(P_PERIPHS_PIN_MUX_2,0x3f<<10); + ^ +include/drivers/serial/serial.h:60:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define clrbits_le32(reg,val) (*((volatile unsigned *)reg))&=(~val) + ^ +bl2/firmware/sdpinmux.c:33:13: note: in expansion of macro ‘clrbits_le32’ + clrbits_le32(P_PERIPHS_PIN_MUX_6,(0x3f<<24)); + ^ +bl2/firmware/sdpinmux.c: In function ‘enable_sdio’: +include/drivers/serial/serial.h:60:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define clrbits_le32(reg,val) (*((volatile unsigned *)reg))&=(~val) + ^ +bl2/firmware/sdpinmux.c:43:5: note: in expansion of macro ‘clrbits_le32’ + clrbits_le32(P_PREG_PAD_GPIO5_O,(1<<31)); + ^ +include/drivers/serial/serial.h:60:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define clrbits_le32(reg,val) (*((volatile unsigned *)reg))&=(~val) + ^ +bl2/firmware/sdpinmux.c:44:5: note: in expansion of macro ‘clrbits_le32’ + clrbits_le32(P_PREG_PAD_GPIO5_EN_N,(1<<31)); + ^ +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/sdpinmux.c:49:13: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_PERIPHS_PIN_MUX_8,0x3f); + ^ +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/sdpinmux.c:53:13: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_PERIPHS_PIN_MUX_2,0x3f<<10); + ^ +include/drivers/serial/serial.h:60:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define clrbits_le32(reg,val) (*((volatile unsigned *)reg))&=(~val) + ^ +bl2/firmware/sdpinmux.c:57:13: note: in expansion of macro ‘clrbits_le32’ + clrbits_le32(P_PERIPHS_PIN_MUX_2,(0x1f<<22)); + ^ +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/sdpinmux.c:58:13: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_PERIPHS_PIN_MUX_6,(0x3f<<24)); + ^ +bl2/firmware/pll.c: In function ‘clk_util_clk_msr’: +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/pll.c:19:2: note: in expansion of macro ‘writel’ + writel((uS_gate_time-1),P_MSR_CLK_REG0); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/pll.c:22:2: note: in expansion of macro ‘writel’ + writel(readl(P_MSR_CLK_REG0)|(clk_mux<<20) |(1<<19)|(1<<16), + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +include/drivers/serial/serial.h:57:56: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/pll.c:22:9: note: in expansion of macro ‘readl’ + writel(readl(P_MSR_CLK_REG0)|(clk_mux<<20) |(1<<19)|(1<<16), + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/pll.c:26:15: note: in expansion of macro ‘readl’ + { dummy_rd = readl(P_MSR_CLK_REG0); } + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/pll.c:29:10: note: in expansion of macro ‘readl’ + while( (readl(P_MSR_CLK_REG0) & (1 << 31)) ) {} + ^ +include/drivers/serial/serial.h:60:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define clrbits_le32(reg,val) (*((volatile unsigned *)reg))&=(~val) + ^ +bl2/firmware/pll.c:32:2: note: in expansion of macro ‘clrbits_le32’ + clrbits_le32(P_MSR_CLK_REG0, 1<<16 ); + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/pll.c:34:17: note: in expansion of macro ‘readl’ + measured_val = readl(P_MSR_CLK_REG2)&0xFFFFF; //20bit length + ^ +In file included from bl2/firmware/spl.c:29:0, + from bl2/bl2_main.c:43: +bl2/firmware/pll.c:16:18: warning: variable ‘dummy_rd’ set but not used [-Wunused-but-set-variable] + unsigned long dummy_rd; + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/pll.c: In function ‘pll_init’: +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:33:3: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); \ + ^ +bl2/firmware/timing.h:138:5: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); \ + ^ +bl2/firmware/pll.c:121:3: note: in expansion of macro ‘PLL_LOCK_CHECK’ + PLL_LOCK_CHECK(n_pll_try_times,1); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:34:3: note: in expansion of macro ‘writel’ + writel((10|((1<<AML_WATCHDOG_ENABLE_OFFSET)| \ + ^ +bl2/firmware/timing.h:138:5: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); \ + ^ +bl2/firmware/pll.c:121:3: note: in expansion of macro ‘PLL_LOCK_CHECK’ + PLL_LOCK_CHECK(n_pll_try_times,1); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:33:3: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); \ + ^ +bl2/firmware/timing.h:138:5: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); \ + ^ +bl2/firmware/pll.c:149:3: note: in expansion of macro ‘PLL_LOCK_CHECK’ + PLL_LOCK_CHECK(n_pll_try_times,5); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:34:3: note: in expansion of macro ‘writel’ + writel((10|((1<<AML_WATCHDOG_ENABLE_OFFSET)| \ + ^ +bl2/firmware/timing.h:138:5: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); \ + ^ +bl2/firmware/pll.c:149:3: note: in expansion of macro ‘PLL_LOCK_CHECK’ + PLL_LOCK_CHECK(n_pll_try_times,5); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:33:3: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); \ + ^ +bl2/firmware/timing.h:138:5: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); \ + ^ +bl2/firmware/pll.c:184:3: note: in expansion of macro ‘PLL_LOCK_CHECK’ + PLL_LOCK_CHECK(n_pll_try_times,2); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:34:3: note: in expansion of macro ‘writel’ + writel((10|((1<<AML_WATCHDOG_ENABLE_OFFSET)| \ + ^ +bl2/firmware/timing.h:138:5: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); \ + ^ +bl2/firmware/pll.c:184:3: note: in expansion of macro ‘PLL_LOCK_CHECK’ + PLL_LOCK_CHECK(n_pll_try_times,2); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:33:3: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); \ + ^ +bl2/firmware/timing.h:138:5: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); \ + ^ +bl2/firmware/pll.c:203:4: note: in expansion of macro ‘PLL_LOCK_CHECK’ + PLL_LOCK_CHECK(n_pll_try_times,6); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:34:3: note: in expansion of macro ‘writel’ + writel((10|((1<<AML_WATCHDOG_ENABLE_OFFSET)| \ + ^ +bl2/firmware/timing.h:138:5: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); \ + ^ +bl2/firmware/pll.c:203:4: note: in expansion of macro ‘PLL_LOCK_CHECK’ + PLL_LOCK_CHECK(n_pll_try_times,6); + ^ +In file included from bl2/firmware/spl.c:32:0, + from bl2/bl2_main.c:43: +bl2/firmware/power.c: At top level: +bl2/firmware/power.c:46:30: warning: ISO C forbids empty initializer braces [-Wpedantic] + static char format_buf[12] = {}; + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/power.c: In function ‘vcck_set_default_voltage’: +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/power.c:121:5: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_PERIPHS_PIN_MUX_2, (1 << 2)); + ^ +include/drivers/serial/serial.h:60:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define clrbits_le32(reg,val) (*((volatile unsigned *)reg))&=(~val) + ^ +bl2/firmware/power.c:122:5: note: in expansion of macro ‘clrbits_le32’ + clrbits_le32(P_PERIPHS_PIN_MUX_1, (1 << 29)); + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/power.c:123:15: note: in expansion of macro ‘readl’ + misc_cd = readl(P_PWM_MISC_REG_CD); + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/power.c:139:20: note: in expansion of macro ‘readl’ + serial_put_hex(readl(P_PWM_PWM_C), 32); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/power.c:143:5: note: in expansion of macro ‘writel’ + writel(vcck_pwm_table[i].pwm_value, P_PWM_PWM_C); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/power.c:144:5: note: in expansion of macro ‘writel’ + writel(((misc_cd & ~(0x7f << 8)) | ((1 << 15) | (PWM_PRE_DIV << 8) | (1 << 0))), P_PWM_MISC_REG_CD); + ^ +bl2/firmware/ddr_init_hw.c: In function ‘init_dmc_m8m2’: +bl2/firmware/ddr_init_hw.c:7:37: error: ‘P_DMC_DDR_CTRL’ undeclared (first use in this function) + writel(timing_set->t_mmc_ddr_ctrl, P_DMC_DDR_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:14:21: error: ‘DMC_SEC_AM_PORT_CTRL’ undeclared (first use in this function) + writel(0xffffffff, DMC_SEC_AM_PORT_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:15:21: error: ‘DMC_DEV_RANGE_CTRL’ undeclared (first use in this function) + writel(0xffffffff, DMC_DEV_RANGE_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:16:21: error: ‘DMC_DEV_RANGE_CTRL1’ undeclared (first use in this function) + writel(0xffffffff, DMC_DEV_RANGE_CTRL1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:17:21: error: ‘M8M2_DMC_SEC_CTRL’ undeclared (first use in this function) + writel(0x80000000, M8M2_DMC_SEC_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:20:30: error: ‘P_DMC_2ARB_CTRL’ undeclared (first use in this function) + writel((0x1f | (0xf << 6)), P_DMC_2ARB_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:23:21: error: ‘P_DMC_REFR_CTRL2’ undeclared (first use in this function) + writel(0x20109a27, P_DMC_REFR_CTRL2); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:24:19: error: ‘P_DMC_REFR_CTRL1’ undeclared (first use in this function) + writel(0x80389f, P_DMC_REFR_CTRL1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:27:17: error: ‘P_DMC_REQ_CTRL’ undeclared (first use in this function) + writel(0xffff, P_DMC_REQ_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +In file included from bl2/firmware/ddr.c:16:0, + from bl2/firmware/spl.c:34, + from bl2/bl2_main.c:43: +bl2/firmware/ddr_init_hw.c:30:2: warning: implicit declaration of function ‘asm’ [-Wimplicit-function-declaration] + asm("NOP"); + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/ddr_init_hw.c: In function ‘init_dmc_m8’: +bl2/firmware/ddr_init_hw.c:51:37: error: ‘P_MMC_DDR_CTRL’ undeclared (first use in this function) + writel(timing_set->t_mmc_ddr_ctrl, P_MMC_DDR_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:53:21: error: ‘DMC_SEC_RANGE0_ST’ undeclared (first use in this function) + writel(0x00000000, DMC_SEC_RANGE0_ST); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:54:21: error: ‘DMC_SEC_RANGE0_END’ undeclared (first use in this function) + writel(0xffffffff, DMC_SEC_RANGE0_END); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:55:17: error: ‘DMC_SEC_PORT0_RANGE0’ undeclared (first use in this function) + writel(0xffff, DMC_SEC_PORT0_RANGE0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:56:17: error: ‘DMC_SEC_PORT1_RANGE0’ undeclared (first use in this function) + writel(0xffff, DMC_SEC_PORT1_RANGE0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:57:17: error: ‘DMC_SEC_PORT2_RANGE0’ undeclared (first use in this function) + writel(0xffff, DMC_SEC_PORT2_RANGE0); + ^ +bl2/firmware/ddr_init_hw.c:57:2: note: in expansion of macro ‘writel’ + writel(0xffff, DMC_SEC_PORT2_RANGE0); + ^ +bl2/firmware/ddr_init_hw.c:58:17: error: ‘DMC_SEC_PORT3_RANGE0’ undeclared (first use in this function) + writel(0xffff, DMC_SEC_PORT3_RANGE0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:59:17: error: ‘DMC_SEC_PORT4_RANGE0’ undeclared (first use in this function) + writel(0xffff, DMC_SEC_PORT4_RANGE0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:60:17: error: ‘DMC_SEC_PORT5_RANGE0’ undeclared (first use in this function) + writel(0xffff, DMC_SEC_PORT5_RANGE0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:61:17: error: ‘DMC_SEC_PORT6_RANGE0’ undeclared (first use in this function) + writel(0xffff, DMC_SEC_PORT6_RANGE0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:62:17: error: ‘DMC_SEC_PORT7_RANGE0’ undeclared (first use in this function) + writel(0xffff, DMC_SEC_PORT7_RANGE0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:63:17: error: ‘DMC_SEC_PORT8_RANGE0’ undeclared (first use in this function) + writel(0xffff, DMC_SEC_PORT8_RANGE0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:64:17: error: ‘DMC_SEC_PORT9_RANGE0’ undeclared (first use in this function) + writel(0xffff, DMC_SEC_PORT9_RANGE0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:65:17: error: ‘DMC_SEC_PORT10_RANGE0’ undeclared (first use in this function) + writel(0xffff, DMC_SEC_PORT10_RANGE0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:66:17: error: ‘DMC_SEC_PORT11_RANGE0’ undeclared (first use in this function) + writel(0xffff, DMC_SEC_PORT11_RANGE0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:67:21: error: ‘M8_DMC_SEC_CTRL’ undeclared (first use in this function) + writel(0x80000000, M8_DMC_SEC_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:75:16: error: ‘P_MMC_REQ_CTRL’ undeclared (first use in this function) + writel(0xfff, P_MMC_REQ_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:79:41: error: ‘P_MMC_DDR_TIMING0’ undeclared (first use in this function) + writel(timing_set->t_mmc_ddr_timming0, P_MMC_DDR_TIMING0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:80:41: error: ‘P_MMC_DDR_TIMING1’ undeclared (first use in this function) + writel(timing_set->t_mmc_ddr_timming1, P_MMC_DDR_TIMING1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:81:41: error: ‘P_MMC_DDR_TIMING2’ undeclared (first use in this function) + writel(timing_set->t_mmc_ddr_timming2, P_MMC_DDR_TIMING2); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:82:39: error: ‘P_MMC_AREFR_CTRL’ undeclared (first use in this function) + writel(timing_set->t_mmc_arefr_ctrl, P_MMC_AREFR_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c:85:12: error: ‘P_MMC_PARB_CTRL’ undeclared (first use in this function) + writel(0, P_MMC_PARB_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_hw.c: In function ‘ddr_init_hw’: +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:33:3: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); \ + ^ +bl2/firmware/ddr_init_hw.c:123:3: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:34:3: note: in expansion of macro ‘writel’ + writel((10|((1<<AML_WATCHDOG_ENABLE_OFFSET)| \ + ^ +bl2/firmware/ddr_init_hw.c:123:3: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +bl2/firmware/ddr_init_hw.c: In function ‘ddr_info_dump’: +bl2/firmware/ddr_init_hw.c:160:30: error: ‘M8M2_DMC_SEC_CTRL’ undeclared (first use in this function) + dmc_sec_ctrl_value = readl(M8M2_DMC_SEC_CTRL); + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/ddr_init_hw.c:166:30: error: ‘M8_DMC_SEC_CTRL’ undeclared (first use in this function) + dmc_sec_ctrl_value = readl(M8_DMC_SEC_CTRL); + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/ddr_init_pctl.c: In function ‘init_pctl_ddr3’: +bl2/firmware/ddr_init_pctl.c:176:13: error: ‘P_DMC_SOFT_RST’ undeclared (first use in this function) + writel(0, P_DMC_SOFT_RST); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:177:13: error: ‘P_DMC_SOFT_RST1’ undeclared (first use in this function) + writel(0, P_DMC_SOFT_RST1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:186:13: error: ‘P_MMC_SOFT_RST’ undeclared (first use in this function) + writel(0, P_MMC_SOFT_RST); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:187:13: error: ‘P_MMC_SOFT_RST1’ undeclared (first use in this function) + writel(0, P_MMC_SOFT_RST1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:210:15: error: ‘P_DDR0_SOFT_RESET’ undeclared (first use in this function) + writel(0x0, P_DDR0_SOFT_RESET); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:214:15: error: ‘P_DDR1_SOFT_RESET’ undeclared (first use in this function) + writel(0x0, P_DDR1_SOFT_RESET); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:221:38: error: ‘P_DDR0_APD_CTRL’ undeclared (first use in this function) + writel(timing_set->t_ddr_apd_ctrl, P_DDR0_APD_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:226:38: error: ‘P_DDR0_CLK_CTRL’ undeclared (first use in this function) + writel(timing_set->t_ddr_clk_ctrl, P_DDR0_CLK_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:233:38: error: ‘P_DDR1_APD_CTRL’ undeclared (first use in this function) + writel(timing_set->t_ddr_apd_ctrl, P_DDR1_APD_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:238:38: error: ‘P_DDR1_CLK_CTRL’ undeclared (first use in this function) + writel(timing_set->t_ddr_clk_ctrl, P_DDR1_CLK_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:243:21: error: ‘P_DDR0_PUB_IOVCR0’ undeclared (first use in this function) + writel(0x49494949,P_DDR0_PUB_IOVCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:244:21: error: ‘P_DDR0_PUB_IOVCR1’ undeclared (first use in this function) + writel(0x49494949,P_DDR0_PUB_IOVCR1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:247:21: error: ‘P_DDR1_PUB_IOVCR0’ undeclared (first use in this function) + writel(0x49494949,P_DDR1_PUB_IOVCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:248:21: error: ‘P_DDR1_PUB_IOVCR1’ undeclared (first use in this function) + writel(0x49494949,P_DDR1_PUB_IOVCR1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:253:40: error: ‘P_DDR0_PCTL_TOGCNT1U’ undeclared (first use in this function) + writel(timing_set->t_pctl_1us_pck, P_DDR0_PCTL_TOGCNT1U); //1us = nn cycles. + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:254:40: error: ‘P_DDR0_PCTL_TOGCNT100N’ undeclared (first use in this function) + writel(timing_set->t_pctl_100ns_pck, P_DDR0_PCTL_TOGCNT100N); //100ns = nn cycles. + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:255:40: error: ‘P_DDR0_PCTL_TINIT’ undeclared (first use in this function) + writel(timing_set->t_pctl_init_us, P_DDR0_PCTL_TINIT); //200us. + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:256:40: error: ‘P_DDR0_PCTL_TRSTH’ undeclared (first use in this function) + writel(timing_set->t_pctl_rsth_us, P_DDR0_PCTL_TRSTH); // 0 for ddr2; 2 for simulation; 500 for ddr3. + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:257:40: error: ‘P_DDR0_PCTL_TRSTL’ undeclared (first use in this function) + writel(timing_set->t_pctl_rstl_us, P_DDR0_PCTL_TRSTL); // 0 for ddr2; 2 for simulation; 500 for ddr3. + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:263:36: error: ‘P_DDR0_PCTL_MCFG’ undeclared (first use in this function) + writel(timing_set->t_pctl_mcfg, P_DDR0_PCTL_MCFG ); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:265:36: error: ‘P_DDR0_PCTL_MCFG1’ undeclared (first use in this function) + writel(timing_set->t_pctl_mcfg1, P_DDR0_PCTL_MCFG1); //enable hardware c_active_in; + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:267:33: error: ‘P_DDR0_PUB_DCR’ undeclared (first use in this function) + writel(timing_set->t_pub_dcr, P_DDR0_PUB_DCR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:269:35: error: ‘P_DDR0_PUB_MR0’ undeclared (first use in this function) + writel(timing_set->t_pub_mr[0], P_DDR0_PUB_MR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:270:35: error: ‘P_DDR0_PUB_MR1’ undeclared (first use in this function) + writel(timing_set->t_pub_mr[1], P_DDR0_PUB_MR1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:271:35: error: ‘P_DDR0_PUB_MR2’ undeclared (first use in this function) + writel(timing_set->t_pub_mr[2], P_DDR0_PUB_MR2); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:272:35: error: ‘P_DDR0_PUB_MR3’ undeclared (first use in this function) + writel(timing_set->t_pub_mr[3], P_DDR0_PUB_MR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:275:38: error: ‘P_DDR0_PUB_DTPR0’ undeclared (first use in this function) + writel( timing_set->t_pub_dtpr[0], P_DDR0_PUB_DTPR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:276:38: error: ‘P_DDR0_PUB_DTPR1’ undeclared (first use in this function) + writel( timing_set->t_pub_dtpr[1], P_DDR0_PUB_DTPR1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:277:38: error: ‘P_DDR0_PUB_DTPR2’ undeclared (first use in this function) + writel( timing_set->t_pub_dtpr[2], P_DDR0_PUB_DTPR2); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:280:60: error: ‘P_DDR0_PUB_PGCR2’ undeclared (first use in this function) + writel( (readl(P_DDR0_PUB_PGCR2) & 0xfffc0000) | 0xc00 , P_DDR0_PUB_PGCR2 ); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:284:98: error: ‘P_DDR0_PUB_DTCR’ undeclared (first use in this function) + writel( ((readl(P_DDR1_PUB_DTCR) & 0x00ffffbf) | (1 << 28 ) | (1 << 24) | (1 << 6) |(1<<23) ), P_DDR0_PUB_DTCR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:284:19: error: ‘P_DDR1_PUB_DTCR’ undeclared (first use in this function) + writel( ((readl(P_DDR1_PUB_DTCR) & 0x00ffffbf) | (1 << 28 ) | (1 << 24) | (1 << 6) |(1<<23) ), P_DDR0_PUB_DTCR); + ^ +include/drivers/serial/serial.h:57:56: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:284:13: note: in expansion of macro ‘readl’ + writel( ((readl(P_DDR1_PUB_DTCR) & 0x00ffffbf) | (1 << 28 ) | (1 << 24) | (1 << 6) |(1<<23) ), P_DDR0_PUB_DTCR); + ^ +bl2/firmware/ddr_init_pctl.c:287:15: error: ‘P_DDR0_PUB_DX0GCR3’ undeclared (first use in this function) + writel(0x8, P_DDR0_PUB_DX0GCR3); //for pdr mode bug //for pdr mode bug this will cause some chip bit deskew jiaxing add + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:288:15: error: ‘P_DDR0_PUB_DX1GCR3’ undeclared (first use in this function) + writel(0x8, P_DDR0_PUB_DX1GCR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:289:15: error: ‘P_DDR0_PUB_DX2GCR3’ undeclared (first use in this function) + writel(0x8, P_DDR0_PUB_DX2GCR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:290:15: error: ‘P_DDR0_PUB_DX3GCR3’ undeclared (first use in this function) + writel(0x8, P_DDR0_PUB_DX3GCR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:296:47: error: ‘P_DDR0_PUB_DSGCR’ undeclared (first use in this function) + writel((readl(P_DDR0_PUB_DSGCR))|(0x1<<06), P_DDR0_PUB_DSGCR); //eanble gate extension dqs gate can help to bit deskew also + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:299:49: error: ‘P_DDR0_PUB_ZQCR’ undeclared (first use in this function) + writel(((readl(P_DDR0_PUB_ZQCR))&0xff01fffc), P_DDR0_PUB_ZQCR); //for vt bug disable IODLMT + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:306:76: error: ‘P_DDR0_PUB_ZQ0PR’ undeclared (first use in this function) + writel((timing_set->t_pub_zq0pr)|((readl(P_DDR0_PUB_ZQ0PR))&0xffffff00), P_DDR0_PUB_ZQ0PR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:309:35: error: ‘P_DDR0_PUB_DXCCR’ undeclared (first use in this function) + writel(timing_set->t_pub_dxccr, P_DDR0_PUB_DXCCR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:310:67: error: ‘P_DDR0_PUB_ACBDLR0’ undeclared (first use in this function) + writel(readl(P_DDR0_PUB_ACBDLR0) | (timing_set->t_pub_acbdlr0), P_DDR0_PUB_ACBDLR0); //place before write level + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:313:37: error: ‘P_DDR0_PUB_PTR0’ undeclared (first use in this function) + writel(timing_set->t_pub_ptr[0] , P_DDR0_PUB_PTR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:314:37: error: ‘P_DDR0_PUB_PTR1’ undeclared (first use in this function) + writel(timing_set->t_pub_ptr[1] , P_DDR0_PUB_PTR1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:317:50: error: ‘P_DDR0_PUB_ACIOCR0’ undeclared (first use in this function) + writel(readl(P_DDR0_PUB_ACIOCR0) & 0xdfffffff, P_DDR0_PUB_ACIOCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:322:37: error: ‘P_DDR0_PUB_PTR3’ undeclared (first use in this function) + writel(timing_set->t_pub_ptr[3] , P_DDR0_PUB_PTR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:323:37: error: ‘P_DDR0_PUB_PTR4’ undeclared (first use in this function) + writel(timing_set->t_pub_ptr[4] , P_DDR0_PUB_PTR4); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:328:40: error: ‘P_DDR1_PCTL_TOGCNT1U’ undeclared (first use in this function) + writel(timing_set->t_pctl_1us_pck, P_DDR1_PCTL_TOGCNT1U); //1us = nn cycles. + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:329:40: error: ‘P_DDR1_PCTL_TOGCNT100N’ undeclared (first use in this function) + writel(timing_set->t_pctl_100ns_pck, P_DDR1_PCTL_TOGCNT100N); //100ns = nn cycles. + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:330:40: error: ‘P_DDR1_PCTL_TINIT’ undeclared (first use in this function) + writel(timing_set->t_pctl_init_us, P_DDR1_PCTL_TINIT); //200us. + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:331:40: error: ‘P_DDR1_PCTL_TRSTH’ undeclared (first use in this function) + writel(timing_set->t_pctl_rsth_us, P_DDR1_PCTL_TRSTH); // 0 for ddr2; 2 for simulation; 500 for ddr3. + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:332:40: error: ‘P_DDR1_PCTL_TRSTL’ undeclared (first use in this function) + writel(timing_set->t_pctl_rstl_us, P_DDR1_PCTL_TRSTL); // 0 for ddr2; 2 for simulation; 500 for ddr3. + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:338:36: error: ‘P_DDR1_PCTL_MCFG’ undeclared (first use in this function) + writel(timing_set->t_pctl_mcfg, P_DDR1_PCTL_MCFG ); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:340:36: error: ‘P_DDR1_PCTL_MCFG1’ undeclared (first use in this function) + writel(timing_set->t_pctl_mcfg1, P_DDR1_PCTL_MCFG1); //enable hardware c_active_in; + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:342:33: error: ‘P_DDR1_PUB_DCR’ undeclared (first use in this function) + writel(timing_set->t_pub_dcr, P_DDR1_PUB_DCR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:344:35: error: ‘P_DDR1_PUB_MR0’ undeclared (first use in this function) + writel(timing_set->t_pub_mr[0], P_DDR1_PUB_MR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:345:35: error: ‘P_DDR1_PUB_MR1’ undeclared (first use in this function) + writel(timing_set->t_pub_mr[1], P_DDR1_PUB_MR1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:346:35: error: ‘P_DDR1_PUB_MR2’ undeclared (first use in this function) + writel(timing_set->t_pub_mr[2], P_DDR1_PUB_MR2); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:347:35: error: ‘P_DDR1_PUB_MR3’ undeclared (first use in this function) + writel(timing_set->t_pub_mr[3], P_DDR1_PUB_MR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:353:47: error: ‘P_DDR1_PUB_DSGCR’ undeclared (first use in this function) + writel((readl(P_DDR1_PUB_DSGCR))|(0x1<<06), P_DDR1_PUB_DSGCR); //eanble gate extension dqs gate can help to bit deskew also + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:356:49: error: ‘P_DDR1_PUB_ZQCR’ undeclared (first use in this function) + writel(((readl(P_DDR1_PUB_ZQCR))&0xff01fffc), P_DDR1_PUB_ZQCR); //for vt bug disable IODLMT + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:358:38: error: ‘P_DDR1_PUB_DTPR0’ undeclared (first use in this function) + writel( timing_set->t_pub_dtpr[0], P_DDR1_PUB_DTPR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:359:38: error: ‘P_DDR1_PUB_DTPR1’ undeclared (first use in this function) + writel( timing_set->t_pub_dtpr[1], P_DDR1_PUB_DTPR1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:360:38: error: ‘P_DDR1_PUB_DTPR2’ undeclared (first use in this function) + writel( timing_set->t_pub_dtpr[2], P_DDR1_PUB_DTPR2); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:363:60: error: ‘P_DDR1_PUB_PGCR2’ undeclared (first use in this function) + writel( (readl(P_DDR1_PUB_PGCR2) & 0xfffc0000) | 0xc00 , P_DDR1_PUB_PGCR2 ); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:370:15: error: ‘P_DDR1_PUB_DX0GCR3’ undeclared (first use in this function) + writel(0x8, P_DDR1_PUB_DX0GCR3); //for pdr mode bug //for pdr mode bug this will cause some chip bit deskew jiaxing add + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:371:15: error: ‘P_DDR1_PUB_DX1GCR3’ undeclared (first use in this function) + writel(0x8, P_DDR1_PUB_DX1GCR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:372:15: error: ‘P_DDR1_PUB_DX2GCR3’ undeclared (first use in this function) + writel(0x8, P_DDR1_PUB_DX2GCR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:373:15: error: ‘P_DDR1_PUB_DX3GCR3’ undeclared (first use in this function) + writel(0x8, P_DDR1_PUB_DX3GCR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:389:76: error: ‘P_DDR1_PUB_ZQ0PR’ undeclared (first use in this function) + writel((timing_set->t_pub_zq0pr)|((readl(P_DDR1_PUB_ZQ0PR))&0xffffff00), P_DDR1_PUB_ZQ0PR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:392:35: error: ‘P_DDR1_PUB_DXCCR’ undeclared (first use in this function) + writel(timing_set->t_pub_dxccr, P_DDR1_PUB_DXCCR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:393:67: error: ‘P_DDR1_PUB_ACBDLR0’ undeclared (first use in this function) + writel(readl(P_DDR1_PUB_ACBDLR0) | (timing_set->t_pub_acbdlr0), P_DDR1_PUB_ACBDLR0); //place before write level + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:396:37: error: ‘P_DDR1_PUB_PTR0’ undeclared (first use in this function) + writel(timing_set->t_pub_ptr[0] , P_DDR1_PUB_PTR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:397:37: error: ‘P_DDR1_PUB_PTR1’ undeclared (first use in this function) + writel(timing_set->t_pub_ptr[1] , P_DDR1_PUB_PTR1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:400:50: error: ‘P_DDR1_PUB_ACIOCR0’ undeclared (first use in this function) + writel(readl(P_DDR1_PUB_ACIOCR0) & 0xdfffffff, P_DDR1_PUB_ACIOCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:405:37: error: ‘P_DDR1_PUB_PTR3’ undeclared (first use in this function) + writel(timing_set->t_pub_ptr[3] , P_DDR1_PUB_PTR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:406:37: error: ‘P_DDR1_PUB_PTR4’ undeclared (first use in this function) + writel(timing_set->t_pub_ptr[4] , P_DDR1_PUB_PTR4); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:410:17: error: ‘P_DDR0_PCTL_DFISTSTAT0’ undeclared (first use in this function) + while(!(readl(P_DDR0_PCTL_DFISTSTAT0) & 1)) { + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/ddr_init_pctl.c:414:13: error: ‘P_DDR0_PCTL_POWCTL’ undeclared (first use in this function) + writel(1, P_DDR0_PCTL_POWCTL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:415:17: error: ‘P_DDR0_PCTL_POWSTAT’ undeclared (first use in this function) + while(!(readl(P_DDR0_PCTL_POWSTAT) & 1) ) { + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/ddr_init_pctl.c:420:17: error: ‘P_DDR1_PCTL_DFISTSTAT0’ undeclared (first use in this function) + while(!(readl(P_DDR1_PCTL_DFISTSTAT0) & 1)) { + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/ddr_init_pctl.c:424:13: error: ‘P_DDR1_PCTL_POWCTL’ undeclared (first use in this function) + writel(1, P_DDR1_PCTL_POWCTL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:425:17: error: ‘P_DDR1_PCTL_POWSTAT’ undeclared (first use in this function) + while(!(readl(P_DDR1_PCTL_POWSTAT) & 1) ) { + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/ddr_init_pctl.c:432:36: error: ‘P_DDR0_PCTL_TRFC’ undeclared (first use in this function) + writel(timing_set->t_pctl_trfc, P_DDR0_PCTL_TRFC); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:433:36: error: ‘P_DDR0_PCTL_TREFI’ undeclared (first use in this function) + writel(timing_set->t_pctl_trefi, P_DDR0_PCTL_TREFI); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:435:45: error: ‘P_DDR0_PCTL_TREFI_MEM_DDR3’ undeclared (first use in this function) + writel(timing_set->t_pctl_trefi_mem_ddr3, P_DDR0_PCTL_TREFI_MEM_DDR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:436:35: error: ‘P_DDR0_PCTL_TMRD’ undeclared (first use in this function) + writel(timing_set->t_pctl_tmrd, P_DDR0_PCTL_TMRD); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:437:34: error: ‘P_DDR0_PCTL_TRP’ undeclared (first use in this function) + writel(timing_set->t_pctl_trp, P_DDR0_PCTL_TRP); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:438:34: error: ‘P_DDR0_PCTL_TAL’ undeclared (first use in this function) + writel(timing_set->t_pctl_tal, P_DDR0_PCTL_TAL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:439:35: error: ‘P_DDR0_PCTL_TCWL’ undeclared (first use in this function) + writel(timing_set->t_pctl_tcwl, P_DDR0_PCTL_TCWL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:440:34: error: ‘P_DDR0_PCTL_TCL’ undeclared (first use in this function) + writel(timing_set->t_pctl_tcl, P_DDR0_PCTL_TCL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:441:35: error: ‘P_DDR0_PCTL_TRAS’ undeclared (first use in this function) + writel(timing_set->t_pctl_tras, P_DDR0_PCTL_TRAS); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:442:34: error: ‘P_DDR0_PCTL_TRC’ undeclared (first use in this function) + writel(timing_set->t_pctl_trc, P_DDR0_PCTL_TRC); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:443:35: error: ‘P_DDR0_PCTL_TRCD’ undeclared (first use in this function) + writel(timing_set->t_pctl_trcd, P_DDR0_PCTL_TRCD); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:444:35: error: ‘P_DDR0_PCTL_TRRD’ undeclared (first use in this function) + writel(timing_set->t_pctl_trrd, P_DDR0_PCTL_TRRD); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:445:35: error: ‘P_DDR0_PCTL_TRTP’ undeclared (first use in this function) + writel(timing_set->t_pctl_trtp, P_DDR0_PCTL_TRTP); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:446:34: error: ‘P_DDR0_PCTL_TWR’ undeclared (first use in this function) + writel(timing_set->t_pctl_twr, P_DDR0_PCTL_TWR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:447:35: error: ‘P_DDR0_PCTL_TWTR’ undeclared (first use in this function) + writel(timing_set->t_pctl_twtr, P_DDR0_PCTL_TWTR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:448:36: error: ‘P_DDR0_PCTL_TEXSR’ undeclared (first use in this function) + writel(timing_set->t_pctl_texsr, P_DDR0_PCTL_TEXSR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:449:34: error: ‘P_DDR0_PCTL_TXP’ undeclared (first use in this function) + writel(timing_set->t_pctl_txp, P_DDR0_PCTL_TXP); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:450:35: error: ‘P_DDR0_PCTL_TDQS’ undeclared (first use in this function) + writel(timing_set->t_pctl_tdqs, P_DDR0_PCTL_TDQS); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:451:35: error: ‘P_DDR0_PCTL_TRTW’ undeclared (first use in this function) + writel(timing_set->t_pctl_trtw, P_DDR0_PCTL_TRTW); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:452:37: error: ‘P_DDR0_PCTL_TCKSRE’ undeclared (first use in this function) + writel(timing_set->t_pctl_tcksre, P_DDR0_PCTL_TCKSRE); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:453:37: error: ‘P_DDR0_PCTL_TCKSRX’ undeclared (first use in this function) + writel(timing_set->t_pctl_tcksrx, P_DDR0_PCTL_TCKSRX); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:454:35: error: ‘P_DDR0_PCTL_TMOD’ undeclared (first use in this function) + writel(timing_set->t_pctl_tmod, P_DDR0_PCTL_TMOD); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:455:35: error: ‘P_DDR0_PCTL_TCKE’ undeclared (first use in this function) + writel(timing_set->t_pctl_tcke, P_DDR0_PCTL_TCKE); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:456:36: error: ‘P_DDR0_PCTL_TZQCS’ undeclared (first use in this function) + writel(timing_set->t_pctl_tzqcs, P_DDR0_PCTL_TZQCS); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:457:36: error: ‘P_DDR0_PCTL_TZQCL’ undeclared (first use in this function) + writel(timing_set->t_pctl_tzqcl, P_DDR0_PCTL_TZQCL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:458:37: error: ‘P_DDR0_PCTL_TXPDLL’ undeclared (first use in this function) + writel(timing_set->t_pctl_txpdll, P_DDR0_PCTL_TXPDLL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:459:37: error: ‘P_DDR0_PCTL_TZQCSI’ undeclared (first use in this function) + writel(timing_set->t_pctl_tzqcsi, P_DDR0_PCTL_TZQCSI); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:460:36: error: ‘P_DDR0_PCTL_SCFG’ undeclared (first use in this function) + writel(timing_set->t_pctl_scfg, P_DDR0_PCTL_SCFG); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:469:36: error: ‘P_DDR1_PCTL_TRFC’ undeclared (first use in this function) + writel(timing_set->t_pctl_trfc, P_DDR1_PCTL_TRFC); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:470:36: error: ‘P_DDR1_PCTL_TREFI’ undeclared (first use in this function) + writel(timing_set->t_pctl_trefi, P_DDR1_PCTL_TREFI); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:472:45: error: ‘P_DDR1_PCTL_TREFI_MEM_DDR3’ undeclared (first use in this function) + writel(timing_set->t_pctl_trefi_mem_ddr3, P_DDR1_PCTL_TREFI_MEM_DDR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:473:35: error: ‘P_DDR1_PCTL_TMRD’ undeclared (first use in this function) + writel(timing_set->t_pctl_tmrd, P_DDR1_PCTL_TMRD); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:474:34: error: ‘P_DDR1_PCTL_TRP’ undeclared (first use in this function) + writel(timing_set->t_pctl_trp, P_DDR1_PCTL_TRP); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:475:34: error: ‘P_DDR1_PCTL_TAL’ undeclared (first use in this function) + writel(timing_set->t_pctl_tal, P_DDR1_PCTL_TAL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:476:35: error: ‘P_DDR1_PCTL_TCWL’ undeclared (first use in this function) + writel(timing_set->t_pctl_tcwl, P_DDR1_PCTL_TCWL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:477:34: error: ‘P_DDR1_PCTL_TCL’ undeclared (first use in this function) + writel(timing_set->t_pctl_tcl, P_DDR1_PCTL_TCL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:478:35: error: ‘P_DDR1_PCTL_TRAS’ undeclared (first use in this function) + writel(timing_set->t_pctl_tras, P_DDR1_PCTL_TRAS); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:479:34: error: ‘P_DDR1_PCTL_TRC’ undeclared (first use in this function) + writel(timing_set->t_pctl_trc, P_DDR1_PCTL_TRC); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:480:35: error: ‘P_DDR1_PCTL_TRCD’ undeclared (first use in this function) + writel(timing_set->t_pctl_trcd, P_DDR1_PCTL_TRCD); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:481:35: error: ‘P_DDR1_PCTL_TRRD’ undeclared (first use in this function) + writel(timing_set->t_pctl_trrd, P_DDR1_PCTL_TRRD); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:482:35: error: ‘P_DDR1_PCTL_TRTP’ undeclared (first use in this function) + writel(timing_set->t_pctl_trtp, P_DDR1_PCTL_TRTP); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:483:34: error: ‘P_DDR1_PCTL_TWR’ undeclared (first use in this function) + writel(timing_set->t_pctl_twr, P_DDR1_PCTL_TWR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:484:35: error: ‘P_DDR1_PCTL_TWTR’ undeclared (first use in this function) + writel(timing_set->t_pctl_twtr, P_DDR1_PCTL_TWTR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:485:36: error: ‘P_DDR1_PCTL_TEXSR’ undeclared (first use in this function) + writel(timing_set->t_pctl_texsr, P_DDR1_PCTL_TEXSR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:486:34: error: ‘P_DDR1_PCTL_TXP’ undeclared (first use in this function) + writel(timing_set->t_pctl_txp, P_DDR1_PCTL_TXP); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:487:35: error: ‘P_DDR1_PCTL_TDQS’ undeclared (first use in this function) + writel(timing_set->t_pctl_tdqs, P_DDR1_PCTL_TDQS); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:488:35: error: ‘P_DDR1_PCTL_TRTW’ undeclared (first use in this function) + writel(timing_set->t_pctl_trtw, P_DDR1_PCTL_TRTW); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:489:37: error: ‘P_DDR1_PCTL_TCKSRE’ undeclared (first use in this function) + writel(timing_set->t_pctl_tcksre, P_DDR1_PCTL_TCKSRE); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:490:37: error: ‘P_DDR1_PCTL_TCKSRX’ undeclared (first use in this function) + writel(timing_set->t_pctl_tcksrx, P_DDR1_PCTL_TCKSRX); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:491:35: error: ‘P_DDR1_PCTL_TMOD’ undeclared (first use in this function) + writel(timing_set->t_pctl_tmod, P_DDR1_PCTL_TMOD); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:492:35: error: ‘P_DDR1_PCTL_TCKE’ undeclared (first use in this function) + writel(timing_set->t_pctl_tcke, P_DDR1_PCTL_TCKE); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:493:36: error: ‘P_DDR1_PCTL_TZQCS’ undeclared (first use in this function) + writel(timing_set->t_pctl_tzqcs, P_DDR1_PCTL_TZQCS); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:494:36: error: ‘P_DDR1_PCTL_TZQCL’ undeclared (first use in this function) + writel(timing_set->t_pctl_tzqcl, P_DDR1_PCTL_TZQCL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:495:37: error: ‘P_DDR1_PCTL_TXPDLL’ undeclared (first use in this function) + writel(timing_set->t_pctl_txpdll, P_DDR1_PCTL_TXPDLL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:496:37: error: ‘P_DDR1_PCTL_TZQCSI’ undeclared (first use in this function) + writel(timing_set->t_pctl_tzqcsi, P_DDR1_PCTL_TZQCSI); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:497:36: error: ‘P_DDR1_PCTL_SCFG’ undeclared (first use in this function) + writel(timing_set->t_pctl_scfg, P_DDR1_PCTL_SCFG); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:505:28: error: ‘P_DDR0_PCTL_SCTL’ undeclared (first use in this function) + writel(UPCTL_CMD_CONFIG, P_DDR0_PCTL_SCTL); //DDR 0 + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:506:17: error: ‘P_DDR0_PCTL_STAT’ undeclared (first use in this function) + while(!(readl(P_DDR0_PCTL_STAT) & 1)) { + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/ddr_init_pctl.c:511:28: error: ‘P_DDR1_PCTL_SCTL’ undeclared (first use in this function) + writel(UPCTL_CMD_CONFIG, P_DDR1_PCTL_SCTL); //DDR 1 + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:512:17: error: ‘P_DDR1_PCTL_STAT’ undeclared (first use in this function) + while(!(readl(P_DDR1_PCTL_STAT) & 1)) { + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/ddr_init_pctl.c:519:23: error: ‘P_DDR0_PCTL_PPCFG’ undeclared (first use in this function) + writel((0xf0 << 1),P_DDR0_PCTL_PPCFG); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:524:14: error: ‘P_DDR0_PUB_DX2GCR0’ undeclared (first use in this function) + writel(0, P_DDR0_PUB_DX2GCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:525:14: error: ‘P_DDR0_PUB_DX3GCR0’ undeclared (first use in this function) + writel(0, P_DDR0_PUB_DX3GCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:526:14: error: ‘P_DDR0_PUB_DX4GCR0’ undeclared (first use in this function) + writel(0, P_DDR0_PUB_DX4GCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:527:14: error: ‘P_DDR0_PUB_DX5GCR0’ undeclared (first use in this function) + writel(0, P_DDR0_PUB_DX5GCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:533:23: error: ‘P_DDR1_PCTL_PPCFG’ undeclared (first use in this function) + writel((0xf0 << 1),P_DDR1_PCTL_PPCFG); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:538:14: error: ‘P_DDR1_PUB_DX2GCR0’ undeclared (first use in this function) + writel(0, P_DDR1_PUB_DX2GCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:539:14: error: ‘P_DDR1_PUB_DX3GCR0’ undeclared (first use in this function) + writel(0, P_DDR1_PUB_DX3GCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:540:14: error: ‘P_DDR1_PUB_DX4GCR0’ undeclared (first use in this function) + writel(0, P_DDR1_PUB_DX4GCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:541:14: error: ‘P_DDR1_PUB_DX5GCR0’ undeclared (first use in this function) + writel(0, P_DDR1_PUB_DX5GCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:547:12: error: ‘P_DDR0_PCTL_DFISTCFG0’ undeclared (first use in this function) + writel(4,P_DDR0_PCTL_DFISTCFG0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:548:12: error: ‘P_DDR0_PCTL_DFISTCFG1’ undeclared (first use in this function) + writel(1,P_DDR0_PCTL_DFISTCFG1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:549:12: error: ‘P_DDR0_PCTL_DFITCTRLDELAY’ undeclared (first use in this function) + writel(2,P_DDR0_PCTL_DFITCTRLDELAY); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:550:12: error: ‘P_DDR0_PCTL_DFITPHYWRDATA’ undeclared (first use in this function) + writel(1,P_DDR0_PCTL_DFITPHYWRDATA); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:559:19: error: ‘P_DDR0_PCTL_DFITPHYWRLAT’ undeclared (first use in this function) + writel(nTempVal,P_DDR0_PCTL_DFITPHYWRLAT); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:562:19: error: ‘P_DDR0_PCTL_DFITRDDATAEN’ undeclared (first use in this function) + writel(nTempVal,P_DDR0_PCTL_DFITRDDATAEN); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:565:13: error: ‘P_DDR0_PCTL_DFITPHYRDLAT’ undeclared (first use in this function) + writel(13,P_DDR0_PCTL_DFITPHYRDLAT); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:566:12: error: ‘P_DDR0_PCTL_DFITDRAMCLKDIS’ undeclared (first use in this function) + writel(1,P_DDR0_PCTL_DFITDRAMCLKDIS); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:567:12: error: ‘P_DDR0_PCTL_DFITDRAMCLKEN’ undeclared (first use in this function) + writel(1,P_DDR0_PCTL_DFITDRAMCLKEN); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:568:17: error: ‘P_DDR0_PCTL_DFITCTRLUPDMIN’ undeclared (first use in this function) + writel(0x4000,P_DDR0_PCTL_DFITCTRLUPDMIN); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:570:4: error: ‘P_DDR0_PCTL_DFILPCFG0’ undeclared (first use in this function) + P_DDR0_PCTL_DFILPCFG0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:571:16: error: ‘P_DDR0_PCTL_DFITPHYUPDTYPE1’ undeclared (first use in this function) + writel(0x200,P_DDR0_PCTL_DFITPHYUPDTYPE1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:575:12: error: ‘P_DDR0_PCTL_DFIODTCFG’ undeclared (first use in this function) + writel(8,P_DDR0_PCTL_DFIODTCFG); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:577:31: error: ‘P_DDR0_PCTL_DFIODTCFG1’ undeclared (first use in this function) + writel(( 0x0 | (0x6 << 16)),P_DDR0_PCTL_DFIODTCFG1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:580:44: error: ‘P_DDR0_PUB_DTAR0’ undeclared (first use in this function) + writel((0x0 + timing_set->t_pub0_dtar), P_DDR0_PUB_DTAR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:581:44: error: ‘P_DDR0_PUB_DTAR1’ undeclared (first use in this function) + writel((0x08 + timing_set->t_pub0_dtar), P_DDR0_PUB_DTAR1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:582:44: error: ‘P_DDR0_PUB_DTAR2’ undeclared (first use in this function) + writel((0x10 + timing_set->t_pub0_dtar), P_DDR0_PUB_DTAR2); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:583:44: error: ‘P_DDR0_PUB_DTAR3’ undeclared (first use in this function) + writel((0x18 + timing_set->t_pub0_dtar), P_DDR0_PUB_DTAR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:588:12: error: ‘P_DDR1_PCTL_DFISTCFG0’ undeclared (first use in this function) + writel(4,P_DDR1_PCTL_DFISTCFG0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:589:12: error: ‘P_DDR1_PCTL_DFISTCFG1’ undeclared (first use in this function) + writel(1,P_DDR1_PCTL_DFISTCFG1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:590:12: error: ‘P_DDR1_PCTL_DFITCTRLDELAY’ undeclared (first use in this function) + writel(2,P_DDR1_PCTL_DFITCTRLDELAY); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:591:12: error: ‘P_DDR1_PCTL_DFITPHYWRDATA’ undeclared (first use in this function) + writel(1,P_DDR1_PCTL_DFITPHYWRDATA); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:600:19: error: ‘P_DDR1_PCTL_DFITPHYWRLAT’ undeclared (first use in this function) + writel(nTempVal,P_DDR1_PCTL_DFITPHYWRLAT); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:603:19: error: ‘P_DDR1_PCTL_DFITRDDATAEN’ undeclared (first use in this function) + writel(nTempVal,P_DDR1_PCTL_DFITRDDATAEN); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:606:13: error: ‘P_DDR1_PCTL_DFITPHYRDLAT’ undeclared (first use in this function) + writel(13,P_DDR1_PCTL_DFITPHYRDLAT); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:607:12: error: ‘P_DDR1_PCTL_DFITDRAMCLKDIS’ undeclared (first use in this function) + writel(1,P_DDR1_PCTL_DFITDRAMCLKDIS); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:608:12: error: ‘P_DDR1_PCTL_DFITDRAMCLKEN’ undeclared (first use in this function) + writel(1,P_DDR1_PCTL_DFITDRAMCLKEN); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:609:17: error: ‘P_DDR1_PCTL_DFITCTRLUPDMIN’ undeclared (first use in this function) + writel(0x4000,P_DDR1_PCTL_DFITCTRLUPDMIN); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:611:4: error: ‘P_DDR1_PCTL_DFILPCFG0’ undeclared (first use in this function) + P_DDR1_PCTL_DFILPCFG0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:612:16: error: ‘P_DDR1_PCTL_DFITPHYUPDTYPE1’ undeclared (first use in this function) + writel(0x200,P_DDR1_PCTL_DFITPHYUPDTYPE1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:616:12: error: ‘P_DDR1_PCTL_DFIODTCFG’ undeclared (first use in this function) + writel(8,P_DDR1_PCTL_DFIODTCFG); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:618:31: error: ‘P_DDR1_PCTL_DFIODTCFG1’ undeclared (first use in this function) + writel(( 0x0 | (0x6 << 16)),P_DDR1_PCTL_DFIODTCFG1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:621:44: error: ‘P_DDR1_PUB_DTAR0’ undeclared (first use in this function) + writel((0x0 + timing_set->t_pub1_dtar), P_DDR1_PUB_DTAR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:622:44: error: ‘P_DDR1_PUB_DTAR1’ undeclared (first use in this function) + writel((0x08 + timing_set->t_pub1_dtar), P_DDR1_PUB_DTAR1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:623:44: error: ‘P_DDR1_PUB_DTAR2’ undeclared (first use in this function) + writel((0x10 + timing_set->t_pub1_dtar), P_DDR1_PUB_DTAR2); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:624:44: error: ‘P_DDR1_PUB_DTAR3’ undeclared (first use in this function) + writel((0x18 + timing_set->t_pub1_dtar), P_DDR1_PUB_DTAR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:628:12: error: ‘P_DDR0_PCTL_CMDTSTATEN’ undeclared (first use in this function) + writel(1,P_DDR0_PCTL_CMDTSTATEN); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:629:17: error: ‘P_DDR0_PCTL_CMDTSTAT’ undeclared (first use in this function) + while(!(readl(P_DDR0_PCTL_CMDTSTAT) & 0x1)) { + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/ddr_init_pctl.c:634:12: error: ‘P_DDR1_PCTL_CMDTSTATEN’ undeclared (first use in this function) + writel(1,P_DDR1_PCTL_CMDTSTATEN); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:635:17: error: ‘P_DDR1_PCTL_CMDTSTAT’ undeclared (first use in this function) + while(!(readl(P_DDR1_PCTL_CMDTSTAT) & 0x1)) { + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/ddr_init_pctl.c:648:20: error: ‘P_DDR0_PUB_PIR’ undeclared (first use in this function) + writel(nTempVal, P_DDR0_PUB_PIR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:653:16: error: ‘P_DDR0_PUB_PGSR0’ undeclared (first use in this function) + while((readl(P_DDR0_PUB_PGSR0) != 0x8000000f) && + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/ddr_init_pctl.c:671:20: error: ‘P_DDR1_PUB_PIR’ undeclared (first use in this function) + writel(nTempVal, P_DDR1_PUB_PIR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:676:16: error: ‘P_DDR1_PUB_PGSR0’ undeclared (first use in this function) + while((readl(P_DDR1_PUB_PGSR0) != 0x8000000f) && + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/ddr_init_pctl.c:1000:46: error: ‘P_DDR0_PUB_PGCR0’ undeclared (first use in this function) + writel((readl(P_DDR0_PUB_PGCR0) & (~0x3F)),P_DDR0_PUB_PGCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:1036:46: error: ‘P_DDR1_PUB_PGCR0’ undeclared (first use in this function) + writel((readl(P_DDR1_PUB_PGCR0) & (~0x3F)),P_DDR1_PUB_PGCR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:1044:47: error: ‘P_DDR0_PUB_PGCR3’ undeclared (first use in this function) + writel((0x7d<<9)|(readl(P_DDR0_PUB_PGCR3)), P_DDR0_PUB_PGCR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:1055:47: error: ‘P_DDR1_PUB_PGCR3’ undeclared (first use in this function) + writel((0x7d<<9)|(readl(P_DDR1_PUB_PGCR3)), P_DDR1_PUB_PGCR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:1068:17: error: ‘P_DDR0_PUB_PLLCR’ undeclared (first use in this function) + writel(1<<29, P_DDR0_PUB_PLLCR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_init_pctl.c:1080:17: error: ‘P_DDR1_PUB_PLLCR’ undeclared (first use in this function) + writel(1<<29, P_DDR1_PUB_PLLCR); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c: In function ‘print_ddr_channel’: +bl2/firmware/ddr_auto_detect.c:32:23: error: ‘P_DMC_DDR_CTRL’ undeclared (first use in this function) + channel_set = readl(P_DMC_DDR_CTRL); + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/ddr_auto_detect.c:43:23: error: ‘P_MMC_DDR_CTRL’ undeclared (first use in this function) + channel_set = readl(P_MMC_DDR_CTRL); + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +In file included from bl2/firmware/ddr.c:18:0, + from bl2/firmware/spl.c:34, + from bl2/bl2_main.c:43: +bl2/firmware/ddr_auto_detect.c: In function ‘print_ddr_size’: +bl2/firmware/ddr_auto_detect.c:62:64: warning: ISO C forbids conditional expr with only one void side [-Wpedantic] + (((mem_size>>9)&0x1)&&((mem_size)>=1024)) ? serial_puts(".5") : 0; + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/ddr_auto_detect.c: In function ‘dtar_reset’: +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:33:3: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); \ + ^ +bl2/firmware/ddr_auto_detect.c:183:5: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:34:3: note: in expansion of macro ‘writel’ + writel((10|((1<<AML_WATCHDOG_ENABLE_OFFSET)| \ + ^ +bl2/firmware/ddr_auto_detect.c:183:5: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +bl2/firmware/ddr_auto_detect.c:232:38: error: ‘P_DMC_DDR_CTRL’ undeclared (first use in this function) + writel(timing_reg->t_mmc_ddr_ctrl, P_DMC_DDR_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c:241:38: error: ‘P_MMC_DDR_CTRL’ undeclared (first use in this function) + writel(timing_reg->t_mmc_ddr_ctrl, P_MMC_DDR_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c:251:39: error: ‘P_DDR0_CLK_CTRL’ undeclared (first use in this function) + writel(readl(P_DDR0_CLK_CTRL) | 0x1, P_DDR0_CLK_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c:252:39: error: ‘P_DDR1_CLK_CTRL’ undeclared (first use in this function) + writel(readl(P_DDR1_CLK_CTRL) | 0x1, P_DDR1_CLK_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c:255:43: error: ‘P_DDR0_PUB_DTAR0’ undeclared (first use in this function) + writel((0x0 + timing_reg->t_pub0_dtar), P_DDR0_PUB_DTAR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c:256:43: error: ‘P_DDR0_PUB_DTAR1’ undeclared (first use in this function) + writel((0x08 + timing_reg->t_pub0_dtar), P_DDR0_PUB_DTAR1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c:257:43: error: ‘P_DDR0_PUB_DTAR2’ undeclared (first use in this function) + writel((0x10 + timing_reg->t_pub0_dtar), P_DDR0_PUB_DTAR2); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c:258:43: error: ‘P_DDR0_PUB_DTAR3’ undeclared (first use in this function) + writel((0x18 + timing_reg->t_pub0_dtar), P_DDR0_PUB_DTAR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c:260:43: error: ‘P_DDR1_PUB_DTAR0’ undeclared (first use in this function) + writel((0x0 + timing_reg->t_pub1_dtar), P_DDR1_PUB_DTAR0); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c:261:43: error: ‘P_DDR1_PUB_DTAR1’ undeclared (first use in this function) + writel((0x08 + timing_reg->t_pub1_dtar), P_DDR1_PUB_DTAR1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c:262:43: error: ‘P_DDR1_PUB_DTAR2’ undeclared (first use in this function) + writel((0x10 + timing_reg->t_pub1_dtar), P_DDR1_PUB_DTAR2); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c:263:43: error: ‘P_DDR1_PUB_DTAR3’ undeclared (first use in this function) + writel((0x18 + timing_reg->t_pub1_dtar), P_DDR1_PUB_DTAR3); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c: In function ‘ddr_size_auto_detect’: +bl2/firmware/ddr_auto_detect.c:312:27: error: ‘P_DMC_DDR_CTRL’ undeclared (first use in this function) + writel(dmc_reg_setting, P_DMC_DDR_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c:314:27: error: ‘P_MMC_DDR_CTRL’ undeclared (first use in this function) + writel(dmc_reg_setting, P_MMC_DDR_CTRL); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr_auto_detect.c:323:3: note: in expansion of macro ‘writel’ + writel(DDR_SIZE_AUTO_DETECT_PATTERN, cur_mask_addr); + ^ +In file included from bl2/firmware/ddr.c:18:0, + from bl2/firmware/spl.c:34, + from bl2/bl2_main.c:43: +bl2/firmware/ddr_auto_detect.c:331:3: error: ‘asm’ undeclared (first use in this function) + asm volatile("DSB"); /*sync ddr data*/ + ^ +bl2/firmware/ddr_auto_detect.c:331:7: error: expected ‘;’ before ‘volatile’ + asm volatile("DSB"); /*sync ddr data*/ + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:33:3: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); \ + ^ +bl2/firmware/ddr_auto_detect.c:343:4: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:34:3: note: in expansion of macro ‘writel’ + writel((10|((1<<AML_WATCHDOG_ENABLE_OFFSET)| \ + ^ +bl2/firmware/ddr_auto_detect.c:343:4: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +bl2/firmware/ddr.c: In function ‘set_ddr_clock’: +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:33:3: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); \ + ^ +bl2/firmware/timing.h:138:5: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); \ + ^ +bl2/firmware/ddr.c:69:3: note: in expansion of macro ‘PLL_LOCK_CHECK’ + PLL_LOCK_CHECK(n_pll_try_times,3); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:34:3: note: in expansion of macro ‘writel’ + writel((10|((1<<AML_WATCHDOG_ENABLE_OFFSET)| \ + ^ +bl2/firmware/timing.h:138:5: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); \ + ^ +bl2/firmware/ddr.c:69:3: note: in expansion of macro ‘PLL_LOCK_CHECK’ + PLL_LOCK_CHECK(n_pll_try_times,3); + ^ +bl2/firmware/ddr.c:74:12: error: ‘P_DDR0_SOFT_RESET’ undeclared (first use in this function) + writel(0, P_DDR0_SOFT_RESET); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr.c:75:12: error: ‘P_DDR1_SOFT_RESET’ undeclared (first use in this function) + writel(0, P_DDR1_SOFT_RESET); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +In file included from bl2/firmware/spl.c:34:0, + from bl2/bl2_main.c:43: +bl2/firmware/ddr.c:76:2: warning: implicit declaration of function ‘MMC_Wr’ [-Wimplicit-function-declaration] + MMC_Wr(AM_DDR_CLK_CNTL, 0x80004040); // enable DDR PLL CLOCK. + ^ +bl2/firmware/ddr.c:76:9: error: ‘AM_DDR_CLK_CNTL’ undeclared (first use in this function) + MMC_Wr(AM_DDR_CLK_CNTL, 0x80004040); // enable DDR PLL CLOCK. + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/ddr.c:83:22: error: ‘P_DMC_SOFT_RST’ undeclared (first use in this function) + writel(0xffffffff, P_DMC_SOFT_RST); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr.c:84:22: error: ‘P_DMC_SOFT_RST1’ undeclared (first use in this function) + writel(0xffffffff, P_DMC_SOFT_RST1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr.c:87:22: error: ‘P_MMC_SOFT_RST’ undeclared (first use in this function) + writel(0xffffffff, P_MMC_SOFT_RST); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/ddr.c:88:22: error: ‘P_MMC_SOFT_RST1’ undeclared (first use in this function) + writel(0xffffffff, P_MMC_SOFT_RST1); + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +In file included from bl2/firmware/spl.c:34:0, + from bl2/bl2_main.c:43: +bl2/firmware/ddr.c: In function ‘lowlevel_mem_test_device’: +bl2/firmware/ddr.c:157:38: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + return tag&&(unsigned)memTestDevice((volatile datum *)(timing_reg->phy_memory_start),timing_reg->phy_memory_size); + ^ +bl2/firmware/ddr.c:157:14: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + return tag&&(unsigned)memTestDevice((volatile datum *)(timing_reg->phy_memory_start),timing_reg->phy_memory_size); + ^ +bl2/firmware/ddr.c: In function ‘lowlevel_mem_test_data’: +bl2/firmware/ddr.c:166:39: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + return tag&&(unsigned)memTestDataBus((volatile datum *) (timing_reg->phy_memory_start)); + ^ +bl2/firmware/ddr.c: In function ‘lowlevel_mem_test_addr’: +bl2/firmware/ddr.c:180:42: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + return tag&&(unsigned)memTestAddressBus((volatile datum *)(timing_reg->phy_memory_start), timing_reg->phy_memory_size); + ^ +bl2/firmware/ddr.c:180:14: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + return tag&&(unsigned)memTestAddressBus((volatile datum *)(timing_reg->phy_memory_start), timing_reg->phy_memory_size); + ^ +bl2/firmware/ddr.c: At top level: +bl2/firmware/ddr.c:196:10: error: conflicting types for ‘ddr_test’ + unsigned ddr_test(int arg) + ^ +In file included from bl2/bl2_main.c:42:0: +bl2/ddr/ddr.c:325:14: note: previous definition of ‘ddr_test’ was here + unsigned int ddr_test(void){ + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/ddr.c: In function ‘ddr_init_test’: +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:33:3: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); \ + ^ +bl2/firmware/ddr.c:298:3: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:34:3: note: in expansion of macro ‘writel’ + writel((10|((1<<AML_WATCHDOG_ENABLE_OFFSET)| \ + ^ +bl2/firmware/ddr.c:298:3: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:33:3: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); \ + ^ +bl2/firmware/ddr.c:326:3: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:34:3: note: in expansion of macro ‘writel’ + writel((10|((1<<AML_WATCHDOG_ENABLE_OFFSET)| \ + ^ +bl2/firmware/ddr.c:326:3: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +In file included from bl2/firmware/nfio.c:10:0, + from bl2/firmware/sdio.c:6, + from bl2/firmware/spl.c:36, + from bl2/bl2_main.c:43: +bl2/firmware/aml_a9_cache.c: At top level: +bl2/firmware/aml_a9_cache.c:38:1: error: unknown type name ‘s32’ + static inline s32 log_2_n_round_up(u32 n) + ^ +bl2/firmware/aml_a9_cache.c:38:36: error: unknown type name ‘u32’ + static inline s32 log_2_n_round_up(u32 n) + ^ +bl2/firmware/aml_a9_cache.c:54:24: error: unknown type name ‘u32’ + static void set_csselr(u32 level, u32 type) + ^ +bl2/firmware/aml_a9_cache.c:54:35: error: unknown type name ‘u32’ + static void set_csselr(u32 level, u32 type) + ^ +bl2/firmware/aml_a9_cache.c:61:1: error: unknown type name ‘u32’ + static u32 get_ccsidr(void) + ^ +bl2/firmware/aml_a9_cache.c: In function ‘get_ccsidr’: +bl2/firmware/aml_a9_cache.c:63:2: error: unknown type name ‘u32’ + u32 ccsidr; + ^ +bl2/firmware/aml_a9_cache.c:66:2: error: ‘asm’ undeclared (first use in this function) + asm volatile ("mrc p15, 1, %0, c0, c0, 0" : "=r" (ccsidr)); + ^ +bl2/firmware/aml_a9_cache.c:66:6: error: expected ‘;’ before ‘volatile’ + asm volatile ("mrc p15, 1, %0, c0, c0, 0" : "=r" (ccsidr)); + ^ +bl2/firmware/aml_a9_cache.c: At top level: +bl2/firmware/aml_a9_cache.c:70:1: error: unknown type name ‘u32’ + static u32 get_clidr(void) + ^ +bl2/firmware/aml_a9_cache.c: In function ‘get_clidr’: +bl2/firmware/aml_a9_cache.c:72:2: error: unknown type name ‘u32’ + u32 clidr; + ^ +bl2/firmware/aml_a9_cache.c:75:2: error: ‘asm’ undeclared (first use in this function) + asm volatile ("mrc p15,1,%0,c0,c0,1" : "=r" (clidr)); + ^ +bl2/firmware/aml_a9_cache.c:75:6: error: expected ‘;’ before ‘volatile’ + asm volatile ("mrc p15,1,%0,c0,c0,1" : "=r" (clidr)); + ^ +bl2/firmware/aml_a9_cache.c: At top level: +bl2/firmware/aml_a9_cache.c:79:42: error: unknown type name ‘u32’ + static void v7_inval_dcache_level_setway(u32 level, u32 num_sets, + ^ +bl2/firmware/aml_a9_cache.c:79:53: error: unknown type name ‘u32’ + static void v7_inval_dcache_level_setway(u32 level, u32 num_sets, + ^ +bl2/firmware/aml_a9_cache.c:80:7: error: unknown type name ‘u32’ + u32 num_ways, u32 way_shift, + ^ +bl2/firmware/aml_a9_cache.c:80:21: error: unknown type name ‘u32’ + u32 num_ways, u32 way_shift, + ^ +bl2/firmware/aml_a9_cache.c:81:7: error: unknown type name ‘u32’ + u32 log2_line_len) + ^ +bl2/firmware/aml_a9_cache.c:103:48: error: unknown type name ‘u32’ + static void v7_clean_inval_dcache_level_setway(u32 level, u32 num_sets, + ^ +bl2/firmware/aml_a9_cache.c:103:59: error: unknown type name ‘u32’ + static void v7_clean_inval_dcache_level_setway(u32 level, u32 num_sets, + ^ +bl2/firmware/aml_a9_cache.c:104:13: error: unknown type name ‘u32’ + u32 num_ways, u32 way_shift, + ^ +bl2/firmware/aml_a9_cache.c:104:27: error: unknown type name ‘u32’ + u32 num_ways, u32 way_shift, + ^ +bl2/firmware/aml_a9_cache.c:105:13: error: unknown type name ‘u32’ + u32 log2_line_len) + ^ +bl2/firmware/aml_a9_cache.c:130:42: error: unknown type name ‘u32’ + static void v7_maint_dcache_level_setway(u32 level, u32 operation) + ^ +bl2/firmware/aml_a9_cache.c:130:53: error: unknown type name ‘u32’ + static void v7_maint_dcache_level_setway(u32 level, u32 operation) + ^ +bl2/firmware/aml_a9_cache.c:165:33: error: unknown type name ‘u32’ + static void v7_maint_dcache_all(u32 operation) + ^ +bl2/firmware/aml_a9_cache.c:181:41: error: unknown type name ‘u32’ + static void v7_dcache_clean_inval_range(u32 start, + ^ +bl2/firmware/aml_a9_cache.c:182:6: error: unknown type name ‘u32’ + u32 stop, u32 line_len) + ^ +bl2/firmware/aml_a9_cache.c:182:16: error: unknown type name ‘u32’ + u32 stop, u32 line_len) + ^ +bl2/firmware/aml_a9_cache.c:194:35: error: unknown type name ‘u32’ + static void v7_dcache_inval_range(u32 start, u32 stop, u32 line_len) + ^ +bl2/firmware/aml_a9_cache.c:194:46: error: unknown type name ‘u32’ + static void v7_dcache_inval_range(u32 start, u32 stop, u32 line_len) + ^ +bl2/firmware/aml_a9_cache.c:194:56: error: unknown type name ‘u32’ + static void v7_dcache_inval_range(u32 start, u32 stop, u32 line_len) + ^ +bl2/firmware/aml_a9_cache.c:224:35: error: unknown type name ‘u32’ + static void v7_dcache_maint_range(u32 start, u32 stop, u32 range_op) + ^ +bl2/firmware/aml_a9_cache.c:224:46: error: unknown type name ‘u32’ + static void v7_dcache_maint_range(u32 start, u32 stop, u32 range_op) + ^ +bl2/firmware/aml_a9_cache.c:224:56: error: unknown type name ‘u32’ + static void v7_dcache_maint_range(u32 start, u32 stop, u32 range_op) + ^ +bl2/firmware/aml_a9_cache.c: In function ‘v7_inval_tlb’: +bl2/firmware/aml_a9_cache.c:253:2: error: ‘asm’ undeclared (first use in this function) + asm volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0)); + ^ +bl2/firmware/aml_a9_cache.c:253:6: error: expected ‘;’ before ‘volatile’ + asm volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0)); + ^ +bl2/firmware/aml_a9_cache.c:255:6: error: expected ‘;’ before ‘volatile’ + asm volatile ("mcr p15, 0, %0, c8, c6, 0" : : "r" (0)); + ^ +bl2/firmware/aml_a9_cache.c:257:6: error: expected ‘;’ before ‘volatile’ + asm volatile ("mcr p15, 0, %0, c8, c5, 0" : : "r" (0)); + ^ +bl2/firmware/aml_a9_cache.c:8:25: error: expected ‘;’ before ‘volatile’ + #define CP15DSB asm volatile("dsb": : : "memory"); + ^ +bl2/firmware/aml_a9_cache.c:259:2: note: in expansion of macro ‘CP15DSB’ + CP15DSB; + ^ +bl2/firmware/aml_a9_cache.c:9:25: error: expected ‘;’ before ‘volatile’ + #define CP15ISB asm volatile("isb": : : "memory"); + ^ +bl2/firmware/aml_a9_cache.c:261:2: note: in expansion of macro ‘CP15ISB’ + CP15ISB; + ^ +bl2/firmware/aml_a9_cache.c: In function ‘invalidate_dcache_all’: +bl2/firmware/aml_a9_cache.c:266:2: warning: implicit declaration of function ‘v7_maint_dcache_all’ [-Wimplicit-function-declaration] + v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL); + ^ +bl2/firmware/aml_a9_cache.c: In function ‘invalidate_dcache_range’: +bl2/firmware/aml_a9_cache.c:287:2: warning: implicit declaration of function ‘v7_dcache_maint_range’ [-Wimplicit-function-declaration] + v7_dcache_maint_range(start, stop, ARMV7_DCACHE_INVAL_RANGE); + ^ +bl2/firmware/aml_a9_cache.c: In function ‘cp_delay’: +bl2/firmware/aml_a9_cache.c:323:3: warning: implicit declaration of function ‘nop’ [-Wimplicit-function-declaration] + nop(); + ^ +bl2/firmware/aml_a9_cache.c:324:2: error: ‘asm’ undeclared (first use in this function) + asm volatile("" : : : "memory"); + ^ +bl2/firmware/aml_a9_cache.c:324:6: error: expected ‘;’ before ‘volatile’ + asm volatile("" : : : "memory"); + ^ +bl2/firmware/aml_a9_cache.c: In function ‘mmu_setup’: +bl2/firmware/aml_a9_cache.c:334:2: error: ‘asm’ undeclared (first use in this function) + asm volatile("mov r0, #0");// @ set up for MCR + ^ +bl2/firmware/aml_a9_cache.c:334:6: error: expected ‘;’ before ‘volatile’ + asm volatile("mov r0, #0");// @ set up for MCR + ^ +bl2/firmware/aml_a9_cache.c:335:6: error: expected ‘;’ before ‘volatile’ + asm volatile("mcr p15, 0, r0, c8, c7, 0");// @ invalidate TLBs + ^ +bl2/firmware/aml_a9_cache.c:336:6: error: expected ‘;’ before ‘volatile’ + asm volatile("mcr p15, 0, r0, c7, c5, 0");// @ invalidate icache + ^ +bl2/firmware/aml_a9_cache.c:341:6: error: expected ‘;’ before ‘volatile’ + asm volatile("mrc p15, 0, r0, c1, c0, 0");// + ^ +bl2/firmware/aml_a9_cache.c:342:6: error: expected ‘;’ before ‘volatile’ + asm volatile("bic r0, r0, #0x00002000");// @ clear bits 13(--V--) + ^ +bl2/firmware/aml_a9_cache.c:344:6: error: expected ‘;’ before ‘volatile’ + asm volatile("bic r0, r0, #0x00000007");// @ clear bits 2:0 (-CAM) + ^ +bl2/firmware/aml_a9_cache.c:346:6: error: expected ‘;’ before ‘volatile’ + asm volatile("orr r0, r0, #0x00000002");// @ set bit 1 (--A-) Align + ^ +bl2/firmware/aml_a9_cache.c:348:6: error: expected ‘;’ before ‘volatile’ + asm volatile("orr r0, r0, #0x00000800");// @ set bit 12 (Z---) BTB + ^ +bl2/firmware/aml_a9_cache.c:349:6: error: expected ‘;’ before ‘volatile’ + asm volatile("mcr p15, 0, r0, c1, c0, 0");// + ^ +bl2/firmware/aml_a9_cache.c:354:2: error: unknown type name ‘uint’ + uint nVal = 0; + ^ +bl2/firmware/aml_a9_cache.c:360:20: error: ‘SEC_PROT_RW_RW’ undeclared (first use in this function) + nVal = (i<<20)|(SEC_PROT_RW_RW | SEC_WB); + ^ +bl2/firmware/aml_a9_cache.c:360:37: error: ‘SEC_WB’ undeclared (first use in this function) + nVal = (i<<20)|(SEC_PROT_RW_RW | SEC_WB); + ^ +bl2/firmware/aml_a9_cache.c:362:20: error: ‘SEC_PROT_RW_NA’ undeclared (first use in this function) + nVal = (i<<20)|(SEC_PROT_RW_NA | SEC_XN | SEC_SO_MEM); + ^ +bl2/firmware/aml_a9_cache.c:362:37: error: ‘SEC_XN’ undeclared (first use in this function) + nVal = (i<<20)|(SEC_PROT_RW_NA | SEC_XN | SEC_SO_MEM); + ^ +bl2/firmware/aml_a9_cache.c:362:46: error: ‘SEC_SO_MEM’ undeclared (first use in this function) + nVal = (i<<20)|(SEC_PROT_RW_NA | SEC_XN | SEC_SO_MEM); + ^ +bl2/firmware/aml_a9_cache.c:364:47: error: ‘SEC_DEVICE’ undeclared (first use in this function) + nVal = (i<<20)|(SEC_PROT_RW_NA | SEC_XN | SEC_DEVICE); + ^ +bl2/firmware/aml_a9_cache.c:366:46: error: ‘SECTION’ undeclared (first use in this function) + nVal = (i<<20)|(SEC_PROT_RW_NA | SEC_XN | SECTION); + ^ +bl2/firmware/aml_a9_cache.c:407:2: error: unknown type name ‘u32’ + u32 *page_table = (u32 *)(pVMMUTable); + ^ +bl2/firmware/aml_a9_cache.c:407:21: error: ‘u32’ undeclared (first use in this function) + u32 *page_table = (u32 *)(pVMMUTable); + ^ +bl2/firmware/aml_a9_cache.c:407:26: error: expected expression before ‘)’ token + u32 *page_table = (u32 *)(pVMMUTable); + ^ +bl2/firmware/aml_a9_cache.c:409:6: error: expected ‘;’ before ‘reg’ + u32 reg; + ^ +bl2/firmware/aml_a9_cache.c:412:6: error: expected ‘;’ before ‘volatile’ + asm volatile("mcr p15, 0, %0, c2, c0, 0" + ^ +bl2/firmware/aml_a9_cache.c:415:6: error: expected ‘;’ before ‘volatile’ + asm volatile("mcr p15, 0, %0, c3, c0, 0" + ^ +bl2/firmware/aml_a9_cache.c:418:7: error: expected ‘;’ before ‘volatile’ + asm volatile("mcr p15, 0, %0, c7, c5, 6" : : "r" (0)); // invalidate BTAC + ^ +bl2/firmware/aml_a9_cache.c:419:7: error: expected ‘;’ before ‘volatile’ + asm volatile("mcr p15, 0, %0, c7, c5, 0" : : "r" (0)); // invalidate ICache + ^ +bl2/firmware/aml_a9_cache.c:420:9: error: expected ‘;’ before ‘volatile’ + asm volatile("dsb"); + ^ +bl2/firmware/aml_a9_cache.c:421:9: error: expected ‘;’ before ‘volatile’ + asm volatile("mcr p15, 0, %0, c8, c7, 0" : : "r" (0)); // invalidate TLBs + ^ +bl2/firmware/aml_a9_cache.c:422:6: error: expected ‘;’ before ‘volatile’ + asm volatile("dsb"); + ^ +bl2/firmware/aml_a9_cache.c:423:7: error: expected ‘;’ before ‘volatile’ + asm volatile("isb"); + ^ +bl2/firmware/aml_a9_cache.c:426:2: error: ‘reg’ undeclared (first use in this function) + reg = get_cr(); /* get control reg. */ + ^ +bl2/firmware/aml_a9_cache.c:426:2: warning: implicit declaration of function ‘get_cr’ [-Wimplicit-function-declaration] +bl2/firmware/aml_a9_cache.c:428:2: warning: implicit declaration of function ‘set_cr’ [-Wimplicit-function-declaration] + set_cr(reg | CR_M); + ^ +bl2/firmware/aml_a9_cache.c:428:15: error: ‘CR_M’ undeclared (first use in this function) + set_cr(reg | CR_M); + ^ +bl2/firmware/aml_a9_cache.c:407:7: warning: unused variable ‘page_table’ [-Wunused-variable] + u32 *page_table = (u32 *)(pVMMUTable); + ^ +bl2/firmware/aml_a9_cache.c: In function ‘cache_enable’: +bl2/firmware/aml_a9_cache.c:437:19: error: ‘CR_C’ undeclared (first use in this function) + if (cache_bit == CR_C) + ^ +bl2/firmware/aml_a9_cache.c: In function ‘cache_disable’: +bl2/firmware/aml_a9_cache.c:450:19: error: ‘CR_C’ undeclared (first use in this function) + if (cache_bit == CR_C) { + ^ +bl2/firmware/aml_a9_cache.c:456:16: error: ‘CR_M’ undeclared (first use in this function) + cache_bit |= CR_M; + ^ +bl2/firmware/aml_a9_cache.c: In function ‘aml_cache_disable’: +bl2/firmware/aml_a9_cache.c:468:16: error: ‘CR_I’ undeclared (first use in this function) + cache_disable(CR_I); + ^ +bl2/firmware/aml_a9_cache.c:469:16: error: ‘CR_C’ undeclared (first use in this function) + cache_disable(CR_C); + ^ +bl2/firmware/aml_a9_cache.c: In function ‘aml_cache_enable’: +bl2/firmware/aml_a9_cache.c:478:15: error: ‘CR_I’ undeclared (first use in this function) + cache_enable(CR_I); + ^ +bl2/firmware/aml_a9_cache.c:479:15: error: ‘CR_C’ undeclared (first use in this function) + cache_enable(CR_C); + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/nfio.c: In function ‘nfio_reset’: +bl2/firmware/aml_nand.h:8:62: error: ‘IO_CBUS_BASE’ undeclared (first use in this function) + #define NAND_CMD ((0xc1108600-IO_CBUS_BASE)>>2) + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/aml_nand.h:44:65: note: in expansion of macro ‘NAND_CMD’ + #define P_NAND_CMD CBUS_REG_ADDR(NAND_CMD) + ^ +bl2/firmware/nfio.c:106:16: note: in expansion of macro ‘P_NAND_CMD’ + while ((readl(P_NAND_CMD)>>22&0x1f) > 0); + ^ +bl2/firmware/nfio.c: In function ‘nfio_read_id’: +bl2/firmware/aml_nand.h:8:62: error: ‘IO_CBUS_BASE’ undeclared (first use in this function) + #define NAND_CMD ((0xc1108600-IO_CBUS_BASE)>>2) + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/aml_nand.h:44:65: note: in expansion of macro ‘NAND_CMD’ + #define P_NAND_CMD CBUS_REG_ADDR(NAND_CMD) + ^ +bl2/firmware/nfio.c:137:27: note: in expansion of macro ‘P_NAND_CMD’ + writel((CE0 | IDLE | 0), P_NAND_CMD); + ^ +In file included from bl2/firmware/sdio.c:6:0, + from bl2/firmware/spl.c:36, + from bl2/bl2_main.c:43: +bl2/firmware/nfio.c:151:2: warning: implicit declaration of function ‘readb’ [-Wimplicit-function-declaration] + nand_retry.id = readb(P_NAND_BUF)&0xff; + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/nfio.c: In function ‘nfio_page_read_hwctrl’: +bl2/firmware/aml_nand.h:8:62: error: ‘IO_CBUS_BASE’ undeclared (first use in this function) + #define NAND_CMD ((0xc1108600-IO_CBUS_BASE)>>2) + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/aml_nand.h:44:65: note: in expansion of macro ‘NAND_CMD’ + #define P_NAND_CMD CBUS_REG_ADDR(NAND_CMD) + ^ +bl2/firmware/nfio.c:510:16: note: in expansion of macro ‘P_NAND_CMD’ + while ((readl(P_NAND_CMD)>>22&0x1f) > 0); + ^ +bl2/firmware/nfio.c: In function ‘nf_init’: +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/nfio.c:716:2: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_PAD_PULL_UP_EN_REG2, 0x85ff); + ^ +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/nfio.c:719:2: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_PAD_PULL_UP_REG2, 0x0500); + ^ +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/nfio.c:722:2: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_PERIPHS_PIN_MUX_2, ((0x3ff<<18) | (1<<17))); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/nfio.c:742:2: note: in expansion of macro ‘writel’ + writel((((0<<9) | (1<<8) | 3)), P_HHI_NAND_CLK_CNTL); + ^ +bl2/firmware/aml_nand.h:9:62: error: ‘IO_CBUS_BASE’ undeclared (first use in this function) + #define NAND_CFG ((0xc1108604-IO_CBUS_BASE)>>2) + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/aml_nand.h:45:65: note: in expansion of macro ‘NAND_CFG’ + #define P_NAND_CFG CBUS_REG_ADDR(NAND_CFG) + ^ +bl2/firmware/nfio.c:755:9: note: in expansion of macro ‘P_NAND_CFG’ + , P_NAND_CFG); + ^ +In file included from bl2/firmware/sdio.c:6:0, + from bl2/firmware/spl.c:36, + from bl2/bl2_main.c:43: +bl2/firmware/nfio.c:825:25: error: ‘NAND_MFR_SANDISK’ undeclared (first use in this function) + if (nand_retry.id == NAND_MFR_SANDISK) { + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/nfio.c: In function ‘nf_set_pux’: +bl2/firmware/aml_nand.h:8:62: error: ‘IO_CBUS_BASE’ undeclared (first use in this function) + #define NAND_CMD ((0xc1108600-IO_CBUS_BASE)>>2) + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/aml_nand.h:44:65: note: in expansion of macro ‘NAND_CMD’ + #define P_NAND_CMD CBUS_REG_ADDR(NAND_CMD) + ^ +bl2/firmware/nfio.c:884:27: note: in expansion of macro ‘P_NAND_CMD’ + writel((ce | IDLE | 40), P_NAND_CMD); + ^ +bl2/firmware/nfio.c: In function ‘send_plane0_cmd’: +bl2/firmware/aml_nand.h:8:62: error: ‘IO_CBUS_BASE’ undeclared (first use in this function) + #define NAND_CMD ((0xc1108600-IO_CBUS_BASE)>>2) + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/aml_nand.h:44:65: note: in expansion of macro ‘NAND_CMD’ + #define P_NAND_CMD CBUS_REG_ADDR(NAND_CMD) + ^ +bl2/firmware/nfio.c:985:21: note: in expansion of macro ‘P_NAND_CMD’ + writel(ce | IDLE, P_NAND_CMD); + ^ +In file included from bl2/firmware/sdio.c:6:0, + from bl2/firmware/spl.c:36, + from bl2/bl2_main.c:43: +bl2/firmware/nfio.c:944:35: warning: variable ‘ran_mode’ set but not used [-Wunused-but-set-variable] + unsigned int /*nand_read_info,*/ ran_mode; + ^ +bl2/firmware/nfio.c:943:21: warning: variable ‘plane_mode’ set but not used [-Wunused-but-set-variable] + int /*chip_num,*/ plane_mode; + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/nfio.c: In function ‘send_plane1_cmd’: +bl2/firmware/aml_nand.h:8:62: error: ‘IO_CBUS_BASE’ undeclared (first use in this function) + #define NAND_CMD ((0xc1108600-IO_CBUS_BASE)>>2) + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/aml_nand.h:44:65: note: in expansion of macro ‘NAND_CMD’ + #define P_NAND_CMD CBUS_REG_ADDR(NAND_CMD) + ^ +bl2/firmware/nfio.c:1108:21: note: in expansion of macro ‘P_NAND_CMD’ + writel(ce | IDLE, P_NAND_CMD); + ^ +In file included from bl2/firmware/sdio.c:6:0, + from bl2/firmware/spl.c:36, + from bl2/bl2_main.c:43: +bl2/firmware/nfio.c:1092:53: warning: variable ‘plane0’ set but not used [-Wunused-but-set-variable] + unsigned page_in_blk, blk_num, /*pages_in_block,*/ plane0, plane1; + ^ +bl2/firmware/nfio.c:1089:21: warning: variable ‘plane_mode’ set but not used [-Wunused-but-set-variable] + int /*chip_num,*/ plane_mode; + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/nfio.c: In function ‘send_read_cmd’: +bl2/firmware/aml_nand.h:8:62: error: ‘IO_CBUS_BASE’ undeclared (first use in this function) + #define NAND_CMD ((0xc1108600-IO_CBUS_BASE)>>2) + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/aml_nand.h:44:65: note: in expansion of macro ‘NAND_CMD’ + #define P_NAND_CMD CBUS_REG_ADDR(NAND_CMD) + ^ +bl2/firmware/nfio.c:1168:28: note: in expansion of macro ‘P_NAND_CMD’ + writel(ce | CLE | 0xa2, P_NAND_CMD); + ^ +In file included from bl2/firmware/sdio.c:6:0, + from bl2/firmware/spl.c:36, + from bl2/bl2_main.c:43: +bl2/firmware/nfio.c:1159:21: warning: variable ‘plane_mode’ set but not used [-Wunused-but-set-variable] + int /*chip_num,*/ plane_mode; + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/nfio.c: In function ‘send_reset_cmd’: +bl2/firmware/aml_nand.h:8:62: error: ‘IO_CBUS_BASE’ undeclared (first use in this function) + #define NAND_CMD ((0xc1108600-IO_CBUS_BASE)>>2) + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/aml_nand.h:44:65: note: in expansion of macro ‘NAND_CMD’ + #define P_NAND_CMD CBUS_REG_ADDR(NAND_CMD) + ^ +bl2/firmware/nfio.c:1232:29: note: in expansion of macro ‘P_NAND_CMD’ + writel((ce | CLE | 0xff), P_NAND_CMD); //reset + ^ +bl2/firmware/nfio.c: In function ‘nf_read_check’: +bl2/firmware/aml_nand.h:8:62: error: ‘IO_CBUS_BASE’ undeclared (first use in this function) + #define NAND_CMD ((0xc1108600-IO_CBUS_BASE)>>2) + ^ +include/drivers/serial/serial.h:58:45: note: in definition of macro ‘readl’ + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/aml_nand.h:44:65: note: in expansion of macro ‘NAND_CMD’ + #define P_NAND_CMD CBUS_REG_ADDR(NAND_CMD) + ^ +bl2/firmware/nfio.c:1271:16: note: in expansion of macro ‘P_NAND_CMD’ + while ((readl(P_NAND_CMD)>>22&0x1f) > 0); + ^ +bl2/firmware/nfio.c: In function ‘nf_normal_read_page_hwctrl’: +bl2/firmware/aml_nand.h:11:62: error: ‘IO_CBUS_BASE’ undeclared (first use in this function) + #define NAND_IADR ((0xc110860c-IO_CBUS_BASE)>>2) + ^ +include/drivers/serial/serial.h:57:49: note: in definition of macro ‘writel’ + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/aml_nand.h:47:65: note: in expansion of macro ‘NAND_IADR’ + #define P_NAND_IADR CBUS_REG_ADDR(NAND_IADR) + ^ +bl2/firmware/nfio.c:1374:19: note: in expansion of macro ‘P_NAND_IADR’ + writel(info_adr, P_NAND_IADR); + ^ +In file included from bl2/firmware/sdio.c:6:0, + from bl2/firmware/spl.c:36, + from bl2/bl2_main.c:43: +bl2/firmware/nfio.c:1342:46: warning: variable ‘newoobtype’ set but not used [-Wunused-but-set-variable] + int i, k, chip_num, plane_mode=0, ecc_mode, newoobtype = 0,extra_len=0; + ^ +In file included from bl2/firmware/spl.c:36:0, + from bl2/bl2_main.c:43: +bl2/firmware/sdio.c: In function ‘wait_busy’: +bl2/firmware/sdio.c:132:5: warning: implicit declaration of function ‘WRITE_CBUS_REG’ [-Wimplicit-function-declaration] + WRITE_CBUS_REG(SDIO_STATUS_IRQ,0x1fff<<sdio_timing_out_count_bit); + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/sdio.c: In function ‘sdio_send_cmd’: +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:147:5: note: in expansion of macro ‘writel’ + writel(arg,P_CMD_ARGUMENT); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:148:5: note: in expansion of macro ‘writel’ + writel(cmd,P_CMD_SEND); + ^ +In file included from bl2/firmware/spl.c:36:0, + from bl2/bl2_main.c:43: +bl2/firmware/sdio.c: In function ‘sdio_read’: +bl2/firmware/sdio.c:247:37: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + WRITE_CBUS_REG(SDIO_M_ADDR, (unsigned)((unsigned char *)&switch_status)); + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:286:7: note: in expansion of macro ‘writel’ + writel(1<<8,P_SDIO_MULT_CONFIG); + ^ +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/sdio.c:346:5: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_SDIO_IRQ_CONFIG,1<<soft_reset_bit); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:347:2: note: in expansion of macro ‘writel’ + writel(((1<<8) | (1<<9)),P_SDIO_STATUS_IRQ); + ^ +bl2/firmware/sdio.c: In function ‘sdio_init’: +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/sdio.c:425:5: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_SDIO_IRQ_CONFIG,1<<soft_reset_bit); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:427:5: note: in expansion of macro ‘writel’ + writel( (2 << sdio_write_CRC_ok_status_bit) | + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:437:5: note: in expansion of macro ‘writel’ + writel(SD_boot_type,P_SDIO_MULT_CONFIG); + ^ +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/sdio.c:446:5: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_SDIO_IRQ_CONFIG,1<<soft_reset_bit); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:447:5: note: in expansion of macro ‘writel’ + writel(((1<<8) | (1<<9)),P_SDIO_STATUS_IRQ); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:452:5: note: in expansion of macro ‘writel’ + writel(0,P_CMD_ARGUMENT);// delay some time for sdio_card ready + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:453:5: note: in expansion of macro ‘writel’ + writel(0,P_CMD_ARGUMENT); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:454:5: note: in expansion of macro ‘writel’ + writel(0,P_CMD_ARGUMENT); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:455:5: note: in expansion of macro ‘writel’ + writel(0,P_CMD_ARGUMENT); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:456:5: note: in expansion of macro ‘writel’ + writel(0,P_CMD_ARGUMENT); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:457:5: note: in expansion of macro ‘writel’ + writel(0,P_CMD_ARGUMENT); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:458:5: note: in expansion of macro ‘writel’ + writel(0,P_CMD_ARGUMENT); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:459:5: note: in expansion of macro ‘writel’ + writel(0,P_CMD_ARGUMENT); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:460:5: note: in expansion of macro ‘writel’ + writel(0,P_CMD_ARGUMENT); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:468:9: note: in expansion of macro ‘writel’ + writel(1<<8,P_SDIO_MULT_CONFIG); + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/sdio.c:469:13: note: in expansion of macro ‘readl’ + if((readl(P_CMD_ARGUMENT)&0x1ff) == 0x1aa) + ^ +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/sdio.c:478:9: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_SDIO_IRQ_CONFIG,1<<soft_reset_bit); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:479:9: note: in expansion of macro ‘writel’ + writel(((1<<8) | (1<<9)),P_SDIO_STATUS_IRQ); + ^ +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/sdio.c:506:9: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_SDIO_IRQ_CONFIG,1<<soft_reset_bit); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:507:9: note: in expansion of macro ‘writel’ + writel(((1<<8) | (1<<9)),P_SDIO_STATUS_IRQ); + ^ +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/sdio.c:519:13: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_SDIO_IRQ_CONFIG,1<<soft_reset_bit); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:520:13: note: in expansion of macro ‘writel’ + writel(((1<<8) | (1<<9)),P_SDIO_STATUS_IRQ); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:528:13: note: in expansion of macro ‘writel’ + writel(1<<8,P_SDIO_MULT_CONFIG); + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/sdio.c:530:20: note: in expansion of macro ‘readl’ + temp = readl(P_CMD_ARGUMENT); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:545:9: note: in expansion of macro ‘writel’ + writel(0x8300,P_SDIO_EXTENSION); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:560:9: note: in expansion of macro ‘writel’ + writel(1<<8,P_SDIO_MULT_CONFIG); + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/sdio.c:561:16: note: in expansion of macro ‘readl’ + temp = readl(P_CMD_ARGUMENT); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:602:5: note: in expansion of macro ‘writel’ + writel(1<<8,P_SDIO_MULT_CONFIG); + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/sdio.c:606:15: note: in expansion of macro ‘readl’ + cid = readl(P_CMD_ARGUMENT) ; + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:610:5: note: in expansion of macro ‘writel’ + writel(1<<8,P_SDIO_MULT_CONFIG); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:619:5: note: in expansion of macro ‘writel’ + writel(1<<8,P_SDIO_MULT_CONFIG); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:646:9: note: in expansion of macro ‘writel’ + writel(0x80000000,P_SDIO_M_ADDR); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/sdio.c:647:9: note: in expansion of macro ‘writel’ + writel(79<<16,P_SDIO_EXTENSION); + ^ +In file included from bl2/bl2_main.c:43:0: +bl2/firmware/spl.c: At top level: +bl2/firmware/spl.c:39:45: error: unknown type name ‘__kernel_size_t’ + extern void ipl_memcpy(void*, const void *, __kernel_size_t); + ^ +In file included from bl2/firmware/romboot.c:6:0, + from bl2/firmware/loaduboot.c:13, + from bl2/firmware/spl.c:42, + from bl2/bl2_main.c:43: +bl2/firmware/secure.c: In function ‘aml_m8_sec_boot_check’: +bl2/firmware/secure.c:137:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_v3 fp_01 = (t_func_v3)g_action[g_nStep][1]; //void rsa_init(1,2,3) + ^ +bl2/firmware/secure.c:138:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_r3 fp_02 = (t_func_r3)g_action[g_nStep][2]; //int mpi_read_string(1,2,3) + ^ +bl2/firmware/secure.c:139:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_v3 fp_03 = (t_func_v3)g_action[g_nStep][3]; //void efuse_read(1,2,3) + ^ +bl2/firmware/secure.c:140:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_r2 fp_04 = (t_func_r2)g_action[g_nStep][4]; //int boot_rsa_read_puk(a,b) + ^ +bl2/firmware/secure.c:141:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_r3 fp_05 = (t_func_r3)g_action[g_nStep][5]; //int rsa_public(1,2,3) + ^ +bl2/firmware/secure.c:142:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_v2 fp_06 = (t_func_v2)g_action[g_nStep][6]; //void boot_aes_setkey_dec(1,2) + ^ +bl2/firmware/secure.c:143:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_v1 fp_07 = (t_func_v1)g_action[g_nStep][7]; //void boot_aes_setiv_init(1) + ^ +bl2/firmware/secure.c:144:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_v4 fp_08 = (t_func_v4)g_action[g_nStep][8]; //void boot_aes_crypt_cbc(1,2,3,4) + ^ +bl2/firmware/secure.c:145:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_v4 fp_09 = (t_func_v4)g_action[g_nStep][9]; //void sha2(1,2,3,4) + ^ +bl2/firmware/secure.c:146:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_r3 fp_10 = (t_func_r3)g_action[g_nStep][10]; //int memcpy(1,2,3) + ^ +bl2/firmware/secure.c:147:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_r3 fp_11 = (t_func_r3)g_action[g_nStep][11];//int memcmp(1,2,3) + ^ +bl2/firmware/secure.c:148:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_r1 fp_12 = (t_func_r1)g_action[g_nStep][12];//int mpi_msb(1) + ^ +bl2/firmware/secure.c:149:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_v3 fp_13 = (t_func_v3)g_action[g_nStep][13];//void memset(1,2,3) + ^ +bl2/firmware/secure.c:153:8: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_01((int)&cb1_ctx,0,0); + ^ +bl2/firmware/secure.c:157:12: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + if(fp_02((int)cb1_ctx.szBuf1,(int)pkey1,nkey1Len) || fp_02((int)cb1_ctx.szBuf2,(int)pkey2,nkey2Len)) + ^ +bl2/firmware/secure.c:157:32: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + if(fp_02((int)cb1_ctx.szBuf1,(int)pkey1,nkey1Len) || fp_02((int)cb1_ctx.szBuf2,(int)pkey2,nkey2Len)) + ^ +bl2/firmware/secure.c:157:62: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + if(fp_02((int)cb1_ctx.szBuf1,(int)pkey1,nkey1Len) || fp_02((int)cb1_ctx.szBuf2,(int)pkey2,nkey2Len)) + ^ +bl2/firmware/secure.c:157:82: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + if(fp_02((int)cb1_ctx.szBuf1,(int)pkey1,nkey1Len) || fp_02((int)cb1_ctx.szBuf2,(int)pkey2,nkey2Len)) + ^ +bl2/firmware/secure.c:159:25: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + cb1_ctx.len = ( fp_12((int)cb1_ctx.szBuf1 ) + 7 ) >> 3; + ^ +bl2/firmware/secure.c:164:9: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_03((int)&nState,0,4); + ^ +bl2/firmware/secure.c:172:9: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_04((int)&cb1_ctx,(nState & (1<<23)) ? 1 : 0); + ^ +bl2/firmware/secure.c:176:8: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_10((int)(unsigned char*)&chk_blk,(int)(unsigned char*)pSRC,sizeof(chk_blk)); + ^ +bl2/firmware/secure.c:176:38: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_10((int)(unsigned char*)&chk_blk,(int)(unsigned char*)pSRC,sizeof(chk_blk)); + ^ +bl2/firmware/secure.c:179:12: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + if(fp_05((int)&cb1_ctx, (int)pBuf+i,(int)pBuf+i )) + ^ +bl2/firmware/secure.c:179:27: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + if(fp_05((int)&cb1_ctx, (int)pBuf+i,(int)pBuf+i )) + ^ +bl2/firmware/secure.c:179:39: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + if(fp_05((int)&cb1_ctx, (int)pBuf+i,(int)pBuf+i )) + ^ +bl2/firmware/secure.c:195:9: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_10((int)(void*)pSRC,(int)(void*)(pSRC+chk_blk.nLength1), + ^ +bl2/firmware/secure.c:195:26: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_10((int)(void*)pSRC,(int)(void*)(pSRC+chk_blk.nLength1), + ^ +bl2/firmware/secure.c:198:8: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_10((int)(void*)szkey,(int)(void*)chk_blk.szkey2,sizeof(szkey)); + ^ +bl2/firmware/secure.c:198:26: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_10((int)(void*)szkey,(int)(void*)chk_blk.szkey2,sizeof(szkey)); + ^ +bl2/firmware/secure.c:200:8: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_06((int) &cb2_ctx,(int)szkey ); + ^ +bl2/firmware/secure.c:200:23: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_06((int) &cb2_ctx,(int)szkey ); + ^ +bl2/firmware/secure.c:202:8: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_07((int)&szkey[32]); + ^ +bl2/firmware/secure.c:205:10: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_08 ((int) &cb2_ctx, (int)&szkey[32],(int) &ct32[i*4],(int) &ct32[i*4] ); + ^ +bl2/firmware/secure.c:205:26: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_08 ((int) &cb2_ctx, (int)&szkey[32],(int) &ct32[i*4],(int) &ct32[i*4] ); + ^ +bl2/firmware/secure.c:205:42: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_08 ((int) &cb2_ctx, (int)&szkey[32],(int) &ct32[i*4],(int) &ct32[i*4] ); + ^ +bl2/firmware/secure.c:205:59: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_08 ((int) &cb2_ctx, (int)&szkey[32],(int) &ct32[i*4],(int) &ct32[i*4] ); + ^ +bl2/firmware/secure.c:207:8: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_09((int) pSRC,chk_blk.nLength3,(int)szkey, 0 ); + ^ +bl2/firmware/secure.c:207:36: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_09((int) pSRC,chk_blk.nLength3,(int)szkey, 0 ); + ^ +bl2/firmware/secure.c:209:11: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + if(fp_11((int)szkey,(int)chk_blk.szkey1,32)) + ^ +bl2/firmware/secure.c:209:22: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + if(fp_11((int)szkey,(int)chk_blk.szkey1,32)) + ^ +bl2/firmware/secure.c: In function ‘aml_sec_boot_check’: +bl2/firmware/secure.c:255:29: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + unsigned int nBLKStart = ((unsigned int )aml_sec_boot_check) & (0xFFFF8000); + ^ +bl2/firmware/secure.c:282:22: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + aml_spl_blk *pblk = (aml_spl_blk *)(nBLKStart + nSPLLen - 1152 ); + ^ +bl2/firmware/secure.c:284:19: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_v3 fp_3 = (t_func_v3)g_action[g_nStep][3]; + ^ +bl2/firmware/secure.c:285:19: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_v4 fp_9 = (t_func_v4)g_action[g_nStep][9]; + ^ +bl2/firmware/secure.c:286:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_r3 fp_11 = (t_func_r3)g_action[g_nStep][11]; + ^ +bl2/firmware/secure.c:288:7: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_3((int)szCheck,452,36); + ^ +bl2/firmware/secure.c:290:7: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_9((int)pblk->sz2,260,(int)szHash, 0 ); + ^ +bl2/firmware/secure.c:290:26: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_9((int)pblk->sz2,260,(int)szHash, 0 ); + ^ +bl2/firmware/secure.c:292:15: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + nRet = fp_11((int)szCheck+2,(int)szHash,32); + ^ +bl2/firmware/secure.c:292:30: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + nRet = fp_11((int)szCheck+2,(int)szHash,32); + ^ +bl2/firmware/secure.c:314:62: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_9((int)(nBLKStart+pblk->nSPLStartOffset),pblk->splLenght,(int)szHash, 0 ); + ^ +bl2/firmware/secure.c:316:15: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + nRet = fp_11((int)pblk->sz4,(int)szHash,32); + ^ +bl2/firmware/secure.c:316:30: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + nRet = fp_11((int)pblk->sz4,(int)szHash,32); + ^ +bl2/firmware/secure.c: In function ‘aml_is_secure_set’: +bl2/firmware/secure.c:482:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_v3 fp_03 = (t_func_v3)g_action[g_nStep][3]; + ^ +bl2/firmware/secure.c:483:20: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + t_func_v3 fp_13 = (t_func_v3)g_action[g_nStep][13]; + ^ +bl2/firmware/secure.c:486:8: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + fp_03((int)&nState,0,4); + ^ +In file included from bl2/firmware/loaduboot.c:13:0, + from bl2/firmware/spl.c:42, + from bl2/bl2_main.c:43: +bl2/firmware/romboot.c: In function ‘fw_print_info’: +bl2/firmware/romboot.c:53:7: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + if((((unsigned int)fw_print_info >> 24) & 0xFF) != 0xD9) + ^ +bl2/firmware/romboot.c: In function ‘fw_load_intl’: +bl2/firmware/romboot.c:153:7: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + if((((unsigned int)fw_load_intl >> 24) & 0xFF) != ((AHB_SRAM_BASE>>24)&0xFF)) + ^ +bl2/firmware/romboot.c:155:3: warning: implicit declaration of function ‘ipl_memcpy’ [-Wimplicit-function-declaration] + memcpy((void*)temp_addr,(void*)target,size); //here need fine tune!! + ^ +bl2/firmware/romboot.c:155:10: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + memcpy((void*)temp_addr,(void*)target,size); //here need fine tune!! + ^ +bl2/firmware/romboot.c:155:27: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + memcpy((void*)temp_addr,(void*)target,size); //here need fine tune!! + ^ +bl2/firmware/romboot.c:213:13: warning: implicit declaration of function ‘spi_init’ [-Wimplicit-function-declaration] + spi_init(); + ^ +bl2/firmware/romboot.c:222:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + ipl_memcpy((unsigned char*)temp_addr,(unsigned char*)mem,size); + ^ +bl2/firmware/romboot.c:247:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + if(aml_sec_boot_check((unsigned char *)temp_addr)) + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:33:3: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); \ + ^ +bl2/firmware/romboot.c:249:3: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:34:3: note: in expansion of macro ‘writel’ + writel((10|((1<<AML_WATCHDOG_ENABLE_OFFSET)| \ + ^ +bl2/firmware/romboot.c:249:3: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +In file included from bl2/firmware/loaduboot.c:13:0, + from bl2/firmware/spl.c:42, + from bl2/bl2_main.c:43: +bl2/firmware/romboot.c:272:26: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + rc=uclDecompress((char*)target,&len,(char*)temp_addr); + ^ +bl2/firmware/romboot.c:272:45: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + rc=uclDecompress((char*)target,&len,(char*)temp_addr); + ^ +bl2/firmware/romboot.c:281:22: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + rc=check_sum((unsigned*)target,magic_info->crc[1],size); + ^ +bl2/firmware/romboot.c: In function ‘fw_load_extl’: +bl2/firmware/romboot.c:313:7: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + if((((unsigned int)fw_load_extl >> 24) & 0xFF) != ((AHB_SRAM_BASE>>24)&0xFF)) + ^ +bl2/firmware/romboot.c:315:10: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + memcpy((void*)temp_addr,(void*)target,size); //here need fine tune!! + ^ +bl2/firmware/romboot.c:315:27: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + memcpy((void*)temp_addr,(void*)target,size); //here need fine tune!! + ^ +bl2/firmware/romboot.c:330:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + if(aml_sec_boot_check((unsigned char *)temp_addr)) + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:33:3: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); \ + ^ +bl2/firmware/romboot.c:332:3: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:34:3: note: in expansion of macro ‘writel’ + writel((10|((1<<AML_WATCHDOG_ENABLE_OFFSET)| \ + ^ +bl2/firmware/romboot.c:332:3: note: in expansion of macro ‘AML_WATCH_DOG_START’ + AML_WATCH_DOG_START(); + ^ +In file included from bl2/firmware/loaduboot.c:13:0, + from bl2/firmware/spl.c:42, + from bl2/bl2_main.c:43: +bl2/firmware/romboot.c:357:23: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + rc=uclDecompress((char*)target,&len,(char*)temp_addr); + ^ +bl2/firmware/romboot.c:357:42: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + rc=uclDecompress((char*)target,&len,(char*)temp_addr); + ^ +bl2/firmware/romboot.c:367:22: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + rc=check_sum((unsigned*)target,magic_info->crc[1],size); + ^ +bl2/firmware/romboot.c: In function ‘load_ext’: +bl2/firmware/romboot.c:406:30: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + rc=uclDecompress((char*)(__load_table[i].dest),&len,(char*)(temp_addr+__load_table[i].src)); + ^ +bl2/firmware/romboot.c:406:65: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + rc=uclDecompress((char*)(__load_table[i].dest),&len,(char*)(temp_addr+__load_table[i].src)); + ^ +bl2/firmware/romboot.c:415:16: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + memcpy((void*)(__load_table[i].dest),(const void*)(__load_table[i].src+temp_addr),__load_table[i].size&0x3fffff); + ^ +bl2/firmware/romboot.c:415:46: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + memcpy((void*)(__load_table[i].dest),(const void*)(__load_table[i].src+temp_addr),__load_table[i].size&0x3fffff); + ^ +In file included from bl2/firmware/spl.c:42:0, + from bl2/bl2_main.c:43: +bl2/firmware/loaduboot.c: In function ‘load_uboot’: +bl2/firmware/loaduboot.c:86:43: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + unsigned int *pAUINF = (unsigned int *)(((unsigned int)load_uboot & 0xFFFF8000)+(AML_UBOOT_SINFO_OFFSET)); + ^ +In file included from bl2/ddr/ddr.c:22:0, + from bl2/bl2_main.c:42: +bl2/firmware/spl.c: In function ‘main’: +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:20:2: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); \ + ^ +bl2/firmware/spl.c:62:2: note: in expansion of macro ‘AML_WATCH_DOG_SET’ + AML_WATCH_DOG_SET(5000); //5s + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:21:2: note: in expansion of macro ‘writel’ + writel((((int)(time * 1000 / AML_WATCHDOG_TIME_SLICE)) | \ + ^ +bl2/firmware/spl.c:62:2: note: in expansion of macro ‘AML_WATCH_DOG_SET’ + AML_WATCH_DOG_SET(5000); //5s + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/spl.c:111:22: note: in expansion of macro ‘readl’ + unsigned pinmux_2 = readl(P_PERIPHS_PIN_MUX_2); + ^ +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/spl.c:135:2: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_PREG_PAD_GPIO0_O,0x3f<<22); + ^ +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/spl.c:136:2: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_PREG_PAD_GPIO0_EN_N,0x3f<<22); + ^ +include/drivers/serial/serial.h:60:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define clrbits_le32(reg,val) (*((volatile unsigned *)reg))&=(~val) + ^ +bl2/firmware/spl.c:137:2: note: in expansion of macro ‘clrbits_le32’ + clrbits_le32(P_PERIPHS_PIN_MUX_2,7<<12); //clear sd d1~d3 pinmux + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/spl.c:139:7: note: in expansion of macro ‘readl’ + if(!(readl(P_PREG_PAD_GPIO0_I)&(1<<26))){ //sd_d3 low, debug board in + ^ +include/drivers/serial/serial.h:59:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define setbits_le32(reg,val) (*((volatile unsigned *)reg))|=val + ^ +bl2/firmware/spl.c:142:3: note: in expansion of macro ‘setbits_le32’ + setbits_le32(P_PERIPHS_PIN_MUX_8,3<<9); + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/spl.c:144:7: note: in expansion of macro ‘readl’ + if((readl(P_PREG_PAD_GPIO0_I)&(1<<22))) + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/spl.c:149:3: note: in expansion of macro ‘writel’ + writel(pinmux_2,P_PERIPHS_PIN_MUX_2); + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/spl.c:211:22: note: in expansion of macro ‘readl’ + unsigned int nPLL = readl(P_HHI_A9_CLK_CNTL); + ^ +include/drivers/serial/serial.h:58:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define readl(reg) (*((volatile unsigned *)reg)) + ^ +bl2/firmware/spl.c:215:10: note: in expansion of macro ‘readl’ + nPLL = readl(P_HHI_SYS_PLL_CNTL); + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:27:2: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_TC); \ + ^ +bl2/firmware/spl.c:279:2: note: in expansion of macro ‘AML_WATCH_DOG_DISABLE’ + AML_WATCH_DOG_DISABLE(); //disable watchdog + ^ +include/drivers/serial/serial.h:57:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + #define writel(val,reg) (*((volatile unsigned *)reg))=(val) + ^ +bl2/firmware/plat-cpu.h:28:2: note: in expansion of macro ‘writel’ + writel(0, P_WATCHDOG_RESET); + ^ +bl2/firmware/spl.c:279:2: note: in expansion of macro ‘AML_WATCH_DOG_DISABLE’ + AML_WATCH_DOG_DISABLE(); //disable watchdog + ^ +In file included from bl2/firmware/spl.c:29:0, + from bl2/bl2_main.c:43: +bl2/bl2_main.c: At top level: +bl2/firmware/pll.c:41:13: warning: ‘wait_clock’ defined but not used [-Wunused-function] + static void wait_clock(unsigned clk,unsigned dest) + ^ +In file included from bl2/firmware/spl.c:32:0, + from bl2/bl2_main.c:43: +bl2/firmware/power.c:115:12: warning: ‘vcck_set_default_voltage’ defined but not used [-Wunused-function] + static int vcck_set_default_voltage(int voltage) + ^ +In file included from bl2/firmware/spl.c:34:0, + from bl2/bl2_main.c:43: +bl2/firmware/ddr.c:13:13: warning: ‘wait_pll’ declared ‘static’ but never defined [-Wunused-function] + static void wait_pll(unsigned clk,unsigned dest); + ^ +In file included from bl2/firmware/ddr.c:17:0, + from bl2/firmware/spl.c:34, + from bl2/bl2_main.c:43: +bl2/firmware/ddr_init_pctl.c:28:13: warning: ‘serial_put_dec_nothing’ defined but not used [-Wunused-function] + static void serial_put_dec_nothing(unsigned int data){ + ^ +In file included from bl2/firmware/nfio.c:10:0, + from bl2/firmware/sdio.c:6, + from bl2/firmware/spl.c:36, + from bl2/bl2_main.c:43: +bl2/firmware/aml_a9_cache.c:61:12: warning: ‘get_ccsidr’ defined but not used [-Wunused-function] + static u32 get_ccsidr(void) + ^ +bl2/firmware/aml_a9_cache.c:70:12: warning: ‘get_clidr’ defined but not used [-Wunused-function] + static u32 get_clidr(void) + ^ +make: *** [build/juno/debug/bl2/bl2_main.o] Error 1 diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c new file mode 100644 index 0000000..2abf29d --- /dev/null +++ b/plat/common/aarch64/plat_common.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <xlat_tables.h> + +/* + * The following 2 platform setup functions are weakly defined. They + * provide typical implementations that may be re-used by multiple + * platforms but may also be overridden by a platform if required. + */ +#pragma weak bl31_plat_enable_mmu +#pragma weak bl32_plat_enable_mmu + +void bl31_plat_enable_mmu() +{ + enable_mmu_el3(); +} + +void bl32_plat_enable_mmu() +{ + enable_mmu_el1(); +} diff --git a/plat/common/aarch64/platform_helpers.S b/plat/common/aarch64/platform_helpers.S new file mode 100644 index 0000000..f6ac13e --- /dev/null +++ b/plat/common/aarch64/platform_helpers.S @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> +#include <platform_def.h> + + + .weak platform_get_core_pos + .weak platform_is_primary_cpu + .weak platform_check_mpidr + .weak plat_report_exception + + /* ----------------------------------------------------- + * int platform_get_core_pos(int mpidr); + * With this function: CorePos = (ClusterId * 4) + + * CoreId + * ----------------------------------------------------- + */ +func platform_get_core_pos + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret + + /* ----------------------------------------------------- + * void platform_is_primary_cpu (unsigned int mpid); + * + * Given the mpidr say whether this cpu is the primary + * cpu (applicable ony after a cold boot) + * ----------------------------------------------------- + */ +func platform_is_primary_cpu + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, #PRIMARY_CPU + cset x0, eq + ret + + /* ----------------------------------------------------- + * Placeholder function which should be redefined by + * each platform. + * ----------------------------------------------------- + */ +func platform_check_mpidr + mov x0, xzr + ret + + /* ----------------------------------------------------- + * Placeholder function which should be redefined by + * each platform. + * ----------------------------------------------------- + */ +func plat_report_exception + ret diff --git a/plat/common/aarch64/platform_mp_stack.S b/plat/common/aarch64/platform_mp_stack.S new file mode 100644 index 0000000..801ec7f --- /dev/null +++ b/plat/common/aarch64/platform_mp_stack.S @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> +#include <platform_def.h> + + + .local pcpu_dv_mem_stack + .local platform_normal_stacks + .weak platform_set_stack + .weak platform_get_stack + .weak platform_set_coherent_stack + + + /* ----------------------------------------------------- + * void platform_set_coherent_stack (unsigned long mpidr) + * + * For a given CPU, this function sets the stack pointer + * to a stack allocated in device memory. This stack can + * be used by C code which enables/disables the SCTLR.M + * SCTLR.C bit e.g. while powering down a cpu + * ----------------------------------------------------- + */ +func platform_set_coherent_stack + mov x5, x30 // lr + get_mp_stack pcpu_dv_mem_stack, PCPU_DV_MEM_STACK_SIZE + mov sp, x0 + ret x5 + + /* ----------------------------------------------------- + * unsigned long platform_get_stack (unsigned long mpidr) + * + * For a given CPU, this function returns the stack + * pointer for a stack allocated in device memory. + * ----------------------------------------------------- + */ +func platform_get_stack + mov x10, x30 // lr + get_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE + ret x10 + + /* ----------------------------------------------------- + * void platform_set_stack (unsigned long mpidr) + * + * For a given CPU, this function sets the stack pointer + * to a stack allocated in normal memory. + * ----------------------------------------------------- + */ +func platform_set_stack + mov x9, x30 // lr + bl platform_get_stack + mov sp, x0 + ret x9 + + /* ----------------------------------------------------- + * Per-cpu stacks in normal memory. + * Used for C code during runtime execution (when coherent + * stacks are not required). + * Each cpu gets a stack of PLATFORM_STACK_SIZE bytes. + * ----------------------------------------------------- + */ +declare_stack platform_normal_stacks, tzfw_normal_stacks, \ + PLATFORM_STACK_SIZE, PLATFORM_CORE_COUNT + + /* ----------------------------------------------------- + * Per-cpu stacks in device memory. + * Used for C code just before power down or right after + * power up when the MMU or caches need to be turned on + * or off. + * Each cpu gets a stack of PCPU_DV_MEM_STACK_SIZE bytes. + * ----------------------------------------------------- + */ +declare_stack pcpu_dv_mem_stack, tzfw_coherent_mem, \ + PCPU_DV_MEM_STACK_SIZE, PLATFORM_CORE_COUNT diff --git a/plat/common/aarch64/platform_up_stack.S b/plat/common/aarch64/platform_up_stack.S new file mode 100644 index 0000000..45a96a6 --- /dev/null +++ b/plat/common/aarch64/platform_up_stack.S @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> +#include <platform_def.h> + + + .local pcpu_dv_mem_stack + .local platform_normal_stacks + .globl platform_set_stack + .globl platform_get_stack + .globl platform_set_coherent_stack + + + /* ----------------------------------------------------- + * void platform_set_coherent_stack (unsigned long) + * + * For cold-boot BL images, only the primary CPU needs a + * stack. This function sets the stack pointer to a stack + * allocated in device memory. + * ----------------------------------------------------- + */ +func platform_set_coherent_stack + get_up_stack pcpu_dv_mem_stack, PCPU_DV_MEM_STACK_SIZE + mov sp, x0 + ret + + + /* ----------------------------------------------------- + * unsigned long platform_get_stack (unsigned long) + * + * For cold-boot BL images, only the primary CPU needs a + * stack. This function returns the stack pointer for a + * stack allocated in device memory. + * ----------------------------------------------------- + */ +func platform_get_stack + get_up_stack platform_normal_stacks, PLATFORM_STACK_SIZE + ret + + /* ----------------------------------------------------- + * void platform_set_stack (unsigned long) + * + * For cold-boot BL images, only the primary CPU needs a + * stack. This function sets the stack pointer to a stack + * allocated in normal memory. + * ----------------------------------------------------- + */ +func platform_set_stack + get_up_stack platform_normal_stacks, PLATFORM_STACK_SIZE + mov sp, x0 + ret + + /* ----------------------------------------------------- + * Single cpu stack in normal memory. + * Used for C code during boot, PLATFORM_STACK_SIZE bytes + * are allocated + * ----------------------------------------------------- + */ +declare_stack platform_normal_stacks, tzfw_normal_stacks, \ + PLATFORM_STACK_SIZE, 1 + + /* ----------------------------------------------------- + * Single cpu stack in device/coherent memory. + * PCPU_DV_MEM_STACK_SIZE bytes are allocated. + * ----------------------------------------------------- + */ +declare_stack pcpu_dv_mem_stack, tzfw_coherent_mem, \ + PCPU_DV_MEM_STACK_SIZE, 1 diff --git a/plat/fvp/aarch64/fvp_common.c b/plat/fvp/aarch64/fvp_common.c new file mode 100644 index 0000000..3a07844 --- /dev/null +++ b/plat/fvp/aarch64/fvp_common.c @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <cci400.h> +#include <debug.h> +#include <mmio.h> +#include <platform.h> +#include <xlat_tables.h> +#include "../fvp_def.h" + +/******************************************************************************* + * This array holds the characteristics of the differences between the three + * FVP platforms (Base, A53_A57 & Foundation). It will be populated during cold + * boot at each boot stage by the primary before enabling the MMU (to allow cci + * configuration) & used thereafter. Each BL will have its own copy to allow + * independent operation. + ******************************************************************************/ +static unsigned long fvp_config[CONFIG_LIMIT]; + +/* + * Table of regions to map using the MMU. + * This doesn't include TZRAM as the 'mem_layout' argument passed to + * configure_mmu_elx() will give the available subset of that, + */ +const mmap_region_t fvp_mmap[] = { + { TZROM_BASE, TZROM_SIZE, MT_MEMORY | MT_RO | MT_SECURE }, + { TZDRAM_BASE, TZDRAM_SIZE, MT_MEMORY | MT_RW | MT_SECURE }, + { FLASH0_BASE, FLASH0_SIZE, MT_MEMORY | MT_RO | MT_SECURE }, + { FLASH1_BASE, FLASH1_SIZE, MT_MEMORY | MT_RO | MT_SECURE }, + { VRAM_BASE, VRAM_SIZE, MT_MEMORY | MT_RW | MT_SECURE }, + { DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, + { NSRAM_BASE, NSRAM_SIZE, MT_MEMORY | MT_RW | MT_NS }, + { DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, + /* 2nd GB as device for now...*/ + { 0x40000000, 0x40000000, MT_DEVICE | MT_RW | MT_SECURE }, + { DRAM1_BASE, DRAM1_SIZE, MT_MEMORY | MT_RW | MT_NS }, + {0} +}; + +/******************************************************************************* + * Macro generating the code for the function setting up the pagetables as per + * the platform memory map & initialize the mmu, for the given exception level + ******************************************************************************/ +#define DEFINE_CONFIGURE_MMU_EL(_el) \ + void fvp_configure_mmu_el##_el(unsigned long total_base, \ + unsigned long total_size, \ + unsigned long ro_start, \ + unsigned long ro_limit, \ + unsigned long coh_start, \ + unsigned long coh_limit) \ + { \ + mmap_add_region(total_base, \ + total_size, \ + MT_MEMORY | MT_RW | MT_SECURE); \ + mmap_add_region(ro_start, ro_limit - ro_start, \ + MT_MEMORY | MT_RO | MT_SECURE); \ + mmap_add_region(coh_start, coh_limit - coh_start, \ + MT_DEVICE | MT_RW | MT_SECURE); \ + mmap_add(fvp_mmap); \ + init_xlat_tables(); \ + \ + enable_mmu_el##_el(); \ + } + +/* Define EL1 and EL3 variants of the function initialising the MMU */ +DEFINE_CONFIGURE_MMU_EL(1) +DEFINE_CONFIGURE_MMU_EL(3) + +/* Simple routine which returns a configuration variable value */ +unsigned long fvp_get_cfgvar(unsigned int var_id) +{ + assert(var_id < CONFIG_LIMIT); + return fvp_config[var_id]; +} + +/******************************************************************************* + * A single boot loader stack is expected to work on both the Foundation FVP + * models and the two flavours of the Base FVP models (AEMv8 & Cortex). The + * SYS_ID register provides a mechanism for detecting the differences between + * these platforms. This information is stored in a per-BL array to allow the + * code to take the correct path.Per BL platform configuration. + ******************************************************************************/ +int fvp_config_setup(void) +{ + unsigned int rev, hbi, bld, arch, sys_id, midr_pn; + + sys_id = mmio_read_32(VE_SYSREGS_BASE + V2M_SYS_ID); + rev = (sys_id >> SYS_ID_REV_SHIFT) & SYS_ID_REV_MASK; + hbi = (sys_id >> SYS_ID_HBI_SHIFT) & SYS_ID_HBI_MASK; + bld = (sys_id >> SYS_ID_BLD_SHIFT) & SYS_ID_BLD_MASK; + arch = (sys_id >> SYS_ID_ARCH_SHIFT) & SYS_ID_ARCH_MASK; + + if ((rev != REV_FVP) || (arch != ARCH_MODEL)) + panic(); + + /* + * The build field in the SYS_ID tells which variant of the GIC + * memory is implemented by the model. + */ + switch (bld) { + case BLD_GIC_VE_MMAP: + fvp_config[CONFIG_GICD_ADDR] = VE_GICD_BASE; + fvp_config[CONFIG_GICC_ADDR] = VE_GICC_BASE; + fvp_config[CONFIG_GICH_ADDR] = VE_GICH_BASE; + fvp_config[CONFIG_GICV_ADDR] = VE_GICV_BASE; + break; + case BLD_GIC_A53A57_MMAP: + fvp_config[CONFIG_GICD_ADDR] = BASE_GICD_BASE; + fvp_config[CONFIG_GICC_ADDR] = BASE_GICC_BASE; + fvp_config[CONFIG_GICH_ADDR] = BASE_GICH_BASE; + fvp_config[CONFIG_GICV_ADDR] = BASE_GICV_BASE; + break; + default: + assert(0); + } + + /* + * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010 + * for the Foundation FVP. + */ + switch (hbi) { + case HBI_FOUNDATION: + fvp_config[CONFIG_MAX_AFF0] = 4; + fvp_config[CONFIG_MAX_AFF1] = 1; + fvp_config[CONFIG_CPU_SETUP] = 0; + fvp_config[CONFIG_BASE_MMAP] = 0; + fvp_config[CONFIG_HAS_CCI] = 0; + fvp_config[CONFIG_HAS_TZC] = 0; + break; + case HBI_FVP_BASE: + midr_pn = (read_midr() >> MIDR_PN_SHIFT) & MIDR_PN_MASK; + if ((midr_pn == MIDR_PN_A57) || (midr_pn == MIDR_PN_A53)) + fvp_config[CONFIG_CPU_SETUP] = 1; + else + fvp_config[CONFIG_CPU_SETUP] = 0; + + fvp_config[CONFIG_MAX_AFF0] = 4; + fvp_config[CONFIG_MAX_AFF1] = 2; + fvp_config[CONFIG_BASE_MMAP] = 1; + fvp_config[CONFIG_HAS_CCI] = 1; + fvp_config[CONFIG_HAS_TZC] = 1; + break; + default: + assert(0); + } + + return 0; +} + +unsigned long plat_get_ns_image_entrypoint(void) +{ + return NS_IMAGE_OFFSET; +} + +uint64_t plat_get_syscnt_freq(void) +{ + uint64_t counter_base_frequency; + + /* Read the frequency from Frequency modes table */ + counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF); + + /* The first entry of the frequency modes table must not be 0 */ + assert(counter_base_frequency != 0); + + return counter_base_frequency; +} + +void fvp_cci_setup(void) +{ + unsigned long cci_setup; + + /* + * Enable CCI-400 for this cluster. No need + * for locks as no other cpu is active at the + * moment + */ + cci_setup = fvp_get_cfgvar(CONFIG_HAS_CCI); + if (cci_setup) + cci_enable_coherency(read_mpidr()); +} + + +/******************************************************************************* + * Set SPSR and secure state for BL32 image + ******************************************************************************/ +void fvp_set_bl32_ep_info(entry_point_info_t *bl32_ep_info) +{ + SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE); + /* + * The Secure Payload Dispatcher service is responsible for + * setting the SPSR prior to entry into the BL32 image. + */ + bl32_ep_info->spsr = 0; +} + +/******************************************************************************* + * Set SPSR and secure state for BL33 image + ******************************************************************************/ +void fvp_set_bl33_ep_info(entry_point_info_t *bl33_ep_info) +{ + unsigned long el_status; + unsigned int mode; + + /* Figure out what mode we enter the non-secure world in */ + el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; + el_status &= ID_AA64PFR0_ELX_MASK; + + if (el_status) + mode = MODE_EL2; + else + mode = MODE_EL1; + + /* + * TODO: Consider the possibility of specifying the SPSR in + * the FIP ToC and allowing the platform to have a say as + * well. + */ + bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE); +} diff --git a/plat/fvp/aarch64/fvp_helpers.S b/plat/fvp/aarch64/fvp_helpers.S new file mode 100644 index 0000000..f856f46 --- /dev/null +++ b/plat/fvp/aarch64/fvp_helpers.S @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> +#include <bl_common.h> +#include <gic_v2.h> +#include "../drivers/pwrc/fvp_pwrc.h" +#include "../fvp_def.h" + + .globl platform_get_entrypoint + .globl plat_secondary_cold_boot_setup + .globl platform_mem_init + .globl plat_report_exception + + .macro fvp_choose_gicmmap param1, param2, x_tmp, w_tmp, res + ldr \x_tmp, =VE_SYSREGS_BASE + V2M_SYS_ID + ldr \w_tmp, [\x_tmp] + ubfx \w_tmp, \w_tmp, #SYS_ID_BLD_SHIFT, #SYS_ID_BLD_LENGTH + cmp \w_tmp, #BLD_GIC_VE_MMAP + csel \res, \param1, \param2, eq + .endm + + /* ----------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset e.g + * mark the cpu's presence, mechanism to place it in a + * holding pen etc. + * TODO: Should we read the PSYS register to make sure + * that the request has gone through. + * ----------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + /* --------------------------------------------- + * Power down this cpu. + * TODO: Do we need to worry about powering the + * cluster down as well here. That will need + * locks which we won't have unless an elf- + * loader zeroes out the zi section. + * --------------------------------------------- + */ + mrs x0, mpidr_el1 + ldr x1, =PWRC_BASE + str w0, [x1, #PPOFFR_OFF] + + /* --------------------------------------------- + * Deactivate the gic cpu interface as well + * --------------------------------------------- + */ + ldr x0, =VE_GICC_BASE + ldr x1, =BASE_GICC_BASE + fvp_choose_gicmmap x0, x1, x2, w2, x1 + mov w0, #(IRQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP1) + orr w0, w0, #(IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP0) + str w0, [x1, #GICC_CTLR] + + /* --------------------------------------------- + * There is no sane reason to come out of this + * wfi so panic if we do. This cpu will be pow- + * ered on and reset by the cpu_on pm api + * --------------------------------------------- + */ + dsb sy + wfi +cb_panic: + b cb_panic + + + /* ----------------------------------------------------- + * void platform_get_entrypoint (unsigned int mpid); + * + * Main job of this routine is to distinguish between + * a cold and warm boot. + * On a cold boot the secondaries first wait for the + * platform to be initialized after which they are + * hotplugged in. The primary proceeds to perform the + * platform initialization. + * On a warm boot, each cpu jumps to the address in its + * mailbox. + * + * TODO: Not a good idea to save lr in a temp reg + * TODO: PSYSR is a common register and should be + * accessed using locks. Since its not possible + * to use locks immediately after a cold reset + * we are relying on the fact that after a cold + * reset all cpus will read the same WK field + * ----------------------------------------------------- + */ +func platform_get_entrypoint + mov x9, x30 // lr + mov x2, x0 + ldr x1, =PWRC_BASE + str w2, [x1, #PSYSR_OFF] + ldr w2, [x1, #PSYSR_OFF] + ubfx w2, w2, #PSYSR_WK_SHIFT, #PSYSR_WK_MASK + cbnz w2, warm_reset + mov x0, x2 + b exit +warm_reset: + /* --------------------------------------------- + * A per-cpu mailbox is maintained in the tru- + * sted DRAM. Its flushed out of the caches + * after every update using normal memory so + * its safe to read it here with SO attributes + * --------------------------------------------- + */ + ldr x10, =TZDRAM_BASE + MBOX_OFF + bl platform_get_core_pos + lsl x0, x0, #CACHE_WRITEBACK_SHIFT + ldr x0, [x10, x0] + cbz x0, _panic +exit: + ret x9 +_panic: b _panic + + + /* ----------------------------------------------------- + * void platform_mem_init (void); + * + * Zero out the mailbox registers in the TZDRAM. The + * mmu is turned off right now and only the primary can + * ever execute this code. Secondaries will read the + * mailboxes using SO accesses. In short, BL31 will + * update the mailboxes after mapping the tzdram as + * normal memory. It will flush its copy after update. + * BL1 will always read the mailboxes with the MMU off + * ----------------------------------------------------- + */ +func platform_mem_init + ldr x0, =TZDRAM_BASE + MBOX_OFF + mov w1, #PLATFORM_CORE_COUNT +loop: + str xzr, [x0], #CACHE_WRITEBACK_GRANULE + subs w1, w1, #1 + b.gt loop + ret + + /* --------------------------------------------- + * void plat_report_exception(unsigned int type) + * Function to report an unhandled exception + * with platform-specific means. + * On FVP platform, it updates the LEDs + * to indicate where we are + * --------------------------------------------- + */ +func plat_report_exception + mrs x1, CurrentEl + lsr x1, x1, #MODE_EL_SHIFT + lsl x1, x1, #SYS_LED_EL_SHIFT + lsl x0, x0, #SYS_LED_EC_SHIFT + mov x2, #(SECURE << SYS_LED_SS_SHIFT) + orr x0, x0, x2 + orr x0, x0, x1 + mov x1, #VE_SYSREGS_BASE + add x1, x1, #V2M_SYS_LED + str w0, [x1] + ret diff --git a/plat/fvp/bl1_fvp_setup.c b/plat/fvp/bl1_fvp_setup.c new file mode 100644 index 0000000..f758082 --- /dev/null +++ b/plat/fvp/bl1_fvp_setup.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <console.h> +#include <mmio.h> +#include <platform.h> +#include <platform_def.h> +#include "fvp_def.h" +#include "fvp_private.h" + +/******************************************************************************* + * Declarations of linker defined symbols which will help us find the layout + * of trusted SRAM + ******************************************************************************/ +extern unsigned long __COHERENT_RAM_START__; +extern unsigned long __COHERENT_RAM_END__; + +extern unsigned long __BL1_RAM_START__; +extern unsigned long __BL1_RAM_END__; + +/* + * The next 2 constants identify the extents of the coherent memory region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to + * page-aligned addresses. + */ +#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) +#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) + +#define BL1_RAM_BASE (unsigned long)(&__BL1_RAM_START__) +#define BL1_RAM_LIMIT (unsigned long)(&__BL1_RAM_END__) + + +/* Data structure which holds the extents of the trusted SRAM for BL1*/ +static meminfo_t bl1_tzram_layout; + +meminfo_t *bl1_plat_sec_mem_layout(void) +{ + return &bl1_tzram_layout; +} + +/******************************************************************************* + * Perform any BL1 specific platform actions. + ******************************************************************************/ +void bl1_early_platform_setup(void) +{ + const unsigned long bl1_ram_base = BL1_RAM_BASE; + const unsigned long bl1_ram_limit = BL1_RAM_LIMIT; + const unsigned long tzram_limit = TZRAM_BASE + TZRAM_SIZE; + + /* Initialize the console to provide early debug support */ + console_init(PL011_UART0_BASE); + + /* + * Calculate how much ram is BL1 using & how much remains free. + * This also includes a rudimentary mechanism to detect whether + * the BL1 data is loaded at the top or bottom of memory. + * TODO: add support for discontigous chunks of free ram if + * needed. Might need dynamic memory allocation support + * et al. + */ + bl1_tzram_layout.total_base = TZRAM_BASE; + bl1_tzram_layout.total_size = TZRAM_SIZE; + + if (bl1_ram_limit == tzram_limit) { + /* BL1 has been loaded at the top of memory. */ + bl1_tzram_layout.free_base = TZRAM_BASE; + bl1_tzram_layout.free_size = bl1_ram_base - TZRAM_BASE; + } else { + /* BL1 has been loaded at the bottom of memory. */ + bl1_tzram_layout.free_base = bl1_ram_limit; + bl1_tzram_layout.free_size = + tzram_limit - bl1_ram_limit; + } + + /* Initialize the platform config for future decision making */ + fvp_config_setup(); +} + +/******************************************************************************* + * Function which will evaluate how much of the trusted ram has been gobbled + * up by BL1 and return the base and size of whats available for loading BL2. + * Its called after coherency and the MMU have been turned on. + ******************************************************************************/ +void bl1_platform_setup(void) +{ + /* Initialise the IO layer and register platform IO devices */ + fvp_io_setup(); +} + + +/******************************************************************************* + * Perform the very early platform specific architecture setup here. At the + * moment this only does basic initialization. Later architectural setup + * (bl1_arch_setup()) does not do anything platform specific. + ******************************************************************************/ +void bl1_plat_arch_setup(void) +{ + fvp_cci_setup(); + + fvp_configure_mmu_el3(bl1_tzram_layout.total_base, + bl1_tzram_layout.total_size, + TZROM_BASE, + TZROM_BASE + TZROM_SIZE, + BL1_COHERENT_RAM_BASE, + BL1_COHERENT_RAM_LIMIT); +} + + +/******************************************************************************* + * Before calling this function BL2 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL2 and set SPSR and security state. + * On FVP we are only setting the security state, entrypoint + ******************************************************************************/ +void bl1_plat_set_bl2_ep_info(image_info_t *bl2_image, + entry_point_info_t *bl2_ep) +{ + SET_SECURITY_STATE(bl2_ep->h.attr, SECURE); + bl2_ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); +} diff --git a/plat/fvp/bl2_fvp_setup.c b/plat/fvp/bl2_fvp_setup.c new file mode 100644 index 0000000..72580f9 --- /dev/null +++ b/plat/fvp/bl2_fvp_setup.c @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <console.h> +#include <platform.h> +#include <platform_def.h> +#include <string.h> +#include "fvp_def.h" +#include "fvp_private.h" + +/******************************************************************************* + * Declarations of linker defined symbols which will help us find the layout + * of trusted SRAM + ******************************************************************************/ +extern unsigned long __RO_START__; +extern unsigned long __RO_END__; + +extern unsigned long __COHERENT_RAM_START__; +extern unsigned long __COHERENT_RAM_END__; + +/* + * The next 2 constants identify the extents of the code & RO data region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses. + */ +#define BL2_RO_BASE (unsigned long)(&__RO_START__) +#define BL2_RO_LIMIT (unsigned long)(&__RO_END__) + +/* + * The next 2 constants identify the extents of the coherent memory region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to + * page-aligned addresses. + */ +#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) +#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) + +/* Pointer to memory visible to both BL2 and BL31 for passing data */ +extern unsigned char **bl2_el_change_mem_ptr; + +/* Data structure which holds the extents of the trusted SRAM for BL2 */ +static meminfo_t bl2_tzram_layout +__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE), + section("tzfw_coherent_mem"))); + +/******************************************************************************* + * Reference to structures which holds the arguments which need to be passed + * to BL31 + ******************************************************************************/ +static bl31_params_t *bl2_to_bl31_params; +static entry_point_info_t *bl31_ep_info; + +meminfo_t *bl2_plat_sec_mem_layout(void) +{ + return &bl2_tzram_layout; +} + +/******************************************************************************* + * This function assigns a pointer to the memory that the platform has kept + * aside to pass platform specific and trusted firmware related information + * to BL31. This memory is allocated by allocating memory to + * bl2_to_bl31_params_mem_t structure which is a superset of all the + * structure whose information is passed to BL31 + * NOTE: This function should be called only once and should be done + * before generating params to BL31 + ******************************************************************************/ +bl31_params_t *bl2_plat_get_bl31_params(void) +{ + bl2_to_bl31_params_mem_t *bl31_params_mem; + +#if TSP_RAM_LOCATION_ID == TSP_IN_TZDRAM + /* + * Ensure that the secure DRAM memory used for passing BL31 arguments + * does not overlap with the BL32_BASE. + */ + assert(BL32_BASE > PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t)); +#endif + + /* + * Allocate the memory for all the arguments that needs to + * be passed to BL31 + */ + bl31_params_mem = (bl2_to_bl31_params_mem_t *)PARAMS_BASE; + memset((void *)PARAMS_BASE, 0, sizeof(bl2_to_bl31_params_mem_t)); + + /* Assign memory for TF related information */ + bl2_to_bl31_params = &bl31_params_mem->bl31_params; + SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0); + + /* Fill BL31 related information */ + bl31_ep_info = &bl31_params_mem->bl31_ep_info; + bl2_to_bl31_params->bl31_image_info = &bl31_params_mem->bl31_image_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY, + VERSION_1, 0); + + /* Fill BL32 related information if it exists */ + if (BL32_BASE) { + bl2_to_bl31_params->bl32_ep_info = + &bl31_params_mem->bl32_ep_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, + PARAM_EP, VERSION_1, 0); + bl2_to_bl31_params->bl32_image_info = + &bl31_params_mem->bl32_image_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, + PARAM_IMAGE_BINARY, + VERSION_1, 0); + } + + /* Fill BL33 related information */ + bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem->bl33_ep_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info, + PARAM_EP, VERSION_1, 0); + bl2_to_bl31_params->bl33_image_info = &bl31_params_mem->bl33_image_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY, + VERSION_1, 0); + + return bl2_to_bl31_params; +} + + +/******************************************************************************* + * This function returns a pointer to the shared memory that the platform + * has kept to point to entry point information of BL31 to BL2 + ******************************************************************************/ +struct entry_point_info *bl2_plat_get_bl31_ep_info(void) +{ +#if DEBUG + bl31_ep_info->args.arg1 = FVP_BL31_PLAT_PARAM_VAL; +#endif + return bl31_ep_info; +} + + +/******************************************************************************* + * BL1 has passed the extents of the trusted SRAM that should be visible to BL2 + * in x0. This memory layout is sitting at the base of the free trusted SRAM. + * Copy it to a safe loaction before its reclaimed by later BL2 functionality. + ******************************************************************************/ +void bl2_early_platform_setup(meminfo_t *mem_layout) +{ + /* Initialize the console to provide early debug support */ + console_init(PL011_UART0_BASE); + + /* Setup the BL2 memory layout */ + bl2_tzram_layout.total_base = mem_layout->total_base; + bl2_tzram_layout.total_size = mem_layout->total_size; + bl2_tzram_layout.free_base = mem_layout->free_base; + bl2_tzram_layout.free_size = mem_layout->free_size; + bl2_tzram_layout.attr = mem_layout->attr; + bl2_tzram_layout.next = 0; + + /* Initialize the platform config for future decision making */ + fvp_config_setup(); +} + +/******************************************************************************* + * Perform platform specific setup. For now just initialize the memory location + * to use for passing arguments to BL31. + ******************************************************************************/ +void bl2_platform_setup(void) +{ + /* + * Do initial security configuration to allow DRAM/device access. On + * Base FVP only DRAM security is programmable (via TrustZone), but + * other platforms might have more programmable security devices + * present. + */ + fvp_security_setup(); + + /* Initialise the IO layer and register platform IO devices */ + fvp_io_setup(); +} + +/* Flush the TF params and the TF plat params */ +void bl2_plat_flush_bl31_params(void) +{ + flush_dcache_range((unsigned long)PARAMS_BASE, \ + sizeof(bl2_to_bl31_params_mem_t)); +} + + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only intializes the mmu in a quick and dirty way. + ******************************************************************************/ +void bl2_plat_arch_setup() +{ + fvp_configure_mmu_el1(bl2_tzram_layout.total_base, + bl2_tzram_layout.total_size, + BL2_RO_BASE, + BL2_RO_LIMIT, + BL2_COHERENT_RAM_BASE, + BL2_COHERENT_RAM_LIMIT); +} + +/******************************************************************************* + * Before calling this function BL31 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL31 and set SPSR and security state. + * On FVP we are only setting the security state, entrypoint + ******************************************************************************/ +void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info, + entry_point_info_t *bl31_ep_info) +{ + SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE); + bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS); +} + + +/******************************************************************************* + * Before calling this function BL32 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL32 and set SPSR and security state. + * On FVP we are only setting the security state, entrypoint + ******************************************************************************/ +void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info, + entry_point_info_t *bl32_ep_info) +{ + fvp_set_bl32_ep_info(bl32_ep_info); +} + +/******************************************************************************* + * Before calling this function BL33 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL33 and set SPSR and security state. + * On FVP we are only setting the security state, entrypoint + ******************************************************************************/ +void bl2_plat_set_bl33_ep_info(image_info_t *image, + entry_point_info_t *bl33_ep_info) +{ + fvp_set_bl33_ep_info(bl33_ep_info); +} + + +/******************************************************************************* + * Populate the extents of memory available for loading BL32 + ******************************************************************************/ +void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo) +{ + /* + * Populate the extents of memory available for loading BL32. + */ + bl32_meminfo->total_base = BL32_BASE; + bl32_meminfo->free_base = BL32_BASE; + bl32_meminfo->total_size = + (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; + bl32_meminfo->free_size = + (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; + bl32_meminfo->attr = BOT_LOAD; + bl32_meminfo->next = 0; +} + + +/******************************************************************************* + * Populate the extents of memory available for loading BL33 + ******************************************************************************/ +void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo) +{ + bl33_meminfo->total_base = DRAM_BASE; + bl33_meminfo->total_size = DRAM_SIZE - DRAM1_SEC_SIZE; + bl33_meminfo->free_base = DRAM_BASE; + bl33_meminfo->free_size = DRAM_SIZE - DRAM1_SEC_SIZE; + bl33_meminfo->attr = 0; + bl33_meminfo->attr = 0; +} diff --git a/plat/fvp/bl31_fvp_setup.c b/plat/fvp/bl31_fvp_setup.c new file mode 100644 index 0000000..6554ec3 --- /dev/null +++ b/plat/fvp/bl31_fvp_setup.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <bl31.h> +#include <console.h> +#include <mmio.h> +#include <platform.h> +#include <stddef.h> +#include "drivers/pwrc/fvp_pwrc.h" +#include "fvp_def.h" +#include "fvp_private.h" + +/******************************************************************************* + * Declarations of linker defined symbols which will help us find the layout + * of trusted SRAM + ******************************************************************************/ +extern unsigned long __RO_START__; +extern unsigned long __RO_END__; + +extern unsigned long __COHERENT_RAM_START__; +extern unsigned long __COHERENT_RAM_END__; + +/* + * The next 2 constants identify the extents of the code & RO data region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses. + */ +#define BL31_RO_BASE (unsigned long)(&__RO_START__) +#define BL31_RO_LIMIT (unsigned long)(&__RO_END__) + +/* + * The next 2 constants identify the extents of the coherent memory region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols + * refer to page-aligned addresses. + */ +#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) +#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) + + +#if RESET_TO_BL31 +static entry_point_info_t bl32_entrypoint_info; +static entry_point_info_t bl33_entrypoint_info; +#else +/******************************************************************************* + * Reference to structure which holds the arguments that have been passed to + * BL31 from BL2. + ******************************************************************************/ +static bl31_params_t *bl2_to_bl31_params; +#endif + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for the + * security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ******************************************************************************/ +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + entry_point_info_t *next_image_info; + +#if RESET_TO_BL31 + + if (type == NON_SECURE) + fvp_get_entry_point_info(NON_SECURE, &bl33_entrypoint_info); + else + fvp_get_entry_point_info(SECURE, &bl32_entrypoint_info); + + next_image_info = (type == NON_SECURE) ? + &bl33_entrypoint_info : + &bl32_entrypoint_info; +#else + next_image_info = (type == NON_SECURE) ? + bl2_to_bl31_params->bl33_ep_info : + bl2_to_bl31_params->bl32_ep_info; +#endif + + + /* None of the images on this platform can have 0x0 as the entrypoint */ + if (next_image_info->pc) + return next_image_info; + else + return NULL; +} + +/******************************************************************************* + * Perform any BL31 specific platform actions. Here is an opportunity to copy + * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they + * are lost (potentially). This needs to be done before the MMU is initialized + * so that the memory layout can be used while creating page tables. On the FVP + * we know that BL2 has populated the parameters in secure DRAM. So we just use + * the reference passed in 'from_bl2' instead of copying. The 'data' parameter + * is not used since all the information is contained in 'from_bl2'. Also, BL2 + * has flushed this information to memory, so we are guaranteed to pick up good + * data + ******************************************************************************/ +void bl31_early_platform_setup(bl31_params_t *from_bl2, + void *plat_params_from_bl2) +{ + /* Initialize the console to provide early debug support */ + console_init(PL011_UART0_BASE); + + /* Initialize the platform config for future decision making */ + fvp_config_setup(); + +#if RESET_TO_BL31 + /* There are no parameters from BL2 if BL31 is a reset vector */ + assert(from_bl2 == NULL); + assert(plat_params_from_bl2 == NULL); + + + /* + * Do initial security configuration to allow DRAM/device access. On + * Base FVP only DRAM security is programmable (via TrustZone), but + * other platforms might have more programmable security devices + * present. + */ + fvp_security_setup(); +#else + /* Check params passed from BL2 should not be NULL, + * We are not checking plat_params_from_bl2 as NULL as we are not + * using it on FVP + */ + assert(from_bl2 != NULL); + assert(from_bl2->h.type == PARAM_BL31); + assert(from_bl2->h.version >= VERSION_1); + + bl2_to_bl31_params = from_bl2; + assert(((unsigned long)plat_params_from_bl2) == FVP_BL31_PLAT_PARAM_VAL); +#endif +} + +/******************************************************************************* + * Initialize the gic, configure the CLCD and zero out variables needed by the + * secondaries to boot up correctly. + ******************************************************************************/ +void bl31_platform_setup() +{ + unsigned int reg_val; + + /* Initialize the gic cpu and distributor interfaces */ + gic_setup(); + + /* + * TODO: Configure the CLCD before handing control to + * linux. Need to see if a separate driver is needed + * instead. + */ + mmio_write_32(VE_SYSREGS_BASE + V2M_SYS_CFGDATA, 0); + mmio_write_32(VE_SYSREGS_BASE + V2M_SYS_CFGCTRL, + (1ull << 31) | (1 << 30) | (7 << 20) | (0 << 16)); + + /* Enable and initialize the System level generic timer */ + mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN); + + /* Allow access to the System counter timer module */ + reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT); + reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT); + reg_val |= (1 << CNTACR_RWVT_SHIFT) | (1 << CNTACR_RWPT_SHIFT); + mmio_write_32(SYS_TIMCTL_BASE + CNTACR_BASE(0), reg_val); + mmio_write_32(SYS_TIMCTL_BASE + CNTACR_BASE(1), reg_val); + + reg_val = (1 << CNTNSAR_NS_SHIFT(0)) | (1 << CNTNSAR_NS_SHIFT(1)); + mmio_write_32(SYS_TIMCTL_BASE + CNTNSAR, reg_val); + + /* Intialize the power controller */ + fvp_pwrc_setup(); + + /* Topologies are best known to the platform. */ + fvp_setup_topology(); +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only intializes the mmu in a quick and dirty way. + ******************************************************************************/ +void bl31_plat_arch_setup() +{ +#if RESET_TO_BL31 + fvp_cci_setup(); + +#endif + fvp_configure_mmu_el3(BL31_RO_BASE, + (BL31_COHERENT_RAM_LIMIT - BL31_RO_BASE), + BL31_RO_BASE, + BL31_RO_LIMIT, + BL31_COHERENT_RAM_BASE, + BL31_COHERENT_RAM_LIMIT); +} + +#if RESET_TO_BL31 +/******************************************************************************* + * Generate the entry point info for Non Secure and Secure images + * for transferring control from BL31 + ******************************************************************************/ +void fvp_get_entry_point_info(unsigned long target_security, + entry_point_info_t *target_entry_info) +{ + if (target_security == NON_SECURE) { + SET_PARAM_HEAD(target_entry_info, + PARAM_EP, + VERSION_1, + 0); + /* + * Tell BL31 where the non-trusted software image + * is located and the entry state information + */ + target_entry_info->pc = plat_get_ns_image_entrypoint(); + + fvp_set_bl33_ep_info(target_entry_info); + + } else { + SET_PARAM_HEAD(target_entry_info, + PARAM_EP, + VERSION_1, + 0); + if (BL32_BASE != 0) { + /* Hard coding entry point to the base of the BL32 */ + target_entry_info->pc = BL32_BASE; + fvp_set_bl32_ep_info(target_entry_info); + } + } +} +#endif diff --git a/plat/fvp/bl32_fvp_setup.c b/plat/fvp/bl32_fvp_setup.c new file mode 100644 index 0000000..f8dc3c7 --- /dev/null +++ b/plat/fvp/bl32_fvp_setup.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <bl_common.h> +#include <console.h> +#include <platform.h> +#include "fvp_def.h" +#include "fvp_private.h" + +/******************************************************************************* + * Declarations of linker defined symbols which will help us find the layout + * of trusted SRAM + ******************************************************************************/ +extern unsigned long __RO_START__; +extern unsigned long __RO_END__; + +extern unsigned long __COHERENT_RAM_START__; +extern unsigned long __COHERENT_RAM_END__; + +/* + * The next 2 constants identify the extents of the code & RO data region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses. + */ +#define BL32_RO_BASE (unsigned long)(&__RO_START__) +#define BL32_RO_LIMIT (unsigned long)(&__RO_END__) + +/* + * The next 2 constants identify the extents of the coherent memory region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to + * page-aligned addresses. + */ +#define BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) +#define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) + +/******************************************************************************* + * Initialize the UART + ******************************************************************************/ +void bl32_early_platform_setup(void) +{ + /* + * Initialize a different console than already in use to display + * messages from TSP + */ + console_init(PL011_UART1_BASE); + + /* Initialize the platform config for future decision making */ + fvp_config_setup(); +} + +/******************************************************************************* + * Perform platform specific setup placeholder + ******************************************************************************/ +void bl32_platform_setup() +{ + +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only intializes the MMU + ******************************************************************************/ +void bl32_plat_arch_setup() +{ + fvp_configure_mmu_el1(BL32_RO_BASE, + (BL32_COHERENT_RAM_LIMIT - BL32_RO_BASE), + BL32_RO_BASE, + BL32_RO_LIMIT, + BL32_COHERENT_RAM_BASE, + BL32_COHERENT_RAM_LIMIT); +} diff --git a/plat/fvp/drivers/pwrc/fvp_pwrc.c b/plat/fvp/drivers/pwrc/fvp_pwrc.c new file mode 100644 index 0000000..d1feece --- /dev/null +++ b/plat/fvp/drivers/pwrc/fvp_pwrc.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <bakery_lock.h> +#include <mmio.h> +#include "../../fvp_def.h" +#include "fvp_pwrc.h" + +/* + * TODO: Someday there will be a generic power controller api. At the moment + * each platform has its own pwrc so just exporting functions is fine. + */ +static bakery_lock_t pwrc_lock __attribute__ ((section("tzfw_coherent_mem"))); + +unsigned int fvp_pwrc_get_cpu_wkr(unsigned long mpidr) +{ + unsigned int rc = 0; + bakery_lock_get(mpidr, &pwrc_lock); + mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr); + rc = PSYSR_WK(mmio_read_32(PWRC_BASE + PSYSR_OFF)); + bakery_lock_release(mpidr, &pwrc_lock); + return rc; +} + +unsigned int fvp_pwrc_read_psysr(unsigned long mpidr) +{ + unsigned int rc = 0; + bakery_lock_get(mpidr, &pwrc_lock); + mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr); + rc = mmio_read_32(PWRC_BASE + PSYSR_OFF); + bakery_lock_release(mpidr, &pwrc_lock); + return rc; +} + +void fvp_pwrc_write_pponr(unsigned long mpidr) +{ + bakery_lock_get(mpidr, &pwrc_lock); + mmio_write_32(PWRC_BASE + PPONR_OFF, (unsigned int) mpidr); + bakery_lock_release(mpidr, &pwrc_lock); +} + +void fvp_pwrc_write_ppoffr(unsigned long mpidr) +{ + bakery_lock_get(mpidr, &pwrc_lock); + mmio_write_32(PWRC_BASE + PPOFFR_OFF, (unsigned int) mpidr); + bakery_lock_release(mpidr, &pwrc_lock); +} + +void fvp_pwrc_set_wen(unsigned long mpidr) +{ + bakery_lock_get(mpidr, &pwrc_lock); + mmio_write_32(PWRC_BASE + PWKUPR_OFF, + (unsigned int) (PWKUPR_WEN | mpidr)); + bakery_lock_release(mpidr, &pwrc_lock); +} + +void fvp_pwrc_clr_wen(unsigned long mpidr) +{ + bakery_lock_get(mpidr, &pwrc_lock); + mmio_write_32(PWRC_BASE + PWKUPR_OFF, + (unsigned int) mpidr); + bakery_lock_release(mpidr, &pwrc_lock); +} + +void fvp_pwrc_write_pcoffr(unsigned long mpidr) +{ + bakery_lock_get(mpidr, &pwrc_lock); + mmio_write_32(PWRC_BASE + PCOFFR_OFF, (unsigned int) mpidr); + bakery_lock_release(mpidr, &pwrc_lock); +} + +/* Nothing else to do here apart from initializing the lock */ +int fvp_pwrc_setup(void) +{ + bakery_lock_init(&pwrc_lock); + return 0; +} + + + diff --git a/plat/fvp/drivers/pwrc/fvp_pwrc.h b/plat/fvp/drivers/pwrc/fvp_pwrc.h new file mode 100644 index 0000000..ad1ea85 --- /dev/null +++ b/plat/fvp/drivers/pwrc/fvp_pwrc.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __FVP_PWRC_H__ +#define __FVP_PWRC_H__ + +/* FVP Power controller register offset etc */ +#define PPOFFR_OFF 0x0 +#define PPONR_OFF 0x4 +#define PCOFFR_OFF 0x8 +#define PWKUPR_OFF 0xc +#define PSYSR_OFF 0x10 + +#define PWKUPR_WEN (1ull << 31) + +#define PSYSR_AFF_L2 (1 << 31) +#define PSYSR_AFF_L1 (1 << 30) +#define PSYSR_AFF_L0 (1 << 29) +#define PSYSR_WEN (1 << 28) +#define PSYSR_PC (1 << 27) +#define PSYSR_PP (1 << 26) + +#define PSYSR_WK_SHIFT 24 +#define PSYSR_WK_MASK 0x3 +#define PSYSR_WK(x) (x >> PSYSR_WK_SHIFT) & PSYSR_WK_MASK + +#define WKUP_COLD 0x0 +#define WKUP_RESET 0x1 +#define WKUP_PPONR 0x2 +#define WKUP_GICREQ 0x3 + +#define PSYSR_INVALID 0xffffffff + +#ifndef __ASSEMBLY__ + +/******************************************************************************* + * Function & variable prototypes + ******************************************************************************/ +int fvp_pwrc_setup(void); +void fvp_pwrc_write_pcoffr(unsigned long); +void fvp_pwrc_write_ppoffr(unsigned long); +void fvp_pwrc_write_pponr(unsigned long); +void fvp_pwrc_set_wen(unsigned long); +void fvp_pwrc_clr_wen(unsigned long); +unsigned int fvp_pwrc_read_psysr(unsigned long); +unsigned int fvp_pwrc_get_cpu_wkr(unsigned long); + +#endif /*__ASSEMBLY__*/ + +#endif /* __FVP_PWRC_H__ */ diff --git a/plat/fvp/fvp_def.h b/plat/fvp/fvp_def.h new file mode 100644 index 0000000..04ba611 --- /dev/null +++ b/plat/fvp/fvp_def.h @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __FVP_DEF_H__ +#define __FVP_DEF_H__ + +#include <platform_def.h> /* for TZROM_SIZE */ + + +/* Firmware Image Package */ +#define FIP_IMAGE_NAME "fip.bin" + +/* Constants for accessing platform configuration */ +#define CONFIG_GICD_ADDR 0 +#define CONFIG_GICC_ADDR 1 +#define CONFIG_GICH_ADDR 2 +#define CONFIG_GICV_ADDR 3 +#define CONFIG_MAX_AFF0 4 +#define CONFIG_MAX_AFF1 5 +/* Indicate whether the CPUECTLR SMP bit should be enabled. */ +#define CONFIG_CPU_SETUP 6 +#define CONFIG_BASE_MMAP 7 +/* Indicates whether CCI should be enabled on the platform. */ +#define CONFIG_HAS_CCI 8 +#define CONFIG_HAS_TZC 9 +#define CONFIG_LIMIT 10 + +/******************************************************************************* + * FVP memory map related constants + ******************************************************************************/ + +#define FLASH0_BASE 0x08000000 +#define FLASH0_SIZE TZROM_SIZE + +#define FLASH1_BASE 0x0c000000 +#define FLASH1_SIZE 0x04000000 + +#define PSRAM_BASE 0x14000000 +#define PSRAM_SIZE 0x04000000 + +#define VRAM_BASE 0x18000000 +#define VRAM_SIZE 0x02000000 + +/* Aggregate of all devices in the first GB */ +#define DEVICE0_BASE 0x1a000000 +#define DEVICE0_SIZE 0x12200000 + +#define DEVICE1_BASE 0x2f000000 +#define DEVICE1_SIZE 0x200000 + +#define NSRAM_BASE 0x2e000000 +#define NSRAM_SIZE 0x10000 + +#define MBOX_OFF 0x1000 + +/* Base address where parameters to BL31 are stored */ +#define PARAMS_BASE TZDRAM_BASE + +#define DRAM1_BASE 0x80000000ull +#define DRAM1_SIZE 0x80000000ull +#define DRAM1_END (DRAM1_BASE + DRAM1_SIZE - 1) +#define DRAM1_SEC_SIZE 0x01000000ull + +#define DRAM_BASE DRAM1_BASE +#define DRAM_SIZE DRAM1_SIZE + +#define DRAM2_BASE 0x880000000ull +#define DRAM2_SIZE 0x780000000ull +#define DRAM2_END (DRAM2_BASE + DRAM2_SIZE - 1) + +#define PCIE_EXP_BASE 0x40000000 +#define TZRNG_BASE 0x7fe60000 +#define TZNVCTR_BASE 0x7fe70000 +#define TZROOTKEY_BASE 0x7fe80000 + +/* Memory mapped Generic timer interfaces */ +#define SYS_CNTCTL_BASE 0x2a430000 +#define SYS_CNTREAD_BASE 0x2a800000 +#define SYS_TIMCTL_BASE 0x2a810000 + +/* V2M motherboard system registers & offsets */ +#define VE_SYSREGS_BASE 0x1c010000 +#define V2M_SYS_ID 0x0 +#define V2M_SYS_LED 0x8 +#define V2M_SYS_CFGDATA 0xa0 +#define V2M_SYS_CFGCTRL 0xa4 + +/* Load address of BL33 in the FVP port */ +#define NS_IMAGE_OFFSET (DRAM1_BASE + 0x8000000) /* DRAM + 128MB */ + +/* Special value used to verify platform parameters from BL2 to BL3-1 */ +#define FVP_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL + +/* + * V2M sysled bit definitions. The values written to this + * register are defined in arch.h & runtime_svc.h. Only + * used by the primary cpu to diagnose any cold boot issues. + * + * SYS_LED[0] - Security state (S=0/NS=1) + * SYS_LED[2:1] - Exception Level (EL3-EL0) + * SYS_LED[7:3] - Exception Class (Sync/Async & origin) + * + */ +#define SYS_LED_SS_SHIFT 0x0 +#define SYS_LED_EL_SHIFT 0x1 +#define SYS_LED_EC_SHIFT 0x3 + +#define SYS_LED_SS_MASK 0x1 +#define SYS_LED_EL_MASK 0x3 +#define SYS_LED_EC_MASK 0x1f + +/* V2M sysid register bits */ +#define SYS_ID_REV_SHIFT 27 +#define SYS_ID_HBI_SHIFT 16 +#define SYS_ID_BLD_SHIFT 12 +#define SYS_ID_ARCH_SHIFT 8 +#define SYS_ID_FPGA_SHIFT 0 + +#define SYS_ID_REV_MASK 0xf +#define SYS_ID_HBI_MASK 0xfff +#define SYS_ID_BLD_MASK 0xf +#define SYS_ID_ARCH_MASK 0xf +#define SYS_ID_FPGA_MASK 0xff + +#define SYS_ID_BLD_LENGTH 4 + +#define REV_FVP 0x0 +#define HBI_FVP_BASE 0x020 +#define HBI_FOUNDATION 0x010 + +#define BLD_GIC_VE_MMAP 0x0 +#define BLD_GIC_A53A57_MMAP 0x1 + +#define ARCH_MODEL 0x1 + +/* FVP Power controller base address*/ +#define PWRC_BASE 0x1c100000 + + +/******************************************************************************* + * CCI-400 related constants + ******************************************************************************/ +#define CCI400_BASE 0x2c090000 +#define CCI400_SL_IFACE_CLUSTER0 3 +#define CCI400_SL_IFACE_CLUSTER1 4 +#define CCI400_SL_IFACE_INDEX(mpidr) (mpidr & MPIDR_CLUSTER_MASK ? \ + CCI400_SL_IFACE_CLUSTER1 : \ + CCI400_SL_IFACE_CLUSTER0) + +/******************************************************************************* + * GIC-400 & interrupt handling related constants + ******************************************************************************/ +/* VE compatible GIC memory map */ +#define VE_GICD_BASE 0x2c001000 +#define VE_GICC_BASE 0x2c002000 +#define VE_GICH_BASE 0x2c004000 +#define VE_GICV_BASE 0x2c006000 + +/* Base FVP compatible GIC memory map */ +#define BASE_GICD_BASE 0x2f000000 +#define BASE_GICR_BASE 0x2f100000 +#define BASE_GICC_BASE 0x2c000000 +#define BASE_GICH_BASE 0x2c010000 +#define BASE_GICV_BASE 0x2c02f000 + +#define IRQ_TZ_WDOG 56 +#define IRQ_SEC_PHY_TIMER 29 +#define IRQ_SEC_SGI_0 8 +#define IRQ_SEC_SGI_1 9 +#define IRQ_SEC_SGI_2 10 +#define IRQ_SEC_SGI_3 11 +#define IRQ_SEC_SGI_4 12 +#define IRQ_SEC_SGI_5 13 +#define IRQ_SEC_SGI_6 14 +#define IRQ_SEC_SGI_7 15 +#define IRQ_SEC_SGI_8 16 + +/******************************************************************************* + * PL011 related constants + ******************************************************************************/ +#define PL011_UART0_BASE 0x1c090000 +#define PL011_UART1_BASE 0x1c0a0000 +#define PL011_UART2_BASE 0x1c0b0000 +#define PL011_UART3_BASE 0x1c0c0000 + +/******************************************************************************* + * TrustZone address space controller related constants + ******************************************************************************/ +#define TZC400_BASE 0x2a4a0000 + +/* + * The NSAIDs for this platform as used to program the TZC400. + */ + +/* The FVP has 4 bits of NSAIDs. Used with TZC FAIL_ID (ACE Lite ID width) */ +#define FVP_AID_WIDTH 4 + +/* NSAIDs used by devices in TZC filter 0 on FVP */ +#define FVP_NSAID_DEFAULT 0 +#define FVP_NSAID_PCI 1 +#define FVP_NSAID_VIRTIO 8 /* from FVP v5.6 onwards */ +#define FVP_NSAID_AP 9 /* Application Processors */ +#define FVP_NSAID_VIRTIO_OLD 15 /* until FVP v5.5 */ + +/* NSAIDs used by devices in TZC filter 2 on FVP */ +#define FVP_NSAID_HDLCD0 2 +#define FVP_NSAID_CLCD 7 + + +#endif /* __FVP_DEF_H__ */ diff --git a/plat/fvp/fvp_gic.c b/plat/fvp/fvp_gic.c new file mode 100644 index 0000000..3156da9 --- /dev/null +++ b/plat/fvp/fvp_gic.c @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <debug.h> +#include <gic_v2.h> +#include <gic_v3.h> +#include <interrupt_mgmt.h> +#include <platform.h> +#include <stdint.h> +#include "fvp_def.h" +#include "fvp_private.h" + +/******************************************************************************* + * This function does some minimal GICv3 configuration. The Firmware itself does + * not fully support GICv3 at this time and relies on GICv2 emulation as + * provided by GICv3. This function allows software (like Linux) in later stages + * to use full GICv3 features. + ******************************************************************************/ +void gicv3_cpuif_setup(void) +{ + unsigned int scr_val, val; + uintptr_t base; + + /* + * When CPUs come out of reset they have their GICR_WAKER.ProcessorSleep + * bit set. In order to allow interrupts to get routed to the CPU we + * need to clear this bit if set and wait for GICR_WAKER.ChildrenAsleep + * to clear (GICv3 Architecture specification 5.4.23). + * GICR_WAKER is NOT banked per CPU, compute the correct base address + * per CPU. + */ + base = gicv3_get_rdist(BASE_GICR_BASE, read_mpidr()); + if (base == (uintptr_t)NULL) { + /* No re-distributor base address. This interface cannot be + * configured. + */ + panic(); + } + + val = gicr_read_waker(base); + + val &= ~WAKER_PS; + gicr_write_waker(base, val); + dsb(); + + /* We need to wait for ChildrenAsleep to clear. */ + val = gicr_read_waker(base); + while (val & WAKER_CA) { + val = gicr_read_waker(base); + } + + /* + * We need to set SCR_EL3.NS in order to see GICv3 non-secure state. + * Restore SCR_EL3.NS again before exit. + */ + scr_val = read_scr(); + write_scr(scr_val | SCR_NS_BIT); + isb(); /* ensure NS=1 takes effect before accessing ICC_SRE_EL2 */ + + /* + * By default EL2 and NS-EL1 software should be able to enable GICv3 + * System register access without any configuration at EL3. But it turns + * out that GICC PMR as set in GICv2 mode does not affect GICv3 mode. So + * we need to set it here again. In order to do that we need to enable + * register access. We leave it enabled as it should be fine and might + * prevent problems with later software trying to access GIC System + * Registers. + */ + val = read_icc_sre_el3(); + write_icc_sre_el3(val | ICC_SRE_EN | ICC_SRE_SRE); + + val = read_icc_sre_el2(); + write_icc_sre_el2(val | ICC_SRE_EN | ICC_SRE_SRE); + + write_icc_pmr_el1(GIC_PRI_MASK); + isb(); /* commite ICC_* changes before setting NS=0 */ + + /* Restore SCR_EL3 */ + write_scr(scr_val); + isb(); /* ensure NS=0 takes effect immediately */ +} + +/******************************************************************************* + * This function does some minimal GICv3 configuration when cores go + * down. + ******************************************************************************/ +void gicv3_cpuif_deactivate(void) +{ + unsigned int val; + uintptr_t base; + + /* + * When taking CPUs down we need to set GICR_WAKER.ProcessorSleep and + * wait for GICR_WAKER.ChildrenAsleep to get set. + * (GICv3 Architecture specification 5.4.23). + * GICR_WAKER is NOT banked per CPU, compute the correct base address + * per CPU. + */ + base = gicv3_get_rdist(BASE_GICR_BASE, read_mpidr()); + if (base == (uintptr_t)NULL) { + /* No re-distributor base address. This interface cannot be + * configured. + */ + panic(); + } + + val = gicr_read_waker(base); + val |= WAKER_PS; + gicr_write_waker(base, val); + dsb(); + + /* We need to wait for ChildrenAsleep to set. */ + val = gicr_read_waker(base); + while ((val & WAKER_CA) == 0) { + val = gicr_read_waker(base); + } +} + + +/******************************************************************************* + * Enable secure interrupts and use FIQs to route them. Disable legacy bypass + * and set the priority mask register to allow all interrupts to trickle in. + ******************************************************************************/ +void gic_cpuif_setup(unsigned int gicc_base) +{ + unsigned int val; + + val = gicc_read_iidr(gicc_base); + + /* + * If GICv3 we need to do a bit of additional setup. We want to + * allow default GICv2 behaviour but allow the next stage to + * enable full gicv3 features. + */ + if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3) { + gicv3_cpuif_setup(); + } + + val = ENABLE_GRP0 | FIQ_EN | FIQ_BYP_DIS_GRP0; + val |= IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1; + + gicc_write_pmr(gicc_base, GIC_PRI_MASK); + gicc_write_ctlr(gicc_base, val); +} + +/******************************************************************************* + * Place the cpu interface in a state where it can never make a cpu exit wfi as + * as result of an asserted interrupt. This is critical for powering down a cpu + ******************************************************************************/ +void gic_cpuif_deactivate(unsigned int gicc_base) +{ + unsigned int val; + + /* Disable secure, non-secure interrupts and disable their bypass */ + val = gicc_read_ctlr(gicc_base); + val &= ~(ENABLE_GRP0 | ENABLE_GRP1); + val |= FIQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP0; + val |= IRQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP1; + gicc_write_ctlr(gicc_base, val); + + val = gicc_read_iidr(gicc_base); + + /* + * If GICv3 we need to do a bit of additional setup. Make sure the + * RDIST is put to sleep. + */ + if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3) { + gicv3_cpuif_deactivate(); + } +} + +/******************************************************************************* + * Per cpu gic distributor setup which will be done by all cpus after a cold + * boot/hotplug. This marks out the secure interrupts & enables them. + ******************************************************************************/ +void gic_pcpu_distif_setup(unsigned int gicd_base) +{ + gicd_write_igroupr(gicd_base, 0, ~0); + + gicd_clr_igroupr(gicd_base, IRQ_SEC_PHY_TIMER); + gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_0); + gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_1); + gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_2); + gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_3); + gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_4); + gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_5); + gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_6); + gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_7); + + gicd_set_ipriorityr(gicd_base, IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY); + gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY); + gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY); + gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY); + gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY); + gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY); + gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY); + gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY); + gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY); + + gicd_set_isenabler(gicd_base, IRQ_SEC_PHY_TIMER); + gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_0); + gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_1); + gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_2); + gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_3); + gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_4); + gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_5); + gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_6); + gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_7); +} + +/******************************************************************************* + * Global gic distributor setup which will be done by the primary cpu after a + * cold boot. It marks out the secure SPIs, PPIs & SGIs and enables them. It + * then enables the secure GIC distributor interface. + ******************************************************************************/ +void gic_distif_setup(unsigned int gicd_base) +{ + unsigned int ctr, num_ints, ctlr; + + /* Disable the distributor before going further */ + ctlr = gicd_read_ctlr(gicd_base); + ctlr &= ~(ENABLE_GRP0 | ENABLE_GRP1); + gicd_write_ctlr(gicd_base, ctlr); + + /* + * Mark out non-secure interrupts. Calculate number of + * IGROUPR registers to consider. Will be equal to the + * number of IT_LINES + */ + num_ints = gicd_read_typer(gicd_base) & IT_LINES_NO_MASK; + num_ints++; + for (ctr = 0; ctr < num_ints; ctr++) + gicd_write_igroupr(gicd_base, ctr << IGROUPR_SHIFT, ~0); + + /* Configure secure interrupts now */ + gicd_clr_igroupr(gicd_base, IRQ_TZ_WDOG); + gicd_set_ipriorityr(gicd_base, IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY); + gicd_set_itargetsr(gicd_base, IRQ_TZ_WDOG, + platform_get_core_pos(read_mpidr())); + gicd_set_isenabler(gicd_base, IRQ_TZ_WDOG); + gic_pcpu_distif_setup(gicd_base); + + gicd_write_ctlr(gicd_base, ctlr | ENABLE_GRP0); +} + +void gic_setup(void) +{ + unsigned int gicd_base, gicc_base; + + gicd_base = fvp_get_cfgvar(CONFIG_GICD_ADDR); + gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR); + + gic_cpuif_setup(gicc_base); + gic_distif_setup(gicd_base); +} + +/******************************************************************************* + * An ARM processor signals interrupt exceptions through the IRQ and FIQ pins. + * The interrupt controller knows which pin/line it uses to signal a type of + * interrupt. The platform knows which interrupt controller type is being used + * in a particular security state e.g. with an ARM GIC, normal world could use + * the GICv2 features while the secure world could use GICv3 features and vice + * versa. + * This function is exported by the platform to let the interrupt management + * framework determine for a type of interrupt and security state, which line + * should be used in the SCR_EL3 to control its routing to EL3. The interrupt + * line is represented as the bit position of the IRQ or FIQ bit in the SCR_EL3. + ******************************************************************************/ +uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state) +{ + uint32_t gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR); + + assert(type == INTR_TYPE_S_EL1 || + type == INTR_TYPE_EL3 || + type == INTR_TYPE_NS); + + assert(security_state == NON_SECURE || security_state == SECURE); + + /* + * We ignore the security state parameter under the assumption that + * both normal and secure worlds are using ARM GICv2. This parameter + * will be used when the secure world starts using GICv3. + */ +#if FVP_GIC_ARCH == 2 + return gicv2_interrupt_type_to_line(gicc_base, type); +#else +#error "Invalid GIC architecture version specified for FVP port" +#endif +} + +#if FVP_GIC_ARCH == 2 +/******************************************************************************* + * This function returns the type of the highest priority pending interrupt at + * the GIC cpu interface. INTR_TYPE_INVAL is returned when there is no + * interrupt pending. + ******************************************************************************/ +uint32_t plat_ic_get_pending_interrupt_type() +{ + uint32_t id, gicc_base; + + gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR); + id = gicc_read_hppir(gicc_base); + + /* Assume that all secure interrupts are S-EL1 interrupts */ + if (id < 1022) + return INTR_TYPE_S_EL1; + + if (id == GIC_SPURIOUS_INTERRUPT) + return INTR_TYPE_INVAL; + + return INTR_TYPE_NS; +} + +/******************************************************************************* + * This function returns the id of the highest priority pending interrupt at + * the GIC cpu interface. INTR_ID_UNAVAILABLE is returned when there is no + * interrupt pending. + ******************************************************************************/ +uint32_t plat_ic_get_pending_interrupt_id() +{ + uint32_t id, gicc_base; + + gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR); + id = gicc_read_hppir(gicc_base); + + if (id < 1022) + return id; + + if (id == 1023) + return INTR_ID_UNAVAILABLE; + + /* + * Find out which non-secure interrupt it is under the assumption that + * the GICC_CTLR.AckCtl bit is 0. + */ + return gicc_read_ahppir(gicc_base); +} + +/******************************************************************************* + * This functions reads the GIC cpu interface Interrupt Acknowledge register + * to start handling the pending interrupt. It returns the contents of the IAR. + ******************************************************************************/ +uint32_t plat_ic_acknowledge_interrupt() +{ + return gicc_read_IAR(fvp_get_cfgvar(CONFIG_GICC_ADDR)); +} + +/******************************************************************************* + * This functions writes the GIC cpu interface End Of Interrupt register with + * the passed value to finish handling the active interrupt + ******************************************************************************/ +void plat_ic_end_of_interrupt(uint32_t id) +{ + gicc_write_EOIR(fvp_get_cfgvar(CONFIG_GICC_ADDR), id); + return; +} + +/******************************************************************************* + * This function returns the type of the interrupt id depending upon the group + * this interrupt has been configured under by the interrupt controller i.e. + * group0 or group1. + ******************************************************************************/ +uint32_t plat_ic_get_interrupt_type(uint32_t id) +{ + uint32_t group; + + group = gicd_get_igroupr(fvp_get_cfgvar(CONFIG_GICD_ADDR), id); + + /* Assume that all secure interrupts are S-EL1 interrupts */ + if (group == GRP0) + return INTR_TYPE_S_EL1; + else + return INTR_TYPE_NS; +} + +#else +#error "Invalid GIC architecture version specified for FVP port" +#endif diff --git a/plat/fvp/fvp_io_storage.c b/plat/fvp/fvp_io_storage.c new file mode 100644 index 0000000..c32cca9 --- /dev/null +++ b/plat/fvp/fvp_io_storage.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <debug.h> +#include <io_driver.h> +#include <io_fip.h> +#include <io_memmap.h> +#include <io_storage.h> +#include <io_semihosting.h> +#include <semihosting.h> /* For FOPEN_MODE_... */ +#include <string.h> +#include "fvp_def.h" + +/* IO devices */ +static io_plat_data_t io_data; +static const io_dev_connector_t *sh_dev_con; +static uintptr_t sh_dev_spec; +static uintptr_t sh_init_params; +static uintptr_t sh_dev_handle; +static const io_dev_connector_t *fip_dev_con; +static uintptr_t fip_dev_spec; +static uintptr_t fip_dev_handle; +static const io_dev_connector_t *memmap_dev_con; +static uintptr_t memmap_dev_spec; +static uintptr_t memmap_init_params; +static uintptr_t memmap_dev_handle; + +static const io_block_spec_t fip_block_spec = { + .offset = FLASH0_BASE, + .length = FLASH0_SIZE +}; + +static const io_file_spec_t bl2_file_spec = { + .path = BL2_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl31_file_spec = { + .path = BL31_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl32_file_spec = { + .path = BL32_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl33_file_spec = { + .path = BL33_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static int open_fip(const uintptr_t spec); +static int open_memmap(const uintptr_t spec); + +struct plat_io_policy { + char *image_name; + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +static const struct plat_io_policy policies[] = { + { + FIP_IMAGE_NAME, + &memmap_dev_handle, + (uintptr_t)&fip_block_spec, + open_memmap + }, { + BL2_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl2_file_spec, + open_fip + }, { + BL31_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl31_file_spec, + open_fip + }, { + BL32_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl32_file_spec, + open_fip + }, { + BL33_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl33_file_spec, + open_fip + }, { + 0, 0, 0 + } +}; + + +static int open_fip(const uintptr_t spec) +{ + int result = IO_FAIL; + + /* See if a Firmware Image Package is available */ + result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_NAME); + if (result == IO_SUCCESS) { + INFO("Using FIP\n"); + /*TODO: Check image defined in spec is present in FIP. */ + } + return result; +} + + +static int open_memmap(const uintptr_t spec) +{ + int result = IO_FAIL; + uintptr_t local_image_handle; + + result = io_dev_init(memmap_dev_handle, memmap_init_params); + if (result == IO_SUCCESS) { + result = io_open(memmap_dev_handle, spec, &local_image_handle); + if (result == IO_SUCCESS) { + /* INFO("Using Memmap IO\n"); */ + io_close(local_image_handle); + } + } + return result; +} + + +static int open_semihosting(const uintptr_t spec) +{ + int result = IO_FAIL; + uintptr_t local_image_handle; + + /* See if the file exists on semi-hosting.*/ + result = io_dev_init(sh_dev_handle, sh_init_params); + if (result == IO_SUCCESS) { + result = io_open(sh_dev_handle, spec, &local_image_handle); + if (result == IO_SUCCESS) { + INFO("Using Semi-hosting IO\n"); + io_close(local_image_handle); + } + } + return result; +} + +void fvp_io_setup (void) +{ + int io_result = IO_FAIL; + + /* Initialise the IO layer */ + io_init(&io_data); + + /* Register the IO devices on this platform */ + io_result = register_io_dev_sh(&sh_dev_con); + assert(io_result == IO_SUCCESS); + + io_result = register_io_dev_fip(&fip_dev_con); + assert(io_result == IO_SUCCESS); + + io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == IO_SUCCESS); + + /* Open connections to devices and cache the handles */ + io_result = io_dev_open(sh_dev_con, sh_dev_spec, &sh_dev_handle); + assert(io_result == IO_SUCCESS); + + io_result = io_dev_open(fip_dev_con, fip_dev_spec, &fip_dev_handle); + assert(io_result == IO_SUCCESS); + + io_result = io_dev_open(memmap_dev_con, memmap_dev_spec, + &memmap_dev_handle); + assert(io_result == IO_SUCCESS); + + /* Ignore improbable errors in release builds */ + (void)io_result; +} + + +/* Return an IO device handle and specification which can be used to access + * an image. Use this to enforce platform load policy */ +int plat_get_image_source(const char *image_name, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int result = IO_FAIL; + const struct plat_io_policy *policy; + + if ((image_name != NULL) && (dev_handle != NULL) && + (image_spec != NULL)) { + policy = policies; + while (policy->image_name != NULL) { + if (strcmp(policy->image_name, image_name) == 0) { + result = policy->check(policy->image_spec); + if (result == IO_SUCCESS) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + break; + } else { + result = open_semihosting( + policy->image_spec); + if (result == IO_SUCCESS) { + *dev_handle = sh_dev_handle; + *image_spec = + policy->image_spec; + } + } + } + policy++; + } + } else { + result = IO_FAIL; + } + return result; +} diff --git a/plat/fvp/fvp_pm.c b/plat/fvp/fvp_pm.c new file mode 100644 index 0000000..d702643 --- /dev/null +++ b/plat/fvp/fvp_pm.c @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bakery_lock.h> +#include <cci400.h> +#include <mmio.h> +#include <platform.h> +#include <platform_def.h> +#include <psci.h> +#include "drivers/pwrc/fvp_pwrc.h" +#include "fvp_def.h" +#include "fvp_private.h" + +/******************************************************************************* + * FVP handler called when an affinity instance is about to enter standby. + ******************************************************************************/ +int fvp_affinst_standby(unsigned int power_state) +{ + unsigned int target_afflvl; + + /* Sanity check the requested state */ + target_afflvl = psci_get_pstate_afflvl(power_state); + + /* + * It's possible to enter standby only on affinity level 0 i.e. a cpu + * on the FVP. Ignore any other affinity level. + */ + if (target_afflvl != MPIDR_AFFLVL0) + return PSCI_E_INVALID_PARAMS; + + /* + * Enter standby state + * dsb is good practice before using wfi to enter low power states + */ + dsb(); + wfi(); + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * FVP handler called when an affinity instance is about to be turned on. The + * level and mpidr determine the affinity instance. + ******************************************************************************/ +int fvp_affinst_on(unsigned long mpidr, + unsigned long sec_entrypoint, + unsigned long ns_entrypoint, + unsigned int afflvl, + unsigned int state) +{ + int rc = PSCI_E_SUCCESS; + unsigned long linear_id; + mailbox_t *fvp_mboxes; + unsigned int psysr; + + /* + * It's possible to turn on only affinity level 0 i.e. a cpu + * on the FVP. Ignore any other affinity level. + */ + if (afflvl != MPIDR_AFFLVL0) + goto exit; + + /* + * Ensure that we do not cancel an inflight power off request + * for the target cpu. That would leave it in a zombie wfi. + * Wait for it to power off, program the jump address for the + * target cpu and then program the power controller to turn + * that cpu on + */ + do { + psysr = fvp_pwrc_read_psysr(mpidr); + } while (psysr & PSYSR_AFF_L0); + + linear_id = platform_get_core_pos(mpidr); + fvp_mboxes = (mailbox_t *) (TZDRAM_BASE + MBOX_OFF); + fvp_mboxes[linear_id].value = sec_entrypoint; + flush_dcache_range((unsigned long) &fvp_mboxes[linear_id], + sizeof(unsigned long)); + + fvp_pwrc_write_pponr(mpidr); + +exit: + return rc; +} + +/******************************************************************************* + * FVP handler called when an affinity instance is about to be turned off. The + * level and mpidr determine the affinity instance. The 'state' arg. allows the + * platform to decide whether the cluster is being turned off and take apt + * actions. + * + * CAUTION: This function is called with coherent stacks so that caches can be + * turned off, flushed and coherency disabled. There is no guarantee that caches + * will remain turned on across calls to this function as each affinity level is + * dealt with. So do not write & read global variables across calls. It will be + * wise to do flush a write to the global to prevent unpredictable results. + ******************************************************************************/ +int fvp_affinst_off(unsigned long mpidr, + unsigned int afflvl, + unsigned int state) +{ + int rc = PSCI_E_SUCCESS; + unsigned int gicc_base, ectlr; + unsigned long cpu_setup, cci_setup; + + switch (afflvl) { + case MPIDR_AFFLVL1: + if (state == PSCI_STATE_OFF) { + /* + * Disable coherency if this cluster is to be + * turned off + */ + cci_setup = fvp_get_cfgvar(CONFIG_HAS_CCI); + if (cci_setup) { + cci_disable_coherency(mpidr); + } + + /* + * Program the power controller to turn the + * cluster off + */ + fvp_pwrc_write_pcoffr(mpidr); + + } + break; + + case MPIDR_AFFLVL0: + if (state == PSCI_STATE_OFF) { + + /* + * Take this cpu out of intra-cluster coherency if + * the FVP flavour supports the SMP bit. + */ + cpu_setup = fvp_get_cfgvar(CONFIG_CPU_SETUP); + if (cpu_setup) { + ectlr = read_cpuectlr(); + ectlr &= ~CPUECTLR_SMP_BIT; + write_cpuectlr(ectlr); + } + + /* + * Prevent interrupts from spuriously waking up + * this cpu + */ + gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR); + gic_cpuif_deactivate(gicc_base); + + /* + * Program the power controller to power this + * cpu off + */ + fvp_pwrc_write_ppoffr(mpidr); + } + break; + + default: + assert(0); + } + + return rc; +} + +/******************************************************************************* + * FVP handler called when an affinity instance is about to be suspended. The + * level and mpidr determine the affinity instance. The 'state' arg. allows the + * platform to decide whether the cluster is being turned off and take apt + * actions. + * + * CAUTION: This function is called with coherent stacks so that caches can be + * turned off, flushed and coherency disabled. There is no guarantee that caches + * will remain turned on across calls to this function as each affinity level is + * dealt with. So do not write & read global variables across calls. It will be + * wise to do flush a write to the global to prevent unpredictable results. + ******************************************************************************/ +int fvp_affinst_suspend(unsigned long mpidr, + unsigned long sec_entrypoint, + unsigned long ns_entrypoint, + unsigned int afflvl, + unsigned int state) +{ + int rc = PSCI_E_SUCCESS; + unsigned int gicc_base, ectlr; + unsigned long cpu_setup, cci_setup, linear_id; + mailbox_t *fvp_mboxes; + + switch (afflvl) { + case MPIDR_AFFLVL1: + if (state == PSCI_STATE_OFF) { + /* + * Disable coherency if this cluster is to be + * turned off + */ + cci_setup = fvp_get_cfgvar(CONFIG_HAS_CCI); + if (cci_setup) { + cci_disable_coherency(mpidr); + } + + /* + * Program the power controller to turn the + * cluster off + */ + fvp_pwrc_write_pcoffr(mpidr); + + } + break; + + case MPIDR_AFFLVL0: + if (state == PSCI_STATE_OFF) { + /* + * Take this cpu out of intra-cluster coherency if + * the FVP flavour supports the SMP bit. + */ + cpu_setup = fvp_get_cfgvar(CONFIG_CPU_SETUP); + if (cpu_setup) { + ectlr = read_cpuectlr(); + ectlr &= ~CPUECTLR_SMP_BIT; + write_cpuectlr(ectlr); + } + + /* Program the jump address for the target cpu */ + linear_id = platform_get_core_pos(mpidr); + fvp_mboxes = (mailbox_t *) (TZDRAM_BASE + MBOX_OFF); + fvp_mboxes[linear_id].value = sec_entrypoint; + flush_dcache_range((unsigned long) &fvp_mboxes[linear_id], + sizeof(unsigned long)); + + /* + * Prevent interrupts from spuriously waking up + * this cpu + */ + gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR); + gic_cpuif_deactivate(gicc_base); + + /* + * Program the power controller to power this + * cpu off and enable wakeup interrupts. + */ + fvp_pwrc_set_wen(mpidr); + fvp_pwrc_write_ppoffr(mpidr); + } + break; + + default: + assert(0); + } + + return rc; +} + +/******************************************************************************* + * FVP handler called when an affinity instance has just been powered on after + * being turned off earlier. The level and mpidr determine the affinity + * instance. The 'state' arg. allows the platform to decide whether the cluster + * was turned off prior to wakeup and do what's necessary to setup it up + * correctly. + ******************************************************************************/ +int fvp_affinst_on_finish(unsigned long mpidr, + unsigned int afflvl, + unsigned int state) +{ + int rc = PSCI_E_SUCCESS; + unsigned long linear_id, cpu_setup; + mailbox_t *fvp_mboxes; + unsigned int gicd_base, gicc_base, reg_val, ectlr; + + switch (afflvl) { + + case MPIDR_AFFLVL1: + /* Enable coherency if this cluster was off */ + if (state == PSCI_STATE_OFF) { + + /* + * This CPU might have woken up whilst the + * cluster was attempting to power down. In + * this case the FVP power controller will + * have a pending cluster power off request + * which needs to be cleared by writing to the + * PPONR register. This prevents the power + * controller from interpreting a subsequent + * entry of this cpu into a simple wfi as a + * power down request. + */ + fvp_pwrc_write_pponr(mpidr); + + fvp_cci_setup(); + } + break; + + case MPIDR_AFFLVL0: + /* + * Ignore the state passed for a cpu. It could only have + * been off if we are here. + */ + + /* + * Turn on intra-cluster coherency if the FVP flavour supports + * it. + */ + cpu_setup = fvp_get_cfgvar(CONFIG_CPU_SETUP); + if (cpu_setup) { + ectlr = read_cpuectlr(); + ectlr |= CPUECTLR_SMP_BIT; + write_cpuectlr(ectlr); + } + + /* + * Clear PWKUPR.WEN bit to ensure interrupts do not interfere + * with a cpu power down unless the bit is set again + */ + fvp_pwrc_clr_wen(mpidr); + + /* Zero the jump address in the mailbox for this cpu */ + fvp_mboxes = (mailbox_t *) (TZDRAM_BASE + MBOX_OFF); + linear_id = platform_get_core_pos(mpidr); + fvp_mboxes[linear_id].value = 0; + flush_dcache_range((unsigned long) &fvp_mboxes[linear_id], + sizeof(unsigned long)); + + gicd_base = fvp_get_cfgvar(CONFIG_GICD_ADDR); + gicc_base = fvp_get_cfgvar(CONFIG_GICC_ADDR); + + /* Enable the gic cpu interface */ + gic_cpuif_setup(gicc_base); + + /* TODO: This setup is needed only after a cold boot */ + gic_pcpu_distif_setup(gicd_base); + + /* Allow access to the System counter timer module */ + reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT); + reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT); + reg_val |= (1 << CNTACR_RWVT_SHIFT) | (1 << CNTACR_RWPT_SHIFT); + mmio_write_32(SYS_TIMCTL_BASE + CNTACR_BASE(0), reg_val); + mmio_write_32(SYS_TIMCTL_BASE + CNTACR_BASE(1), reg_val); + + reg_val = (1 << CNTNSAR_NS_SHIFT(0)) | + (1 << CNTNSAR_NS_SHIFT(1)); + mmio_write_32(SYS_TIMCTL_BASE + CNTNSAR, reg_val); + + break; + + default: + assert(0); + } + + return rc; +} + +/******************************************************************************* + * FVP handler called when an affinity instance has just been powered on after + * having been suspended earlier. The level and mpidr determine the affinity + * instance. + * TODO: At the moment we reuse the on finisher and reinitialize the secure + * context. Need to implement a separate suspend finisher. + ******************************************************************************/ +int fvp_affinst_suspend_finish(unsigned long mpidr, + unsigned int afflvl, + unsigned int state) +{ + return fvp_affinst_on_finish(mpidr, afflvl, state); +} + + +/******************************************************************************* + * Export the platform handlers to enable psci to invoke them + ******************************************************************************/ +static const plat_pm_ops_t fvp_plat_pm_ops = { + fvp_affinst_standby, + fvp_affinst_on, + fvp_affinst_off, + fvp_affinst_suspend, + fvp_affinst_on_finish, + fvp_affinst_suspend_finish, +}; + +/******************************************************************************* + * Export the platform specific power ops & initialize the fvp power controller + ******************************************************************************/ +int platform_setup_pm(const plat_pm_ops_t **plat_ops) +{ + *plat_ops = &fvp_plat_pm_ops; + return 0; +} diff --git a/plat/fvp/fvp_private.h b/plat/fvp/fvp_private.h new file mode 100644 index 0000000..2331bb7 --- /dev/null +++ b/plat/fvp/fvp_private.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __FVP_PRIVATE_H__ +#define __FVP_PRIVATE_H__ + +#include <bl_common.h> +#include <platform_def.h> + + +typedef volatile struct mailbox { + unsigned long value + __attribute__((__aligned__(CACHE_WRITEBACK_GRANULE))); +} mailbox_t; + +/******************************************************************************* + * This structure represents the superset of information that is passed to + * BL31 e.g. while passing control to it from BL2 which is bl31_params + * and bl31_plat_params and its elements + ******************************************************************************/ +typedef struct bl2_to_bl31_params_mem { + bl31_params_t bl31_params; + image_info_t bl31_image_info; + image_info_t bl32_image_info; + image_info_t bl33_image_info; + entry_point_info_t bl33_ep_info; + entry_point_info_t bl32_ep_info; + entry_point_info_t bl31_ep_info; +} bl2_to_bl31_params_mem_t; + +/******************************************************************************* + * Forward declarations + ******************************************************************************/ +struct meminfo; + +/******************************************************************************* + * Function and variable prototypes + ******************************************************************************/ +void fvp_configure_mmu_el1(unsigned long total_base, + unsigned long total_size, + unsigned long, + unsigned long, + unsigned long, + unsigned long); +void fvp_configure_mmu_el3(unsigned long total_base, + unsigned long total_size, + unsigned long, + unsigned long, + unsigned long, + unsigned long); +unsigned long fvp_get_cfgvar(unsigned int); +int fvp_config_setup(void); + +#if RESET_TO_BL31 +void fvp_get_entry_point_info(unsigned long target_security, + struct entry_point_info *target_entry_info); +#endif +void fvp_cci_setup(void); + +/* Declarations for fvp_gic.c */ +void gic_cpuif_deactivate(unsigned int); +void gic_cpuif_setup(unsigned int); +void gic_pcpu_distif_setup(unsigned int); +void gic_setup(void); + +/* Declarations for fvp_topology.c */ +int fvp_setup_topology(void); + +/* Declarations for fvp_io_storage.c */ +void fvp_io_setup(void); + +/* Declarations for fvp_security.c */ +void fvp_security_setup(void); + +/* Sets the entrypoint for BL32 */ +void fvp_set_bl32_ep_info(struct entry_point_info *bl32_ep); + +/* Sets the entrypoint for BL33 */ +void fvp_set_bl33_ep_info(struct entry_point_info *bl33_ep); + + +#endif /* __FVP_PRIVATE_H__ */ diff --git a/plat/fvp/fvp_security.c b/plat/fvp/fvp_security.c new file mode 100644 index 0000000..76c4541 --- /dev/null +++ b/plat/fvp/fvp_security.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <debug.h> +#include <tzc400.h> +#include "fvp_def.h" +#include "fvp_private.h" + +/* Used to improve readability for configuring regions. */ +#define FILTER_SHIFT(filter) (1 << filter) + +/* + * For the moment we assume that all security programming is done by the + * primary core. + * TODO: + * Might want to enable interrupt on violations when supported? + */ +void fvp_security_setup(void) +{ + tzc_instance_t controller; + + /* + * The Base FVP has a TrustZone address space controller, the Foundation + * FVP does not. Trying to program the device on the foundation FVP will + * cause an abort. + * + * If the platform had additional peripheral specific security + * configurations, those would be configured here. + */ + + if (!fvp_get_cfgvar(CONFIG_HAS_TZC)) + return; + + /* + * The TrustZone controller controls access to main DRAM. Give + * full NS access for the moment to use with OS. + */ + INFO("Configuring TrustZone Controller\n"); + + /* + * The driver does some error checking and will assert. + * - Provide base address of device on platform. + * - Provide width of ACE-Lite IDs on platform. + */ + controller.base = TZC400_BASE; + controller.aid_width = FVP_AID_WIDTH; + tzc_init(&controller); + + /* + * Currently only filters 0 and 2 are connected on Base FVP. + * Filter 0 : CPU clusters (no access to DRAM by default) + * Filter 1 : not connected + * Filter 2 : LCDs (access to VRAM allowed by default) + * Filter 3 : not connected + * Programming unconnected filters will have no effect at the + * moment. These filter could, however, be connected in future. + * So care should be taken not to configure the unused filters. + */ + + /* Disable all filters before programming. */ + tzc_disable_filters(&controller); + + /* + * Allow only non-secure access to all DRAM to supported devices. + * Give access to the CPUs and Virtio. Some devices + * would normally use the default ID so allow that too. We use + * two regions to cover the blocks of physical memory in the FVPs. + * + * Software executing in the secure state, such as a secure + * boot-loader, can access the DRAM by using the NS attributes in + * the MMU translation tables and descriptors. + */ + + /* Set to cover the first block of DRAM */ + tzc_configure_region(&controller, FILTER_SHIFT(0), 1, + DRAM1_BASE, DRAM1_END - DRAM1_SEC_SIZE, + TZC_REGION_S_NONE, + TZC_REGION_ACCESS_RDWR(FVP_NSAID_DEFAULT) | + TZC_REGION_ACCESS_RDWR(FVP_NSAID_PCI) | + TZC_REGION_ACCESS_RDWR(FVP_NSAID_AP) | + TZC_REGION_ACCESS_RDWR(FVP_NSAID_VIRTIO) | + TZC_REGION_ACCESS_RDWR(FVP_NSAID_VIRTIO_OLD)); + + /* Set to cover the secure reserved region */ + tzc_configure_region(&controller, FILTER_SHIFT(0), 3, + (DRAM1_END - DRAM1_SEC_SIZE) + 1 , DRAM1_END, + TZC_REGION_S_RDWR, + 0x0); + + /* Set to cover the second block of DRAM */ + tzc_configure_region(&controller, FILTER_SHIFT(0), 2, + DRAM2_BASE, DRAM2_END, TZC_REGION_S_NONE, + TZC_REGION_ACCESS_RDWR(FVP_NSAID_DEFAULT) | + TZC_REGION_ACCESS_RDWR(FVP_NSAID_PCI) | + TZC_REGION_ACCESS_RDWR(FVP_NSAID_AP) | + TZC_REGION_ACCESS_RDWR(FVP_NSAID_VIRTIO) | + TZC_REGION_ACCESS_RDWR(FVP_NSAID_VIRTIO_OLD)); + + /* + * TODO: Interrupts are not currently supported. The only + * options we have are for access errors to occur quietly or to + * cause an exception. We choose to cause an exception. + */ + tzc_set_action(&controller, TZC_ACTION_ERR); + + /* Enable filters. */ + tzc_enable_filters(&controller); +} diff --git a/plat/fvp/fvp_topology.c b/plat/fvp/fvp_topology.c new file mode 100644 index 0000000..cf21503 --- /dev/null +++ b/plat/fvp/fvp_topology.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <platform_def.h> +/* TODO: Reusing psci error codes & state information. Get our own! */ +#include <psci.h> +#include "drivers/pwrc/fvp_pwrc.h" + +/* We treat '255' as an invalid affinity instance */ +#define AFFINST_INVAL 0xff + +/******************************************************************************* + * We support 3 flavours of the FVP: Foundation, Base AEM & Base Cortex. Each + * flavour has a different topology. The common bit is that there can be a max. + * of 2 clusters (affinity 1) and 4 cpus (affinity 0) per cluster. So we define + * a tree like data structure which caters to these maximum bounds. It simply + * marks the absent affinity level instances as PSCI_AFF_ABSENT e.g. there is no + * cluster 1 on the Foundation FVP. The 'data' field is currently unused. + ******************************************************************************/ +typedef struct affinity_info { + unsigned char sibling; + unsigned char child; + unsigned char state; + unsigned int data; +} affinity_info_t; + +/******************************************************************************* + * The following two data structures store the topology tree for the fvp. There + * is a separate array for each affinity level i.e. cpus and clusters. The child + * and sibling references allow traversal inside and in between the two arrays. + ******************************************************************************/ +static affinity_info_t fvp_aff1_topology_map[PLATFORM_CLUSTER_COUNT]; +static affinity_info_t fvp_aff0_topology_map[PLATFORM_CORE_COUNT]; + +/* Simple global variable to safeguard us from stupidity */ +static unsigned int topology_setup_done; + +/******************************************************************************* + * This function implements a part of the critical interface between the psci + * generic layer and the platform to allow the former to detect the platform + * topology. psci queries the platform to determine how many affinity instances + * are present at a particular level for a given mpidr e.g. consider a dual + * cluster platform where each cluster has 4 cpus. A call to this function with + * (0, 0x100) will return the number of cpus implemented under cluster 1 i.e. 4. + * Similarly a call with (1, 0x100) will return 2 i.e. the number of clusters. + * This is 'cause we are effectively asking how many affinity level 1 instances + * are implemented under affinity level 2 instance 0. + ******************************************************************************/ +unsigned int plat_get_aff_count(unsigned int aff_lvl, + unsigned long mpidr) +{ + unsigned int aff_count = 1, ctr; + unsigned char parent_aff_id; + + assert(topology_setup_done == 1); + + switch (aff_lvl) { + case 3: + case 2: + /* + * Assert if the parent affinity instance is not 0. + * This also takes care of level 3 in an obfuscated way + */ + parent_aff_id = (mpidr >> MPIDR_AFF3_SHIFT) & MPIDR_AFFLVL_MASK; + assert(parent_aff_id == 0); + + /* + * Report that we implement a single instance of + * affinity levels 2 & 3 which are AFF_ABSENT + */ + break; + case 1: + /* Assert if the parent affinity instance is not 0. */ + parent_aff_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK; + assert(parent_aff_id == 0); + + /* Fetch the starting index in the aff1 array */ + for (ctr = 0; + fvp_aff1_topology_map[ctr].sibling != AFFINST_INVAL; + ctr = fvp_aff1_topology_map[ctr].sibling) { + aff_count++; + } + + break; + case 0: + /* Assert if the cluster id is anything apart from 0 or 1 */ + parent_aff_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + assert(parent_aff_id < PLATFORM_CLUSTER_COUNT); + + /* Fetch the starting index in the aff0 array */ + for (ctr = fvp_aff1_topology_map[parent_aff_id].child; + fvp_aff0_topology_map[ctr].sibling != AFFINST_INVAL; + ctr = fvp_aff0_topology_map[ctr].sibling) { + aff_count++; + } + + break; + default: + assert(0); + } + + return aff_count; +} + +/******************************************************************************* + * This function implements a part of the critical interface between the psci + * generic layer and the platform to allow the former to detect the state of a + * affinity instance in the platform topology. psci queries the platform to + * determine whether an affinity instance is present or absent. This caters for + * topologies where an intermediate affinity level instance is missing e.g. + * consider a platform which implements a single cluster with 4 cpus and there + * is another cpu sitting directly on the interconnect along with the cluster. + * The mpidrs of the cluster would range from 0x0-0x3. The mpidr of the single + * cpu would be 0x100 to highlight that it does not belong to cluster 0. Cluster + * 1 is however missing but needs to be accounted to reach this single cpu in + * the topology tree. Hence it will be marked as PSCI_AFF_ABSENT. This is not + * applicable to the FVP but depicted as an example. + ******************************************************************************/ +unsigned int plat_get_aff_state(unsigned int aff_lvl, + unsigned long mpidr) +{ + unsigned int aff_state = PSCI_AFF_ABSENT, idx; + idx = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + + assert(topology_setup_done == 1); + + switch (aff_lvl) { + case 3: + case 2: + /* Report affinity levels 2 & 3 as absent */ + break; + case 1: + aff_state = fvp_aff1_topology_map[idx].state; + break; + case 0: + /* + * First get start index of the aff0 in its array & then add + * to it the affinity id that we want the state of + */ + idx = fvp_aff1_topology_map[idx].child; + idx += (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; + aff_state = fvp_aff0_topology_map[idx].state; + break; + default: + assert(0); + } + + return aff_state; +} + +/******************************************************************************* + * Handy optimization to prevent the psci implementation from traversing through + * affinity levels which are not present while detecting the platform topology. + ******************************************************************************/ +int plat_get_max_afflvl() +{ + return MPIDR_AFFLVL1; +} + +/******************************************************************************* + * This function populates the FVP specific topology information depending upon + * the FVP flavour its running on. We construct all the mpidrs we can handle + * and rely on the PWRC.PSYSR to flag absent cpus when their status is queried. + ******************************************************************************/ +int fvp_setup_topology() +{ + unsigned char aff0, aff1, aff_state, aff0_offset = 0; + unsigned long mpidr; + + topology_setup_done = 0; + + for (aff1 = 0; aff1 < PLATFORM_CLUSTER_COUNT; aff1++) { + + fvp_aff1_topology_map[aff1].child = aff0_offset; + fvp_aff1_topology_map[aff1].sibling = aff1 + 1; + + for (aff0 = 0; aff0 < PLATFORM_MAX_CPUS_PER_CLUSTER; aff0++) { + + mpidr = aff1 << MPIDR_AFF1_SHIFT; + mpidr |= aff0 << MPIDR_AFF0_SHIFT; + + if (fvp_pwrc_read_psysr(mpidr) != PSYSR_INVALID) { + /* + * Presence of even a single aff0 indicates + * presence of parent aff1 on the FVP. + */ + aff_state = PSCI_AFF_PRESENT; + fvp_aff1_topology_map[aff1].state = + PSCI_AFF_PRESENT; + } else { + aff_state = PSCI_AFF_ABSENT; + } + + fvp_aff0_topology_map[aff0_offset].child = AFFINST_INVAL; + fvp_aff0_topology_map[aff0_offset].state = aff_state; + fvp_aff0_topology_map[aff0_offset].sibling = + aff0_offset + 1; + + /* Increment the absolute number of aff0s traversed */ + aff0_offset++; + } + + /* Tie-off the last aff0 sibling to -1 to avoid overflow */ + fvp_aff0_topology_map[aff0_offset - 1].sibling = AFFINST_INVAL; + } + + /* Tie-off the last aff1 sibling to AFFINST_INVAL to avoid overflow */ + fvp_aff1_topology_map[aff1 - 1].sibling = AFFINST_INVAL; + + topology_setup_done = 1; + return 0; +} diff --git a/plat/fvp/include/plat_macros.S b/plat/fvp/include/plat_macros.S new file mode 100644 index 0000000..bdd402d --- /dev/null +++ b/plat/fvp/include/plat_macros.S @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <gic_v2.h> +#include "../fvp_def.h" + +.section .rodata.gic_reg_name, "aS" +gic_regs: .asciz "gic_iar", "gic_ctlr", "" + +/* Currently we have only 2 GIC registers to report */ +#define GIC_REG_SIZE (2 * 8) + /* --------------------------------------------- + * The below macro prints out relevant GIC + * registers whenever an unhandled exception is + * taken in BL31. + * --------------------------------------------- + */ + .macro plat_print_gic_regs + mov x0, #CONFIG_GICC_ADDR + bl fvp_get_cfgvar + /* gic base address is now in x0 */ + ldr w1, [x0, #GICC_IAR] + ldr w2, [x0, #GICD_CTLR] + sub sp, sp, #GIC_REG_SIZE + stp x1, x2, [sp] /* we store the gic registers as 64 bit */ + adr x0, gic_regs + mov x1, sp + bl print_string_value + add sp, sp, #GIC_REG_SIZE + .endm diff --git a/plat/fvp/include/platform_def.h b/plat/fvp/include/platform_def.h new file mode 100644 index 0000000..46a9f24 --- /dev/null +++ b/plat/fvp/include/platform_def.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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_DEF_H__ +#define __PLATFORM_DEF_H__ + +#include <arch.h> + + +/******************************************************************************* + * Platform binary types for linking + ******************************************************************************/ +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +/******************************************************************************* + * Generic platform constants + ******************************************************************************/ + +/* Size of cacheable stacks */ +#define PLATFORM_STACK_SIZE 0x800 + +/* Size of coherent stacks for debug and release builds */ +#if DEBUG +#define PCPU_DV_MEM_STACK_SIZE 0x400 +#else +#define PCPU_DV_MEM_STACK_SIZE 0x300 +#endif + +#define FIRMWARE_WELCOME_STR "Booting trusted firmware boot loader stage 1\n\r" + +/* Trusted Boot Firmware BL2 */ +#define BL2_IMAGE_NAME "bl2.bin" + +/* EL3 Runtime Firmware BL31 */ +#define BL31_IMAGE_NAME "bl31.bin" + +/* Secure Payload BL32 (Trusted OS) */ +#define BL32_IMAGE_NAME "bl32.bin" + +/* Non-Trusted Firmware BL33 */ +#define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */ + +#define PLATFORM_CACHE_LINE_SIZE 64 +#define PLATFORM_CLUSTER_COUNT 2ull +#define PLATFORM_CLUSTER0_CORE_COUNT 4 +#define PLATFORM_CLUSTER1_CORE_COUNT 4 +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ + PLATFORM_CLUSTER0_CORE_COUNT) +#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 +#define PRIMARY_CPU 0x0 +#define MAX_IO_DEVICES 3 +#define MAX_IO_HANDLES 4 + +/******************************************************************************* + * Platform memory map related constants + ******************************************************************************/ +#define TZROM_BASE 0x00000000 +#define TZROM_SIZE 0x04000000 + +#define TZRAM_BASE 0x04000000 +#define TZRAM_SIZE 0x40000 + +/* Location of trusted dram on the base fvp */ +#define TZDRAM_BASE 0x06000000 +#define TZDRAM_SIZE 0x02000000 + +/******************************************************************************* + * BL1 specific defines. + * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of + * addresses. + ******************************************************************************/ +#define BL1_RO_BASE TZROM_BASE +#define BL1_RO_LIMIT (TZROM_BASE + TZROM_SIZE) +#define BL1_RW_BASE TZRAM_BASE +#define BL1_RW_LIMIT BL31_BASE + +/******************************************************************************* + * BL2 specific defines. + ******************************************************************************/ +#define BL2_BASE (TZRAM_BASE + TZRAM_SIZE - 0xc000) +#define BL2_LIMIT (TZRAM_BASE + TZRAM_SIZE) + +/******************************************************************************* + * BL31 specific defines. + ******************************************************************************/ +#define BL31_BASE (TZRAM_BASE + 0x6000) +#if TSP_RAM_LOCATION_ID == TSP_IN_TZRAM +#define BL31_LIMIT BL32_BASE +#elif TSP_RAM_LOCATION_ID == TSP_IN_TZDRAM +#define BL31_LIMIT BL2_BASE +#endif + +/******************************************************************************* + * BL32 specific defines. + ******************************************************************************/ +/* + * On FVP, the TSP can execute either from Trusted SRAM or Trusted DRAM. + */ +#define TSP_IN_TZRAM 0 +#define TSP_IN_TZDRAM 1 + +#if TSP_RAM_LOCATION_ID == TSP_IN_TZRAM +# define TSP_SEC_MEM_BASE TZRAM_BASE +# define TSP_SEC_MEM_SIZE TZRAM_SIZE +# define BL32_BASE (TZRAM_BASE + TZRAM_SIZE - 0x1c000) +# define BL32_LIMIT BL2_BASE +#elif TSP_RAM_LOCATION_ID == TSP_IN_TZDRAM +# define TSP_SEC_MEM_BASE TZDRAM_BASE +# define TSP_SEC_MEM_SIZE TZDRAM_SIZE +# define BL32_BASE (TZDRAM_BASE + 0x2000) +# define BL32_LIMIT (TZDRAM_BASE + (1 << 21)) +#else +# error "Unsupported TSP_RAM_LOCATION_ID value" +#endif + +/******************************************************************************* + * Platform specific page table and MMU setup constants + ******************************************************************************/ +#define ADDR_SPACE_SIZE (1ull << 32) +#define MAX_XLAT_TABLES 3 +#define MAX_MMAP_REGIONS 16 + +/******************************************************************************* + * ID of the secure physical generic timer interrupt. + ******************************************************************************/ +#define IRQ_SEC_PHY_TIMER 29 + +/******************************************************************************* + * CCI-400 related constants + ******************************************************************************/ +#define CCI400_BASE 0x2c090000 +#define CCI400_SL_IFACE_CLUSTER0 3 +#define CCI400_SL_IFACE_CLUSTER1 4 +#define CCI400_SL_IFACE_INDEX(mpidr) (mpidr & MPIDR_CLUSTER_MASK ? \ + CCI400_SL_IFACE_CLUSTER1 : \ + CCI400_SL_IFACE_CLUSTER0) + + +/******************************************************************************* + * Declarations and constants to access the mailboxes safely. Each mailbox is + * aligned on the biggest cache line size in the platform. This is known only + * to the platform as it might have a combination of integrated and external + * caches. Such alignment ensures that two maiboxes do not sit on the same cache + * line at any cache level. They could belong to different cpus/clusters & + * get written while being protected by different locks causing corruption of + * a valid mailbox address. + ******************************************************************************/ +#define CACHE_WRITEBACK_SHIFT 6 +#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) + + +#endif /* __PLATFORM_DEF_H__ */ diff --git a/plat/fvp/platform.mk b/plat/fvp/platform.mk new file mode 100644 index 0000000..4cc4d1e --- /dev/null +++ b/plat/fvp/platform.mk @@ -0,0 +1,94 @@ +# +# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 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. +# +# Neither the name of ARM nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific +# prior written permission. +# +# 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. +# + +# On FVP, the TSP can execute either from Trusted SRAM or Trusted DRAM. +# Trusted SRAM is the default. +TSP_RAM_LOCATION := tsram + +ifeq (${TSP_RAM_LOCATION}, tsram) + TSP_RAM_LOCATION_ID := TSP_IN_TZRAM +else ifeq (${TSP_RAM_LOCATION}, tdram) + TSP_RAM_LOCATION_ID := TSP_IN_TZDRAM +else + $(error "Unsupported TSP_RAM_LOCATION value") +endif + +# Process TSP_RAM_LOCATION_ID flag +$(eval $(call add_define,TSP_RAM_LOCATION_ID)) + +PLAT_INCLUDES := -Iplat/fvp/include/ + +PLAT_BL_COMMON_SOURCES := drivers/arm/pl011/pl011.c \ + drivers/arm/pl011/pl011_console.c \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + drivers/io/io_semihosting.c \ + lib/mmio.c \ + lib/aarch64/sysreg_helpers.S \ + lib/aarch64/xlat_tables.c \ + lib/semihosting/semihosting.c \ + lib/semihosting/aarch64/semihosting_call.S \ + plat/common/aarch64/plat_common.c \ + plat/fvp/fvp_io_storage.c + +BL1_SOURCES += drivers/arm/cci400/cci400.c \ + plat/common/aarch64/platform_up_stack.S \ + plat/fvp/bl1_fvp_setup.c \ + plat/fvp/aarch64/fvp_common.c \ + plat/fvp/aarch64/fvp_helpers.S + +BL2_SOURCES += drivers/arm/tzc400/tzc400.c \ + plat/common/aarch64/platform_up_stack.S \ + plat/fvp/bl2_fvp_setup.c \ + plat/fvp/fvp_security.c \ + plat/fvp/aarch64/fvp_common.c + +BL31_SOURCES += drivers/arm/gic/gic_v2.c \ + drivers/arm/gic/gic_v3.c \ + drivers/arm/gic/aarch64/gic_v3_sysregs.S \ + drivers/arm/cci400/cci400.c \ + plat/common/aarch64/platform_mp_stack.S \ + plat/fvp/bl31_fvp_setup.c \ + plat/fvp/fvp_gic.c \ + plat/fvp/fvp_pm.c \ + plat/fvp/fvp_topology.c \ + plat/fvp/aarch64/fvp_helpers.S \ + plat/fvp/aarch64/fvp_common.c \ + plat/fvp/drivers/pwrc/fvp_pwrc.c + +ifeq (${RESET_TO_BL31}, 1) +BL31_SOURCES += drivers/arm/tzc400/tzc400.c \ + plat/fvp/fvp_security.c +endif + +# Flag used by the FVP port to determine the version of ARM GIC architecture +# to use for interrupt management in EL3. +FVP_GIC_ARCH := 2 +$(eval $(call add_define,FVP_GIC_ARCH)) diff --git a/plat/gxb/aarch64/bl1_plat_helpers.S b/plat/gxb/aarch64/bl1_plat_helpers.S new file mode 100644 index 0000000..97d04c3 --- /dev/null +++ b/plat/gxb/aarch64/bl1_plat_helpers.S @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> +#include "../plat_def.h" + + .globl platform_get_entrypoint + .globl platform_cold_boot_init + .globl plat_secondary_cold_boot_setup + + + /* ----------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset e.g + * mark the cpu's presence, mechanism to place it in a + * holding pen etc. + * ----------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + /* PLAT todo: Implement secondary CPU cold boot setup on PLAT */ +cb_panic: + b cb_panic + + + /* ----------------------------------------------------- + * void platform_get_entrypoint (unsigned int mpid); + * + * Main job of this routine is to distinguish between + * a cold and warm boot. + * On a cold boot the secondaries first wait for the + * platform to be initialized after which they are + * hotplugged in. The primary proceeds to perform the + * platform initialization. + * On a warm boot, each cpu jumps to the address in its + * mailbox. + * + * TODO: Not a good idea to save lr in a temp reg + * ----------------------------------------------------- + */ +func platform_get_entrypoint + mov x9, x30 // lr + bl platform_get_core_pos + ldr x1, =TRUSTED_MAILBOXES_BASE + lsl x0, x0, #TRUSTED_MAILBOX_SHIFT + ldr x0, [x1, x0] + ret x9 + + + /* ----------------------------------------------------- + * void platform_cold_boot_init (bl1_main function); + * + * Routine called only by the primary cpu after a cold + * boot to perform early platform initialization + * ----------------------------------------------------- + */ +func platform_cold_boot_init + mov x20, x0 + + /* --------------------------------------------- + * Give ourselves a small coherent stack to + * ease the pain of initializing the MMU and + * CCI in assembler + * --------------------------------------------- + */ + mrs x0, mpidr_el1 + bl platform_set_coherent_stack + + /* --------------------------------------------- + * Architectural init. can be generic e.g. + * enabling stack alignment and platform spec- + * ific e.g. MMU & page table setup as per the + * platform memory map. Perform the latter here + * and the former in bl1_main. + * --------------------------------------------- + */ + bl bl1_early_platform_setup + bl bl1_plat_arch_setup + + /* --------------------------------------------- + * Give ourselves a stack allocated in Normal + * -IS-WBWA memory + * --------------------------------------------- + */ + mrs x0, mpidr_el1 + bl platform_set_stack + + /* --------------------------------------------- + * Jump to the main function. Returning from it + * is a terminal error. + * --------------------------------------------- + */ + blr x20 + +cb_init_panic: + b cb_init_panic diff --git a/plat/gxb/aarch64/cache.S b/plat/gxb/aarch64/cache.S new file mode 100644 index 0000000..d80c716 --- /dev/null +++ b/plat/gxb/aarch64/cache.S @@ -0,0 +1,38 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * This file is based on sample code from ARMv8 ARM. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <arch.h> +#include <asm_macros.S> + + .global disable_mmu_el1 + .global disable_mmu_icache_el1 + +/* + * void disable_mmu_el1(void) + * + * disable mmu and dcache. + */ +func disable_mmu_el1 + mov x1, #(SCTLR_M_BIT | SCTLR_C_BIT) +do_disable_mmu: + mrs x0, sctlr_el1 + bic x0, x0, x1 + msr sctlr_el1, x0 + isb // ensure MMU is off + mov x0, #DCCISW // DCache clean and invalidate + b dcsw_op_all + +/* + * void disable_mmu_icache_el1(void) + * + * disable mmu and dcache. + */ +func disable_mmu_icache_el1 + mov x1, #(SCTLR_M_BIT | SCTLR_C_BIT | SCTLR_I_BIT) + b do_disable_mmu
\ No newline at end of file diff --git a/plat/gxb/aarch64/common.c b/plat/gxb/aarch64/common.c new file mode 100644 index 0000000..2982880 --- /dev/null +++ b/plat/gxb/aarch64/common.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <mmio.h> +#include <platform.h> +#include <platform_def.h> +#include <xlat_tables.h> +#include "../plat_def.h" +#include <runtime_svc.h> +#include <arch_helpers.h> +#include <asm/arch/watchdog.h> +#include <stdio.h> + +extern int console_puts(const char *s); +extern void console_put_hex(unsigned long data,unsigned int bitlen); + +#ifdef BL2_ENABLE_MMU +/* + * Table of regions to map using the MMU. + * This doesn't include Trusted RAM as the 'mem_layout' argument passed to + * configure_mmu_elx() will give the available subset of that, + */ +static const mmap_region_t plat_mmap[] = { + { MAILBOX_START, MAILBOX_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, + { TZROM_BASE, TZROM_SIZE, MT_MEMORY | MT_RO | MT_SECURE }, + { DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS }, + { SPI_BASE, SPI_SIZE, MT_MEMORY | MT_RW | MT_SECURE }, + { DEVICEC_BASE, DEVICEC_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, + { DEVICED_BASE, DEVICED_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, + { DEVICEE_BASE, DEVICEE_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, + {0} +}; + +/******************************************************************************* + * Macro generating the code for the function setting up the pagetables as per + * the platform memory map & initialize the mmu, for the given exception level + ******************************************************************************/ +#define DEFINE_CONFIGURE_MMU_EL(_el) \ + void configure_mmu_el##_el(unsigned long total_base, \ + unsigned long total_size, \ + unsigned long ro_start, \ + unsigned long ro_limit, \ + unsigned long coh_start, \ + unsigned long coh_limit) \ + { \ + mmap_add_region(total_base, \ + total_size, \ + MT_MEMORY | MT_RW | MT_SECURE); \ + mmap_add_region(ro_start, ro_limit - ro_start, \ + MT_MEMORY | MT_RO | MT_SECURE); \ + mmap_add_region(coh_start, coh_limit - coh_start,\ + MT_DEVICE | MT_RW | MT_SECURE); \ + mmap_add(plat_mmap); \ + init_xlat_tables(); \ + \ + enable_mmu_el##_el(); \ + } + +/* Define EL1 and EL3 variants of the function initialising the MMU */ +DEFINE_CONFIGURE_MMU_EL(1) +DEFINE_CONFIGURE_MMU_EL(3) +#endif + +unsigned long plat_get_ns_image_entrypoint(void) +{ + return NS_IMAGE_OFFSET; +} + +uint64_t plat_get_syscnt_freq(void) +{ + uint64_t counter_base_frequency; + + /* Read the frequency from Frequency modes table */ + counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF); + + /* The first entry of the frequency modes table must not be 0 */ + assert(counter_base_frequency != 0); + + return counter_base_frequency; +} + +void plat_report_exception(void){ + serial_puts("Enter exception!\nValue: 0x"); + serial_put_hex(read_esr_el1(), 32); + serial_puts("\n"); + reset_system(); + /*never return*/ + while (1) ; +}
\ No newline at end of file diff --git a/plat/gxb/aarch64/plat_helpers.S b/plat/gxb/aarch64/plat_helpers.S new file mode 100644 index 0000000..e69dd4b --- /dev/null +++ b/plat/gxb/aarch64/plat_helpers.S @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> +#include <bl_common.h> +#include <platform_def.h> +#include "../plat_def.h" + + .globl platform_mem_init + + /* --------------------------------------------- + * void plat_report_exception(unsigned int type) + * Function to report an unhandled exception + * with platform-specific means. + * On ${PLAT} platform, it updates the LEDs + * to indicate where we are + * --------------------------------------------- + */ + + /* + * Return 0 to 3 for the A53s and 4 or 5 for the A57s + */ + .globl platform_get_core_pos +func platform_get_core_pos + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + eor x0, x0, #(1 << MPIDR_AFFINITY_BITS) // swap A53/A57 order + add x0, x1, x0, LSR #6 + ret + + + /* ----------------------------------------------------- + * void platform_is_primary_cpu (unsigned int mpid); + * + * Given the mpidr say whether this cpu is the primary + * cpu (applicable ony after a cold boot) + * ----------------------------------------------------- + */ + .globl platform_is_primary_cpu +func platform_is_primary_cpu + /* Warning: this function is called without a valid stack */ + /* ${PLAT} todo: allow configuration of primary CPU using SCC */ + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, #PRIMARY_CPU + cset x0, eq + ret + + + /* ----------------------------------------------------- + * void platform_mem_init(void); + * + * We don't need to carry out any memory initialization + * on ${PLAT}. The Secure RAM is accessible straight away. + * ----------------------------------------------------- + */ +func platform_mem_init + ret diff --git a/plat/gxb/bl2_plat_setup.c b/plat/gxb/bl2_plat_setup.c new file mode 100644 index 0000000..54b40f9 --- /dev/null +++ b/plat/gxb/bl2_plat_setup.c @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <serial.h> +#include <debug.h> +#include <platform.h> +#include <platform_def.h> +#include <string.h> +#include "plat_def.h" +#include "plat_private.h" +#include "scp_bootloader.h" +#include <xlat_tables.h> +#include <io.h> +#include "storage.h" + +/******************************************************************************* + * Declarations of linker defined symbols which will help us find the layout + * of trusted RAM + ******************************************************************************/ +extern unsigned long __RO_START__; +extern unsigned long __RO_END__; + +extern unsigned long __COHERENT_RAM_START__; +extern unsigned long __COHERENT_RAM_END__; + +/* + * The next 2 constants identify the extents of the code & RO data region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses. + */ +#define BL2_RO_BASE (unsigned long)(&__RO_START__) +#define BL2_RO_LIMIT (unsigned long)(&__RO_END__) + +/* + * The next 2 constants identify the extents of the coherent memory region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to + * page-aligned addresses. + */ +#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) +#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) + +/* Data structure which holds the extents of the trusted RAM for BL2 */ +static meminfo_t bl2_tzram_layout +__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE), + section("tzfw_coherent_mem"))); + +/******************************************************************************* + * Structure which holds the arguments which need to be passed to BL3-1 + ******************************************************************************/ +static bl2_to_bl31_params_mem_t bl31_params_mem; + +meminfo_t *bl2_plat_sec_mem_layout(void) +{ + return &bl2_tzram_layout; +} + +/******************************************************************************* + * This function assigns a pointer to the memory that the platform has kept + * aside to pass platform specific and trusted firmware related information + * to BL31. This memory is allocated by allocating memory to + * bl2_to_bl31_params_mem_t structure which is a superset of all the + * structure whose information is passed to BL31 + * NOTE: This function should be called only once and should be done + * before generating params to BL31 + ******************************************************************************/ +bl31_params_t *bl2_plat_get_bl31_params(void) +{ + bl31_params_t *bl2_to_bl31_params; + + /* + * Initialise the memory for all the arguments that needs to + * be passed to BL3-1 + */ + memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t)); + + /* Assign memory for TF related information */ + bl2_to_bl31_params = &bl31_params_mem.bl31_params; + SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0); + + /* Fill BL3-1 related information */ + bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY, + VERSION_1, 0); + + /* Fill BL3-2 related information if it exists */ +#if BL32_BASE + bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP, + VERSION_1, 0); + bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY, + VERSION_1, 0); +#endif + + /* Fill BL3-3 related information */ + bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info, + PARAM_EP, VERSION_1, 0); + /* UEFI expects to receive the primary CPU MPID (through x0) */ + bl2_to_bl31_params->bl33_ep_info->args.arg0 = PRIMARY_CPU; + + bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY, + VERSION_1, 0); + + return bl2_to_bl31_params; +} + +/******************************************************************************* + * This function returns a pointer to the shared memory that the platform + * has kept to point to entry point information of BL31 to BL2 + ******************************************************************************/ +struct entry_point_info *bl2_plat_get_bl31_ep_info(void) +{ +#if DEBUG + bl31_params_mem.bl31_ep_info.args.arg1 = PLAT_BL31_PLAT_PARAM_VAL; +#endif + + return &bl31_params_mem.bl31_ep_info; +} + +/******************************************************************************* + * BL1 has passed the extents of the trusted RAM that should be visible to BL2 + * in x0. This memory layout is sitting at the base of the free trusted RAM. + * Copy it to a safe loaction before its reclaimed by later BL2 functionality. + ******************************************************************************/ +void bl2_early_platform_setup(meminfo_t *mem_layout) +{ + //serial_init(52); //24M + + bl2_tzram_layout.total_base = TZRAM_BASE; + bl2_tzram_layout.total_size = TZRAM_SIZE; + bl2_tzram_layout.free_base = TZRAM_BL2_FREE_BASE; + bl2_tzram_layout.free_size = TZRAM_BL2_FREE_SIZE; + bl2_tzram_layout.attr = (unsigned long)0x0E939E2E8CF8EFFD; + bl2_tzram_layout.next = 0; +} + +/******************************************************************************* + * Perform platform specific setup, i.e. initialize the IO layer, load BL3-0 + * image and initialise the memory location to use for passing arguments to + * BL3-1. + ******************************************************************************/ +void bl2_platform_setup(void) +{ +#ifdef BL2_ENABLE_MMU + /* setup mmu */ + configure_mmu_el1(bl2_tzram_layout.total_base, + bl2_tzram_layout.total_size, + BL2_RO_BASE, + BL2_RO_LIMIT, + BL2_COHERENT_RAM_BASE, + BL2_COHERENT_RAM_LIMIT); +#endif + + /* storage init */ + storage_init(); +} + +/* Flush the TF params and the TF plat params */ +void bl2_plat_flush_bl31_params(void) +{ + flush_dcache_range((unsigned long)&bl31_params_mem, + sizeof(bl2_to_bl31_params_mem_t)); +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only intializes the mmu in a quick and dirty way. + ******************************************************************************/ +void bl2_plat_arch_setup(void) +{ + return; +} + +/******************************************************************************* + * Before calling this function BL31 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL31 and set SPSR and security state. + * On ${PLAT} we are only setting the security state, entrypoint + ******************************************************************************/ +void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info, + entry_point_info_t *bl31_ep_info) +{ + SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE); + bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS); +} + + +/******************************************************************************* + * Before calling this function BL32 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL32 and set SPSR and security state. + * On ${PLAT} we are only setting the security state, entrypoint + ******************************************************************************/ +void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info, + entry_point_info_t *bl32_ep_info) +{ + SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE); + /* + * The Secure Payload Dispatcher service is responsible for + * setting the SPSR prior to entry into the BL32 image. + */ + bl32_ep_info->spsr = 0; +} + +/******************************************************************************* + * Before calling this function BL33 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL33 and set SPSR and security state. + * On ${PLAT} we are only setting the security state, entrypoint + ******************************************************************************/ +void bl2_plat_set_bl33_ep_info(image_info_t *image, + entry_point_info_t *bl33_ep_info) +{ + unsigned long el_status; + unsigned int mode; + + /* Figure out what mode we enter the non-secure world in */ + el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; + el_status &= ID_AA64PFR0_ELX_MASK; + + if (el_status) + mode = MODE_EL2; + else + mode = MODE_EL1; + + /* + * TODO: Consider the possibility of specifying the SPSR in + * the FIP ToC and allowing the platform to have a say as + * well. + */ + bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS); + SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE); +} + +/******************************************************************************* + * Populate the extents of memory available for loading BL3-2 + ******************************************************************************/ +#ifdef BL32_BASE +void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo) +{ + /* + * Populate the extents of memory available for loading BL3-2. + */ + bl32_meminfo->total_base = BL32_BASE; + bl32_meminfo->free_base = BL32_BASE; + bl32_meminfo->total_size = + (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; + bl32_meminfo->free_size = + (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; + bl32_meminfo->attr = BOT_LOAD; + bl32_meminfo->next = 0; +} +#endif + +/******************************************************************************* + * Populate the extents of memory available for loading BL3-3 + ******************************************************************************/ +void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo) +{ + bl33_meminfo->total_base = DRAM_BASE; + bl33_meminfo->total_size = DRAM_SIZE; + bl33_meminfo->free_base = DRAM_BASE; + bl33_meminfo->free_size = DRAM_SIZE; + bl33_meminfo->attr = 0; + bl33_meminfo->attr = 0; +} diff --git a/plat/gxb/crypto/bignum.c b/plat/gxb/crypto/bignum.c new file mode 100644 index 0000000..ac0c811 --- /dev/null +++ b/plat/gxb/crypto/bignum.c @@ -0,0 +1,1355 @@ +/* + * Multi-precision integer library + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * This MPI implementation is based on: + * + * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf + * http://www.stillhq.com/extracted/gnupg-api/mpi/ + * http://math.libtomcrypt.com/files/tommath.pdf + */ + +#include "common.h" +#include <string.h> +#include <rsa_config.h> +#include <stdio.h> + + +#if defined(POLARSSL_BIGNUM_C) + +#include "bignum.h" +#include "bn_mul.h" + +#define ciL (sizeof(t_uint)) /* chars in limb */ +#define biL (ciL << 3) /* bits in limb */ +#define biH (ciL << 2) /* half limb size */ + +/* + * Convert between bits/chars and number of limbs + */ +#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL) +#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL) + + +#define CONFIG_MALLOC_MAX (128 * 1024) + +//char malloc_buffer[CONFIG_MALLOC_MAX]; +//static unsigned char * malloc_buffer = (unsigned char *)(0x10400000); +static int malloc_addr = 0; + +void *mymalloc(int size) +{ + void *p; + + if (malloc_addr + size > CONFIG_MALLOC_MAX) + p = NULL; + else + //p = (char *)&malloc_buffer[0] + malloc_addr; + p = (char *)(unsigned long)(0x1700000+ malloc_addr); + + if (p) + malloc_addr += size; + //ss_printf("malloc size %d/%d addr %p\n", size, malloc_addr, p); + + //printf("aml log : malloc_buffer=%p malloc_addr=0x%x p=%p size=%d\n", + // malloc_buffer,malloc_addr,p,size); + + return p; +} + +void myfree(void *ptr) +{ +} + +void mymallocreset() +{ + malloc_addr = 0; +} + + +/* + * Initialize one MPI + */ +void mpi_init( mpi *X ) +{ + if ( X == NULL ) + return; + + X->s = 1; + X->n = 0; + X->p = NULL; +} + +/* + * Unallocate one MPI + */ +void mpi_free( mpi *X ) +{ + if ( X == NULL ) + return; + + if ( X->p != NULL ) + { + memset( X->p, 0, X->n * ciL ); + myfree( X->p ); + } + + X->s = 1; + X->n = 0; + X->p = NULL; +} + +/* + * Enlarge to the specified number of limbs + */ +int mpi_grow( mpi *X, size_t nblimbs ) +{ + t_uint *p; + + if ( nblimbs > POLARSSL_MPI_MAX_LIMBS ) + return( POLARSSL_ERR_MPI_MALLOC_FAILED ); + + + if ( X->n < nblimbs ) + { + + if ( ( p = (t_uint *) mymalloc( nblimbs * ciL ) ) == NULL ) + return( POLARSSL_ERR_MPI_MALLOC_FAILED ); + + memset( p, 0, nblimbs * ciL ); + + if ( X->p != NULL ) + { + memcpy( p, X->p, X->n * ciL ); + memset( X->p, 0, X->n * ciL ); + myfree( X->p ); + } + + X->n = nblimbs; + X->p = p; + } + + return( 0 ); +} + +/* + * Copy the contents of Y into X + */ +int mpi_copy( mpi *X, const mpi *Y ) +{ + int ret; + size_t i; + + if ( X == Y ) + return( 0 ); + + for ( i = Y->n - 1; i > 0; i-- ) + if ( Y->p[i] != 0 ) + break; + i++; + + X->s = Y->s; + + MPI_CHK( mpi_grow( X, i ) ); + + memset( X->p, 0, X->n * ciL ); + memcpy( X->p, Y->p, i * ciL ); + +cleanup: + + return( ret ); +} + +/* + * Swap the contents of X and Y + */ +void mpi_swap( mpi *X, mpi *Y ) +{ + mpi T; + + memcpy( &T, X, sizeof( mpi ) ); + memcpy( X, Y, sizeof( mpi ) ); + memcpy( Y, &T, sizeof( mpi ) ); +} + +/* + * Set value from integer + */ +int mpi_lset( mpi *X, t_sint z ) +{ + int ret; + + MPI_CHK( mpi_grow( X, 1 ) ); + memset( X->p, 0, X->n * ciL ); + + X->p[0] = ( z < 0 ) ? -z : z; + X->s = ( z < 0 ) ? -1 : 1; + +cleanup: + + return( ret ); +} + +/* + * Get a specific bit + */ +int mpi_get_bit( const mpi *X, size_t pos ) +{ + if ( X->n * biL <= pos ) + return( 0 ); + + return ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01; +} + +/* + * Set a bit to a specific value of 0 or 1 + */ +int mpi_set_bit( mpi *X, size_t pos, unsigned char val ) +{ + int ret = 0; + size_t off = pos / biL; + size_t idx = pos % biL; + + if ( val != 0 && val != 1 ) + return POLARSSL_ERR_MPI_BAD_INPUT_DATA; + + if ( X->n * biL <= pos ) + { + if ( val == 0 ) + return ( 0 ); + + MPI_CHK( mpi_grow( X, off + 1 ) ); + } + + X->p[off] = ( X->p[off] & ~( 0x01 << idx ) ) | ( val << idx ); + +cleanup: + + return( ret ); +} + +/* + * Return the number of least significant bits + */ +size_t mpi_lsb( const mpi *X ) +{ + size_t i, j, count = 0; + + for ( i = 0; i < X->n; i++ ) + for ( j = 0; j < biL; j++, count++ ) + if ( ( ( X->p[i] >> j ) & 1 ) != 0 ) + return( count ); + + return( 0 ); +} + +/* + * Return the number of most significant bits + */ +size_t mpi_msb( const mpi *X ) +{ + size_t i, j; + + for ( i = X->n - 1; i > 0; i-- ) + if ( X->p[i] != 0 ) + break; + + for ( j = biL; j > 0; j-- ) + if ( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 ) + break; + + return( ( i * biL ) + j ); +} + +/* + * Return the total size in bytes + */ +size_t mpi_size( const mpi *X ) +{ + return( ( mpi_msb( X ) + 7 ) >> 3 ); +} + + +/* + * Import X from unsigned binary data, big endian + */ +int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen ) +{ + int ret; + size_t i, j, n; + + for ( n = 0; n < buflen; n++ ) + if ( buf[n] != 0 ) + break; + MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) ); + + MPI_CHK( mpi_lset( X, 0 ) ); + + + for ( i = buflen, j = 0; i > n; i--, j++ ) + X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3); + +cleanup: + + return( ret ); +} + +/* + * Export X into unsigned binary data, big endian + */ +int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen ) +{ + size_t i, j, n; + + n = mpi_size( X ); + + if ( buflen < n ) + return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); + + memset( buf, 0, buflen ); + + for ( i = buflen - 1, j = 0; n > 0; i--, j++, n-- ) + buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) ); + + return( 0 ); +} + +/* + * Left-shift: X <<= count + */ +int mpi_shift_l( mpi *X, size_t count ) +{ + int ret; + size_t i, v0, t1; + t_uint r0 = 0, r1; + + v0 = count / (biL ); + t1 = count & (biL - 1); + + i = mpi_msb( X ) + count; + + if ( X->n * biL < i ) + MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) ); + + ret = 0; + + /* + * shift by count / limb_size + */ + if ( v0 > 0 ) + { + for ( i = X->n; i > v0; i-- ) + X->p[i - 1] = X->p[i - v0 - 1]; + + for ( ; i > 0; i-- ) + X->p[i - 1] = 0; + } + + /* + * shift by count % limb_size + */ + if ( t1 > 0 ) + { + for ( i = v0; i < X->n; i++ ) + { + r1 = X->p[i] >> (biL - t1); + X->p[i] <<= t1; + X->p[i] |= r0; + r0 = r1; + } + } + +cleanup: + + return( ret ); +} + +/* + * Right-shift: X >>= count + */ +int mpi_shift_r( mpi *X, size_t count ) +{ + size_t i, v0, v1; + t_uint r0 = 0, r1; + + v0 = count / biL; + v1 = count & (biL - 1); + + if ( v0 > X->n || ( v0 == X->n && v1 > 0 ) ) + return mpi_lset( X, 0 ); + + /* + * shift by count / limb_size + */ + if ( v0 > 0 ) + { + for ( i = 0; i < X->n - v0; i++ ) + X->p[i] = X->p[i + v0]; + + for ( ; i < X->n; i++ ) + X->p[i] = 0; + } + + /* + * shift by count % limb_size + */ + if ( v1 > 0 ) + { + for ( i = X->n; i > 0; i-- ) + { + r1 = X->p[i - 1] << (biL - v1); + X->p[i - 1] >>= v1; + X->p[i - 1] |= r0; + r0 = r1; + } + } + + return( 0 ); +} + +/* + * Compare unsigned values + */ +int mpi_cmp_abs( const mpi *X, const mpi *Y ) +{ + size_t i, j; + + for ( i = X->n; i > 0; i-- ) + if ( X->p[i - 1] != 0 ) + break; + + for ( j = Y->n; j > 0; j-- ) + if ( Y->p[j - 1] != 0 ) + break; + + if ( i == 0 && j == 0 ) + return( 0 ); + + if ( i > j ) return( 1 ) ; + if ( j > i ) return( -1 ) ; + + for ( ; i > 0; i-- ) + { + if ( X->p[i - 1] > Y->p[i - 1] ) return( 1 ) ; + if ( X->p[i - 1] < Y->p[i - 1] ) return( -1 ) ; + } + + return( 0 ); +} + +/* + * Compare signed values + */ +int mpi_cmp_mpi( const mpi *X, const mpi *Y ) +{ + size_t i, j; + + for ( i = X->n; i > 0; i-- ) + if ( X->p[i - 1] != 0 ) + break; + + for ( j = Y->n; j > 0; j-- ) + if ( Y->p[j - 1] != 0 ) + break; + + if ( i == 0 && j == 0 ) + return( 0 ); + + if ( i > j ) return( X->s ) ; + if ( j > i ) return( -Y->s ) ; + + if ( X->s > 0 && Y->s < 0 ) return( 1 ) ; + if ( Y->s > 0 && X->s < 0 ) return( -1 ) ; + + for ( ; i > 0; i-- ) + { + if ( X->p[i - 1] > Y->p[i - 1] ) return( X->s ) ; + if ( X->p[i - 1] < Y->p[i - 1] ) return( -X->s ) ; + } + + return( 0 ); +} + +/* + * Compare signed values + */ +int mpi_cmp_int( const mpi *X, t_sint z ) +{ + mpi Y; + t_uint p[1]; + + *p = ( z < 0 ) ? -z : z; + Y.s = ( z < 0 ) ? -1 : 1; + Y.n = 1; + Y.p = p; + + return( mpi_cmp_mpi( X, &Y ) ); +} + +/* + * Unsigned addition: X = |A| + |B| (HAC 14.7) + */ +int mpi_add_abs( mpi *X, const mpi *A, const mpi *B ) +{ + int ret; + size_t i, j; + t_uint *o, *p, c; + + if ( X == B ) + { + const mpi *T = A; A = X; B = T; + } + + if ( X != A ) + MPI_CHK( mpi_copy( X, A ) ); + + /* + * X should always be positive as a result of unsigned additions. + */ + X->s = 1; + + for ( j = B->n; j > 0; j-- ) + if ( B->p[j - 1] != 0 ) + break; + + MPI_CHK( mpi_grow( X, j ) ); + + o = B->p; p = X->p; c = 0; + + for ( i = 0; i < j; i++, o++, p++ ) + { + *p += c; c = ( *p < c ); + *p += *o; c += ( *p < *o ); + } + + while ( c != 0 ) + { + if ( i >= X->n ) + { + MPI_CHK( mpi_grow( X, i + 1 ) ); + p = X->p + i; + } + + *p += c; c = ( *p < c ); i++; p++; + } + +cleanup: + + return( ret ); +} + +/* + * Helper for mpi substraction + */ +static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d ) +{ + size_t i; + t_uint c, z; + + for ( i = c = 0; i < n; i++, s++, d++ ) + { + z = ( *d < c ); *d -= c; + c = ( *d < *s ) + z; *d -= *s; + } + + while ( c != 0 ) + { + z = ( *d < c ); *d -= c; + c = z; i++; d++; + } +} + +/* + * Unsigned substraction: X = |A| - |B| (HAC 14.9) + */ +int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B ) +{ + mpi TB; + int ret; + size_t n; + + if ( mpi_cmp_abs( A, B ) < 0 ) + return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); + + mpi_init( &TB ); + + if ( X == B ) + { + MPI_CHK( mpi_copy( &TB, B ) ); + B = &TB; + } + + if ( X != A ) + MPI_CHK( mpi_copy( X, A ) ); + + /* + * X should always be positive as a result of unsigned substractions. + */ + X->s = 1; + + ret = 0; + + for ( n = B->n; n > 0; n-- ) + if ( B->p[n - 1] != 0 ) + break; + + mpi_sub_hlp( n, B->p, X->p ); + +cleanup: + + mpi_free( &TB ); + + return( ret ); +} + +/* + * Signed addition: X = A + B + */ +int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B ) +{ + int ret, s = A->s; + + if ( A->s * B->s < 0 ) + { + if ( mpi_cmp_abs( A, B ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( X, A, B ) ); + X->s = s; + } + else + { + MPI_CHK( mpi_sub_abs( X, B, A ) ); + X->s = -s; + } + } + else + { + MPI_CHK( mpi_add_abs( X, A, B ) ); + X->s = s; + } + +cleanup: + + return( ret ); +} + +/* + * Signed substraction: X = A - B + */ +int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B ) +{ + int ret, s = A->s; + + if ( A->s * B->s > 0 ) + { + if ( mpi_cmp_abs( A, B ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( X, A, B ) ); + X->s = s; + } + else + { + MPI_CHK( mpi_sub_abs( X, B, A ) ); + X->s = -s; + } + } + else + { + MPI_CHK( mpi_add_abs( X, A, B ) ); + X->s = s; + } + +cleanup: + + return( ret ); +} + +/* + * Signed addition: X = A + b + */ +int mpi_add_int( mpi *X, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_add_mpi( X, A, &_B ) ); +} + +/* + * Signed substraction: X = A - b + */ +int mpi_sub_int( mpi *X, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_sub_mpi( X, A, &_B ) ); +} + +/* + * Helper for mpi multiplication + */ +static void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b ) +{ + t_uint c = 0, t = 0; + +#if defined(MULADDC_HUIT) + for ( ; i >= 8; i -= 8 ) + { + MULADDC_INIT + MULADDC_HUIT + MULADDC_STOP + } + + for ( ; i > 0; i-- ) + { + MULADDC_INIT + MULADDC_CORE + MULADDC_STOP + } +#else + for ( ; i >= 16; i -= 16 ) + { + MULADDC_INIT + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_STOP + } + + for ( ; i >= 8; i -= 8 ) + { + MULADDC_INIT + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_STOP + } + + for ( ; i > 0; i-- ) + { + MULADDC_INIT + MULADDC_CORE + MULADDC_STOP + } +#endif + + t++; + + do { + *d += c; c = ( *d < c ); d++; + } + while ( c != 0 ) ; +} + +/* + * Baseline multiplication: X = A * B (HAC 14.12) + */ +int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B ) +{ + int ret; + size_t i, j; + mpi TA, TB; + + mpi_init( &TA ); mpi_init( &TB ); + + if ( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ) ; A = &TA; } + if ( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ) ; B = &TB; } + + for ( i = A->n; i > 0; i-- ) + if ( A->p[i - 1] != 0 ) + break; + + for ( j = B->n; j > 0; j-- ) + if ( B->p[j - 1] != 0 ) + break; + + MPI_CHK( mpi_grow( X, i + j ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + for ( i++; j > 0; j-- ) + mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] ); + + X->s = A->s * B->s; + +cleanup: + + mpi_free( &TB ); mpi_free( &TA ); + + return( ret ); +} + +/* + * Baseline multiplication: X = A * b + */ +int mpi_mul_int( mpi *X, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + _B.s = 1; + _B.n = 1; + _B.p = p; + p[0] = b; + + return( mpi_mul_mpi( X, A, &_B ) ); +} + +/* + * Division by mpi: A = Q * B + R (HAC 14.20) + */ +int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ) +{ + int ret; + size_t i, n, t, k; + mpi X, Y, Z, T1, T2; + + if ( mpi_cmp_int( B, 0 ) == 0 ) + return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); + + mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z ); + mpi_init( &T1 ); mpi_init( &T2 ); + + if ( mpi_cmp_abs( A, B ) < 0 ) + { + if ( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) ) ; + if ( R != NULL ) MPI_CHK( mpi_copy( R, A ) ) ; + return( 0 ); + } + + MPI_CHK( mpi_copy( &X, A ) ); + MPI_CHK( mpi_copy( &Y, B ) ); + X.s = Y.s = 1; + + MPI_CHK( mpi_grow( &Z, A->n + 2 ) ); + MPI_CHK( mpi_lset( &Z, 0 ) ); + MPI_CHK( mpi_grow( &T1, 2 ) ); + MPI_CHK( mpi_grow( &T2, 3 ) ); + + k = mpi_msb( &Y ) % biL; + if ( k < biL - 1 ) + { + k = biL - 1 - k; + MPI_CHK( mpi_shift_l( &X, k ) ); + MPI_CHK( mpi_shift_l( &Y, k ) ); + } + else k = 0; + + n = X.n - 1; + t = Y.n - 1; + MPI_CHK( mpi_shift_l( &Y, biL * (n - t) ) ); + + while ( mpi_cmp_mpi( &X, &Y ) >= 0 ) + { + Z.p[n - t]++; + mpi_sub_mpi( &X, &X, &Y ); + } + mpi_shift_r( &Y, biL * (n - t) ); + + for ( i = n; i > t ; i-- ) + { + if ( X.p[i] >= Y.p[t] ) + Z.p[i - t - 1] = ~0; + else + { +#if defined(POLARSSL_HAVE_UDBL) + t_udbl r; + + r = (t_udbl) X.p[i] << biL; + r |= (t_udbl) X.p[i - 1]; + r /= Y.p[t]; + if ( r > ((t_udbl) 1 << biL) - 1) + r = ((t_udbl) 1 << biL) - 1; + + Z.p[i - t - 1] = (t_uint) r; +#else + /* + * __udiv_qrnnd_c, from gmp/longlong.h + */ + t_uint q0, q1, r0, r1; + t_uint d0, d1, d, m; + + d = Y.p[t]; + d0 = ( d << biH ) >> biH; + d1 = ( d >> biH ); + + q1 = X.p[i] / d1; + r1 = X.p[i] - d1 * q1; + r1 <<= biH; + r1 |= ( X.p[i - 1] >> biH ); + + m = q1 * d0; + if ( r1 < m ) + { + q1--, r1 += d; + while ( r1 >= d && r1 < m ) + q1--, r1 += d; + } + r1 -= m; + + q0 = r1 / d1; + r0 = r1 - d1 * q0; + r0 <<= biH; + r0 |= ( X.p[i - 1] << biH ) >> biH; + + m = q0 * d0; + if ( r0 < m ) + { + q0--, r0 += d; + while ( r0 >= d && r0 < m ) + q0--, r0 += d; + } + r0 -= m; + + Z.p[i - t - 1] = ( q1 << biH ) | q0; +#endif + } + + Z.p[i - t - 1]++; + do + { + Z.p[i - t - 1]--; + + MPI_CHK( mpi_lset( &T1, 0 ) ); + T1.p[0] = (t < 1) ? 0 : Y.p[t - 1]; + T1.p[1] = Y.p[t]; + MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) ); + + MPI_CHK( mpi_lset( &T2, 0 ) ); + T2.p[0] = (i < 2) ? 0 : X.p[i - 2]; + T2.p[1] = (i < 1) ? 0 : X.p[i - 1]; + T2.p[2] = X.p[i]; + } + while ( mpi_cmp_mpi( &T1, &T2 ) > 0 ) ; + + MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) ); + MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) ); + MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); + + if ( mpi_cmp_int( &X, 0 ) < 0 ) + { + MPI_CHK( mpi_copy( &T1, &Y ) ); + MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) ); + MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) ); + Z.p[i - t - 1]--; + } + } + + if ( Q != NULL ) + { + mpi_copy( Q, &Z ); + Q->s = A->s * B->s; + } + + if ( R != NULL ) + { + mpi_shift_r( &X, k ); + X.s = A->s; + mpi_copy( R, &X ); + + if ( mpi_cmp_int( R, 0 ) == 0 ) + R->s = 1; + } + +cleanup: + + mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z ); + mpi_free( &T1 ); mpi_free( &T2 ); + + return( ret ); +} +/* + * Modulo: R = A mod B + */ +int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B ) +{ + int ret; + + if ( mpi_cmp_int( B, 0 ) < 0 ) + return POLARSSL_ERR_MPI_NEGATIVE_VALUE; + + MPI_CHK( mpi_div_mpi( NULL, R, A, B ) ); + + while ( mpi_cmp_int( R, 0 ) < 0 ) + MPI_CHK( mpi_add_mpi( R, R, B ) ); + + while ( mpi_cmp_mpi( R, B ) >= 0 ) + MPI_CHK( mpi_sub_mpi( R, R, B ) ); + +cleanup: + + return( ret ); +} + +/* + * Modulo: r = A mod b + */ +int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ) +{ + size_t i; + t_uint x, y, z; + + if ( b == 0 ) + return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); + + if ( b < 0 ) + return POLARSSL_ERR_MPI_NEGATIVE_VALUE; + + /* + * handle trivial cases + */ + if ( b == 1 ) + { + *r = 0; + return( 0 ); + } + + if ( b == 2 ) + { + *r = A->p[0] & 1; + return( 0 ); + } + + /* + * general case + */ + for ( i = A->n, y = 0; i > 0; i-- ) + { + x = A->p[i - 1]; + y = ( y << biH ) | ( x >> biH ); + z = y / b; + y -= z * b; + + x <<= biH; + y = ( y << biH ) | ( x >> biH ); + z = y / b; + y -= z * b; + } + + /* + * If A is negative, then the current y represents a negative value. + * Flipping it to the positive side. + */ + if ( A->s < 0 && y != 0 ) + y = b - y; + + *r = y; + + return( 0 ); +} + +/* + * Fast Montgomery initialization (thanks to Tom St Denis) + */ +static void mpi_montg_init( t_uint *mm, const mpi *N ) +{ + t_uint x, m0 = N->p[0]; + + x = m0; + x += ( ( m0 + 2 ) & 4 ) << 1; + x *= ( 2 - ( m0 * x ) ); + + if ( biL >= 16 ) x *= ( 2 - ( m0 * x ) ) ; + if ( biL >= 32 ) x *= ( 2 - ( m0 * x ) ) ; + if ( biL >= 64 ) x *= ( 2 - ( m0 * x ) ) ; + + *mm = ~x + 1; +} + +/* + * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) + */ +static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T ) +{ + size_t i, n, m; + t_uint u0, u1, *d; + + memset( T->p, 0, T->n * ciL ); + + d = T->p; + n = N->n; + m = ( B->n < n ) ? B->n : n; + + for ( i = 0; i < n; i++ ) + { + /* + * T = (T + u0*B + u1*N) / 2^biL + */ + u0 = A->p[i]; + u1 = ( d[0] + u0 * B->p[0] ) * mm; + + mpi_mul_hlp( m, B->p, d, u0 ); + mpi_mul_hlp( n, N->p, d, u1 ); + + *d++ = u0; d[n + 1] = 0; + } + + memcpy( A->p, d, (n + 1) * ciL ); + + if ( mpi_cmp_abs( A, N ) >= 0 ) + mpi_sub_hlp( n, N->p, A->p ); + else + /* prevent timing attacks */ + mpi_sub_hlp( n, A->p, T->p ); +} + +/* + * Montgomery reduction: A = A * R^-1 mod N + */ +static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T ) +{ + t_uint z = 1; + mpi U; + + U.n = U.s = (int) z; + U.p = &z; + + mpi_montmul( A, &U, N, mm, T ); +} + +/* + * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) + */ +int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) +{ + int ret; + size_t wbits, wsize, one = 1; + size_t i, j, nblimbs; + size_t bufsize, nbits; + t_uint ei, mm, state; + mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos; + int neg; + + if ( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + if ( mpi_cmp_int( E, 0 ) < 0 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + /* + * Init temps and window size + */ + mpi_montg_init( &mm, N ); + mpi_init( &RR ); mpi_init( &T ); + memset( W, 0, sizeof( W ) ); + + i = mpi_msb( E ); + + wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : + ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; + + if ( wsize > POLARSSL_MPI_WINDOW_SIZE ) + wsize = POLARSSL_MPI_WINDOW_SIZE; + + j = N->n + 1; + MPI_CHK( mpi_grow( X, j ) ); + MPI_CHK( mpi_grow( &W[1], j ) ); + MPI_CHK( mpi_grow( &T, j * 2 ) ); + + /* + * Compensate for negative A (and correct at the end) + */ + neg = ( A->s == -1 ); + + mpi_init( &Apos ); + if ( neg ) + { + MPI_CHK( mpi_copy( &Apos, A ) ); + Apos.s = 1; + A = &Apos; + } + + /* + * If 1st call, pre-compute R^2 mod N + */ + if ( _RR == NULL || _RR->p == NULL ) + { + MPI_CHK( mpi_lset( &RR, 1 ) ); + MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) ); + MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) ); + + if ( _RR != NULL ) + memcpy( _RR, &RR, sizeof( mpi ) ); + } + else + memcpy( &RR, _RR, sizeof( mpi ) ); + + /* + * W[1] = A * R^2 * R^-1 mod N = A * R mod N + */ + if ( mpi_cmp_mpi( A, N ) >= 0 ) + mpi_mod_mpi( &W[1], A, N ); + else mpi_copy( &W[1], A ); + + mpi_montmul( &W[1], &RR, N, mm, &T ); + + /* + * X = R^2 * R^-1 mod N = R mod N + */ + MPI_CHK( mpi_copy( X, &RR ) ); + mpi_montred( X, N, mm, &T ); + + if ( wsize > 1 ) + { + /* + * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1) + */ + j = one << (wsize - 1); + + MPI_CHK( mpi_grow( &W[j], N->n + 1 ) ); + MPI_CHK( mpi_copy( &W[j], &W[1] ) ); + + for ( i = 0; i < wsize - 1; i++ ) + mpi_montmul( &W[j], &W[j], N, mm, &T ); + + /* + * W[i] = W[i - 1] * W[1] + */ + for ( i = j + 1; i < (one << wsize); i++ ) + { + MPI_CHK( mpi_grow( &W[i], N->n + 1 ) ); + MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) ); + + mpi_montmul( &W[i], &W[1], N, mm, &T ); + } + } + + nblimbs = E->n; + bufsize = 0; + nbits = 0; + wbits = 0; + state = 0; + + while ( 1 ) + { + if ( bufsize == 0 ) + { + if ( nblimbs-- == 0 ) + break; + + bufsize = sizeof( t_uint ) << 3; + } + + bufsize--; + + ei = (E->p[nblimbs] >> bufsize) & 1; + + /* + * skip leading 0s + */ + if ( ei == 0 && state == 0 ) + continue; + + if ( ei == 0 && state == 1 ) + { + /* + * out of window, square X + */ + mpi_montmul( X, X, N, mm, &T ); + continue; + } + + /* + * add ei to current window + */ + state = 2; + + nbits++; + wbits |= (ei << (wsize - nbits)); + + if ( nbits == wsize ) + { + /* + * X = X^wsize R^-1 mod N + */ + for ( i = 0; i < wsize; i++ ) + mpi_montmul( X, X, N, mm, &T ); + + /* + * X = X * W[wbits] R^-1 mod N + */ + mpi_montmul( X, &W[wbits], N, mm, &T ); + + state--; + nbits = 0; + wbits = 0; + } + } + + /* + * process the remaining bits + */ + for ( i = 0; i < nbits; i++ ) + { + mpi_montmul( X, X, N, mm, &T ); + + wbits <<= 1; + + if ( (wbits & (one << wsize)) != 0 ) + mpi_montmul( X, &W[1], N, mm, &T ); + } + + /* + * X = A^E * R * R^-1 mod N = A^E mod N + */ + mpi_montred( X, N, mm, &T ); + + if ( neg ) + { + X->s = -1; + mpi_add_mpi( X, N, X ); + } + +cleanup: + + for ( i = (one << (wsize - 1)); i < (one << wsize); i++ ) + mpi_free( &W[i] ); + + mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos ); + + if ( _RR == NULL ) + mpi_free( &RR ); + + return( ret ); +} + +#endif diff --git a/plat/gxb/crypto/ndma_utils.c b/plat/gxb/crypto/ndma_utils.c new file mode 100644 index 0000000..29147e0 --- /dev/null +++ b/plat/gxb/crypto/ndma_utils.c @@ -0,0 +1,183 @@ +#include <stdint.h> +#include "ndma_utils.h" +#include <asm/arch/secure_apb.h> +#include <arch_helpers.h> + +uint32_t NDMA_table_ptr_start[4]; +uint32_t NDMA_table_ptr_curr[4]; +uint32_t NDMA_table_ptr_end[4]; + + +#define NDMA_Wr(addr, data) *(volatile uint32_t *)(addr)=(data) +#define NDMA_Rd(addr) *(volatile uint32_t *)(addr) +// -------------------------------------------- +// NDMA_set_table_position_secure +// -------------------------------------------- +void NDMA_set_table_position_secure( uint32_t thread_num, uint32_t table_start, uint32_t table_end ) +{ + NDMA_table_ptr_start[thread_num] = table_start; + NDMA_table_ptr_curr[thread_num] = table_start; + NDMA_table_ptr_end[thread_num] = table_end; + switch ( thread_num ) { + case 3: NDMA_Wr( SEC_SEC_BLKMV_THREAD_TABLE_START3, table_start ); + NDMA_Wr( SEC_SEC_BLKMV_THREAD_TABLE_END3, table_end ); + // Pulse thread init to register the new start/end locations + NDMA_Wr( NDMA_THREAD_REG, NDMA_Rd(NDMA_THREAD_REG) | (1 << 27) ); + break; + case 2: NDMA_Wr( SEC_SEC_BLKMV_THREAD_TABLE_START2, table_start ); + NDMA_Wr( SEC_SEC_BLKMV_THREAD_TABLE_END2, table_end ); + // Pulse thread init to register the new start/end locations + NDMA_Wr( NDMA_THREAD_REG, NDMA_Rd(NDMA_THREAD_REG) | (1 << 26) ); + break; + case 1: NDMA_Wr( SEC_SEC_BLKMV_THREAD_TABLE_START1, table_start ); + NDMA_Wr( SEC_SEC_BLKMV_THREAD_TABLE_END1, table_end ); + // Pulse thread init to register the new start/end locations + NDMA_Wr( NDMA_THREAD_REG, NDMA_Rd(NDMA_THREAD_REG) | (1 << 25) ); + break; + case 0: NDMA_Wr( SEC_SEC_BLKMV_THREAD_TABLE_START0, table_start ); + NDMA_Wr( SEC_SEC_BLKMV_THREAD_TABLE_END0, table_end ); + // Pulse thread init to register the new start/end locations + NDMA_Wr( SEC_NDMA_THREAD_REG, NDMA_Rd(NDMA_THREAD_REG) | (1 << 24) ); + break; + } +} + + +// -------------------------------------------- +// NDMA_start() +// -------------------------------------------- +// Start the block move procedure +// +void NDMA_start(uint32_t thread_num) +{ + NDMA_Wr(SEC_NDMA_CNTL_REG0,NDMA_Rd(SEC_NDMA_CNTL_REG0) | (1 << NDMA_ENABLE) ); + + // NDMA_Wr(NDMA_CNTL_REG0,0xf8634000 ); + NDMA_Wr(SEC_NDMA_THREAD_REG,NDMA_Rd(SEC_NDMA_THREAD_REG) | (1 << (thread_num + 8)) ); +} +// -------------------------------------------- +// NDMA_wait_for_completion() +// -------------------------------------------- +// Wait for all block moves to complete +// +void NDMA_wait_for_completion(uint32_t thread_num) +{ + if ( !NDMA_table_ptr_start[thread_num] ) { // there are no table entries + return; + } + + while ( (NDMA_Rd(SEC_NDMA_TABLE_ADD_REG) & (0xFF << (thread_num*8))) ) { } +} + +void NDMA_stop(uint32_t thread_num) +{ + NDMA_Wr(NDMA_THREAD_REG,NDMA_Rd(NDMA_THREAD_REG) & ~(1 << (thread_num + 8)) ); + // If no threads enabled, then shut down the DMA engine completely + if ( !(NDMA_Rd(NDMA_THREAD_REG) & (0xF << 8)) ) { + NDMA_Wr(NDMA_CNTL_REG0,NDMA_Rd(NDMA_CNTL_REG0) & ~(1 << NDMA_ENABLE) ); + } +} +// -------------------------------------------- +// NDMA_add_descriptor_aes +// -------------------------------------------- +// Simple add function for AES +void NDMA_add_descriptor_aes( +uint32_t thread_num, +uint32_t irq, +uint32_t cbc_enable, +uint32_t cbc_reset, +uint32_t encrypt, // 0 = decrypt, 1 = encrypt +uint32_t aes_type, // 00 = 128, 01 = 192, 10 = 256 +uint32_t pre_endian, +uint32_t post_endian, +uint32_t bytes_to_move, +uint32_t src_addr, +uint32_t dest_addr, +uint32_t ctr_endian, +uint32_t ctr_limit ) +{ + volatile uint32_t *p = (volatile uint32_t *)(unsigned long)NDMA_table_ptr_curr[thread_num]; + (*p++) = (0x01 << 30) | // owned by CPU + (0 << 27) | + (0 << 26) | + (0 << 25) | + (4 << 22) | // AES + (irq << 21)| (1<<8); + (*p++) = src_addr; + (*p++) = dest_addr; + (*p++) = bytes_to_move & 0x01FFFFFF; + (*p++) = 0x00000000; // no skip + (*p++) = 0x00000000; // no skip + // Prepare the pointer for the next descriptor boundary + // inline processing + bytes to move extension + (*p++) = + (ctr_endian << 16) | + (ctr_limit << 14) | + (cbc_enable << 12) | + (cbc_reset << 11) | + (encrypt << 10) | + (aes_type << 8) | + (post_endian << 4) | + (pre_endian << 0); + + #if 0 + _clean_dcache_addr(NDMA_table_ptr_curr[thread_num]); + _clean_invd_dcache_addr (NDMA_table_ptr_curr[thread_num]); + _clean_dcache_addr(NDMA_table_ptr_curr[thread_num]+32); + _clean_invd_dcache_addr (NDMA_table_ptr_curr[thread_num]+32); + #endif + + if ( NDMA_table_ptr_curr[thread_num] == NDMA_table_ptr_end[thread_num] ) { + NDMA_table_ptr_curr[thread_num] = NDMA_table_ptr_start[thread_num]; + } else { + NDMA_table_ptr_curr[thread_num] += 32; // point to the next location (8-4 byte table entries) + } + NDMA_Wr( NDMA_TABLE_ADD_REG, (thread_num << 8) | (1 << 0) ); +} + +// -------------------------------------------- +// NDMA_add_descriptor_sha +// -------------------------------------------- +// Simple add function for SHA +void NDMA_add_descriptor_sha( +uint32_t thread_num, +uint32_t irq, +uint32_t sha_mode, // 1:sha1;2:sha2-256;3:sha2_224 +uint32_t pre_endian, +uint32_t bytes_to_move, +uint32_t src_addr, +uint32_t last_block ) +{ + volatile uint32_t *p = (volatile uint32_t *)(unsigned long)NDMA_table_ptr_curr[thread_num]; + (*p++) = (0x01 << 30) | // owned by CPU + (0 << 27) | + (0 << 26) | + (0 << 25) | + (5 << 22) | // SHA + (irq << 21) ; + (*p++) = src_addr; + (*p++) = 0x00000000; + (*p++) = bytes_to_move & 0x01FFFFFF; + (*p++) = 0x00000000; // no skip + (*p++) = 0x00000000; // no skip + // Prepare the pointer for the next descriptor boundary + // inline processing + bytes to move extension + (*p++) = (sha_mode << 8) | + (last_block << 4) | + (pre_endian << 0); + + #if 0 + _clean_dcache_addr(NDMA_table_ptr_curr[thread_num]); + _clean_invd_dcache_addr (NDMA_table_ptr_curr[thread_num]); + _clean_dcache_addr(NDMA_table_ptr_curr[thread_num]+32); + _clean_invd_dcache_addr (NDMA_table_ptr_curr[thread_num]+32); + #endif + + if ( NDMA_table_ptr_curr[thread_num] == NDMA_table_ptr_end[thread_num] ) { + NDMA_table_ptr_curr[thread_num] = NDMA_table_ptr_start[thread_num]; + } else { + NDMA_table_ptr_curr[thread_num] += 32; // point to the next location (8-4 byte table entries) + } + NDMA_Wr( SEC_NDMA_TABLE_ADD_REG, (thread_num << 8) | (1 << 0) ); +} + diff --git a/plat/gxb/crypto/rsa.c b/plat/gxb/crypto/rsa.c new file mode 100644 index 0000000..988dec3 --- /dev/null +++ b/plat/gxb/crypto/rsa.c @@ -0,0 +1,240 @@ +/* + * The RSA public-key cryptosystem + * + * Copyright (C) 2006-2011, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman. + * + * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf + * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf + */ + +#include <rsa_config.h> +#include <string.h> + +#if defined(POLARSSL_RSA_C) + +#include <rsa.h> + +#include <stdio.h> + +/* + * Initialize an RSA context + */ + +extern void mymallocreset(); + +void rsa_init( rsa_context *ctx, + int padding, + int hash_id ) +{ + memset( ctx, 0, sizeof( rsa_context ) ); + + ctx->padding = padding; + ctx->hash_id = hash_id; + + mymallocreset(); +} + +/* + * Do an RSA public key operation + */ +int rsa_public( rsa_context *ctx, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + size_t olen; + mpi T; + mpi_init( &T ); + MPI_CHK( mpi_read_binary( &T, input, ctx->len ) ); + + if ( mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) + { + mpi_free( &T ); + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + olen = ctx->len; + MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) ); + MPI_CHK( mpi_write_binary( &T, output, olen ) ); + +cleanup: + + mpi_free( &T ); + + if ( ret != 0 ) + return( POLARSSL_ERR_RSA_PUBLIC_FAILED + ret ); + return( 0 ); +} + +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function + */ +int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx, + int mode, + int hash_id, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + int ret; + size_t len, siglen; + unsigned char *p, c; + unsigned char buf[POLARSSL_MPI_MAX_SIZE]; + + if ( ctx->padding != RSA_PKCS_V15 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + siglen = ctx->len; + + if ( siglen < 16 || siglen > sizeof( buf ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + +#ifdef CONFIG_EMU_BUILD + ret = ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, sig, buf ) + : rsa_private( ctx, sig, buf ); +#else + if (mode != RSA_PUBLIC) + return ( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + ret = rsa_public( ctx, sig, buf ); +#endif /* CONFIG_EMU_BUILD */ + + if ( ret != 0 ) + return( ret ); + + p = buf; + + if ( *p++ != 0 || *p++ != RSA_SIGN ) + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + + while ( *p != 0 ) + { + if ( p >= buf + siglen - 1 || *p != 0xFF ) + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + p++; + } + p++; + + len = siglen - ( p - buf ); + + if ( len == 33 && hash_id == SIG_RSA_SHA1 ) + { + if ( memcmp( p, ASN1_HASH_SHA1_ALT, 13 ) == 0 && + memcmp( p + 13, hash, 20 ) == 0 ) + return( 0 ); + else + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + } + if ( len == 34 ) + { + c = p[13]; + p[13] = 0; + + if ( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if ( ( c == 2 && hash_id == SIG_RSA_MD2 ) || + ( c == 4 && hash_id == SIG_RSA_MD4 ) || + ( c == 5 && hash_id == SIG_RSA_MD5 ) ) + { + if ( memcmp( p + 18, hash, 16 ) == 0 ) + return( 0 ); + else + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + } + } + + if ( len == 35 && hash_id == SIG_RSA_SHA1 ) + { + if ( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 && + memcmp( p + 15, hash, 20 ) == 0 ) + return( 0 ); + else + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + } + if ( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) || + ( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) || + ( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) || + ( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) ) + { + c = p[1] - 17; + p[1] = 17; + p[14] = 0; + + if( p[18] == c && + memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 && + memcmp( p + 19, hash, c ) == 0 ) + return( 0 ); + else + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + } + + if ( len == hashlen && hash_id == SIG_RSA_RAW ) + { + if ( memcmp( p, hash, hashlen ) == 0 ) + return( 0 ); + else + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + } + + return( POLARSSL_ERR_RSA_INVALID_PADDING ); +} + +/* + * Do an RSA operation and check the message digest + */ +int rsa_pkcs1_verify( rsa_context *ctx, + int mode, + int hash_id, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + int ret; + switch ( ctx->padding ) + { + case RSA_PKCS_V15: + ret = rsa_rsassa_pkcs1_v15_verify( ctx, mode, hash_id, + hashlen, hash, sig ); + break; + default: + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } + + return ret; +} + +/* + * Free the components of an RSA key + */ +void rsa_free( rsa_context *ctx ) +{ + mpi_free( &ctx->RQ ); mpi_free( &ctx->RP ); mpi_free( &ctx->RN ); + mpi_free( &ctx->QP ); mpi_free( &ctx->DQ ); mpi_free( &ctx->DP ); + mpi_free( &ctx->Q ); mpi_free( &ctx->P ); mpi_free( &ctx->D ); + mpi_free( &ctx->E ); mpi_free( &ctx->N ); +} + +#endif diff --git a/plat/gxb/crypto/secureboot.c b/plat/gxb/crypto/secureboot.c new file mode 100644 index 0000000..fc36dd7 --- /dev/null +++ b/plat/gxb/crypto/secureboot.c @@ -0,0 +1,749 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/common/plat/gxb/crypto/secureboot.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +//for polarssl RSA +#include <rsa.h> +#include <string.h> +#include <stdio.h> +#include <sha2.h> +#include <asm/arch/secure_apb.h> +#include <arch_helpers.h> + +#include <ndma_utils.h> + +//#define AML_DEBUG_SHOW + +#if defined(AML_DEBUG_SHOW) + #define aml_printf printf +#else + #define aml_printf(...) +#endif + +////////////////////////////////////////////////////////////////////////////////////// +//following code will be used for romcode +//only signature check +// +////////////////////////////////////////////////////////////////////////////////////// +//following code will be used for romcode +//only signature check +//copy from here... +//return 0 for success, others for fail + +///////////////////////////////////////////////////////////////////////////////////////// +//amlogic secure boot solution +typedef enum{ + AML_SIG_TYPE_NONE=0, + AML_SIG_TYPE_RSA_PKCS_V15, + AML_SIG_TYPE_RSA_PKCS_V21, //?? + AML_SIG_TYPE_RSA_PKCS_V15_AES, +}e_aml_sig_type; + +typedef enum{ + AML_DATA_TYPE_NONE=0, + AML_DATA_TYPE_RSA_KEY, + AML_DATA_TYPE_AES_KEY, + AML_DATA_TYPE_PROGRAM_GO, //need this? + AML_DATA_TYPE_PROGRAM_CALL, //need this? +}e_aml_data_type; + + +#define AML_BLK_ID (0x4C4D4140) +#define AML_BLK_VER_MJR (1) +#define AML_BLK_VER_MIN (0) + + +typedef struct __st_aml_block_header{ + //16 + unsigned int dwMagic; //"@AML" + unsigned int nTotalSize; //total size: sizeof(hdr)+ + // nSigLen + nDataLen + unsigned char bySizeHdr; //sizeof(st_aml_block) + unsigned char byRootKeyIndex;//root key index; only romcode + // will use it, others just skip + unsigned char byVerMajor; //major version + unsigned char byVerMinor; //minor version + + unsigned char szPadding1[4]; //padding??? + + //16+16 + unsigned int nSigType; //e_aml_sig_type : AML_SIG_TYPE_NONE... + unsigned int nSigOffset; //sig data offset, include header + unsigned int nSigLen; //sig data length + //unsigned char szPadding2[4]; //padding??? + unsigned int nCHKStart; //begin to be protected with SHA2 + + //32+16 + unsigned int nPUKType; //e_aml_data_type : AML_DATA_TYPE_PROGRAM + unsigned int nPUKOffset; //raw data offset, include header + unsigned int nPUKDataLen; //raw data length + //unsigned char szPadding4[4]; //padding??? + unsigned int nCHKSize; //size to be protected with SHA2 + + //48+16 + unsigned int nDataType; //e_aml_data_type : AML_DATA_TYPE_PROGRAM + unsigned int nDataOffset; //raw data offset, include header + unsigned int nDataLen; //raw data length + unsigned char szPadding3[4]; //padding??? + + //64 +} st_aml_block_header; + +typedef enum{ + AML_ITEM_TYPE_NONE=0, + AML_ITEM_TYPE_RAW_RSA_N, + AML_ITEM_TYPE_RAW_RSA_E, + AML_ITEM_TYPE_RAW_RSA_D, +}e_aml_big_num_type; + + +typedef struct __stBigNumber{ + //8 + unsigned short nBigNMType; //e_aml_big_num_type + unsigned short nOffset; //offset for each data, after HDR + unsigned short nSize; //size of raw data + unsigned char szReserved[2]; //for future ? padding + //unsigned char szSHA2Item[32];//SHA2 of raw data ?? need this ?? + //8 +}st_BIG_NUMBER; + +typedef struct __stBigNumberStore{ + //8 + unsigned short nBigNMType; //e_aml_big_num_type + unsigned short nOffset; //offset for each data, after HDR + unsigned short nSize; //size of raw data + unsigned char szReserved[2]; //for future ? padding + unsigned char pBuffer[1024]; + //unsigned char szSHA2Item[32];//SHA2 of raw data ?? need this ?? + //8 +}st_BIG_NUMBER_store; + +typedef enum{ + AML_RSA_TYPE_NONE=0, + AML_RSA_TYPE_1024, + AML_RSA_TYPE_2048, + AML_RSA_TYPE_4096, + AML_RSA_TYPE_8192, + AML_RSA_TYPE_1024_SHA2, + AML_RSA_TYPE_2048_SHA2, + AML_RSA_TYPE_4096_SHA2, + AML_RSA_TYPE_8192_SHA2, + +}e_aml_rsa_type_t; + +typedef struct __stItemHeader{ + //4 + unsigned char byCount; //amount + unsigned char byUnitSize; //sizeof(st_BIG_NUMBER) + unsigned char szPad1[2]; //padding + + //4+12 + unsigned short nItemsOffset; //arrBNM[] + unsigned short nItemTotalSize; //(byCount X byUnitSize) + unsigned short nRAWOffset; //arrBNM[] + unsigned short nRAWSize; //sum(arrBNM[byCount].nSize) + unsigned char szPad2[4]; //padding + //16 +}st_ITEM_HDR; + +/* +typedef struct __stItemHeader{ + st_ITEM_HDR header; + //...... + //...... + st_BIG_NUMBER arrBNM[]; +}st_ITEM; +*/ + +#define AML_KEY_ID (0x59454B40) +#define AML_KEY_VER (1) + +#define AML_KEY_RSA1024 (0x41533152) +#define AML_KEY_RSA2048 (0x41533252) +#define AML_KEY_RSA4096 (0x41533452) +#define AML_KEY_RSA8192 (0x41533852) + +#define AML_KEY_RSA1024_SHA (0x41483152) +#define AML_KEY_RSA2048_SHA (0x41483252) +#define AML_KEY_RSA4096_SHA (0x41483452) +#define AML_KEY_RSA8192_SHA (0x41483852) + +typedef struct __stKeyHeader{ + //16 + unsigned int dwMagic; //"@KEY" 0x59454B40 + unsigned int nTotalSize; //total size + unsigned char byVersion; //version + unsigned char byKeyType; //e_aml_rsa_type_t + unsigned char byHeadSize; //sizeof(st_KEY_HDR) + unsigned char szPad1[1]; //padding + unsigned int dwTypeInfo; // + + //16+32 + union{ + unsigned char szKeySHA2[32]; + st_ITEM_HDR itemHdr; + }un; + + //48 +}st_KEY_HDR; + +#define AML_KEY_MATRIX_ID (0x584D4B40) +#define AML_KEY_MATRIX_VER (1) +#define AML_KEY_MAX_KEY_NUM (4) + +typedef struct __stKeyMaxHeader{ + //8 + unsigned int dwMagic; //"@KMX" 0x584D4B40 + unsigned char byVersion; //version + unsigned char szPad1; //padding + unsigned short nHeadSize; //sizeof(st_KEY_MAX_HDR) + + //8+8 + unsigned int nTotalSize; //nHeadSize + (byCount x byUnitSize) + // + sum(arrKeyHdr[byCount].itemHdr.nItemTotalSize) + unsigned char byCount; //key amount + unsigned char byUnitSize; //sizeof(st_KEY_HDR) + unsigned char szPad2[2]; //padding + + //16 +}st_KEY_MAX_HDR; + +//---------------------------------------------- +typedef struct __stKeyMax{ + st_KEY_MAX_HDR header; + st_KEY_HDR arrKeyHdr[4]; +}st_KEY_MAX; + + +#if defined(AML_DEBUG_SHOW) +void aml_u8_printf( unsigned char *p, int size ) +{ + int i; + for (i=0; i<size; i++) + printf("%02X%s", p[i], ((i+1) % 16==0) ? "\n" :" "); +} +#endif + +#if defined(CONFIG_AML_SECURE_UBOOT) +static int aml_key_match_check_tpl(unsigned char szKeySHA2[32]) +{ + int nReturn = -1; + int i = 0; + volatile st_KEY_MAX *pKeyMax = (volatile st_KEY_MAX *)(0xd9000808); + for (i = 0;i<pKeyMax->header.byCount;++i) + { + if (!memcmp(szKeySHA2,(void *)pKeyMax->arrKeyHdr[i].un.szKeySHA2,32)) + { + nReturn = 0; + break; + } + } + + return nReturn; +} +int aml_load_rsa_puk(rsa_context *prsa_ctx, + unsigned char *pBlock,unsigned char szSHA2[32]) +{ + int nRet = -1; + st_aml_block_header *pblkHdr = (st_aml_block_header *)pBlock; + st_KEY_HDR * pkeyHdr = (st_KEY_HDR *)(pBlock + pblkHdr->nPUKOffset); + st_ITEM_HDR * pHdr = (st_ITEM_HDR*)&pkeyHdr->un.itemHdr; + st_BIG_NUMBER *pBGN = (st_BIG_NUMBER *)(pBlock + pHdr->nItemsOffset); + unsigned char *pRAW = (unsigned char *)(pBlock + pHdr->nRAWOffset); + mpi *pMPI = 0; + int i =0; + + if (!prsa_ctx || !pBlock ) + goto exit; + + //following is just for this verison pollarssl code + //just disable them if use the standard copy + //begin + //extern int g_nMX_RSA_keyFormat; + //g_nMX_RSA_keyFormat = 1; + //end + + pblkHdr = (st_aml_block_header *)pBlock; + pkeyHdr = (st_KEY_HDR *)(pBlock + pblkHdr->nPUKOffset); + pHdr = (st_ITEM_HDR*)&pkeyHdr->un.itemHdr; + pBGN = (st_BIG_NUMBER *)(pBlock + pHdr->nItemsOffset); + pRAW = (unsigned char *)(pBlock + pHdr->nRAWOffset); + + + sha2(pRAW,pHdr->nRAWSize,szSHA2,0); + + //u8_printf(pBGN,32); + //u8_printf(pRAW,32); + + for ( i = 0;i< pHdr->byCount;++i) + { + switch (pBGN->nBigNMType) + { + case AML_ITEM_TYPE_RAW_RSA_N: pMPI = &prsa_ctx->N; break; + case AML_ITEM_TYPE_RAW_RSA_E: pMPI = &prsa_ctx->E; break; + case AML_ITEM_TYPE_RAW_RSA_D: pMPI = &prsa_ctx->D; break; + default: pMPI = 0; break; + } + + if (!pMPI) + while (1) ; + + mpi_read_binary(pMPI,pRAW,pBGN->nSize); + + pRAW += pBGN->nSize; + pBGN += 1; + } + + prsa_ctx->len = ( mpi_msb( &prsa_ctx->N ) + 7 ) >> 3; + + switch (prsa_ctx->len) + { + case 0x80: //R1024 + case 0x100: //R2048 + case 0x200: nRet = 0;break; //R4096 + } + +exit: + + return nRet; +} +#endif //CONFIG_AML_SECURE_UBOOT + +///////////////////////////////////////////////////////////////////////// +/** + * pBuffer : st_aml_block_header + signature data + st_aml_block_header(mirror) + [PUK] + raw data + * 1. st_aml_block_header will have offset, length, type for signature data, PUK and raw data + * 2. signature data is a PKCS #1 v1.5 RSA signature of SHA256 (st_aml_block_header(mirror) + [PUK] + raw data) + * signed with the PUK's corresponding private key. + * 3. st_aml_block_header(mirror) is a mirror copy of st_aml_block_header for data consistency + * 4. PUK is a RSA Public Key to be used for signature check (PKCSv15 format) + * 5. raw data: has two types for romcode + * 5.1 1st stage: two keymax : the first is for 4 root key SHA256 and the second is for 4 user key SHA256 + * 5.2 2nd stage: BL2 raw data + * pKeyMax : 4 SHA256 hashes of the keys (N+E) + * 1. for 1st stage: pKeyMax is 0 for the root keymax and user keymax check + * 2. for 2nd stage: pKeyMax is the user keymax to verify the PUK for BL2 signature + * pEntry : offset for BL2 start + * + * return 0 for success and pEntry is the BL2 start address and all others value for check fail +*/ +int aml_sig_check_buffer(unsigned long pBuffer,unsigned int *pEntry) +{ + + int nReturn = __LINE__; +#if defined(CONFIG_AML_SECURE_UBOOT) + rsa_context rsa_ctx; + unsigned char szPUKSHA2[32]; + unsigned char *pSig; +#endif + + int nTick; + +//#define AML_SECURE_LOG_TE 1 + +#if defined(AML_SECURE_LOG_TE) + #define AML_GET_TE(a) do{a = *((volatile unsigned int*)0xc1109988);}while(0); + unsigned nT1,nT2; +#else + #define AML_GET_TE(...) +#endif + + unsigned char *pData=0; + st_aml_block_header * pBlkHdr = 0; + int nBL3XSigFlag = 0; + unsigned char szSHA2[32]; + unsigned char *szAMLBLK= (unsigned char *)(unsigned long)(0x10800000); + sha2_ctx sha_ctx; + pBlkHdr = (st_aml_block_header *)pBuffer; + + aml_printf("aml log : Ln = %d\n",__LINE__); + + if (AML_BLK_ID != pBlkHdr->dwMagic) + goto exit; + + if (AML_BLK_VER_MJR != pBlkHdr->byVerMajor) + goto exit; + if (AML_BLK_VER_MIN != pBlkHdr->byVerMinor) + goto exit; + + if (sizeof(st_aml_block_header) != pBlkHdr->bySizeHdr) + goto exit; + + //more check + if (sizeof(st_aml_block_header) != pBlkHdr->nSigOffset) + goto exit; + + aml_printf("aml log : Ln = %d\n",__LINE__); + + nReturn = __LINE__; + +#if defined(CONFIG_AML_SECURE_UBOOT) + //RSA key load + rsa_init( &rsa_ctx, RSA_PKCS_V15, 0 ); +#endif //CONFIG_AML_SECURE_UBOOT + + switch (pBlkHdr->nSigType) + { +#if defined(CONFIG_AML_SECURE_UBOOT) + case AML_RSA_TYPE_1024: + case AML_RSA_TYPE_2048: + case AML_RSA_TYPE_4096: + { + switch (pBlkHdr->nSigLen) + { + case 0x80: //R1024 + case 0x100: //R2048 + case 0x200: //R4096 + { + nBL3XSigFlag = 1; + if (aml_load_rsa_puk(&rsa_ctx,(unsigned char *)pBuffer,szPUKSHA2)) + goto exit; + + aml_printf("aml log : PUK is RSA%d\n",(rsa_ctx.len<<3)); + + }break;//R4096 + default: goto exit; + } + }break; +#endif //CONFIG_AML_SECURE_UBOOT + case AML_RSA_TYPE_NONE:break; + default: goto exit; + } + + aml_printf("aml log : Ln = %d\n",__LINE__); + + nReturn = __LINE__; + //check chip is secure enabled or not + //if enabled just fail for next boot device + //if(aml_check_secure_set_match(nBL3XSigFlag)) + // goto exit; + + nTick = 64 - (pBlkHdr->nPUKDataLen & (63)); + //backup header + memcpy((void*)szAMLBLK,(void*)pBuffer,pBlkHdr->nDataOffset); + pBlkHdr = (st_aml_block_header *)szAMLBLK; + + flush_dcache_range((unsigned long )szAMLBLK, pBlkHdr->nDataOffset); + + //move original + memcpy((void*)pBuffer,(void *)(pBuffer + pBlkHdr->nDataLen),pBlkHdr->nDataOffset); + + flush_dcache_range((unsigned long )pBuffer, pBlkHdr->nDataOffset); + + memcpy((void*)(szAMLBLK+pBlkHdr->nDataOffset),(void*)pBuffer,nTick); + flush_dcache_range((unsigned long )(szAMLBLK+pBlkHdr->nDataOffset), nTick); + + aml_printf("aml log : Ln = %d\n",__LINE__); + + pData =(unsigned char *)(szAMLBLK + pBlkHdr->nCHKStart); + +#if defined(CONFIG_AML_SECURE_UBOOT) + pSig = (unsigned char *)(szAMLBLK + pBlkHdr->nSigOffset); +#endif //#if defined(CONFIG_AML_SECURE_UBOOT) + + AML_GET_TE(nT1); + + SHA2_init( &sha_ctx, 256); + //hash header + SHA2_update( &sha_ctx, szAMLBLK, pBlkHdr->bySizeHdr); + //skip signature + //hash PUK + SHA2_update( &sha_ctx, pData, pBlkHdr->nPUKDataLen+nTick); + SHA2_final( &sha_ctx, (unsigned char *)(pBuffer+nTick), pBlkHdr->nDataLen-nTick); + AML_GET_TE(nT2); + + //flush_dcache_range((unsigned long )sha_ctx.buf,32); + +#if defined(AML_SECURE_LOG_TE) + printf("aml log : SHA %d (bytes) used %d(us)\n",pBlkHdr->nDataLen+ pBlkHdr->nPUKDataLen +pBlkHdr->bySizeHdr, + nT2 - nT1); +#endif + + memcpy(szSHA2,sha_ctx.buf,32); + + flush_dcache_range((unsigned long )szSHA2,32); + +#if defined(AML_DEBUG_SHOW) + aml_printf("\naml log : dump cal SHA2 :\n"); + aml_u8_printf((unsigned char *)szSHA2,32); +#endif + + if (!nBL3XSigFlag) + { + aml_printf("aml log : normal check Ln = %d\n",__LINE__); + nReturn = memcmp((const void*)szSHA2, + (const void*)(szAMLBLK+pBlkHdr->nSigOffset),sizeof(szSHA2)); + +#if defined(AML_DEBUG_SHOW) + aml_printf("\naml log : dump org SHA :\n"); + aml_u8_printf((unsigned char *)(szAMLBLK+pBlkHdr->nSigOffset),32); +#endif + //if(!nReturn && pEntry) + // *pEntry = 0; + //else + if (nReturn) + nReturn = __LINE__; + + goto exit; + } + +#if defined(CONFIG_AML_SECURE_UBOOT) + //verify PUK is valid or not + if (aml_key_match_check_tpl(szPUKSHA2)) + { + //error + aml_printf("aml log: PUK is not a valid key!\n"); + nReturn = __LINE__; + goto exit; + } + + nReturn = rsa_pkcs1_verify( &rsa_ctx, RSA_PUBLIC, SIG_RSA_SHA256,32, szSHA2, pSig ); + + if (nReturn) + { + aml_printf("aml log : Sig check fail! Return = %d\n",nReturn); + nReturn = __LINE__; + goto exit; + } + else + { + aml_printf("aml log : Sig check pass!\n"); + + if (pEntry) + *pEntry = 0; + + } + + //printf("aml log : RSA-%d check %s!\n",rsa_ctx.len<<3, nReturn ? "fail": "pass"); + serial_puts("aml log : RSA-"); + serial_put_dec(rsa_ctx.len<<3); + serial_puts(" check "); + serial_puts(nReturn ? "fail": "pass"); + serial_puts("!\n"); +#endif //CONFIG_AML_SECURE_UBOOT + +exit: + + return nReturn; +} + +#if defined(CONFIG_AML_SECURE_UBOOT) + +//#define CONFIG_AML_HW_AES_PIO + +#if defined(CONFIG_AML_HW_AES_PIO) +void aes_setkey( const uint8_t *key) +{ + uint32_t i; + uint32_t *key32 = (uint32_t *)key; + + // select aes + clrbits_le32(SEC_SEC_BLKMV_GEN_REG0, (3<<12)); + + // setup aes 256 cbc decrypto pio + writel((2<<18) | (1<<16), SEC_SEC_BLKMV_AES_REG0); + + // aes=4, request pio and wait for grant. + writel((1<<4) | 4, SEC_SEC_BLKMV_PIO_CNTL0); + while (((readl(SEC_SEC_BLKMV_PIO_CNTL0) >> 31) & 1) == 0); + + // Write the Key + for (i=0; i<8; i++) { + writel(key32[i], SEC_SEC_BLKMV_PIO_DATA0 + i*4); + } + + //set IV + for (i=0; i<4; i++) writel(0, SEC_SEC_BLKMV_PIO_DATA8 + i*4); + + // load iv + setbits_le32(SEC_SEC_BLKMV_AES_REG0, (1<<1)); + +} + +/** + * Perform AES 256 CBC decryption + * cpt: array of 16 bytes of cipher text and plain text output + */ +void aes_cbc_decrypt(uint32_t *cpt) +{ + uint32_t i; + + for (i=0; i<4; i++) writel(cpt[i], SEC_SEC_BLKMV_AES_PIO_W0 + i*4); + + // Wait for the AES process to complete + while ((readl(SEC_NDMA_CNTL_REG0) >> 12) & 1) ; + + for (i=0; i<4; i++) cpt[i] = readl(SEC_SEC_BLKMV_PIO_DATA0 + i*4); +} +#else +//HW AES DMA +#define AES_Wr(addr, data) *(volatile uint32_t *)(addr)=(data) +#define AES_Rd(addr) *(volatile uint32_t *)(addr) +#define THREAD0_TABLE_LOC 0x5500000 +int g_n_aes_thread_num = 0; +void aes_setkey( const uint8_t *key) +{ + uint32_t *key32 = (uint32_t *)key; + + g_n_aes_thread_num = 0; //fixed thread number to 0 + + AES_Wr( SEC_SEC_BLKMV_PIO_CNTL0, (AES_Rd(SEC_SEC_BLKMV_PIO_CNTL0)| (5<<0)) ); + + AES_Wr(SEC_SEC_BLKMV_GEN_REG0, ((AES_Rd(SEC_SEC_BLKMV_GEN_REG0) & ~(0xf << 8)) | (0xf << 8)) ); + AES_Wr(SEC_SEC_BLKMV_GEN_REG0, ((AES_Rd(SEC_SEC_BLKMV_GEN_REG0) & ~(0xf << 0)) | (0 << 0)) ); + + AES_Wr(SEC_SEC_BLKMV_GEN_REG0, ((AES_Rd(SEC_SEC_BLKMV_GEN_REG0) & ~(0xf << 4)) | (0x0<< 4)) ); // only thread 2 can issue Secure transfers + + AES_Wr( SEC_SEC_BLKMV_AES_REG0, (AES_Rd(SEC_SEC_BLKMV_AES_REG0) & ~(0x1 << 3)) ); + AES_Wr( NDMA_AES_REG0, (AES_Rd(NDMA_AES_REG0) & ~(0x3 << 8)) | (g_n_aes_thread_num << 8) ); + + //key + AES_Wr( NDMA_AES_KEY_0, (key32[0]) ); + AES_Wr( NDMA_AES_KEY_1, (key32[1]) ); + AES_Wr( NDMA_AES_KEY_2, (key32[2]) ); + AES_Wr( NDMA_AES_KEY_3, (key32[3]) ); + AES_Wr( NDMA_AES_KEY_4, (key32[4]) ); + AES_Wr( NDMA_AES_KEY_5, (key32[5]) ); + AES_Wr( NDMA_AES_KEY_6, (key32[6]) ); + AES_Wr( NDMA_AES_KEY_7, (key32[7]) ); + + //set IV + AES_Wr( NDMA_AES_IV_0, 0); + AES_Wr( NDMA_AES_IV_1, 0); + AES_Wr( NDMA_AES_IV_2, 0); + AES_Wr( NDMA_AES_IV_3, 0); + + NDMA_set_table_position_secure( g_n_aes_thread_num, THREAD0_TABLE_LOC, THREAD0_TABLE_LOC + (10*32) ); // 2 thread entries + +} + +void aes_cbc_decrypt(uint32_t *ct,uint32_t *pt,int nLen) +{ + NDMA_add_descriptor_aes( g_n_aes_thread_num, // uint32_t thread_num, + 1, // uint32_t irq, + 1, // uint32_t cbc_enable, + 1, // uint32_t cbc_reset, + 0, // uint32_t encrypt, // 0 = decrypt, 1 = encrypt + 2, // uint32_t aes_type, // 00 = 128, 01 = 192, 10 = 256 + 0, // uint32_t pre_endian, + 0, // uint32_t post_endian, + nLen, // uint32_t bytes_to_move, + (unsigned int)(long)ct, // uint32_t src_addr, + (unsigned int)(long)pt, // uint32_t dest_addr ) + 0xf, // uint32_t ctr_endian, + 0 ); // uint32_t ctr_limit ) + NDMA_start(g_n_aes_thread_num); + + NDMA_wait_for_completion(g_n_aes_thread_num); + + NDMA_stop(g_n_aes_thread_num); + +} + +#endif +#endif //CONFIG_AML_SECURE_UBOOT + +int aml_data_check(unsigned long pBuffer,unsigned long pBufferDST,unsigned int nLength,unsigned int nAESFlag) +{ + +#define TOC_HEADER_NAME (0xAA640001) +#define TOC_HEADER_SERIAL_NUMBER (0x12345678) + +#if defined(CONFIG_AML_SECURE_UBOOT) + unsigned char szAESKey[32]; + #if defined(CONFIG_AML_HW_AES_PIO) + unsigned int *ct32; + int i = 0; + #endif + unsigned char *pDST= (unsigned char *)(pBufferDST); +#endif //CONFIG_AML_SECURE_UBOOT + +#if defined(AML_DEBUG_SHOW) + int nBegin,nEnd; +#endif + + unsigned int *pCHK = (unsigned int *)pBuffer; + +#if defined(AML_DEBUG_SHOW) + nBegin = *((volatile unsigned int*)0xc1109988); +#endif + + if (TOC_HEADER_NAME == *pCHK && TOC_HEADER_SERIAL_NUMBER == *(pCHK+1)) + { + return 0; + } + + +#if defined(CONFIG_AML_SECURE_UBOOT) + +#if defined(AML_DEBUG_SHOW) + aml_printf("aml log : begin dump buffer before AES nTPLAESFlag = %d:\n",nAESFlag); + aml_u8_printf((unsigned char *)pBuffer,32); +#endif + + if (nAESFlag) + { + + if (nAESFlag) + pCHK = (unsigned int*)pDST; + + sha2((unsigned char *)0xd9000000,16,szAESKey,0); + aes_setkey(szAESKey); + +#if defined(CONFIG_AML_HW_AES_PIO) + //HW AES PIO + ct32 = (unsigned int *)pBuffer; + + for (i=0; i<nLength/16; i++) + aes_cbc_decrypt(&ct32[i*4]); + + memcpy(pDST,(void*)pBuffer,nLength); +#else + //HW AES DMA + aes_cbc_decrypt((unsigned int *)pBuffer,(unsigned int *)pDST,nLength); +#endif + pBuffer = (unsigned long)pDST; + + flush_dcache_range((unsigned long )pDST, nLength); + +#if defined(AML_DEBUG_SHOW) + nEnd = *((volatile unsigned int*)0xc1109988); + aml_printf("aml log : begin dump buffer after AES nTPLAESFlag=%d len=%d time=%dus\n", + nAESFlag,nLength,nEnd - nBegin); + aml_u8_printf((unsigned char *)pBuffer,32); +#endif + if (TOC_HEADER_NAME == *pCHK && TOC_HEADER_SERIAL_NUMBER == *(pCHK+1)) + return 0; + } + +#if defined(AML_DEBUG_SHOW) + aml_printf("aml log : begin dump buffer after AES nTPLAESFlag = %d:\n",nAESFlag); + aml_u8_printf((unsigned char *)pBuffer,32); +#endif + +#endif //CONFIG_AML_SECURE_UBOOT + + return aml_sig_check_buffer(pBuffer,0); + +} + + +////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////// diff --git a/plat/gxb/ddr/ddr.c b/plat/gxb/ddr/ddr.c new file mode 100644 index 0000000..68438c6 --- /dev/null +++ b/plat/gxb/ddr/ddr.c @@ -0,0 +1,863 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/ddr/ddr.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <stdio.h> +#include "ddr_pctl_define.h" +#include "ddr_pub_define.h" +#include "dmc_define.h" +#include "mmc_define.h" +#include "sec_mmc_define.h" +#include <timer.h> +#include <asm/arch/ddr.h> +#include <asm/arch/secure_apb.h> +#include <pll.h> +#include <config.h> +#include <asm/arch/cpu.h> +#include <asm/arch/timing.h> +#include <memtest.h> +#include <asm/arch/watchdog.h> +#include <cache.h> +#include "timing.c" +#include "ddr_detect.c" + +static ddr_set_t * p_ddr_set = &__ddr_setting; +static ddr_timing_t * p_ddr_timing = NULL; +static unsigned int ddr0_enabled; +static unsigned int ddr1_enabled; + +unsigned int ddr_init(void){ + /*detect hot boot or cold boot*/ + //if(hot_boot()){ + // serial_puts("hot boot, skip ddr init!\n"); + // return 0; + //} + + ddr_init_pll(); + ddr_pre_init(); + ddr_init_pctl(); + ddr_init_dmc(); + ddr_print_info(); +#ifndef CONFIG_PXP_EMULATOR +//can not enable ddr test on pxp, for kernel and dtb already load in ddr +#ifdef CONFIG_SPL_DDR_DUMP + if (CONFIG_SPL_DDR_DUMP_FLAG != readl(P_PREG_STICKY_REG0)) { + ddr_test(); + } +#else + ddr_test(); +#endif +#endif + return 0; +} + +unsigned int ddr_init_pll(void){ + wr_reg(P_AM_ANALOG_TOP_REG1, rd_reg(P_AM_ANALOG_TOP_REG1) | (1<<0)); + wr_reg(P_HHI_MPLL_CNTL5, rd_reg(P_HHI_MPLL_CNTL5) | (1<<0)); + + /* DDR PLL BANDGAP */ + wr_reg(AM_DDR_PLL_CNTL4, rd_reg(AM_DDR_PLL_CNTL4) & (~(1<<12))); + wr_reg(AM_DDR_PLL_CNTL4, rd_reg(AM_DDR_PLL_CNTL4)|(1<<12)); + _udelay(10); + + /* set ddr pll reg */ + if ((p_ddr_set->ddr_clk >= CONFIG_DDR_CLK_LOW) && (p_ddr_set->ddr_clk < 750)) { + // OD N M + p_ddr_set->ddr_pll_ctrl = (2 << 16) | (1 << 9) | ((((p_ddr_set->ddr_clk/6)*6)/12) << 0); + } + else if((p_ddr_set->ddr_clk >= 750) && (p_ddr_set->ddr_clk < CONFIG_DDR_CLK_HIGH)) { + // OD N M + p_ddr_set->ddr_pll_ctrl = (1 << 16) | (1 << 9) | ((((p_ddr_set->ddr_clk/12)*12)/24) << 0); + } + + /* if enabled, change ddr pll setting */ +#ifdef CONFIG_CMD_DDR_TEST + serial_puts("STICKY_REG0: 0x"); + serial_put_hex(rd_reg(P_PREG_STICKY_REG0), 32); + serial_puts("\n"); + serial_puts("STICKY_REG1: 0x"); + serial_put_hex(rd_reg(P_PREG_STICKY_REG1), 32); + serial_puts("\n"); + if ((rd_reg(P_PREG_STICKY_REG0)>>20) == 0xf13) { + unsigned zqcr = rd_reg(P_PREG_STICKY_REG0) & 0xfffff; + if (0 == zqcr) + zqcr = p_ddr_set->t_pub_zq0pr; + serial_puts("ZQCR: 0x"); + serial_put_hex(p_ddr_set->t_pub_zq0pr, 32); + serial_puts(" -> 0x"); + serial_put_hex(zqcr, 32); + serial_puts("\n"); + p_ddr_set->t_pub_zq0pr = zqcr; + p_ddr_set->t_pub_zq1pr = zqcr; + p_ddr_set->t_pub_zq2pr = zqcr; + p_ddr_set->t_pub_zq3pr = zqcr; + serial_puts("PLL : 0x"); + serial_put_hex(p_ddr_set->ddr_pll_ctrl, 32); + serial_puts(" -> 0x"); + serial_put_hex(rd_reg(P_PREG_STICKY_REG1), 32); + serial_puts("\n"); + p_ddr_set->ddr_pll_ctrl = rd_reg(P_PREG_STICKY_REG1); + wr_reg(P_PREG_STICKY_REG0,0); + wr_reg(P_PREG_STICKY_REG1,0); + } +#endif + + /* ddr pll init */ + do { + //wr_reg(AM_DDR_PLL_CNTL1, 0x1); + wr_reg(AM_DDR_PLL_CNTL, (1<<29)); + wr_reg(AM_DDR_PLL_CNTL1, CFG_DDR_PLL_CNTL_1); + wr_reg(AM_DDR_PLL_CNTL2, CFG_DDR_PLL_CNTL_2); + wr_reg(AM_DDR_PLL_CNTL3, CFG_DDR_PLL_CNTL_3); + wr_reg(AM_DDR_PLL_CNTL4, CFG_DDR_PLL_CNTL_4); + wr_reg(AM_DDR_PLL_CNTL, ((1<<29) | (p_ddr_set->ddr_pll_ctrl))); + wr_reg(AM_DDR_PLL_CNTL, rd_reg(AM_DDR_PLL_CNTL)&(~(1<<29))); + _udelay(200); + }while(pll_lock_check(AM_DDR_PLL_CNTL, "DDR PLL")); + + /* Enable the DDR DLL clock input from PLL */ + wr_reg(DDR_CLK_CNTL, 0xb0000000); + wr_reg(DDR_CLK_CNTL, 0xb0000000); + + /* update ddr_clk */ + unsigned int ddr_pll = rd_reg(AM_DDR_PLL_CNTL)&(~(1<<29)); + unsigned int ddr_clk = 2*(((24 * (ddr_pll&0x1ff))/((ddr_pll>>9)&0x1f))>>((ddr_pll>>16)&0x3)); + p_ddr_set->ddr_clk = ddr_clk; + + return 0; +} + +void ddr_print_info(void){ + if (p_ddr_set->ddr_size_detect) + ddr_size_detect(p_ddr_set); + + unsigned int dmc_reg = rd_reg(DMC_DDR_CTRL); + unsigned char ddr_2t_mode = 0; + unsigned char ddr_chl = DDR_USE_2_CHANNEL(p_ddr_set->ddr_channel_set); + + /* 0:1t, 1:2t, 2:f2t(force) */ + ddr_2t_mode = ((rd_reg(DDR0_PCTL_MCFG) >> 3) & 0x1); + if (p_ddr_set->ddr_channel_set == CONFIG_DDR01_SHARE_AC) + ddr_2t_mode = 2; + + for (int i=0; i<=ddr_chl; i++) { + /* ddr info */ + serial_puts("DDR"); + serial_put_dec(i); + serial_puts(": "); + serial_put_dec(1 << (((dmc_reg>>(3*i)) & 0x7)+7)); + serial_puts("MB"); + if (p_ddr_set->ddr_size_detect) + serial_puts("(auto)"); + serial_puts(" @ "); + serial_put_dec(p_ddr_set->ddr_clk); + serial_puts("MHz("); + serial_puts(((ddr_2t_mode==2)?"F1T":((ddr_2t_mode==1)?"2T":"1T"))); + serial_puts(")-"); + serial_put_dec(p_ddr_set->ddr_timing_ind); + serial_puts("\n"); + } + + /* write ddr size to reg */ + wr_reg(SEC_AO_SEC_GP_CFG0, ((rd_reg(SEC_AO_SEC_GP_CFG0) & 0x0000ffff) | ((p_ddr_set->ddr_size) << 16))); +} + +unsigned int ddr_init_dmc(void){ + unsigned int ddr0_size = 0, ddr1_size = 0; + unsigned int ddr0_size_reg = 0, ddr1_size_reg = 0; +// unsigned int i=0, j=0, convert_reg_size = 6; + + /* transfer correct dmc ctrl setting */ + unsigned int ddr_one_chl = DDR_USE_1_CHANNEL(p_ddr_set->ddr_channel_set); + ddr0_size = (p_ddr_set->ddr_size)>>(7-ddr_one_chl); + ddr1_size = ddr_one_chl?0x7:((p_ddr_set->ddr_size)>>7); + ddr1_size_reg=ddr_one_chl?0x5:0x0; + while (!((ddr0_size>>=1)&0x1)) + ddr0_size_reg++; + while (!((ddr1_size>>=1)&0x1)) + ddr1_size_reg++; + + p_ddr_set->ddr_dmc_ctrl &= (~0x3f); //clear ddr capacity reg bits + p_ddr_set->ddr_dmc_ctrl |= ((ddr0_size_reg)|(ddr1_size_reg<<3)); + + wr_reg(DMC_DDR_CTRL, p_ddr_set->ddr_dmc_ctrl); + if ((p_ddr_set->ddr_channel_set == CONFIG_DDR01_SHARE_AC)|| + (p_ddr_set->ddr_channel_set == CONFIG_DDR0_ONLY_16BIT))//jiaxing find use 16bit channel 0 only must write map0-4? + { + //CONIFG DDR PHY comamnd address map to 32bits linear address. + //DDR0 ROW 14:0. DDR1 ROW 13:0. COL 9:0. + wr_reg( DDR0_ADDRMAP_0, ( 0 | 5 << 5 | 6 << 10 | 7 << 15 | 8 << 20 | 9 << 25 )); + wr_reg( DDR0_ADDRMAP_1, ( 13| 30<< 5 | 0 << 10 | 10 << 15 | 11 << 20 | 12 << 25 )); + //wr_reg( DDR0_ADDRMAP_1, ( 0| 0 << 5 | 0 << 10 | 10 << 15 | 11 << 20 | 12 << 25 )); + wr_reg( DDR0_ADDRMAP_2, ( 16| 17 << 5 | 18 << 10 | 19 << 15 | 20 << 20 | 21 << 25 )); + wr_reg( DDR0_ADDRMAP_3, ( 22| 23 << 5 | 24 << 10 | 25 << 15 | 26 << 20 | 27 << 25 )); + wr_reg( DDR0_ADDRMAP_4, ( 29| 14 << 5 | 15 << 10 | 28 << 15 | 0 << 20 | 0 << 25 )); + + wr_reg( DDR1_ADDRMAP_0, ( 0 | 5 << 5 | 6 << 10 | 7 << 15 | 8 << 20 | 9 << 25 )); + wr_reg( DDR1_ADDRMAP_1, ( 13| 30<< 5 | 0 << 10 | 10 << 15 | 11 << 20 | 12 << 25 )); + //wr_reg( DDR1_ADDRMAP_1, ( 13| 0 << 5 | 0 << 10 | 10 << 15 | 11 << 20 | 12 << 25 )); + wr_reg( DDR1_ADDRMAP_2, ( 16| 17 << 5 | 18 << 10 | 19 << 15 | 20 << 20 | 21 << 25 )); + wr_reg( DDR1_ADDRMAP_3, ( 22| 23 << 5 | 24 << 10 | 25 << 15 | 26 << 20 | 27 << 25 )); + wr_reg( DDR1_ADDRMAP_4, ( 29| 14 << 5 | 15 << 10 | 28 << 15 | 0 << 20 | 0 << 25 )); + } + else if(p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_SAME){ + //wr_reg( DDR0_ADDRMAP_1, ( 11| 0 << 5 | 0 << 10 | 0 << 15 | 15 << 20 | 16 << 25 )); + wr_reg( DDR0_ADDRMAP_1, ( 11| 31 << 5 | 0 << 10 | 14 << 15 | 15 << 20 | 16 << 25 )); + wr_reg( DDR0_ADDRMAP_4, ( 30| 12 << 5 | 13 << 10 | 29 << 15 | 0 << 20 | 0 << 25 )); + } + else if(p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_DIFF){ + //wr_reg( DDR0_ADDRMAP_1, ( 11| 0 << 5 | 0 << 10 | 0 << 15 | 15 << 20 | 16 << 25 )); + wr_reg( DDR0_ADDRMAP_1, ( 11| 31 << 5 | 0 << 10 | 14 << 15 | 15 << 20 | 16 << 25 )); + wr_reg( DDR0_ADDRMAP_4, ( 0| 12 << 5 | 13 << 10 | 29 << 15 | 0 << 20 | 30 << 25 )); + } + + wr_reg(DMC_PCTL_LP_CTRL, 0x440620); + //wr_reg(DDR0_APD_CTRL, 0x45); + wr_reg(DDR0_APD_CTRL, (0x20<<8)|(0x20)); + wr_reg(DDR0_CLK_CTRL, 0x5); + + // disable AXI port0 (CPU) IRQ/FIQ security control. + wr_reg(DMC_AXI0_QOS_CTRL1, 0x11); + + //CONFIG DMC security register to enable the all reqeust can access all DDR region. + wr_reg(DMC_SEC_RANGE_CTRL, 0x0 ); + wr_reg(DMC_SEC_CTRL, 0x80000000 ); + wr_reg(DMC_SEC_AXI_PORT_CTRL, 0x55555555); + wr_reg(DMC_DEV_SEC_READ_CTRL, 0x55555555 ); + wr_reg(DMC_DEV_SEC_WRITE_CTRL, 0x55555555 ); + wr_reg(DMC_GE2D_SEC_CTRL, 0x15); + wr_reg(DMC_PARSER_SEC_CTRL, 0x5); + wr_reg(DMC_VPU_SEC_CFG, 0xffffffff); + wr_reg(DMC_VPU_SEC_WRITE_CTRL, 0x55555555 ); + wr_reg(DMC_VPU_SEC_READ_CTRL, 0x55555555 ); + wr_reg(DMC_VDEC_SEC_CFG, 0xffffffff); + wr_reg(DMC_VDEC_SEC_WRITE_CTRL, 0x55555555 ); + wr_reg(DMC_VDEC_SEC_READ_CTRL, 0x55555555 ); + wr_reg(DMC_HCODEC_SEC_CFG, 0xffffffff); + wr_reg(DMC_HCODEC_SEC_WRITE_CTRL, 0x55555555 ); + wr_reg(DMC_HCODEC_SEC_READ_CTRL, 0x55555555 ); + wr_reg(DMC_HEVC_SEC_CFG, 0xffffffff); + wr_reg(DMC_HEVC_SEC_WRITE_CTRL, 0x55555555 ); + wr_reg(DMC_HEVC_SEC_READ_CTRL, 0x55555555 ); + + //// ENABLE THE DC_REQS. + wr_reg(DMC_REQ_CTRL, 0xFFFF); + + // SCRATCH1 + wr_reg(0xC1107d40, 0xbaadf00d); + + // PUT SOME CODE HERE TO TRY TO STOP BUS TRAFFIC + __asm__ volatile("NOP"); + __asm__ volatile("DMB SY"); + __asm__ volatile("ISB"); + + // REMAP THE ADDRESS SPACE BY WRITING TO NIC400 REMAP REGISTER + //wr_reg(0xC1300000, 0x00000001); + //__asm__ volatile("ISB"); + //__asm__ volatile("DMB SY"); + + return 0; +} + +unsigned int ddr_init_pctl(void){ + ddr0_enabled = !(((p_ddr_set->ddr_dmc_ctrl) >> 7) & 0x1); //check if ddr1 only enabled + ddr1_enabled = !(((p_ddr_set->ddr_dmc_ctrl) >> 6) & 0x1); //check if ddr0 only enabled + + // RELEASE THE DDR DLL RESET PIN. + wr_reg(DMC_SOFT_RST, 0xFFFFFFFF); + wr_reg(DMC_SOFT_RST1, 0xFFFFFFFF); + + // ENABLE UPCTL AND PUB CLOCK AND RESET. + //@@@ enable UPCTL and PUB clock and reset. + wr_reg(DMC_PCTL_LP_CTRL, 0x550620); + wr_reg(DDR0_SOFT_RESET, 0xf); + + // INITIALIZATION PHY. + // FOR SIMULATION TO REDUCE THE INIT TIME. + //wr_reg(DDR0_PUB_PTR0, p_ddr_set->t_pub_ptr[0]); + //wr_reg(DDR0_PUB_PTR1, p_ddr_set->t_pub_ptr[1]); + //wr_reg(DDR0_PUB_PTR3, p_ddr_set->t_pub_ptr[3]); + //wr_reg(DDR0_PUB_PTR4, p_ddr_set->t_pub_ptr[4]); + + wr_reg(DDR0_PUB_IOVCR0, 0x49494949); + wr_reg(DDR0_PUB_IOVCR1, 0x49494949); + + // CONFIGURE DDR PHY PUBL REGISTERS. + wr_reg(DDR0_PUB_ODTCR, p_ddr_set->t_pub_odtcr); + + // PROGRAM PUB MRX REGISTERS. + wr_reg(DDR0_PUB_MR0, p_ddr_set->t_pub_mr[0]); + wr_reg(DDR0_PUB_MR1, p_ddr_set->t_pub_mr[1]); + wr_reg(DDR0_PUB_MR2, p_ddr_set->t_pub_mr[2]); + wr_reg(DDR0_PUB_MR3, p_ddr_set->t_pub_mr[3]); + + // PROGRAM DDR SDRAM TIMING PARAMETER. + wr_reg(DDR0_PUB_DTPR0, p_ddr_set->t_pub_dtpr[0]); + wr_reg(DDR0_PUB_DTPR1, p_ddr_set->t_pub_dtpr[1]); + //wr_reg(DDR0_PUB_PGCR0, p_ddr_set->t_pub_pgcr0); //Jiaxing debug low freq issue + wr_reg(DDR0_PUB_PGCR1, p_ddr_set->t_pub_pgcr1); + wr_reg(DDR0_PUB_PGCR2, p_ddr_set->t_pub_pgcr2); + //wr_reg(DDR0_PUB_PGCR2, 0x00f05f97); + wr_reg(DDR0_PUB_PGCR3, p_ddr_set->t_pub_pgcr3); + wr_reg(DDR0_PUB_DXCCR, p_ddr_set->t_pub_dxccr); + + wr_reg(DDR0_PUB_DTPR2, p_ddr_set->t_pub_dtpr[2]); + wr_reg(DDR0_PUB_DTPR3, p_ddr_set->t_pub_dtpr[3]); + wr_reg(DDR0_PUB_DTCR, p_ddr_set->t_pub_dtcr); //use mpr |(1<<6) + + //DDR0_DLL_LOCK_WAIT + wait_set(DDR0_PUB_PGSR0, 0); + + //wr_reg(DDR0_PUB_DTCR, 0x430030c7); + //wr_reg(DDR0_PUB_DTPR3, 0x2010a902); //tmp disable + wr_reg(DDR0_PUB_ACIOCR1, 0); + wr_reg(DDR0_PUB_ACIOCR2, 0); + wr_reg(DDR0_PUB_ACIOCR3, 0); + wr_reg(DDR0_PUB_ACIOCR4, 0); + wr_reg(DDR0_PUB_ACIOCR5, 0); + wr_reg(DDR0_PUB_DX0GCR1, 0); + wr_reg(DDR0_PUB_DX0GCR2, 0); + wr_reg(DDR0_PUB_DX0GCR3, (0x1<<10)|(0x2<<12)); //power down dm recevier + wr_reg(DDR0_PUB_DX1GCR1, 0); + wr_reg(DDR0_PUB_DX1GCR2, 0); + wr_reg(DDR0_PUB_DX1GCR3, (0x1<<10)|(0x2<<12));//power down dm recevier + wr_reg(DDR0_PUB_DX2GCR1, 0); + wr_reg(DDR0_PUB_DX2GCR2, 0); + wr_reg(DDR0_PUB_DX2GCR3, (0x1<<10)|(0x2<<12));//power down dm recevier + wr_reg(DDR0_PUB_DX3GCR1, 0); + wr_reg(DDR0_PUB_DX3GCR2, 0); + wr_reg(DDR0_PUB_DX3GCR3, (0x1<<10)|(0x2<<12));//power down dm recevier + + // 2:0 011: DDR0_ MODE. 100: LPDDR2 MODE. + // 3: 8 BANK. + // 7; MPR FOR DATA TRAINING. + wr_reg(DDR0_PUB_DCR, p_ddr_set->t_pub_dcr); //use mpr |(1<<7) + + wr_reg(DDR0_PUB_DTAR0, p_ddr_set->t_pub_dtar); + wr_reg(DDR0_PUB_DTAR1, (0X8 | p_ddr_set->t_pub_dtar)); + wr_reg(DDR0_PUB_DTAR2, (0X10 | p_ddr_set->t_pub_dtar)); + wr_reg(DDR0_PUB_DTAR3, (0X18 | p_ddr_set->t_pub_dtar)); + + //// DDR PHY INITIALIZATION +#ifdef CONFIG_PXP_EMULATOR + wr_reg(DDR0_PUB_PIR, 0X581); +#endif + wr_reg(DDR0_PUB_DSGCR, p_ddr_set->t_pub_dsgcr); + + //DDR0_SDRAM_INIT_WAIT : + wait_set(DDR0_PUB_PGSR0, 0); + + if (ddr0_enabled) { + // configure DDR0 IP. + wr_reg(DDR0_PCTL_TOGCNT1U, p_ddr_set->t_pctl0_1us_pck); + wr_reg(DDR0_PCTL_TOGCNT100N, p_ddr_set->t_pctl0_100ns_pck); + wr_reg(DDR0_PCTL_TINIT, p_ddr_set->t_pctl0_init_us); //20 + wr_reg(DDR0_PCTL_TRSTH, p_ddr_set->t_pctl0_rsth_us); //50 + wr_reg(DDR0_PCTL_MCFG, (p_ddr_set->t_pctl0_mcfg)|((p_ddr_set->ddr_2t_mode)?(1<<3):(0<<3))); + if (p_ddr_set->ddr_channel_set == CONFIG_DDR01_SHARE_AC) + wr_reg(DDR0_PCTL_MCFG1, ((p_ddr_set->t_pctl0_mcfg1)&0xFFFFFF00)); + else + wr_reg(DDR0_PCTL_MCFG1, p_ddr_set->t_pctl0_mcfg1); + } + + if (ddr1_enabled) { + // configure DDR1 IP. + wr_reg(DDR1_PCTL_TOGCNT1U, p_ddr_set->t_pctl0_1us_pck); + wr_reg(DDR1_PCTL_TOGCNT100N, p_ddr_set->t_pctl0_100ns_pck); + wr_reg(DDR1_PCTL_TINIT, p_ddr_set->t_pctl0_init_us); //20 + wr_reg(DDR1_PCTL_TRSTH, p_ddr_set->t_pctl0_rsth_us); //50 + wr_reg(DDR1_PCTL_MCFG, (p_ddr_set->t_pctl0_mcfg)|((p_ddr_set->ddr_2t_mode)?(1<<3):(0<<3))); + //wr_reg(DDR1_PCTL_MCFG1, p_ddr_set->t_pctl0_mcfg1); + if (p_ddr_set->ddr_channel_set == CONFIG_DDR01_SHARE_AC) + wr_reg(DDR1_PCTL_MCFG1, ((p_ddr_set->t_pctl0_mcfg1)&0xFFFFFF00)); + else + wr_reg(DDR1_PCTL_MCFG1, p_ddr_set->t_pctl0_mcfg1); + } + + _udelay(500); + + // MONITOR DFI INITIALIZATION STATUS. + if (ddr0_enabled) { + wait_set(DDR0_PCTL_DFISTSTAT0, 0); + wr_reg(DDR0_PCTL_POWCTL, 1); + //DDR0_POWER_UP_WAIT + wait_set(DDR0_PCTL_POWSTAT, 0); + } + if (ddr1_enabled) { + wait_set(DDR1_PCTL_DFISTSTAT0, 0); + wr_reg(DDR1_PCTL_POWCTL, 1); + //DDR0_POWER_UP_WAIT + wait_set(DDR1_PCTL_POWSTAT, 0); + } + + if (ddr0_enabled) { + wr_reg(DDR0_PCTL_TRFC, p_ddr_timing->cfg_ddr_rfc); + wr_reg(DDR0_PCTL_TREFI_MEM_DDR3, p_ddr_timing->cfg_ddr_refi_mddr3); + wr_reg(DDR0_PCTL_TMRD, p_ddr_timing->cfg_ddr_mrd); + wr_reg(DDR0_PCTL_TRP, p_ddr_timing->cfg_ddr_rp); + wr_reg(DDR0_PCTL_TAL, p_ddr_timing->cfg_ddr_al); + wr_reg(DDR0_PCTL_TCWL, p_ddr_timing->cfg_ddr_cwl); + wr_reg(DDR0_PCTL_TCL, p_ddr_timing->cfg_ddr_cl); + wr_reg(DDR0_PCTL_TRAS, p_ddr_timing->cfg_ddr_ras); + wr_reg(DDR0_PCTL_TRC, p_ddr_timing->cfg_ddr_rc); + wr_reg(DDR0_PCTL_TRCD, p_ddr_timing->cfg_ddr_rcd); + wr_reg(DDR0_PCTL_TRRD, p_ddr_timing->cfg_ddr_rrd); + wr_reg(DDR0_PCTL_TRTP, p_ddr_timing->cfg_ddr_rtp); + wr_reg(DDR0_PCTL_TWR, p_ddr_timing->cfg_ddr_wr); + wr_reg(DDR0_PCTL_TWTR, p_ddr_timing->cfg_ddr_wtr); + wr_reg(DDR0_PCTL_TEXSR, p_ddr_timing->cfg_ddr_exsr); + wr_reg(DDR0_PCTL_TXP, p_ddr_timing->cfg_ddr_xp); + wr_reg(DDR0_PCTL_TDQS, p_ddr_timing->cfg_ddr_dqs); + wr_reg(DDR0_PCTL_TRTW, p_ddr_timing->cfg_ddr_rtw); + wr_reg(DDR0_PCTL_TCKSRE, p_ddr_timing->cfg_ddr_cksre); + wr_reg(DDR0_PCTL_TCKSRX, p_ddr_timing->cfg_ddr_cksrx); + wr_reg(DDR0_PCTL_TMOD, p_ddr_timing->cfg_ddr_mod); + wr_reg(DDR0_PCTL_TCKE, p_ddr_timing->cfg_ddr_cke); + wr_reg(DDR0_PCTL_TCKESR, p_ddr_timing->cfg_ddr_cke+1); + wr_reg(DDR0_PCTL_TZQCS, p_ddr_timing->cfg_ddr_zqcs); + wr_reg(DDR0_PCTL_TZQCL, p_ddr_timing->cfg_ddr_zqcl); + wr_reg(DDR0_PCTL_TXPDLL, p_ddr_timing->cfg_ddr_xpdll); + wr_reg(DDR0_PCTL_TZQCSI, p_ddr_timing->cfg_ddr_zqcsi); + } + + if (ddr1_enabled) { + wr_reg(DDR1_PCTL_TRFC, p_ddr_timing->cfg_ddr_rfc); + wr_reg(DDR1_PCTL_TREFI_MEM_DDR3, p_ddr_timing->cfg_ddr_refi_mddr3); + wr_reg(DDR1_PCTL_TMRD, p_ddr_timing->cfg_ddr_mrd); + wr_reg(DDR1_PCTL_TRP, p_ddr_timing->cfg_ddr_rp); + wr_reg(DDR1_PCTL_TAL, p_ddr_timing->cfg_ddr_al); + wr_reg(DDR1_PCTL_TCWL, p_ddr_timing->cfg_ddr_cwl); + wr_reg(DDR1_PCTL_TCL, p_ddr_timing->cfg_ddr_cl); + wr_reg(DDR1_PCTL_TRAS, p_ddr_timing->cfg_ddr_ras); + wr_reg(DDR1_PCTL_TRC, p_ddr_timing->cfg_ddr_rc); + wr_reg(DDR1_PCTL_TRCD, p_ddr_timing->cfg_ddr_rcd); + wr_reg(DDR1_PCTL_TRRD, p_ddr_timing->cfg_ddr_rrd); + wr_reg(DDR1_PCTL_TRTP, p_ddr_timing->cfg_ddr_rtp); + wr_reg(DDR1_PCTL_TWR, p_ddr_timing->cfg_ddr_wr); + wr_reg(DDR1_PCTL_TWTR, p_ddr_timing->cfg_ddr_wtr); + wr_reg(DDR1_PCTL_TEXSR, p_ddr_timing->cfg_ddr_exsr); + wr_reg(DDR1_PCTL_TXP, p_ddr_timing->cfg_ddr_xp); + wr_reg(DDR1_PCTL_TDQS, p_ddr_timing->cfg_ddr_dqs); + wr_reg(DDR1_PCTL_TRTW, p_ddr_timing->cfg_ddr_rtw); + wr_reg(DDR1_PCTL_TCKSRE, p_ddr_timing->cfg_ddr_cksre); + wr_reg(DDR1_PCTL_TCKSRX, p_ddr_timing->cfg_ddr_cksrx); + wr_reg(DDR1_PCTL_TMOD, p_ddr_timing->cfg_ddr_mod); + wr_reg(DDR1_PCTL_TCKE, p_ddr_timing->cfg_ddr_cke); + wr_reg(DDR1_PCTL_TCKESR, p_ddr_timing->cfg_ddr_cke+1); + wr_reg(DDR1_PCTL_TZQCS, p_ddr_timing->cfg_ddr_zqcs); + wr_reg(DDR1_PCTL_TZQCL, p_ddr_timing->cfg_ddr_zqcl); + wr_reg(DDR1_PCTL_TXPDLL, p_ddr_timing->cfg_ddr_xpdll); + wr_reg(DDR1_PCTL_TZQCSI, p_ddr_timing->cfg_ddr_zqcsi); + } + + if (ddr0_enabled) { + wr_reg(DDR0_PCTL_SCFG, p_ddr_set->t_pctl0_scfg); + wr_reg(DDR0_PCTL_SCTL, p_ddr_set->t_pctl0_sctl); + } + + if (ddr1_enabled) { + wr_reg(DDR1_PCTL_SCFG, p_ddr_set->t_pctl0_scfg); + wr_reg(DDR1_PCTL_SCTL, p_ddr_set->t_pctl0_sctl); + } + + // SCRATCH1 + wr_reg(0xC1107d40, 0xdeadbeef); + + // NEW HIU + wr_reg(0xC883c010, 0x88776655); + + //DDR0_STAT_CONFIG_WAIT + if (ddr0_enabled) + wait_set(DDR0_PCTL_STAT, 0); + if (ddr1_enabled) + wait_set(DDR1_PCTL_STAT, 0); + + if (ddr0_enabled) { + wr_reg(DDR0_PCTL_PPCFG, p_ddr_set->t_pctl0_ppcfg); /* 16bit or 32bit mode */ + wr_reg(DDR0_PCTL_DFISTCFG0, p_ddr_set->t_pctl0_dfistcfg0); + wr_reg(DDR0_PCTL_DFISTCFG1, p_ddr_set->t_pctl0_dfistcfg1); + wr_reg(DDR0_PCTL_DFITCTRLDELAY, p_ddr_set->t_pctl0_dfitctrldelay); + wr_reg(DDR0_PCTL_DFITPHYWRDATA, p_ddr_set->t_pctl0_dfitphywrdata); + wr_reg(DDR0_PCTL_DFITPHYWRLAT, p_ddr_set->t_pctl0_dfitphywrlta); + wr_reg(DDR0_PCTL_DFITRDDATAEN, p_ddr_set->t_pctl0_dfitrddataen); + wr_reg(DDR0_PCTL_DFITPHYRDLAT, p_ddr_set->t_pctl0_dfitphyrdlat); + wr_reg(DDR0_PCTL_DFITDRAMCLKDIS, p_ddr_set->t_pctl0_dfitdramclkdis); + wr_reg(DDR0_PCTL_DFITDRAMCLKEN, p_ddr_set->t_pctl0_dfitdramclken); + wr_reg(DDR0_PCTL_DFILPCFG0, p_ddr_set->t_pctl0_dfilpcfg0); + wr_reg(DDR0_PCTL_DFITPHYUPDTYPE1, p_ddr_set->t_pctl0_dfitphyupdtype1); + wr_reg(DDR0_PCTL_DFITCTRLUPDMIN, p_ddr_set->t_pctl0_dfitctrlupdmin); + wr_reg(DDR0_PCTL_DFIODTCFG, p_ddr_set->t_pctl0_dfiodtcfg); + wr_reg(DDR0_PCTL_DFIODTCFG1, p_ddr_set->t_pctl0_dfiodtcfg1); + wr_reg(DDR0_PCTL_CMDTSTATEN, p_ddr_set->t_pctl0_cmdtstaten); + } + + if (ddr1_enabled) { + wr_reg(DDR1_PCTL_PPCFG, p_ddr_set->t_pctl0_ppcfg); /* 16bit or 32bit mode */ + wr_reg(DDR1_PCTL_DFISTCFG0, p_ddr_set->t_pctl0_dfistcfg0); + wr_reg(DDR1_PCTL_DFISTCFG1, p_ddr_set->t_pctl0_dfistcfg1); + wr_reg(DDR1_PCTL_DFITCTRLDELAY, p_ddr_set->t_pctl0_dfitctrldelay); + wr_reg(DDR1_PCTL_DFITPHYWRDATA, p_ddr_set->t_pctl0_dfitphywrdata); + wr_reg(DDR1_PCTL_DFITPHYWRLAT, p_ddr_set->t_pctl0_dfitphywrlta); + wr_reg(DDR1_PCTL_DFITRDDATAEN, p_ddr_set->t_pctl0_dfitrddataen); + wr_reg(DDR1_PCTL_DFITPHYRDLAT, p_ddr_set->t_pctl0_dfitphyrdlat); + wr_reg(DDR1_PCTL_DFITDRAMCLKDIS, p_ddr_set->t_pctl0_dfitdramclkdis); + wr_reg(DDR1_PCTL_DFITDRAMCLKEN, p_ddr_set->t_pctl0_dfitdramclken); + wr_reg(DDR1_PCTL_DFILPCFG0, p_ddr_set->t_pctl0_dfilpcfg0); + wr_reg(DDR1_PCTL_DFITPHYUPDTYPE1, p_ddr_set->t_pctl0_dfitphyupdtype1); + wr_reg(DDR1_PCTL_DFITCTRLUPDMIN, p_ddr_set->t_pctl0_dfitctrlupdmin); + wr_reg(DDR1_PCTL_DFIODTCFG, p_ddr_set->t_pctl0_dfiodtcfg); + wr_reg(DDR1_PCTL_DFIODTCFG1, p_ddr_set->t_pctl0_dfiodtcfg1); + wr_reg(DDR1_PCTL_CMDTSTATEN, p_ddr_set->t_pctl0_cmdtstaten); + } + +#ifndef CONFIG_PXP_EMULATOR + wr_reg(DDR0_PUB_ZQ0PR, p_ddr_set->t_pub_zq0pr); + wr_reg(DDR0_PUB_ZQ1PR, p_ddr_set->t_pub_zq1pr); + wr_reg(DDR0_PUB_ZQ2PR, p_ddr_set->t_pub_zq2pr); + wr_reg(DDR0_PUB_ZQ3PR, p_ddr_set->t_pub_zq3pr); + + wr_reg(DDR0_PUB_PIR, 3); + wait_set(DDR0_PUB_PGSR0, 0); + wr_reg(DDR0_PUB_ZQCR,(rd_reg(DDR0_PUB_ZQCR))|(1<<2)|(1<<27)); //jiaxing debug must force update + _udelay(10); + wr_reg(DDR0_PUB_ZQCR,(rd_reg(DDR0_PUB_ZQCR))&(~((1<<2)|(1<<27)))); + _udelay(30); + if (p_ddr_set->ddr_channel_set == CONFIG_DDR0_ONLY_16BIT) + { + wr_reg(DDR0_PUB_DX2GCR0, (0xfffffffe&rd_reg(DDR0_PUB_DX2GCR0))); + wr_reg(DDR0_PUB_DX3GCR0, (0xfffffffe&rd_reg(DDR0_PUB_DX3GCR0))); + } + +#ifdef CONFIG_DDR_CMD_BDL_TUNE + wr_reg(DDR0_PUB_ACLCDLR, DDR_AC_LCDLR); //ck0 + wr_reg(DDR0_PUB_ACBDLR0, DDR_CK0_BDL); //ck0 + wr_reg(DDR0_PUB_ACBDLR1, (DDR_WE_BDL<<16)|(DDR_CAS_BDL<<8)|(DDR_RAS_BDL)); //ras cas we + wr_reg(DDR0_PUB_ACBDLR2, ((DDR_ACPDD_BDL<<24)|(DDR_BA2_BDL<<16)|(DDR_BA1_BDL<<8)|(DDR_BA0_BDL))); //ba0 ba1 ba2 + wr_reg(DDR0_PUB_ACBDLR3, ((DDR_CS1_BDL<<8)|(DDR_CS0_BDL))); //cs0 cs1 + wr_reg(DDR0_PUB_ACBDLR4, ((DDR_ODT1_BDL<<8)|(DDR_ODT0_BDL))); //odt0 odt1 + wr_reg(DDR0_PUB_ACBDLR5, ((DDR_CKE1_BDL<<8)|(DDR_CKE0_BDL))); //cke0 cke1 + wr_reg(DDR0_PUB_ACBDLR6, ((DDR_A3_BDL<<24)|(DDR_A2_BDL<<16)|(DDR_A1_BDL<<8)|(DDR_A0_BDL))); //a0 a1 a2 a3 + wr_reg(DDR0_PUB_ACBDLR7, ((DDR_A7_BDL<<24)|(DDR_A6_BDL<<16)|(DDR_A5_BDL<<8)|(DDR_A4_BDL))); //a4 a5 a6 a7 + wr_reg(DDR0_PUB_ACBDLR8, ((DDR_A11_BDL<<24)|(DDR_A10_BDL<<16)|(DDR_A9_BDL<<8)|(DDR_A8_BDL))); //a8 a9 a10 a11 + wr_reg(DDR0_PUB_ACBDLR9, ((DDR_A15_BDL<<24)|(DDR_A14_BDL<<16)|(DDR_A13_BDL<<8)|(DDR_A12_BDL))); //a12 a13 a14 a15 +#endif + + wr_reg(DDR0_PUB_PIR, (DDR_PIR | PUB_PIR_INIT)); + do { + _udelay(20); + } while(DDR_PGSR0_CHECK()); +#endif + + if ((p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK0_ONLY) || \ + (p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_SAME)) + { + unsigned int i=0, j=0; + i=(rd_reg(DDR0_PUB_DX2LCDLR0)); + wr_reg(DDR0_PUB_DX2LCDLR0,((i>>8)|(i&(0xffffff00)))); + i=(((rd_reg(DDR0_PUB_DX2GTR))>>3)&((7<<0))); + j=(((rd_reg(DDR0_PUB_DX2GTR))>>14)&((3<<0))); + wr_reg(DDR0_PUB_DX2GTR,i|(i<<3)|(j<<12)|(j<<14)); + i=(rd_reg(DDR0_PUB_DX2LCDLR2)); + wr_reg(DDR0_PUB_DX2LCDLR2,((i>>8)|(i&(0xffffff00)))); + i=(rd_reg(DDR0_PUB_DX3LCDLR0)); + wr_reg(DDR0_PUB_DX3LCDLR0,((i>>8)|(i&(0xffffff00)))); + i=(((rd_reg(DDR0_PUB_DX3GTR))>>3)&((7<<0))); + j=(((rd_reg(DDR0_PUB_DX3GTR))>>14)&((3<<0))); + wr_reg(DDR0_PUB_DX3GTR,i|(i<<3)|(j<<12)|(j<<14)); + i=(rd_reg(DDR0_PUB_DX3LCDLR2)); + wr_reg(DDR0_PUB_DX3LCDLR2,((i>>8)|(i&(0xffffff00)))); + i=(rd_reg(DDR0_PUB_DX0LCDLR0)); + wr_reg(DDR0_PUB_DX0LCDLR0,((i<<8)|(i&(0xffff00ff)))); + i=(((rd_reg(DDR0_PUB_DX0GTR))<<0)&((7<<0))); + j=(((rd_reg(DDR0_PUB_DX0GTR))>>12)&((3<<0))); + wr_reg(DDR0_PUB_DX0GTR,i|(i<<3)|(j<<12)|(j<<14)); + i=(rd_reg(DDR0_PUB_DX0LCDLR2)); + wr_reg(DDR0_PUB_DX0LCDLR2,((i<<8)|(i&(0xffff00ff)))); + i=(rd_reg(DDR0_PUB_DX1LCDLR0)); + wr_reg(DDR0_PUB_DX1LCDLR0,((i<<8)|(i&(0xffff00ff)))); + i=(((rd_reg(DDR0_PUB_DX1GTR))<<0)&((7<<0))); + j=(((rd_reg(DDR0_PUB_DX1GTR))>>12)&((3<<0))); + wr_reg(DDR0_PUB_DX1GTR,i|(i<<3)|(j<<12)|(j<<14)); + i=(rd_reg(DDR0_PUB_DX1LCDLR2)); + wr_reg(DDR0_PUB_DX1LCDLR2,((i<<8)|(i&(0xffff00ff)))); + } + if ((p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK0_ONLY) || \ + (p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_SAME) || \ + (p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_DIFF)) { + //wr_reg(DDR0_PUB_PGCR2,((((1<<28))|p_ddr_set->t_pub_pgcr2))); + wr_reg(DDR0_PUB_PGCR2,(((~(1<<28))&p_ddr_set->t_pub_pgcr2))); + } + + if ((p_ddr_set->ddr_2t_mode) && \ + (p_ddr_set->ddr_channel_set != CONFIG_DDR01_SHARE_AC) && \ + (((p_ddr_set->t_pub_dcr)&0x7)== 0x3)) { + //jiaxing mark----must place after training ,because training is 1t mode ,if delay too much training will not ok + wr_reg(DDR0_PUB_ACLCDLR, 0x1f); //delay cmd/address 2t signle not effect cs cke odt + //wr_reg(DDR0_PUB_ACBDLR0, 0x10); //ck0 + /* + wr_reg(DDR0_PUB_ACBDLR1, (0x18<<16)|(0x18<<8)|(0x18)); //ras cas we + wr_reg(DDR0_PUB_ACBDLR2, ((0x18<<16)|(0x18<<8)|(0x18))); //ba0 ba1 ba2 + //wr_reg(DDR0_PUB_ACBDLR3, ((0<<8)|(0))); //cs0 cs1 + //wr_reg(DDR0_PUB_ACBDLR4, ((0<<8)|(0))); //odt0 odt1 + //wr_reg(DDR0_PUB_ACBDLR5, ((0<<8)|(0))); //cke0 cke1 + wr_reg(DDR0_PUB_ACBDLR6, ((0x18<<24)|(0x18<<16)|(0x18<<8)|(0x18))); //a0 a1 a2 a3 + wr_reg(DDR0_PUB_ACBDLR7, ((0x18<<24)|(0x18<<16)|(0x18<<8)|(0x18))); //a4 a5 a6 a7 + wr_reg(DDR0_PUB_ACBDLR8, ((0x18<<24)|(0x18<<16)|(0x18<<8)|(0x18))); //a8 a9 a10 a11 + wr_reg(DDR0_PUB_ACBDLR9, ((0x18<<24)|(0x18<<16)|(0x18<<8)|(0x18))); //a12 a13 a14 a15 + */ + } + //DDR0_CMD_TIMER_WAIT + if (ddr0_enabled) + wait_set(DDR0_PCTL_CMDTSTAT, 0); + if (ddr1_enabled) + wait_set(DDR1_PCTL_CMDTSTAT, 0); + + ////APB_WR(PCTL_PCTL_SCTL, 2); // INIT: 0, CFG: 1, GO: 2, SLEEP: 3, WAKEUP: 4 + if (ddr0_enabled) + wr_reg(DDR0_PCTL_SCTL, UPCTL_CMD_GO); + if (ddr1_enabled) + wr_reg(DDR1_PCTL_SCTL, UPCTL_CMD_GO); + + ////WHILE ((APB_RD(DDR0_PCTL_STAT) & 0x7 ) != 3 ) {} + //DDR0_STAT_GO_WAIT: + if (ddr0_enabled) + wait_equal(DDR0_PCTL_STAT, UPCTL_STAT_ACCESS); + if (ddr1_enabled) + wait_equal(DDR1_PCTL_STAT, UPCTL_STAT_ACCESS); + + wr_reg( DDR0_PUB_ZQCR,(rd_reg(DDR0_PUB_ZQCR))|(1<<2)); + wr_reg( DDR0_PUB_ZQCR,(rd_reg(DDR0_PUB_ZQCR))&(~(1<<2))); + +/* power down zq for power saving */ +#ifdef CONFIG_DDR_ZQ_POWER_DOWN + wr_reg( DDR0_PUB_ZQCR,(rd_reg(DDR0_PUB_ZQCR))|(1<<2)); +#endif + +/* power down phy vref for power saving */ +#ifdef CONFIG_DDR_POWER_DOWN_PHY_VREF + wr_reg(DDR0_PUB_IOVCR0, 0); + wr_reg(DDR0_PUB_IOVCR1, 0); +#endif + + //// ENABLE THE DMC AUTO REFRESH FUNCTION + if (ddr0_enabled) { + wr_reg(DMC_REFR_CTRL1, 0X8800191|(0x3<<2)|(0x1<<0)); + rd_reg(DDR0_PCTL_MCFG); + } + if (ddr1_enabled) { + wr_reg(DMC_REFR_CTRL1, 0X8800191|(0x3<<2)|(0x1<<1)); + rd_reg(DDR1_PCTL_MCFG); + } + wr_reg(DMC_REFR_CTRL2, 0X20100000|(p_ddr_set->ddr_clk/20)|(39<<8)); + + return 0; +} + +void ddr_pre_init(void){ + /* find match ddr timing */ + if ((p_ddr_set->ddr_clk >= CONFIG_DDR_CLK_LOW) && (p_ddr_set->ddr_clk < 533)) { + p_ddr_set->ddr_timing_ind = CONFIG_DDR_TIMMING_DDR3_7; + } + else if ((p_ddr_set->ddr_clk >= 533) && (p_ddr_set->ddr_clk < 667)) { + p_ddr_set->ddr_timing_ind = CONFIG_DDR_TIMMING_DDR3_9; + } + else if ((p_ddr_set->ddr_clk >= 667) && (p_ddr_set->ddr_clk < 800)) { + p_ddr_set->ddr_timing_ind = CONFIG_DDR_TIMMING_DDR3_11; + } + else if ((p_ddr_set->ddr_clk >= 800) && (p_ddr_set->ddr_clk < 933)) { + p_ddr_set->ddr_timing_ind = CONFIG_DDR_TIMMING_DDR3_13; + } + else if ((p_ddr_set->ddr_clk >= 933) && (p_ddr_set->ddr_clk < CONFIG_DDR_CLK_HIGH)) { + p_ddr_set->ddr_timing_ind = CONFIG_DDR_TIMMING_DDR3_14; + } + else { + serial_puts("DDR clk setting error! Reset...\n"); + reset_system(); + } + + p_ddr_set->t_pctl0_1us_pck = (p_ddr_set->ddr_clk / 2); + p_ddr_set->t_pctl0_100ns_pck = (p_ddr_set->ddr_clk / 20); + + /* get match timing config */ + unsigned loop; + for (loop = 0; loop < (sizeof(__ddr_timming)/sizeof(ddr_timing_t)); loop++) { + if (__ddr_timming[loop].identifier == p_ddr_set->ddr_timing_ind) { + p_ddr_timing = &__ddr_timming[loop]; + break; + } + } + if (NULL == p_ddr_timing) { + serial_puts("Can't find ddr timing setting! Reset...\n"); + reset_system(); + } + + unsigned int ddr_dual_rank_sel = 0; + unsigned int ddr_chl_set = 0; + + //BIT22. 1:RANK1 IS SAME AS RANK0 + //BIT21. 0:SEC RANK DISABLE, 1:SEC RANK ENABLE + //BIT20. SHARE AC MODE, 0:DISABLE, 1:ENABLE + if (p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK0_ONLY) { + serial_puts("DDR channel setting: DDR0 Rank0 only\n"); + ddr_chl_set = ((0x2 << 20) | //b'010: BIT22, BIT21, BIT20 + (0 << 16) | //BIT[17:16], DDR0_DDR1 DATA WIDTH, 0:32BIT, 1:16BIT + (1 << 6)); //b'00:DDR0_DDR1, b'01: DDR0_ONLY, b'10:DDR1_ONLY + ddr_dual_rank_sel = 0; //SET PGCR2[28], RANK0 AND RANK1 USE SAME RANK SELECT SIGNAL + p_ddr_set->t_pctl0_ppcfg = (0xF0 << 1); + p_ddr_set->t_pctl0_dfiodtcfg = 0x0808; + } + else if (p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_SAME) { + serial_puts("DDR channel setting: DDR0 Rank0+1 same\n"); + ddr_chl_set = ((0x4 << 20) | (0 << 16) | (1 << 6)); + ddr_dual_rank_sel = 1; + p_ddr_set->t_pctl0_ppcfg = (0xF0 << 1); + p_ddr_set->t_pctl0_dfiodtcfg = 0x08; + } + else if (p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_DIFF) { + serial_puts("DDR channel setting: DDR0 Rank0+1 diff\n"); + ddr_chl_set = ((0x2 << 20) | (0 << 16) | (1 << 6)); + ddr_dual_rank_sel = 0; + p_ddr_set->t_pctl0_ppcfg = (0xF0 << 1); + p_ddr_set->t_pctl0_dfiodtcfg = 0x08; + } + else if (p_ddr_set->ddr_channel_set == CONFIG_DDR0_ONLY_16BIT) { + serial_puts("DDR channel setting: ONLY DDR0 16bit mode\n"); + ddr_chl_set = ((0x2 << 20) | (3 << 16) | (1 << 6)); + ddr_dual_rank_sel = 0; + //p_ddr_set->t_pctl0_ppcfg = (0xF0 << 1); + p_ddr_set->t_pctl0_ppcfg =(0x1fc | 1 ); + p_ddr_set->t_pctl0_dfiodtcfg = 0x08; + } + else if (p_ddr_set->ddr_channel_set == CONFIG_DDR01_SHARE_AC) { + serial_puts("DDR channel setting: DDR0+1 share ac\n"); + ddr_chl_set = ((0x1 << 20) | (3 << 16) | (0 << 6)); + ddr_dual_rank_sel = 1; + p_ddr_set->t_pctl0_ppcfg = (0x1fc | 1 ); + p_ddr_set->t_pctl0_dfiodtcfg = 0x08; + p_ddr_set->ddr_dmc_ctrl |= (5 << 8); + p_ddr_set->ddr_2t_mode = 1; + } + p_ddr_set->ddr_dmc_ctrl |= (ddr_chl_set | + (0x5 << 3) | //set to max size + (0x5 << 0)); //set to max size + /* config t_pub_pgcr2[28] share-ac-dual */ + p_ddr_set->t_pub_pgcr2 |= (ddr_dual_rank_sel << 28); + + /* update pctl timing */ + int tmp_val = 0; + tmp_val =( p_ddr_timing->cfg_ddr_cwl + p_ddr_timing->cfg_ddr_al); + tmp_val = (tmp_val - ((tmp_val%2) ? 3:4))/2; + p_ddr_set->t_pctl0_dfitphywrlta=tmp_val; + + tmp_val = p_ddr_timing->cfg_ddr_cl + p_ddr_timing->cfg_ddr_al; + tmp_val = (tmp_val - ((tmp_val%2) ? 3:4))/2; + p_ddr_set->t_pctl0_dfitrddataen=tmp_val; + + //p_ddr_set->t_pctl0_dfitphyrdlat=16; + if ((p_ddr_timing->cfg_ddr_cl+p_ddr_timing->cfg_ddr_al)%2) { + p_ddr_set->t_pctl0_dfitphyrdlat=14; + } + + /* update pub mr */ + p_ddr_set->t_pub_mr[0] = ((((p_ddr_timing->cfg_ddr_cl - 4) & 0x8)>>1) | + (((p_ddr_timing->cfg_ddr_cl - 4) & 0x7) << 4) | + ((((p_ddr_timing->cfg_ddr_wr <= 8)?(p_ddr_timing->cfg_ddr_wr - 4):(p_ddr_timing->cfg_ddr_wr>>1)) & 7) << 9) | + (0x0) | (0x0 << 3) | (0x0 << 7) | (0x0 << 8) | (0x6 << 9) | (1 << 12)), + p_ddr_set->t_pub_mr[1] = ( ((p_ddr_set->ddr_drv<<1)|((p_ddr_set->ddr_odt&1)<<2) | + (((p_ddr_set->ddr_odt&2)>>1)<<6) | + (((p_ddr_set->ddr_odt&4)>>2)<<9) | + (1<<7) | + ((p_ddr_timing->cfg_ddr_al ? ((p_ddr_timing->cfg_ddr_cl - p_ddr_timing->cfg_ddr_al)&3): 0) << 3 ))), + p_ddr_set->t_pub_mr[2] = ((1<<6) | + (((p_ddr_timing->cfg_ddr_cwl-5)&0x7)<<3)), + p_ddr_set->t_pub_mr[3] = 0x0, + /* update pub dtpr */ + p_ddr_set->t_pub_dtpr[0] = (p_ddr_timing->cfg_ddr_rtp | + (p_ddr_timing->cfg_ddr_wtr << 4) | + (p_ddr_timing->cfg_ddr_rp << 8) | + (p_ddr_timing->cfg_ddr_ras << 16) | + (p_ddr_timing->cfg_ddr_rrd << 22) | + (p_ddr_timing->cfg_ddr_rcd << 26)); + p_ddr_set->t_pub_dtpr[1] = ((p_ddr_timing->cfg_ddr_mod << 2) | + (p_ddr_timing->cfg_ddr_faw << 5) | + (p_ddr_timing->cfg_ddr_rfc << 11) | + (p_ddr_timing->cfg_ddr_wlmrd << 20) | + (p_ddr_timing->cfg_ddr_wlo << 26) | + (0 << 30) ); //TAOND + p_ddr_set->t_pub_dtpr[2] = (p_ddr_timing->cfg_ddr_xs | + (p_ddr_timing->cfg_ddr_xp << 10) | + (p_ddr_timing->cfg_ddr_dllk << 19) | + (0 << 29) | //TRTODT ADDITIONAL + (0 << 30) | //TRTW ADDITIONAL + (0 << 31 )); //TCCD ADDITIONAL + p_ddr_set->t_pub_dtpr[3] = (0 | (0 << 3) | + (p_ddr_timing->cfg_ddr_rc << 6) | + (p_ddr_timing->cfg_ddr_cke << 13) | + (p_ddr_timing->cfg_ddr_mrd << 18) | + (0 << 29)); //tAOFDx + p_ddr_set->t_pctl0_mcfg = ((p_ddr_set->t_pctl0_mcfg)&(~(0x3<<18))) | + (((((p_ddr_timing->cfg_ddr_faw+p_ddr_timing->cfg_ddr_rrd-1)/p_ddr_timing->cfg_ddr_rrd)-4)&0x3)<<18); + p_ddr_set->t_pctl0_mcfg1 |= ((((p_ddr_timing->cfg_ddr_faw%p_ddr_timing->cfg_ddr_rrd)?(p_ddr_timing->cfg_ddr_rrd-(p_ddr_timing->cfg_ddr_faw%p_ddr_timing->cfg_ddr_rrd)):0)&0x7)<<8); +} + +void ddr_test(void){ + if (memTestDataBus((volatile unsigned int *)(uint64_t) \ + (p_ddr_set->ddr_base_addr + p_ddr_set->ddr_start_offset))) { + serial_puts("DataBus test failed!!!\n"); + reset_system(); + } + else + serial_puts("DataBus test pass!\n"); + if (memTestAddressBus((volatile unsigned int *)(uint64_t) \ + (p_ddr_set->ddr_base_addr + p_ddr_set->ddr_start_offset), \ + ((p_ddr_set->ddr_size << 20) - p_ddr_set->ddr_start_offset))) { + serial_puts("AddrBus test failed!!!\n"); + reset_system(); + } + else + serial_puts("AddrBus test pass!\n"); +#if MEM_TEST_DEVICE + if (p_ddr_set->ddr_full_test) { + extern void watchdog_disable(void); + //disable_mmu_el1(); + watchdog_disable(); + if (memTestDevice((volatile unsigned int *)(uint64_t) \ + (p_ddr_set->ddr_base_addr + p_ddr_set->ddr_start_offset), \ + ((p_ddr_set->ddr_size << 20) - p_ddr_set->ddr_start_offset))) { + serial_puts("Device test failed!!!\n"); + reset_system(); + } + else + serial_puts("Device test pass!\n"); + } +#endif// #if MEM_TEST_DEVICE +} + +#if 0 +unsigned int hot_boot(void){ + if (((rd_reg(SCRATCH0) >> 24) & 0xFF) == 0x11) { + /*hot boot*/ + return 0; + } + else{ + return 1; + } +} +#endif diff --git a/plat/gxb/ddr/ddr_detect.c b/plat/gxb/ddr/ddr_detect.c new file mode 100644 index 0000000..a3b28d5 --- /dev/null +++ b/plat/gxb/ddr/ddr_detect.c @@ -0,0 +1,96 @@ + +#define SIZE_16MB 0x01000000 +#define DDR_SIZE_PATTERN 0xAABBCCDD +#define DDR_SIZE_VERI_ADDR SIZE_16MB + +#define DDR_VERI_PATTERN_256M 0 +#define DDR_VERI_PATTERN_512M 0 +#define DDR_VERI_PATTERN_1024M 0xAC7E5AC0 +#define DDR_VERI_PATTERN_2048M 0x1A182515 + +#define DDR_VERI_PATTERN_384M 0 +#define DDR_VERI_PATTERN_768M 0 +#define DDR_VERI_PATTERN_1536M 0 +#define DDR_VERI_PATTERN_3072M 0 + +#define DDR_SIZE_LOOP_MAX 29 + +#ifndef DDR_DETECT_DEBUG +#define DDR_DETECT_DEBUG 0 +#endif + +#if DDR_DETECT_DEBUG +#define debug_serial_puts(a) serial_puts(a) +#define debug_serial_put_hex(a, b) serial_put_hex(a, b) +#else +#define debug_serial_puts(a) +#define debug_serial_put_hex(a, b) +#endif + +#if (CONFIG_DDR_SIZE_AUTO_DETECT) +void ddr_size_detect(ddr_set_t * p_ddr_set) { + /* Set max col, row, bank size */ + debug_serial_puts("DMC_DDR_CTRL: 0x"); + debug_serial_put_hex(rd_reg(DMC_DDR_CTRL), 32); + debug_serial_puts("\n"); + wr_reg(DMC_DDR_CTRL, ((rd_reg(DMC_DDR_CTRL))&(~0x3F))|((5<<3)|5)); + debug_serial_puts("DMC_DDR_CTRL: 0x"); + debug_serial_put_hex(rd_reg(DMC_DDR_CTRL), 32); + debug_serial_puts("\n"); + + uint32_t size_loop=0; + uint64_t write_addr=0; + uint32_t ddr0_size=0; + uint32_t ddr1_size=0; + uint32_t ddr0_size_reg=0; + uint32_t ddr1_size_reg=0; + + //first detect aligned size + for (size_loop=0; size_loop<=DDR_SIZE_LOOP_MAX; size_loop++) { + write_addr = (uint32_t)((0x4<<size_loop)+DDR_SIZE_VERI_ADDR); + debug_serial_puts("size_loop1=0x"); + debug_serial_put_hex(size_loop, 32); + debug_serial_puts("\n"); + wr_reg((unsigned long)DDR_SIZE_VERI_ADDR, 0); + debug_serial_puts("write 0x"); + debug_serial_put_hex(write_addr, 32); + debug_serial_puts("\n"); + wr_reg(write_addr, DDR_SIZE_PATTERN); + _udelay(10); + debug_serial_puts("rd_reg(0):0x"); + debug_serial_put_hex(rd_reg(DDR_SIZE_VERI_ADDR), 32); + debug_serial_puts(", rd_reg(0x4<<size_loop):0x"); + debug_serial_put_hex(rd_reg(write_addr), 32); + debug_serial_puts("\n"); + if ((rd_reg(DDR_SIZE_VERI_ADDR) != 0) && (rd_reg(DDR_SIZE_VERI_ADDR) != DDR_SIZE_PATTERN)) { + debug_serial_puts("find match size1: 0x"); + debug_serial_put_hex(size_loop, 32); + debug_serial_puts("\n"); + /* get correct ddr size */ + p_ddr_set->ddr_size = 1<<(size_loop+2-20); //MB + /* set correct dmc cntl reg */ + unsigned int ddr_one_chl = DDR_USE_1_CHANNEL(p_ddr_set->ddr_channel_set); + ddr0_size = (p_ddr_set->ddr_size)>>(7-ddr_one_chl); + ddr1_size = ddr_one_chl?0x7:((p_ddr_set->ddr_size)>>7); + ddr1_size_reg=ddr_one_chl?0x5:0x0; + while (!((ddr0_size>>=1)&0x1)) + ddr0_size_reg++; + while (!((ddr1_size>>=1)&0x1)) + ddr1_size_reg++; + break; + } + } + debug_serial_puts("DMC_DDR_CTRL: 0x"); + debug_serial_put_hex(rd_reg(DMC_DDR_CTRL), 32); + debug_serial_puts("\n"); + wr_reg(DMC_DDR_CTRL, ((rd_reg(DMC_DDR_CTRL))&(~0x3F))|(ddr1_size_reg<<3|ddr0_size_reg)); + debug_serial_puts("DMC_DDR_CTRL: 0x"); + debug_serial_put_hex(rd_reg(DMC_DDR_CTRL), 32); + debug_serial_puts("\n"); + return; +} +#else +void ddr_size_detect(ddr_set_t * p_ddr_set) { + return; +} +#endif
\ No newline at end of file diff --git a/plat/gxb/ddr/ddr_pctl_define.h b/plat/gxb/ddr/ddr_pctl_define.h new file mode 100644 index 0000000..146391b --- /dev/null +++ b/plat/gxb/ddr/ddr_pctl_define.h @@ -0,0 +1,282 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/ddr/ddr_pctl_define.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#define DDR0_PCTL_SCFG 0xc8839000 +#define DDR0_PCTL_SCTL 0xc8839004 +#define DDR0_PCTL_STAT 0xc8839008 +#define DDR0_PCTL_INTRSTAT 0xc883900c +#define DDR0_PCTL_POWSTAT 0xc8839048 +#define DDR0_PCTL_MRRSTAT0 0xc8839064 +#define DDR0_PCTL_CMDTSTAT 0xc883904c +#define DDR0_PCTL_MCMD 0xc8839040 +#define DDR0_PCTL_MRRSTAT1 0xc8839068 +#define DDR0_PCTL_MRRCFG0 0xc8839060 +#define DDR0_PCTL_CMDTSTATEN 0xc8839050 +#define DDR0_PCTL_POWCTL 0xc8839044 +#define DDR0_PCTL_PPCFG 0xc8839084 +#define DDR0_PCTL_LPDDR23ZQCFG 0xc883908c +#define DDR0_PCTL_MCFG1 0xc883907c +#define DDR0_PCTL_MSTAT 0xc8839088 +#define DDR0_PCTL_MCFG 0xc8839080 +#define DDR0_PCTL_DTUAWDT 0xc88390b0 +#define DDR0_PCTL_DTUPRD2 0xc88390a8 +#define DDR0_PCTL_DTUPRD3 0xc88390ac +#define DDR0_PCTL_DTUNE 0xc883909c +#define DDR0_PCTL_DTUPDES 0xc8839094 +#define DDR0_PCTL_DTUNA 0xc8839098 +#define DDR0_PCTL_DTUPRD0 0xc88390a0 +#define DDR0_PCTL_DTUPRD1 0xc88390a4 +#define DDR0_PCTL_TCKSRE 0xc8839124 +#define DDR0_PCTL_TZQCSI 0xc883911c +#define DDR0_PCTL_TINIT 0xc88390c4 +#define DDR0_PCTL_TDPD 0xc8839144 +#define DDR0_PCTL_TOGCNT1U 0xc88390c0 +#define DDR0_PCTL_TCKE 0xc883912c +#define DDR0_PCTL_TMOD 0xc8839130 +#define DDR0_PCTL_TEXSR 0xc883910c +#define DDR0_PCTL_TAL 0xc88390e4 +#define DDR0_PCTL_TRTP 0xc8839100 +#define DDR0_PCTL_TCKSRX 0xc8839128 +#define DDR0_PCTL_TRTW 0xc88390e0 +#define DDR0_PCTL_TCWL 0xc88390ec +#define DDR0_PCTL_TWR 0xc8839104 +#define DDR0_PCTL_TCL 0xc88390e8 +#define DDR0_PCTL_TDQS 0xc8839120 +#define DDR0_PCTL_TRSTH 0xc88390c8 +#define DDR0_PCTL_TRCD 0xc88390f8 +#define DDR0_PCTL_TXP 0xc8839110 +#define DDR0_PCTL_TOGCNT100N 0xc88390cc +#define DDR0_PCTL_TMRD 0xc88390d4 +#define DDR0_PCTL_TRSTL 0xc8839134 +#define DDR0_PCTL_TREFI 0xc88390d0 +#define DDR0_PCTL_TRAS 0xc88390f0 +#define DDR0_PCTL_TREFI_MEM_DDR3 0xc8839148 +#define DDR0_PCTL_TWTR 0xc8839108 +#define DDR0_PCTL_TRC 0xc88390f4 +#define DDR0_PCTL_TRFC 0xc88390d8 +#define DDR0_PCTL_TMRR 0xc883913c +#define DDR0_PCTL_TCKESR 0xc8839140 +#define DDR0_PCTL_TZQCL 0xc8839138 +#define DDR0_PCTL_TRRD 0xc88390fc +#define DDR0_PCTL_TRP 0xc88390dc +#define DDR0_PCTL_TZQCS 0xc8839118 +#define DDR0_PCTL_TXPDLL 0xc8839114 +#define DDR0_PCTL_ECCCFG 0xc8839180 +#define DDR0_PCTL_ECCLOG 0xc883918c +#define DDR0_PCTL_ECCCLR 0xc8839188 +#define DDR0_PCTL_ECCTST 0xc8839184 +#define DDR0_PCTL_DTUWD0 0xc8839210 +#define DDR0_PCTL_DTUWD1 0xc8839214 +#define DDR0_PCTL_DTUWACTL 0xc8839200 +#define DDR0_PCTL_DTULFSRRD 0xc8839238 +#define DDR0_PCTL_DTUWD2 0xc8839218 +#define DDR0_PCTL_DTUWD3 0xc883921c +#define DDR0_PCTL_DTULFSRWD 0xc8839234 +#define DDR0_PCTL_DTURACTL 0xc8839204 +#define DDR0_PCTL_DTUWDM 0xc8839220 +#define DDR0_PCTL_DTURD0 0xc8839224 +#define DDR0_PCTL_DTURD1 0xc8839228 +#define DDR0_PCTL_DTURD2 0xc883922c +#define DDR0_PCTL_DTURD3 0xc8839230 +#define DDR0_PCTL_DTUCFG 0xc8839208 +#define DDR0_PCTL_DTUEAF 0xc883923c +#define DDR0_PCTL_DTUECTL 0xc883920c +#define DDR0_PCTL_DFIODTCFG1 0xc8839248 +#define DDR0_PCTL_DFITCTRLDELAY 0xc8839240 +#define DDR0_PCTL_DFIODTRANKMAP 0xc883924c +#define DDR0_PCTL_DFIODTCFG 0xc8839244 +#define DDR0_PCTL_DFITPHYWRLAT 0xc8839254 +#define DDR0_PCTL_DFITPHYWRDATA 0xc8839250 +#define DDR0_PCTL_DFITRDDATAEN 0xc8839260 +#define DDR0_PCTL_DFITPHYRDLAT 0xc8839264 +#define DDR0_PCTL_DFITREFMSKI 0xc8839294 +#define DDR0_PCTL_DFITPHYUPDTYPE0 0xc8839270 +#define DDR0_PCTL_DFITPHYUPDTYPE1 0xc8839274 +#define DDR0_PCTL_DFITCTRLUPDDLY 0xc8839288 +#define DDR0_PCTL_DFITPHYUPDTYPE2 0xc8839278 +#define DDR0_PCTL_DFITCTRLUPDMIN 0xc8839280 +#define DDR0_PCTL_DFITPHYUPDTYPE3 0xc883927c +#define DDR0_PCTL_DFIUPDCFG 0xc8839290 +#define DDR0_PCTL_DFITCTRLUPDMAX 0xc8839284 +#define DDR0_PCTL_DFITCTRLUPDI 0xc8839298 +#define DDR0_PCTL_DFITRRDLVLEN 0xc88392b8 +#define DDR0_PCTL_DFITRSTAT0 0xc88392b0 +#define DDR0_PCTL_DFITRWRLVLEN 0xc88392b4 +#define DDR0_PCTL_DFITRCFG0 0xc88392ac +#define DDR0_PCTL_DFITRRDLVLGATEEN 0xc88392bc +#define DDR0_PCTL_DFISTSTAT0 0xc88392c0 +#define DDR0_PCTL_DFISTPARLOG 0xc88392e0 +#define DDR0_PCTL_DFITDRAMCLKEN 0xc88392d0 +#define DDR0_PCTL_DFISTPARCLR 0xc88392dc +#define DDR0_PCTL_DFISTCFG0 0xc88392c4 +#define DDR0_PCTL_DFISTCFG1 0xc88392c8 +#define DDR0_PCTL_DFISTCFG2 0xc88392d8 +#define DDR0_PCTL_DFITDRAMCLKDIS 0xc88392d4 +#define DDR0_PCTL_DFILPCFG0 0xc88392f0 +#define DDR0_PCTL_DFITRWRLVLDELAY0 0xc8839318 +#define DDR0_PCTL_DFITRWRLVLDELAY1 0xc883931c +#define DDR0_PCTL_DFITRWRLVLDELAY2 0xc8839320 +#define DDR0_PCTL_DFITRRDLVLRESP0 0xc883930c +#define DDR0_PCTL_DFITRRDLVLRESP1 0xc8839310 +#define DDR0_PCTL_DFITRRDLVLRESP2 0xc8839314 +#define DDR0_PCTL_DFITRWRLVLRESP0 0xc8839300 +#define DDR0_PCTL_DFITRRDLVLDELAY0 0xc8839324 +#define DDR0_PCTL_DFITRRDLVLDELAY1 0xc8839328 +#define DDR0_PCTL_DFITRWRLVLRESP1 0xc8839304 +#define DDR0_PCTL_DFITRRDLVLDELAY2 0xc883932c +#define DDR0_PCTL_DFITRWRLVLRESP2 0xc8839308 +#define DDR0_PCTL_DFITRRDLVLGATEDELAY0 0xc8839330 +#define DDR0_PCTL_DFITRCMD 0xc883933c +#define DDR0_PCTL_DFITRRDLVLGATEDELAY1 0xc8839334 +#define DDR0_PCTL_DFITRRDLVLGATEDELAY2 0xc8839338 +#define DDR0_PCTL_IPTR 0xc88393fc +#define DDR0_PCTL_IPVR 0xc88393f8 + +#define DDR1_PCTL_SCFG 0xc8839400 +#define DDR1_PCTL_SCTL 0xc8839404 +#define DDR1_PCTL_STAT 0xc8839408 +#define DDR1_PCTL_INTRSTAT 0xc883940c +#define DDR1_PCTL_POWSTAT 0xc8839448 +#define DDR1_PCTL_MRRSTAT0 0xc8839464 +#define DDR1_PCTL_CMDTSTAT 0xc883944c +#define DDR1_PCTL_MCMD 0xc8839440 +#define DDR1_PCTL_MRRSTAT1 0xc8839468 +#define DDR1_PCTL_MRRCFG0 0xc8839460 +#define DDR1_PCTL_CMDTSTATEN 0xc8839450 +#define DDR1_PCTL_POWCTL 0xc8839444 +#define DDR1_PCTL_PPCFG 0xc8839484 +#define DDR1_PCTL_LPDDR23ZQCFG 0xc883948c +#define DDR1_PCTL_MCFG1 0xc883947c +#define DDR1_PCTL_MSTAT 0xc8839488 +#define DDR1_PCTL_MCFG 0xc8839480 +#define DDR1_PCTL_DTUAWDT 0xc88394b0 +#define DDR1_PCTL_DTUPRD2 0xc88394a8 +#define DDR1_PCTL_DTUPRD3 0xc88394ac +#define DDR1_PCTL_DTUNE 0xc883949c +#define DDR1_PCTL_DTUPDES 0xc8839494 +#define DDR1_PCTL_DTUNA 0xc8839498 +#define DDR1_PCTL_DTUPRD0 0xc88394a0 +#define DDR1_PCTL_DTUPRD1 0xc88394a4 +#define DDR1_PCTL_TCKSRE 0xc8839524 +#define DDR1_PCTL_TZQCSI 0xc883951c +#define DDR1_PCTL_TINIT 0xc88394c4 +#define DDR1_PCTL_TDPD 0xc8839544 +#define DDR1_PCTL_TOGCNT1U 0xc88394c0 +#define DDR1_PCTL_TCKE 0xc883952c +#define DDR1_PCTL_TMOD 0xc8839530 +#define DDR1_PCTL_TEXSR 0xc883950c +#define DDR1_PCTL_TAL 0xc88394e4 +#define DDR1_PCTL_TRTP 0xc8839500 +#define DDR1_PCTL_TCKSRX 0xc8839528 +#define DDR1_PCTL_TRTW 0xc88394e0 +#define DDR1_PCTL_TCWL 0xc88394ec +#define DDR1_PCTL_TWR 0xc8839504 +#define DDR1_PCTL_TCL 0xc88394e8 +#define DDR1_PCTL_TDQS 0xc8839520 +#define DDR1_PCTL_TRSTH 0xc88394c8 +#define DDR1_PCTL_TRCD 0xc88394f8 +#define DDR1_PCTL_TXP 0xc8839510 +#define DDR1_PCTL_TOGCNT100N 0xc88394cc +#define DDR1_PCTL_TMRD 0xc88394d4 +#define DDR1_PCTL_TRSTL 0xc8839534 +#define DDR1_PCTL_TREFI 0xc88394d0 +#define DDR1_PCTL_TRAS 0xc88394f0 +#define DDR1_PCTL_TREFI_MEM_DDR3 0xc8839548 +#define DDR1_PCTL_TWTR 0xc8839508 +#define DDR1_PCTL_TRC 0xc88394f4 +#define DDR1_PCTL_TRFC 0xc88394d8 +#define DDR1_PCTL_TMRR 0xc883953c +#define DDR1_PCTL_TCKESR 0xc8839540 +#define DDR1_PCTL_TZQCL 0xc8839538 +#define DDR1_PCTL_TRRD 0xc88394fc +#define DDR1_PCTL_TRP 0xc88394dc +#define DDR1_PCTL_TZQCS 0xc8839518 +#define DDR1_PCTL_TXPDLL 0xc8839514 +#define DDR1_PCTL_ECCCFG 0xc8839580 +#define DDR1_PCTL_ECCLOG 0xc883958c +#define DDR1_PCTL_ECCCLR 0xc8839588 +#define DDR1_PCTL_ECCTST 0xc8839584 +#define DDR1_PCTL_DTUWD0 0xc8839610 +#define DDR1_PCTL_DTUWD1 0xc8839614 +#define DDR1_PCTL_DTUWACTL 0xc8839600 +#define DDR1_PCTL_DTULFSRRD 0xc8839638 +#define DDR1_PCTL_DTUWD2 0xc8839618 +#define DDR1_PCTL_DTUWD3 0xc883961c +#define DDR1_PCTL_DTULFSRWD 0xc8839634 +#define DDR1_PCTL_DTURACTL 0xc8839604 +#define DDR1_PCTL_DTUWDM 0xc8839620 +#define DDR1_PCTL_DTURD0 0xc8839624 +#define DDR1_PCTL_DTURD1 0xc8839628 +#define DDR1_PCTL_DTURD2 0xc883962c +#define DDR1_PCTL_DTURD3 0xc8839630 +#define DDR1_PCTL_DTUCFG 0xc8839608 +#define DDR1_PCTL_DTUEAF 0xc883963c +#define DDR1_PCTL_DTUECTL 0xc883960c +#define DDR1_PCTL_DFIODTCFG1 0xc8839648 +#define DDR1_PCTL_DFITCTRLDELAY 0xc8839640 +#define DDR1_PCTL_DFIODTRANKMAP 0xc883964c +#define DDR1_PCTL_DFIODTCFG 0xc8839644 +#define DDR1_PCTL_DFITPHYWRLAT 0xc8839654 +#define DDR1_PCTL_DFITPHYWRDATA 0xc8839650 +#define DDR1_PCTL_DFITRDDATAEN 0xc8839660 +#define DDR1_PCTL_DFITPHYRDLAT 0xc8839664 +#define DDR1_PCTL_DFITREFMSKI 0xc8839694 +#define DDR1_PCTL_DFITPHYUPDTYPE0 0xc8839670 +#define DDR1_PCTL_DFITPHYUPDTYPE1 0xc8839674 +#define DDR1_PCTL_DFITCTRLUPDDLY 0xc8839688 +#define DDR1_PCTL_DFITPHYUPDTYPE2 0xc8839678 +#define DDR1_PCTL_DFITCTRLUPDMIN 0xc8839680 +#define DDR1_PCTL_DFITPHYUPDTYPE3 0xc883967c +#define DDR1_PCTL_DFIUPDCFG 0xc8839690 +#define DDR1_PCTL_DFITCTRLUPDMAX 0xc8839684 +#define DDR1_PCTL_DFITCTRLUPDI 0xc8839698 +#define DDR1_PCTL_DFITRRDLVLEN 0xc88396b8 +#define DDR1_PCTL_DFITRSTAT0 0xc88396b0 +#define DDR1_PCTL_DFITRWRLVLEN 0xc88396b4 +#define DDR1_PCTL_DFITRCFG0 0xc88396ac +#define DDR1_PCTL_DFITRRDLVLGATEEN 0xc88396bc +#define DDR1_PCTL_DFISTSTAT0 0xc88396c0 +#define DDR1_PCTL_DFISTPARLOG 0xc88396e0 +#define DDR1_PCTL_DFITDRAMCLKEN 0xc88396d0 +#define DDR1_PCTL_DFISTPARCLR 0xc88396dc +#define DDR1_PCTL_DFISTCFG0 0xc88396c4 +#define DDR1_PCTL_DFISTCFG1 0xc88396c8 +#define DDR1_PCTL_DFISTCFG2 0xc88396d8 +#define DDR1_PCTL_DFITDRAMCLKDIS 0xc88396d4 +#define DDR1_PCTL_DFILPCFG0 0xc88396f0 +#define DDR1_PCTL_DFITRWRLVLDELAY0 0xc8839718 +#define DDR1_PCTL_DFITRWRLVLDELAY1 0xc883971c +#define DDR1_PCTL_DFITRWRLVLDELAY2 0xc8839720 +#define DDR1_PCTL_DFITRRDLVLRESP0 0xc883970c +#define DDR1_PCTL_DFITRRDLVLRESP1 0xc8839710 +#define DDR1_PCTL_DFITRRDLVLRESP2 0xc8839714 +#define DDR1_PCTL_DFITRWRLVLRESP0 0xc8839700 +#define DDR1_PCTL_DFITRRDLVLDELAY0 0xc8839724 +#define DDR1_PCTL_DFITRRDLVLDELAY1 0xc8839728 +#define DDR1_PCTL_DFITRWRLVLRESP1 0xc8839704 +#define DDR1_PCTL_DFITRRDLVLDELAY2 0xc883972c +#define DDR1_PCTL_DFITRWRLVLRESP2 0xc8839708 +#define DDR1_PCTL_DFITRRDLVLGATEDELAY0 0xc8839730 +#define DDR1_PCTL_DFITRCMD 0xc883973c +#define DDR1_PCTL_DFITRRDLVLGATEDELAY1 0xc8839734 +#define DDR1_PCTL_DFITRRDLVLGATEDELAY2 0xc8839738 +#define DDR1_PCTL_IPTR 0xc88397fc +#define DDR1_PCTL_IPVR 0xc88397f8 diff --git a/plat/gxb/ddr/ddr_pub_define.h b/plat/gxb/ddr/ddr_pub_define.h new file mode 100644 index 0000000..471965d --- /dev/null +++ b/plat/gxb/ddr/ddr_pub_define.h @@ -0,0 +1,305 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/ddr/ddr_pub_define.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#define DDR0_PUB_REG_BASE 0xc8836000 + +#define DDR0_PUB_RIDR (DDR0_PUB_REG_BASE+(0x00<<2)) +#define DDR0_PUB_PIR (DDR0_PUB_REG_BASE+(0x01<<2)) +#define DDR0_PUB_PGCR0 (DDR0_PUB_REG_BASE+(0x02<<2)) +#define DDR0_PUB_PGCR1 (DDR0_PUB_REG_BASE+(0x03<<2)) +#define DDR0_PUB_PGCR2 (DDR0_PUB_REG_BASE+(0x04<<2)) +#define DDR0_PUB_PGCR3 (DDR0_PUB_REG_BASE+(0x05<<2)) +#define DDR0_PUB_PGSR0 (DDR0_PUB_REG_BASE+(0x06<<2)) +#define DDR0_PUB_PGSR1 (DDR0_PUB_REG_BASE+(0x07<<2)) +#define DDR0_PUB_PLLCR (DDR0_PUB_REG_BASE+(0x08<<2)) +#define DDR0_PUB_PTR0 (DDR0_PUB_REG_BASE+(0x09<<2)) +#define DDR0_PUB_PTR1 (DDR0_PUB_REG_BASE+(0x0A<<2)) +#define DDR0_PUB_PTR2 (DDR0_PUB_REG_BASE+(0x0B<<2)) +#define DDR0_PUB_PTR3 (DDR0_PUB_REG_BASE+(0x0C<<2)) +#define DDR0_PUB_PTR4 (DDR0_PUB_REG_BASE+(0x0D<<2)) +#define DDR0_PUB_ACMDLR (DDR0_PUB_REG_BASE+(0x0E<<2)) +#define DDR0_PUB_ACLCDLR (DDR0_PUB_REG_BASE+(0x0F<<2)) +#define DDR0_PUB_ACBDLR0 (DDR0_PUB_REG_BASE+(0x10<<2)) +#define DDR0_PUB_ACBDLR1 (DDR0_PUB_REG_BASE+(0x11<<2)) +#define DDR0_PUB_ACBDLR2 (DDR0_PUB_REG_BASE+(0x12<<2)) +#define DDR0_PUB_ACBDLR3 (DDR0_PUB_REG_BASE+(0x13<<2)) +#define DDR0_PUB_ACBDLR4 (DDR0_PUB_REG_BASE+(0x14<<2)) +#define DDR0_PUB_ACBDLR5 (DDR0_PUB_REG_BASE+(0x15<<2)) +#define DDR0_PUB_ACBDLR6 (DDR0_PUB_REG_BASE+(0x16<<2)) +#define DDR0_PUB_ACBDLR7 (DDR0_PUB_REG_BASE+(0x17<<2)) +#define DDR0_PUB_ACBDLR8 (DDR0_PUB_REG_BASE+(0x18<<2)) +#define DDR0_PUB_ACBDLR9 (DDR0_PUB_REG_BASE+(0x19<<2)) +#define DDR0_PUB_ACIOCR0 (DDR0_PUB_REG_BASE+(0x1A<<2)) +#define DDR0_PUB_ACIOCR1 (DDR0_PUB_REG_BASE+(0x1B<<2)) +#define DDR0_PUB_ACIOCR2 (DDR0_PUB_REG_BASE+(0x1C<<2)) +#define DDR0_PUB_ACIOCR3 (DDR0_PUB_REG_BASE+(0x1D<<2)) +#define DDR0_PUB_ACIOCR4 (DDR0_PUB_REG_BASE+(0x1E<<2)) +#define DDR0_PUB_ACIOCR5 (DDR0_PUB_REG_BASE+(0x1F<<2)) +#define DDR0_PUB_DXCCR (DDR0_PUB_REG_BASE+(0x20<<2)) +#define DDR0_PUB_DSGCR (DDR0_PUB_REG_BASE+(0x21<<2)) +#define DDR0_PUB_DCR (DDR0_PUB_REG_BASE+(0x22<<2)) +#define DDR0_PUB_DTPR0 (DDR0_PUB_REG_BASE+(0x23<<2)) +#define DDR0_PUB_DTPR1 (DDR0_PUB_REG_BASE+(0x24<<2)) +#define DDR0_PUB_DTPR2 (DDR0_PUB_REG_BASE+(0x25<<2)) +#define DDR0_PUB_DTPR3 (DDR0_PUB_REG_BASE+(0x26<<2)) +#define DDR0_PUB_MR0 (DDR0_PUB_REG_BASE+(0x27<<2)) +#define DDR0_PUB_MR1 (DDR0_PUB_REG_BASE+(0x28<<2)) +#define DDR0_PUB_MR2 (DDR0_PUB_REG_BASE+(0x29<<2)) +#define DDR0_PUB_MR3 (DDR0_PUB_REG_BASE+(0x2A<<2)) +#define DDR0_PUB_ODTCR (DDR0_PUB_REG_BASE+(0x2B<<2)) +#define DDR0_PUB_DTCR (DDR0_PUB_REG_BASE+(0x2C<<2)) +#define DDR0_PUB_DTAR0 (DDR0_PUB_REG_BASE+(0x2D<<2)) +#define DDR0_PUB_DTAR1 (DDR0_PUB_REG_BASE+(0x2E<<2)) +#define DDR0_PUB_DTAR2 (DDR0_PUB_REG_BASE+(0x2F<<2)) +#define DDR0_PUB_DTAR3 (DDR0_PUB_REG_BASE+(0x30<<2)) +#define DDR0_PUB_DTDR0 (DDR0_PUB_REG_BASE+(0x31<<2)) +#define DDR0_PUB_DTDR1 (DDR0_PUB_REG_BASE+(0x32<<2)) +#define DDR0_PUB_DTEDR0 (DDR0_PUB_REG_BASE+(0x33<<2)) +#define DDR0_PUB_DTEDR1 (DDR0_PUB_REG_BASE+(0x34<<2)) +#define DDR0_PUB_RDIMMGCR0 (DDR0_PUB_REG_BASE+(0x35<<2)) +#define DDR0_PUB_RDIMMGCR1 (DDR0_PUB_REG_BASE+(0x36<<2)) +#define DDR0_PUB_RDIMMCR0 (DDR0_PUB_REG_BASE+(0x37<<2)) +#define DDR0_PUB_RDIMMCR1 (DDR0_PUB_REG_BASE+(0x38<<2)) +#define DDR0_PUB_GPR0 (DDR0_PUB_REG_BASE+(0x39<<2)) +#define DDR0_PUB_GPR1 (DDR0_PUB_REG_BASE+(0x3A<<2)) +#define DDR0_PUB_CATR0 (DDR0_PUB_REG_BASE+(0x3B<<2)) +#define DDR0_PUB_CATR1 (DDR0_PUB_REG_BASE+(0x3C<<2)) +//0x3D-32'h5F reserved) +#define DDR0_PUB_DCUAR (DDR0_PUB_REG_BASE+(0x60<<2)) +#define DDR0_PUB_DCUDR (DDR0_PUB_REG_BASE+(0x61<<2)) +#define DDR0_PUB_DCURR (DDR0_PUB_REG_BASE+(0x62<<2)) +#define DDR0_PUB_DCULR (DDR0_PUB_REG_BASE+(0x63<<2)) +#define DDR0_PUB_DCUGCR (DDR0_PUB_REG_BASE+(0x64<<2)) +#define DDR0_PUB_DCUTPR (DDR0_PUB_REG_BASE+(0x65<<2)) +#define DDR0_PUB_DCUSR0 (DDR0_PUB_REG_BASE+(0x66<<2)) +#define DDR0_PUB_DCUSR1 (DDR0_PUB_REG_BASE+(0x67<<2)) +//0x68-32'h6F reserved) +#define DDR0_PUB_BISTRR (DDR0_PUB_REG_BASE+(0x70<<2)) +#define DDR0_PUB_BISTWCR (DDR0_PUB_REG_BASE+(0x71<<2)) +#define DDR0_PUB_BISTMSKR0 (DDR0_PUB_REG_BASE+(0x72<<2)) +#define DDR0_PUB_BISTMSKR1 (DDR0_PUB_REG_BASE+(0x73<<2)) +#define DDR0_PUB_BISTMSKR2 (DDR0_PUB_REG_BASE+(0x74<<2)) +#define DDR0_PUB_BISTLSR (DDR0_PUB_REG_BASE+(0x75<<2)) +#define DDR0_PUB_BISTAR0 (DDR0_PUB_REG_BASE+(0x76<<2)) +#define DDR0_PUB_BISTAR1 (DDR0_PUB_REG_BASE+(0x77<<2)) +#define DDR0_PUB_BISTAR2 (DDR0_PUB_REG_BASE+(0x78<<2)) +#define DDR0_PUB_BISTUDPR (DDR0_PUB_REG_BASE+(0x79<<2)) +#define DDR0_PUB_BISTGSR (DDR0_PUB_REG_BASE+(0x7A<<2)) +#define DDR0_PUB_BISTWER (DDR0_PUB_REG_BASE+(0x7B<<2)) +#define DDR0_PUB_BISTBER0 (DDR0_PUB_REG_BASE+(0x7C<<2)) +#define DDR0_PUB_BISTBER1 (DDR0_PUB_REG_BASE+(0x7D<<2)) +#define DDR0_PUB_BISTBER2 (DDR0_PUB_REG_BASE+(0x7E<<2)) +#define DDR0_PUB_BISTBER3 (DDR0_PUB_REG_BASE+(0x7F<<2)) +#define DDR0_PUB_BISTWCSR (DDR0_PUB_REG_BASE+(0x80<<2)) +#define DDR0_PUB_BISTFWR0 (DDR0_PUB_REG_BASE+(0x81<<2)) +#define DDR0_PUB_BISTFWR1 (DDR0_PUB_REG_BASE+(0x82<<2)) +#define DDR0_PUB_BISTFWR2 (DDR0_PUB_REG_BASE+(0x83<<2)) +//0x84-32'h8D reserved) +#define DDR0_PUB_IOVCR0 (DDR0_PUB_REG_BASE+(0x8E<<2)) +#define DDR0_PUB_IOVCR1 (DDR0_PUB_REG_BASE+(0x8F<<2)) +#define DDR0_PUB_ZQCR (DDR0_PUB_REG_BASE+(0x90<<2)) +#define DDR0_PUB_ZQ0PR (DDR0_PUB_REG_BASE+(0x91<<2)) +#define DDR0_PUB_ZQ0DR (DDR0_PUB_REG_BASE+(0x92<<2)) +#define DDR0_PUB_ZQ0SR (DDR0_PUB_REG_BASE+(0x93<<2)) +//0x94 reserved) +#define DDR0_PUB_ZQ1PR (DDR0_PUB_REG_BASE+(0x95<<2)) +#define DDR0_PUB_ZQ1DR (DDR0_PUB_REG_BASE+(0x96<<2)) +#define DDR0_PUB_ZQ1SR (DDR0_PUB_REG_BASE+(0x97<<2)) +//0x98 reserved) +#define DDR0_PUB_ZQ2PR (DDR0_PUB_REG_BASE+(0x99<<2)) +#define DDR0_PUB_ZQ2DR (DDR0_PUB_REG_BASE+(0x9A<<2)) +#define DDR0_PUB_ZQ2SR (DDR0_PUB_REG_BASE+(0x9B<<2)) +//0x9c reserved) +#define DDR0_PUB_ZQ3PR (DDR0_PUB_REG_BASE+(0x9D<<2)) +#define DDR0_PUB_ZQ3DR (DDR0_PUB_REG_BASE+(0x9E<<2)) +#define DDR0_PUB_ZQ3SR (DDR0_PUB_REG_BASE+(0x9F<<2)) +#define DDR0_PUB_DX0GCR0 (DDR0_PUB_REG_BASE+(0xA0<<2)) +#define DDR0_PUB_DX0GCR1 (DDR0_PUB_REG_BASE+(0xA1<<2)) +#define DDR0_PUB_DX0GCR2 (DDR0_PUB_REG_BASE+(0xA2<<2)) +#define DDR0_PUB_DX0GCR3 (DDR0_PUB_REG_BASE+(0xA3<<2)) +#define DDR0_PUB_DX0GSR0 (DDR0_PUB_REG_BASE+(0xA4<<2)) +#define DDR0_PUB_DX0GSR1 (DDR0_PUB_REG_BASE+(0xA5<<2)) +#define DDR0_PUB_DX0GSR2 (DDR0_PUB_REG_BASE+(0xA6<<2)) +#define DDR0_PUB_DX0BDLR0 (DDR0_PUB_REG_BASE+(0xA7<<2)) +#define DDR0_PUB_DX0BDLR1 (DDR0_PUB_REG_BASE+(0xA8<<2)) +#define DDR0_PUB_DX0BDLR2 (DDR0_PUB_REG_BASE+(0xA9<<2)) +#define DDR0_PUB_DX0BDLR3 (DDR0_PUB_REG_BASE+(0xAA<<2)) +#define DDR0_PUB_DX0BDLR4 (DDR0_PUB_REG_BASE+(0xAB<<2)) +#define DDR0_PUB_DX0BDLR5 (DDR0_PUB_REG_BASE+(0xAC<<2)) +#define DDR0_PUB_DX0BDLR6 (DDR0_PUB_REG_BASE+(0xAD<<2)) +#define DDR0_PUB_DX0LCDLR0 (DDR0_PUB_REG_BASE+(0xAE<<2)) +#define DDR0_PUB_DX0LCDLR1 (DDR0_PUB_REG_BASE+(0xAF<<2)) +#define DDR0_PUB_DX0LCDLR2 (DDR0_PUB_REG_BASE+(0xB0<<2)) +#define DDR0_PUB_DX0MDLR (DDR0_PUB_REG_BASE+(0xB1<<2)) +#define DDR0_PUB_DX0GTR (DDR0_PUB_REG_BASE+(0xB2<<2)) +//0xB4-32'hBF reserved) +#define DDR0_PUB_DX1GCR0 (DDR0_PUB_REG_BASE+(0xC0<<2)) +#define DDR0_PUB_DX1GCR1 (DDR0_PUB_REG_BASE+(0xC1<<2)) +#define DDR0_PUB_DX1GCR2 (DDR0_PUB_REG_BASE+(0xC2<<2)) +#define DDR0_PUB_DX1GCR3 (DDR0_PUB_REG_BASE+(0xC3<<2)) +#define DDR0_PUB_DX1GSR0 (DDR0_PUB_REG_BASE+(0xC4<<2)) +#define DDR0_PUB_DX1GSR1 (DDR0_PUB_REG_BASE+(0xC5<<2)) +#define DDR0_PUB_DX1GSR2 (DDR0_PUB_REG_BASE+(0xC6<<2)) +#define DDR0_PUB_DX1BDLR0 (DDR0_PUB_REG_BASE+(0xC7<<2)) +#define DDR0_PUB_DX1BDLR1 (DDR0_PUB_REG_BASE+(0xC8<<2)) +#define DDR0_PUB_DX1BDLR2 (DDR0_PUB_REG_BASE+(0xC9<<2)) +#define DDR0_PUB_DX1BDLR3 (DDR0_PUB_REG_BASE+(0xCA<<2)) +#define DDR0_PUB_DX1BDLR4 (DDR0_PUB_REG_BASE+(0xCB<<2)) +#define DDR0_PUB_DX1BDLR5 (DDR0_PUB_REG_BASE+(0xCC<<2)) +#define DDR0_PUB_DX1BDLR6 (DDR0_PUB_REG_BASE+(0xCD<<2)) +#define DDR0_PUB_DX1LCDLR0 (DDR0_PUB_REG_BASE+(0xCE<<2)) +#define DDR0_PUB_DX1LCDLR1 (DDR0_PUB_REG_BASE+(0xCF<<2)) +#define DDR0_PUB_DX1LCDLR2 (DDR0_PUB_REG_BASE+(0xD0<<2)) +#define DDR0_PUB_DX1MDLR (DDR0_PUB_REG_BASE+(0xD1<<2)) +#define DDR0_PUB_DX1GTR (DDR0_PUB_REG_BASE+(0xD2<<2)) +#define DDR0_PUB_DX2GCR0 (DDR0_PUB_REG_BASE+(0xE0<<2)) +#define DDR0_PUB_DX2GCR1 (DDR0_PUB_REG_BASE+(0xE1<<2)) +#define DDR0_PUB_DX2GCR2 (DDR0_PUB_REG_BASE+(0xE2<<2)) +#define DDR0_PUB_DX2GCR3 (DDR0_PUB_REG_BASE+(0xE3<<2)) +#define DDR0_PUB_DX2GSR0 (DDR0_PUB_REG_BASE+(0xE4<<2)) +#define DDR0_PUB_DX2GSR1 (DDR0_PUB_REG_BASE+(0xE5<<2)) +#define DDR0_PUB_DX2GSR2 (DDR0_PUB_REG_BASE+(0xE6<<2)) +#define DDR0_PUB_DX2BDLR0 (DDR0_PUB_REG_BASE+(0xE7<<2)) +#define DDR0_PUB_DX2BDLR1 (DDR0_PUB_REG_BASE+(0xE8<<2)) +#define DDR0_PUB_DX2BDLR2 (DDR0_PUB_REG_BASE+(0xE9<<2)) +#define DDR0_PUB_DX2BDLR3 (DDR0_PUB_REG_BASE+(0xEA<<2)) +#define DDR0_PUB_DX2BDLR4 (DDR0_PUB_REG_BASE+(0xEB<<2)) +#define DDR0_PUB_DX2BDLR5 (DDR0_PUB_REG_BASE+(0xEC<<2)) +#define DDR0_PUB_DX2BDLR6 (DDR0_PUB_REG_BASE+(0xED<<2)) +#define DDR0_PUB_DX2LCDLR0 (DDR0_PUB_REG_BASE+(0xEE<<2)) +#define DDR0_PUB_DX2LCDLR1 (DDR0_PUB_REG_BASE+(0xEF<<2)) +#define DDR0_PUB_DX2LCDLR2 (DDR0_PUB_REG_BASE+(0xF0<<2)) +#define DDR0_PUB_DX2MDLR (DDR0_PUB_REG_BASE+(0xF1<<2)) +#define DDR0_PUB_DX2GTR (DDR0_PUB_REG_BASE+(0xF2<<2)) +#define DDR0_PUB_DX3GCR0 (DDR0_PUB_REG_BASE+(0x100<<2)) +#define DDR0_PUB_DX3GCR1 (DDR0_PUB_REG_BASE+(0x101<<2)) +#define DDR0_PUB_DX3GCR2 (DDR0_PUB_REG_BASE+(0x102<<2)) +#define DDR0_PUB_DX3GCR3 (DDR0_PUB_REG_BASE+(0x103<<2)) +#define DDR0_PUB_DX3GSR0 (DDR0_PUB_REG_BASE+(0x104<<2)) +#define DDR0_PUB_DX3GSR1 (DDR0_PUB_REG_BASE+(0x105<<2)) +#define DDR0_PUB_DX3GSR2 (DDR0_PUB_REG_BASE+(0x106<<2)) +#define DDR0_PUB_DX3BDLR0 (DDR0_PUB_REG_BASE+(0x107<<2)) +#define DDR0_PUB_DX3BDLR1 (DDR0_PUB_REG_BASE+(0x108<<2)) +#define DDR0_PUB_DX3BDLR2 (DDR0_PUB_REG_BASE+(0x109<<2)) +#define DDR0_PUB_DX3BDLR3 (DDR0_PUB_REG_BASE+(0x10A<<2)) +#define DDR0_PUB_DX3BDLR4 (DDR0_PUB_REG_BASE+(0x10B<<2)) +#define DDR0_PUB_DX3BDLR5 (DDR0_PUB_REG_BASE+(0x10C<<2)) +#define DDR0_PUB_DX3BDLR6 (DDR0_PUB_REG_BASE+(0x10D<<2)) +#define DDR0_PUB_DX3LCDLR0 (DDR0_PUB_REG_BASE+(0x10E<<2)) +#define DDR0_PUB_DX3LCDLR1 (DDR0_PUB_REG_BASE+(0x10F<<2)) +#define DDR0_PUB_DX3LCDLR2 (DDR0_PUB_REG_BASE+(0x110<<2)) +#define DDR0_PUB_DX3MDLR (DDR0_PUB_REG_BASE+(0x111<<2)) +#define DDR0_PUB_DX3GTR (DDR0_PUB_REG_BASE+(0x112<<2)) +#define DDR0_PUB_DX4GCR0 (DDR0_PUB_REG_BASE+(0x120<<2)) +#define DDR0_PUB_DX4GCR1 (DDR0_PUB_REG_BASE+(0x121<<2)) +#define DDR0_PUB_DX4GCR2 (DDR0_PUB_REG_BASE+(0x122<<2)) +#define DDR0_PUB_DX4GCR3 (DDR0_PUB_REG_BASE+(0x123<<2)) +#define DDR0_PUB_DX4GSR0 (DDR0_PUB_REG_BASE+(0x124<<2)) +#define DDR0_PUB_DX4GSR1 (DDR0_PUB_REG_BASE+(0x125<<2)) +#define DDR0_PUB_DX4GSR2 (DDR0_PUB_REG_BASE+(0x126<<2)) +#define DDR0_PUB_DX4BDLR0 (DDR0_PUB_REG_BASE+(0x127<<2)) +#define DDR0_PUB_DX4BDLR1 (DDR0_PUB_REG_BASE+(0x128<<2)) +#define DDR0_PUB_DX4BDLR2 (DDR0_PUB_REG_BASE+(0x129<<2)) +#define DDR0_PUB_DX4BDLR3 (DDR0_PUB_REG_BASE+(0x12A<<2)) +#define DDR0_PUB_DX4BDLR4 (DDR0_PUB_REG_BASE+(0x12B<<2)) +#define DDR0_PUB_DX4BDLR5 (DDR0_PUB_REG_BASE+(0x12C<<2)) +#define DDR0_PUB_DX4BDLR6 (DDR0_PUB_REG_BASE+(0x12D<<2)) +#define DDR0_PUB_DX4LCDLR0 (DDR0_PUB_REG_BASE+(0x12E<<2)) +#define DDR0_PUB_DX4LCDLR1 (DDR0_PUB_REG_BASE+(0x12F<<2)) +#define DDR0_PUB_DX4LCDLR2 (DDR0_PUB_REG_BASE+(0x130<<2)) +#define DDR0_PUB_DX4MDLR (DDR0_PUB_REG_BASE+(0x131<<2)) +#define DDR0_PUB_DX4GTR (DDR0_PUB_REG_BASE+(0x132<<2)) +#define DDR0_PUB_DX5GCR0 (DDR0_PUB_REG_BASE+(0x140<<2)) +#define DDR0_PUB_DX5GCR1 (DDR0_PUB_REG_BASE+(0x141<<2)) +#define DDR0_PUB_DX5GCR2 (DDR0_PUB_REG_BASE+(0x142<<2)) +#define DDR0_PUB_DX5GCR3 (DDR0_PUB_REG_BASE+(0x143<<2)) +#define DDR0_PUB_DX5GSR0 (DDR0_PUB_REG_BASE+(0x144<<2)) +#define DDR0_PUB_DX5GSR1 (DDR0_PUB_REG_BASE+(0x145<<2)) +#define DDR0_PUB_DX5GSR2 (DDR0_PUB_REG_BASE+(0x146<<2)) +#define DDR0_PUB_DX5BDLR0 (DDR0_PUB_REG_BASE+(0x147<<2)) +#define DDR0_PUB_DX5BDLR1 (DDR0_PUB_REG_BASE+(0x148<<2)) +#define DDR0_PUB_DX5BDLR2 (DDR0_PUB_REG_BASE+(0x149<<2)) +#define DDR0_PUB_DX5BDLR3 (DDR0_PUB_REG_BASE+(0x14A<<2)) +#define DDR0_PUB_DX5BDLR4 (DDR0_PUB_REG_BASE+(0x14B<<2)) +#define DDR0_PUB_DX5BDLR5 (DDR0_PUB_REG_BASE+(0x14C<<2)) +#define DDR0_PUB_DX5BDLR6 (DDR0_PUB_REG_BASE+(0x14D<<2)) +#define DDR0_PUB_DX5LCDLR0 (DDR0_PUB_REG_BASE+(0x14E<<2)) +#define DDR0_PUB_DX5LCDLR1 (DDR0_PUB_REG_BASE+(0x14F<<2)) +#define DDR0_PUB_DX5LCDLR2 (DDR0_PUB_REG_BASE+(0x150<<2)) +#define DDR0_PUB_DX5MDLR (DDR0_PUB_REG_BASE+(0x151<<2)) +#define DDR0_PUB_DX5GTR (DDR0_PUB_REG_BASE+(0x152<<2)) +#define DDR0_PUB_DX6GCR0 (DDR0_PUB_REG_BASE+(0x160<<2)) +#define DDR0_PUB_DX6GCR1 (DDR0_PUB_REG_BASE+(0x161<<2)) +#define DDR0_PUB_DX6GCR2 (DDR0_PUB_REG_BASE+(0x162<<2)) +#define DDR0_PUB_DX6GCR3 (DDR0_PUB_REG_BASE+(0x163<<2)) +#define DDR0_PUB_DX6GSR0 (DDR0_PUB_REG_BASE+(0x164<<2)) +#define DDR0_PUB_DX6GSR1 (DDR0_PUB_REG_BASE+(0x165<<2)) +#define DDR0_PUB_DX6GSR2 (DDR0_PUB_REG_BASE+(0x166<<2)) +#define DDR0_PUB_DX6BDLR0 (DDR0_PUB_REG_BASE+(0x167<<2)) +#define DDR0_PUB_DX6BDLR1 (DDR0_PUB_REG_BASE+(0x168<<2)) +#define DDR0_PUB_DX6BDLR2 (DDR0_PUB_REG_BASE+(0x169<<2)) +#define DDR0_PUB_DX6BDLR3 (DDR0_PUB_REG_BASE+(0x16A<<2)) +#define DDR0_PUB_DX6BDLR4 (DDR0_PUB_REG_BASE+(0x16B<<2)) +#define DDR0_PUB_DX6BDLR5 (DDR0_PUB_REG_BASE+(0x16C<<2)) +#define DDR0_PUB_DX6BDLR6 (DDR0_PUB_REG_BASE+(0x16D<<2)) +#define DDR0_PUB_DX6LCDLR0 (DDR0_PUB_REG_BASE+(0x16E<<2)) +#define DDR0_PUB_DX6LCDLR1 (DDR0_PUB_REG_BASE+(0x16F<<2)) +#define DDR0_PUB_DX6LCDLR2 (DDR0_PUB_REG_BASE+(0x170<<2)) +#define DDR0_PUB_DX6MDLR (DDR0_PUB_REG_BASE+(0x171<<2)) +#define DDR0_PUB_DX6GTR (DDR0_PUB_REG_BASE+(0x172<<2)) +#define DDR0_PUB_DX7GCR0 (DDR0_PUB_REG_BASE+(0x180<<2)) +#define DDR0_PUB_DX7GCR1 (DDR0_PUB_REG_BASE+(0x181<<2)) +#define DDR0_PUB_DX7GCR2 (DDR0_PUB_REG_BASE+(0x182<<2)) +#define DDR0_PUB_DX7GCR3 (DDR0_PUB_REG_BASE+(0x183<<2)) +#define DDR0_PUB_DX7GSR0 (DDR0_PUB_REG_BASE+(0x184<<2)) +#define DDR0_PUB_DX7GSR1 (DDR0_PUB_REG_BASE+(0x185<<2)) +#define DDR0_PUB_DX7GSR2 (DDR0_PUB_REG_BASE+(0x186<<2)) +#define DDR0_PUB_DX7BDLR0 (DDR0_PUB_REG_BASE+(0x187<<2)) +#define DDR0_PUB_DX7BDLR1 (DDR0_PUB_REG_BASE+(0x188<<2)) +#define DDR0_PUB_DX7BDLR2 (DDR0_PUB_REG_BASE+(0x189<<2)) +#define DDR0_PUB_DX7BDLR3 (DDR0_PUB_REG_BASE+(0x18A<<2)) +#define DDR0_PUB_DX7BDLR4 (DDR0_PUB_REG_BASE+(0x18B<<2)) +#define DDR0_PUB_DX7BDLR5 (DDR0_PUB_REG_BASE+(0x18C<<2)) +#define DDR0_PUB_DX7BDLR6 (DDR0_PUB_REG_BASE+(0x18D<<2)) +#define DDR0_PUB_DX7LCDLR0 (DDR0_PUB_REG_BASE+(0x18E<<2)) +#define DDR0_PUB_DX7LCDLR1 (DDR0_PUB_REG_BASE+(0x18F<<2)) +#define DDR0_PUB_DX7LCDLR2 (DDR0_PUB_REG_BASE+(0x190<<2)) +#define DDR0_PUB_DX7MDLR (DDR0_PUB_REG_BASE+(0x191<<2)) +#define DDR0_PUB_DX7GTR (DDR0_PUB_REG_BASE+(0x192<<2)) +#define DDR0_PUB_DX8GCR0 (DDR0_PUB_REG_BASE+(0x1A0<<2)) +#define DDR0_PUB_DX8GCR1 (DDR0_PUB_REG_BASE+(0x1A1<<2)) +#define DDR0_PUB_DX8GCR2 (DDR0_PUB_REG_BASE+(0x1A2<<2)) +#define DDR0_PUB_DX8GCR3 (DDR0_PUB_REG_BASE+(0x1A3<<2)) +#define DDR0_PUB_DX8GSR0 (DDR0_PUB_REG_BASE+(0x1A4<<2)) +#define DDR0_PUB_DX8GSR1 (DDR0_PUB_REG_BASE+(0x1A5<<2)) +#define DDR0_PUB_DX8GSR2 (DDR0_PUB_REG_BASE+(0x1A6<<2)) +#define DDR0_PUB_DX8BDLR0 (DDR0_PUB_REG_BASE+(0x1A7<<2)) +#define DDR0_PUB_DX8BDLR1 (DDR0_PUB_REG_BASE+(0x1A8<<2)) +#define DDR0_PUB_DX8BDLR2 (DDR0_PUB_REG_BASE+(0x1A9<<2)) +#define DDR0_PUB_DX8BDLR3 (DDR0_PUB_REG_BASE+(0x1AA<<2)) +#define DDR0_PUB_DX8BDLR4 (DDR0_PUB_REG_BASE+(0x1AB<<2)) +#define DDR0_PUB_DX8BDLR5 (DDR0_PUB_REG_BASE+(0x1AC<<2)) +#define DDR0_PUB_DX8BDLR6 (DDR0_PUB_REG_BASE+(0x1AD<<2)) +#define DDR0_PUB_DX8LCDLR0 (DDR0_PUB_REG_BASE+(0x1AE<<2)) +#define DDR0_PUB_DX8LCDLR1 (DDR0_PUB_REG_BASE+(0x1AF<<2)) +#define DDR0_PUB_DX8LCDLR2 (DDR0_PUB_REG_BASE+(0x1B0<<2)) +#define DDR0_PUB_DX8MDLR (DDR0_PUB_REG_BASE+(0x1B1<<2)) +#define DDR0_PUB_DX8GTR (DDR0_PUB_REG_BASE+(0x1B2<<2)) diff --git a/plat/gxb/ddr/dmc_define.h b/plat/gxb/ddr/dmc_define.h new file mode 100644 index 0000000..20a607e --- /dev/null +++ b/plat/gxb/ddr/dmc_define.h @@ -0,0 +1,372 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/ddr/dmc_define.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#define DMC_REG_BASE 0xc8838000 + +#define DMC_REQ_CTRL (DMC_REG_BASE + (0x00 <<2 )) + //bit 11. enable dmc request of chan 11. Audio + //bit 10. enable dmc request of chan 10. Device. + //bit 9. enable dmc request of chan 9. VDEC2 + //bit 8. enable dmc request of chan 8. HCODEC + //bit 7. enable dmc request of chan 7. VDEC + //bit 6. enable dmc request of chan 6. VDIN + //bit 5. enable dmc request of chan 5. VDISP2 + //bit 4. enable dmc request of chan 4. VDISP + //bit 3. enable dmc request of chan 3. Mali + //bit 2. enable dmc request of chan 2. Mali + //bit 1. enable dmc request of chan 1. Mali + //bit 0. enable dmc request of chan 0. A9 +#define DMC_SOFT_RST (DMC_REG_BASE + (0x01 <<2 )) +#define DMC_SOFT_RST1 (DMC_REG_BASE + (0x02 <<2 )) +#define DMC_RST_STS (DMC_REG_BASE + (0x03 <<2 )) +#define DMC_RST_STS1 (DMC_REG_BASE + (0x04 <<2 )) +#define DMC_VERSION (DMC_REG_BASE + (0x05 <<2 )) + //read only default = 1. + +#define DMC_RAM_PD (DMC_REG_BASE + (0x11 <<2 )) + +#define DC_CAV_LUT_DATAL (DMC_REG_BASE + (0x12 <<2 )) + //low 32 bits of canvas data which need to be configured to canvas memory. +#define DC_CAV_LUT_DATAH (DMC_REG_BASE + (0x13 <<2 )) + //high 32bits of cavnas data which need to be configured to canvas memory. +#define DC_CAV_LUT_ADDR (DMC_REG_BASE + (0x14 <<2 )) + //bit 9:8. write 9:8 2'b10. the canvas data will saved in canvas memory with addres 7:0. + //bit 7:0. canvas address. +#define DC_CAV_LUT_RDATAL (DMC_REG_BASE + (0x15 <<2 )) +#define DC_CAV_LUT_RDATAH (DMC_REG_BASE + (0x16 <<2 )) +#define DMC_2ARB_CTRL (DMC_REG_BASE + (0x20 <<2 )) + +#define DMC_REFR_CTRL1 (DMC_REG_BASE + (0x23 <<2 )) + //bit23:16 tRFC waiting time, when hold nif command after refresh. + //bit 9 after refresh, hold nif command enable + //bit 8 when refresh req, hold nif command enable + //bit 7 dmc to control auto_refresh enable + //bit 6:4 refresh number per refresh cycle.. + //bit 3 pvt enable + //bit 2 zqc enable + //bit 1 ddr1 auto refresh dmc control select. + //bit 0 ddr0 auto refresh dmc control select. + +#define DMC_REFR_CTRL2 (DMC_REG_BASE + (0x24 <<2 )) + //bit 31:24 tZQCI + //bit 23:16 tPVTI + //bit 15:8 tREFI + //bit 7:0 t100ns + +#define DMC_PARB_CTRL (DMC_REG_BASE + (0x25 <<2 )) + //bit 17. default port1(MALI AXI port) urgent bit. + //bit 16 default port0(A9 AXI port ) urgent bit. + //bit 15:8 t_ugt_gap. when the consecutive urgent request granted over the t_ugt_wd times, we allow the number of non urgent request was granted by the port arbiter. + //bit 7:0. t_ugt_wd. + + +#define DMC_MON_CTRL2 (DMC_REG_BASE + (0x26 <<2 )) + //bit 31. qos_mon_en. write 1 to trigger the enable. polling this bit 0, means finished. or use interrupt to check finish. + //bit 30. qos_mon interrupt clear. clear the qos monitor result. read 1 = qos mon finish interrupt. + //bit 20. qos_mon_trig_sel. 1 = vsync. 0 = timer. + //bit 19:16. qos monitor channel select. select one at one time only. + //bit 15:0. port select for the selected channel. +#define DMC_MON_CTRL3 (DMC_REG_BASE + (0x27 <<2 )) + // qos_mon_clk_timer. How long to measure the bandwidth. + + +#define DMC_MON_ALL_REQ_CNT (DMC_REG_BASE + (0x28 <<2 )) + // at the test period, the whole MMC request time. +#define DMC_MON_ALL_GRANT_CNT (DMC_REG_BASE + (0x29 <<2 )) + // at the test period, the whole MMC granted data cycles. 64bits unit. +#define DMC_MON_ONE_GRANT_CNT (DMC_REG_BASE + (0x2a <<2 )) + // at the test period, the granted data cycles for the selected channel and ports. + +#define DMC_CLKG_CTRL0 (DMC_REG_BASE + (0x30 <<2 )) + //bit 29. enalbe auto clock gating for write rsp generation. + //bit 28. enalbe auto clock gating for read rsp generation. + //bit 27. enalbe auto clock gating for ddr1 read back data buffer. + //bit 26. enalbe auto clock gating for ddr0 read back data buffer. + //bit 25. enalbe auto clock gating for ddr1 command filter. + //bit 24. enalbe auto clock gating for ddr0 command filter. + //bit 23. enalbe auto clock gating for ddr1 write reorder buffer. + //bit 22. enalbe auto clock gating for ddr0 write reorder buffer. + //bit 21. enalbe auto clock gating for ddr1 write data buffer. + //bit 20. enalbe auto clock gating for ddr0 write data buffer. + //bit 19. enalbe auto clock gating for ddr1 read reorder buffer. + //bit 18. enalbe auto clock gating for ddr0 read reorder buffer. + //bit 17. enalbe auto clock gating for read canvas. + //bit 16. enalbe auto clock gating for write canvas. + //bit 15. enalbe auto clock gating for chan 15. + //bit 14. enalbe auto clock gating for chan 14. + //bit 13. enalbe auto clock gating for chan 13. + //bit 12. enalbe auto clock gating for chan 12. + //bit 11. enalbe auto clock gating for chan 11. + //bit 10. enalbe auto clock gating for chan 10. + //bit 9. enalbe auto clock gating for chan 9. + //bit 8. enalbe auto clock gating for chan 8. + //bit 7. enalbe auto clock gating for chan 7. + //bit 6. enalbe auto clock gating for chan 6. + //bit 5. enalbe auto clock gating for chan 5. + //bit 4. enalbe auto clock gating for chan 4. + //bit 3. enalbe auto clock gating for chan 3. + //bit 2. enalbe auto clock gating for chan 2. + //bit 1. enalbe auto clock gating for chan 1. + //bit 0. enalbe auto clock gating for chan 0. + +#define DMC_CLKG_CTRL1 (DMC_REG_BASE + (0x31 <<2 )) + //bit 29. force to disalbe the clock of write rsp generation. + //bit 28. force to disalbe the clock of read rsp generation. + //bit 27. force to disalbe the clock of ddr1 read back data buffer. + //bit 26. force to disalbe the clock of ddr0 read back data buffer. + //bit 25. force to disalbe the clock of ddr1 command filter. + //bit 24. force to disalbe the clock of ddr0 command filter. + //bit 23. force to disalbe the clock of ddr1 write reorder buffer. + //bit 22. force to disalbe the clock of ddr0 write reorder buffer. + //bit 21. force to disalbe the clock of ddr1 write data buffer. + //bit 20. force to disalbe the clock of ddr0 write data buffer. + //bit 19. force to disalbe the clock of ddr1 read reorder buffer. + //bit 18. force to disalbe the clock of ddr0 read reorder buffer. + //bit 17. force to disalbe the clock of read canvas. + //bit 16. force to disalbe the clock of write canvas. + //bit 15. force to disalbe the clock of chan 15. + //bit 14. force to disalbe the clock of chan 14. + //bit 13. force to disalbe the clock of chan 13. + //bit 12. force to disalbe the clock of chan 12. + //bit 11. force to disalbe the clock of chan 11. + //bit 10. force to disalbe the clock of chan 10. + //bit 9. force to disalbe the clock of chan 9. + //bit 8. force to disalbe the clock of chan 8. + //bit 7. force to disalbe the clock of chan 7. + //bit 6. force to disalbe the clock of chan 6. + //bit 5. force to disalbe the clock of chan 5. + //bit 4. force to disalbe the clock of chan 4. + //bit 3. force to disalbe the clock of chan 3. + //bit 2. force to disalbe the clock of chan 2. + //bit 1. force to disalbe the clock of chan 1. + //bit 0. force to disalbe the clock of chan 0. + + +#define DMC_CHAN_STS (DMC_REG_BASE + (0x32 <<2 )) + +#define DMC_CMD_FILTER_CTRL1 (DMC_REG_BASE + (0x40 <<2 )) + //bit 29:20 nugt read buf full access limit + //bit 19:10. ugt read access limit. + //bit 9:0 nugt read access limit + +#define DMC_CMD_FILTER_CTRL2 (DMC_REG_BASE + (0x41 <<2 )) + //bit 29:20 ugt read buf full access limit + //bit 9:0 nugt write access pending limit + //bit 19:10. ugt write access pending limit. + +#define DMC_CMD_FILTER_CTRL3 (DMC_REG_BASE + (0x42 <<2 )) + //bit 26:22 wbuf high level number + //bit 21:17 wbuf mid level number + //bit 16:12 wbuf low level number + //bit 11:8 rbuf high level number + //bit 7:4 rbuf middle level number + //bit 3:0 rbuf low level number + +#define DMC_CMD_FILTER_CTRL4 (DMC_REG_BASE + (0x43 <<2 )) + //bit 24:20. tHIT latency. page hit command latency for next same page not hit command. + //bit 19:15. tIDLE latency. page idle command latency for next same page not hit command. + //bit 14:10. tMISS latency. page miss command latency for next same page not hit command. + //bit 9:0. rbuf idle timer to let the wbuf output. +#define DMC_CMD_FILTER_CTRL5 (DMC_REG_BASE + ( 0x44 << 2)) + +#define DMC_CMD_BUFFER_CTRL (DMC_REG_BASE + (0x45 <<2 )) + //bit 30:25 total write buffer number. default 32. + //bit 24:20 total read buffer number. default 16. + //bit 19:10 ugt age limit. over this age limit, this read buffer would turn to super urgent. + //bit 9:0 nugt age limit. over this age limit, this read buffer would turn to super urgent. +#define DMC_PCTL_LP_CTRL (DMC_REG_BASE + ( 0x46 << 2)) + +#define DMC_AM0_CHAN_CTRL (DMC_REG_BASE + (0x60 <<2 )) +#define DMC_AM0_HOLD_CTRL (DMC_REG_BASE + (0x61 <<2 )) +#define DMC_AM0_QOS_INC (DMC_REG_BASE + (0x62 <<2 )) +#define DMC_AM0_QOS_INCBK (DMC_REG_BASE + (0x63 <<2 )) +#define DMC_AM0_QOS_DEC (DMC_REG_BASE + (0x64 <<2 )) +#define DMC_AM0_QOS_DECBK (DMC_REG_BASE + (0x65 <<2 )) +#define DMC_AM0_QOS_DIS (DMC_REG_BASE + (0x66 <<2 )) +#define DMC_AM0_QOS_DISBK (DMC_REG_BASE + (0x67 <<2 )) +#define DMC_AM0_QOS_CTRL0 (DMC_REG_BASE + (0x68 <<2 )) +#define DMC_AM0_QOS_CTRL1 (DMC_REG_BASE + (0x69 <<2 )) + +#define DMC_AM1_CHAN_CTRL (DMC_REG_BASE + (0x6a <<2 )) +#define DMC_AM1_HOLD_CTRL (DMC_REG_BASE + (0x6b <<2 )) +#define DMC_AM1_QOS_INC (DMC_REG_BASE + (0x6c <<2 )) +#define DMC_AM1_QOS_INCBK (DMC_REG_BASE + (0x6d <<2 )) +#define DMC_AM1_QOS_DEC (DMC_REG_BASE + (0x6e <<2 )) +#define DMC_AM1_QOS_DECBK (DMC_REG_BASE + (0x6f <<2 )) +#define DMC_AM1_QOS_DIS (DMC_REG_BASE + (0x70 <<2 )) +#define DMC_AM1_QOS_DISBK (DMC_REG_BASE + (0x71 <<2 )) +#define DMC_AM1_QOS_CTRL0 (DMC_REG_BASE + (0x72 <<2 )) +#define DMC_AM1_QOS_CTRL1 (DMC_REG_BASE + (0x73 <<2 )) + +#define DMC_AM2_CHAN_CTRL (DMC_REG_BASE + (0x74 <<2 )) +#define DMC_AM2_HOLD_CTRL (DMC_REG_BASE + (0x75 <<2 )) +#define DMC_AM2_QOS_INC (DMC_REG_BASE + (0x76 <<2 )) +#define DMC_AM2_QOS_INCBK (DMC_REG_BASE + (0x77 <<2 )) +#define DMC_AM2_QOS_DEC (DMC_REG_BASE + (0x78 <<2 )) +#define DMC_AM2_QOS_DECBK (DMC_REG_BASE + (0x79 <<2 )) +#define DMC_AM2_QOS_DIS (DMC_REG_BASE + (0x7a <<2 )) +#define DMC_AM2_QOS_DISBK (DMC_REG_BASE + (0x7b <<2 )) +#define DMC_AM2_QOS_CTRL0 (DMC_REG_BASE + (0x7c <<2 )) +#define DMC_AM2_QOS_CTRL1 (DMC_REG_BASE + (0x7d <<2 )) + +#define DMC_AM3_CHAN_CTRL (DMC_REG_BASE + (0x7e <<2 )) +#define DMC_AM3_HOLD_CTRL (DMC_REG_BASE + (0x7f <<2 )) +#define DMC_AM3_QOS_INC (DMC_REG_BASE + (0x80 <<2 )) +#define DMC_AM3_QOS_INCBK (DMC_REG_BASE + (0x81 <<2 )) +#define DMC_AM3_QOS_DEC (DMC_REG_BASE + (0x82 <<2 )) +#define DMC_AM3_QOS_DECBK (DMC_REG_BASE + (0x83 <<2 )) +#define DMC_AM3_QOS_DIS (DMC_REG_BASE + (0x84 <<2 )) +#define DMC_AM3_QOS_DISBK (DMC_REG_BASE + (0x85 <<2 )) +#define DMC_AM3_QOS_CTRL0 (DMC_REG_BASE + (0x86 <<2 )) +#define DMC_AM3_QOS_CTRL1 (DMC_REG_BASE + (0x87 <<2 )) + +#define DMC_AM4_CHAN_CTRL (DMC_REG_BASE + (0x88 <<2 )) +#define DMC_AM4_HOLD_CTRL (DMC_REG_BASE + (0x89 <<2 )) +#define DMC_AM4_QOS_INC (DMC_REG_BASE + (0x8a <<2 )) +#define DMC_AM4_QOS_INCBK (DMC_REG_BASE + (0x8b <<2 )) +#define DMC_AM4_QOS_DEC (DMC_REG_BASE + (0x8c <<2 )) +#define DMC_AM4_QOS_DECBK (DMC_REG_BASE + (0x8d <<2 )) +#define DMC_AM4_QOS_DIS (DMC_REG_BASE + (0x8e <<2 )) +#define DMC_AM4_QOS_DISBK (DMC_REG_BASE + (0x8f <<2 )) +#define DMC_AM4_QOS_CTRL0 (DMC_REG_BASE + (0x90 <<2 )) +#define DMC_AM4_QOS_CTRL1 (DMC_REG_BASE + (0x91 <<2 )) + +#define DMC_AM5_CHAN_CTRL (DMC_REG_BASE + (0x92 <<2 )) +#define DMC_AM5_HOLD_CTRL (DMC_REG_BASE + (0x93 <<2 )) +#define DMC_AM5_QOS_INC (DMC_REG_BASE + (0x94 <<2 )) +#define DMC_AM5_QOS_INCBK (DMC_REG_BASE + (0x95 <<2 )) +#define DMC_AM5_QOS_DEC (DMC_REG_BASE + (0x96 <<2 )) +#define DMC_AM5_QOS_DECBK (DMC_REG_BASE + (0x97 <<2 )) +#define DMC_AM5_QOS_DIS (DMC_REG_BASE + (0x98 <<2 )) +#define DMC_AM5_QOS_DISBK (DMC_REG_BASE + (0x99 <<2 )) +#define DMC_AM5_QOS_CTRL0 (DMC_REG_BASE + (0x9a <<2 )) +#define DMC_AM5_QOS_CTRL1 (DMC_REG_BASE + (0x9b <<2 )) + +#define DMC_AM6_CHAN_CTRL (DMC_REG_BASE + (0x9c <<2 )) +#define DMC_AM6_HOLD_CTRL (DMC_REG_BASE + (0x9d <<2 )) +#define DMC_AM6_QOS_INC (DMC_REG_BASE + (0x9e <<2 )) +#define DMC_AM6_QOS_INCBK (DMC_REG_BASE + (0x9f <<2 )) +#define DMC_AM6_QOS_DEC (DMC_REG_BASE + (0xa0 <<2 )) +#define DMC_AM6_QOS_DECBK (DMC_REG_BASE + (0xa1 <<2 )) +#define DMC_AM6_QOS_DIS (DMC_REG_BASE + (0xa2 <<2 )) +#define DMC_AM6_QOS_DISBK (DMC_REG_BASE + (0xa3 <<2 )) +#define DMC_AM6_QOS_CTRL0 (DMC_REG_BASE + (0xa4 <<2 )) +#define DMC_AM6_QOS_CTRL1 (DMC_REG_BASE + (0xa5 <<2 )) + +#define DMC_AM7_CHAN_CTRL (DMC_REG_BASE + (0xa6 <<2 )) +#define DMC_AM7_HOLD_CTRL (DMC_REG_BASE + (0xa7 <<2 )) +#define DMC_AM7_QOS_INC (DMC_REG_BASE + (0xa8 <<2 )) +#define DMC_AM7_QOS_INCBK (DMC_REG_BASE + (0xa9 <<2 )) +#define DMC_AM7_QOS_DEC (DMC_REG_BASE + (0xaa <<2 )) +#define DMC_AM7_QOS_DECBK (DMC_REG_BASE + (0xab <<2 )) +#define DMC_AM7_QOS_DIS (DMC_REG_BASE + (0xac <<2 )) +#define DMC_AM7_QOS_DISBK (DMC_REG_BASE + (0xad <<2 )) +#define DMC_AM7_QOS_CTRL0 (DMC_REG_BASE + (0xae <<2 )) +#define DMC_AM7_QOS_CTRL1 (DMC_REG_BASE + (0xaf <<2 )) + +#define DMC_AXI0_CHAN_CTRL (DMC_REG_BASE + (0xb0 <<2 )) +#define DMC_AXI0_HOLD_CTRL (DMC_REG_BASE + (0xb1 <<2 )) +#define DMC_AXI0_QOS_INC (DMC_REG_BASE + (0xb2 <<2 )) +#define DMC_AXI0_QOS_INCBK (DMC_REG_BASE + (0xb3 <<2 )) +#define DMC_AXI0_QOS_DEC (DMC_REG_BASE + (0xb4 <<2 )) +#define DMC_AXI0_QOS_DECBK (DMC_REG_BASE + (0xb5 <<2 )) +#define DMC_AXI0_QOS_DIS (DMC_REG_BASE + (0xb6 <<2 )) +#define DMC_AXI0_QOS_DISBK (DMC_REG_BASE + (0xb7 <<2 )) +#define DMC_AXI0_QOS_CTRL0 (DMC_REG_BASE + (0xb8 <<2 )) +#define DMC_AXI0_QOS_CTRL1 (DMC_REG_BASE + (0xb9 <<2 )) + +#define DMC_AXI1_CHAN_CTRL (DMC_REG_BASE + (0xba <<2 )) +#define DMC_AXI1_HOLD_CTRL (DMC_REG_BASE + (0xbb <<2 )) +#define DMC_AXI1_QOS_INC (DMC_REG_BASE + (0xbc <<2 )) +#define DMC_AXI1_QOS_INCBK (DMC_REG_BASE + (0xbd <<2 )) +#define DMC_AXI1_QOS_DEC (DMC_REG_BASE + (0xbe <<2 )) +#define DMC_AXI1_QOS_DECBK (DMC_REG_BASE + (0xbf <<2 )) +#define DMC_AXI1_QOS_DIS (DMC_REG_BASE + (0xc0 <<2 )) +#define DMC_AXI1_QOS_DISBK (DMC_REG_BASE + (0xc1 <<2 )) +#define DMC_AXI1_QOS_CTRL0 (DMC_REG_BASE + (0xc2 <<2 )) +#define DMC_AXI1_QOS_CTRL1 (DMC_REG_BASE + (0xc3 <<2 )) + +#define DMC_AXI2_CHAN_CTRL (DMC_REG_BASE + (0xc4 <<2 )) +#define DMC_AXI2_HOLD_CTRL (DMC_REG_BASE + (0xc5 <<2 )) +#define DMC_AXI2_QOS_INC (DMC_REG_BASE + (0xc6 <<2 )) +#define DMC_AXI2_QOS_INCBK (DMC_REG_BASE + (0xc7 <<2 )) +#define DMC_AXI2_QOS_DEC (DMC_REG_BASE + (0xc8 <<2 )) +#define DMC_AXI2_QOS_DECBK (DMC_REG_BASE + (0xc9 <<2 )) +#define DMC_AXI2_QOS_DIS (DMC_REG_BASE + (0xca <<2 )) +#define DMC_AXI2_QOS_DISBK (DMC_REG_BASE + (0xcb <<2 )) +#define DMC_AXI2_QOS_CTRL0 (DMC_REG_BASE + (0xcc <<2 )) +#define DMC_AXI2_QOS_CTRL1 (DMC_REG_BASE + (0xcd <<2 )) + +#define DMC_AXI3_CHAN_CTRL (DMC_REG_BASE + (0xce <<2 )) +#define DMC_AXI3_HOLD_CTRL (DMC_REG_BASE + (0xcf <<2 )) +#define DMC_AXI3_QOS_INC (DMC_REG_BASE + (0xd0 <<2 )) +#define DMC_AXI3_QOS_INCBK (DMC_REG_BASE + (0xd1 <<2 )) +#define DMC_AXI3_QOS_DEC (DMC_REG_BASE + (0xd2 <<2 )) +#define DMC_AXI3_QOS_DECBK (DMC_REG_BASE + (0xd3 <<2 )) +#define DMC_AXI3_QOS_DIS (DMC_REG_BASE + (0xd4 <<2 )) +#define DMC_AXI3_QOS_DISBK (DMC_REG_BASE + (0xd5 <<2 )) +#define DMC_AXI3_QOS_CTRL0 (DMC_REG_BASE + (0xd6 <<2 )) +#define DMC_AXI3_QOS_CTRL1 (DMC_REG_BASE + (0xd7 <<2 )) + +#define DMC_AXI4_CHAN_CTRL (DMC_REG_BASE + (0xd8 <<2 )) +#define DMC_AXI4_HOLD_CTRL (DMC_REG_BASE + (0xd9 <<2 )) +#define DMC_AXI4_QOS_INC (DMC_REG_BASE + (0xda <<2 )) +#define DMC_AXI4_QOS_INCBK (DMC_REG_BASE + (0xdb <<2 )) +#define DMC_AXI4_QOS_DEC (DMC_REG_BASE + (0xdc <<2 )) +#define DMC_AXI4_QOS_DECBK (DMC_REG_BASE + (0xdd <<2 )) +#define DMC_AXI4_QOS_DIS (DMC_REG_BASE + (0xde <<2 )) +#define DMC_AXI4_QOS_DISBK (DMC_REG_BASE + (0xdf <<2 )) +#define DMC_AXI4_QOS_CTRL0 (DMC_REG_BASE + (0xe0 <<2 )) +#define DMC_AXI4_QOS_CTRL1 (DMC_REG_BASE + (0xe1 <<2 )) + +#define DMC_AXI5_CHAN_CTRL (DMC_REG_BASE + (0xe2 <<2 )) +#define DMC_AXI5_HOLD_CTRL (DMC_REG_BASE + (0xe3 <<2 )) +#define DMC_AXI5_QOS_INC (DMC_REG_BASE + (0xe4 <<2 )) +#define DMC_AXI5_QOS_INCBK (DMC_REG_BASE + (0xe5 <<2 )) +#define DMC_AXI5_QOS_DEC (DMC_REG_BASE + (0xe6 <<2 )) +#define DMC_AXI5_QOS_DECBK (DMC_REG_BASE + (0xe7 <<2 )) +#define DMC_AXI5_QOS_DIS (DMC_REG_BASE + (0xe8 <<2 )) +#define DMC_AXI5_QOS_DISBK (DMC_REG_BASE + (0xe9 <<2 )) +#define DMC_AXI5_QOS_CTRL0 (DMC_REG_BASE + (0xea <<2 )) +#define DMC_AXI5_QOS_CTRL1 (DMC_REG_BASE + (0xeb <<2 )) + +#define DMC_AXI6_CHAN_CTRL (DMC_REG_BASE + (0xec <<2 )) +#define DMC_AXI6_HOLD_CTRL (DMC_REG_BASE + (0xed <<2 )) +#define DMC_AXI6_QOS_INC (DMC_REG_BASE + (0xee <<2 )) +#define DMC_AXI6_QOS_INCBK (DMC_REG_BASE + (0xef <<2 )) +#define DMC_AXI6_QOS_DEC (DMC_REG_BASE + (0xf0 <<2 )) +#define DMC_AXI6_QOS_DECBK (DMC_REG_BASE + (0xf1 <<2 )) +#define DMC_AXI6_QOS_DIS (DMC_REG_BASE + (0xf2 <<2 )) +#define DMC_AXI6_QOS_DISBK (DMC_REG_BASE + (0xf3 <<2 )) +#define DMC_AXI6_QOS_CTRL0 (DMC_REG_BASE + (0xf4 <<2 )) +#define DMC_AXI6_QOS_CTRL1 (DMC_REG_BASE + (0xf5 <<2 )) + +#define DMC_AXI7_CHAN_CTRL (DMC_REG_BASE + (0xf6 <<2 )) +#define DMC_AXI7_HOLD_CTRL (DMC_REG_BASE + (0xf7 <<2 )) +#define DMC_AXI7_QOS_INC (DMC_REG_BASE + (0xf8 <<2 )) +#define DMC_AXI7_QOS_INCBK (DMC_REG_BASE + (0xf9 <<2 )) +#define DMC_AXI7_QOS_DEC (DMC_REG_BASE + (0xfa <<2 )) +#define DMC_AXI7_QOS_DECBK (DMC_REG_BASE + (0xfb <<2 )) +#define DMC_AXI7_QOS_DIS (DMC_REG_BASE + (0xfc <<2 )) +#define DMC_AXI7_QOS_DISBK (DMC_REG_BASE + (0xfd <<2 )) +#define DMC_AXI7_QOS_CTRL0 (DMC_REG_BASE + (0xfe <<2 )) +#define DMC_AXI7_QOS_CTRL1 (DMC_REG_BASE + (0xff <<2 )) + diff --git a/plat/gxb/ddr/mmc_define.h b/plat/gxb/ddr/mmc_define.h new file mode 100644 index 0000000..7f738d8 --- /dev/null +++ b/plat/gxb/ddr/mmc_define.h @@ -0,0 +1,87 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/ddr/mmc_define.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#define AM_DDR_PLL_CNTL 0xc8836800 + //bit 31. PLL lock. read only + //bit 30. PLL power down. 1 = PLL powerdown. 0 = PLL enable. + //bit 29. PLL reset. + //bit 28. SSEN + //bit 27:24. SS_AMP + //bit 23:20. SS_CLK + //bit 17:16. OD. + //bit 15:14. OD1. + //bit 13:9. N. + //bit 8:0 M +#define AM_DDR_PLL_CNTL1 0xc8836804 + //bit 31:28. DPLL_LM_W + //bit 27:22. DPLL_LM_S. + //bit 21. DPFD_LMODE + //bit 20:19. DC_VC_IN. + //bit 18:17. DCO_SDMCK_SEL + //bit 16. DCO_M_EN. + //bit 15. SDM_PR_EN. + //bit 14 DIV_MODE. + //bit 13:2 DIV_FRAC + //bit 1 AFC_DSEL_BYPASS. + //bit 0. AFC_DSEL_IN. +#define AM_DDR_PLL_CNTL2 0xc8836808 + //bit 29:26. FILTER_PVT2. + //bit 25:22. FILTER PVT1. + //bit 21:11. FILTER ACQ2. + //bit 10:0. FILTER ACQ1. +#define AM_DDR_PLL_CNTL3 0xc883680c + //bit 31:20. DPLL REVE. + //bit 13:6. TDC_BUF. + //bit 5. PVT_FIX_EN. + //bit 4:3. DCO_IUP. + //bit 2. IIR_BYPASS_N. + //bit 1 TDC_EN +#define AM_DDR_PLL_CNTL4 0xc8836810 + //bit 21:20. DPLL_CLK_EN. + //bit 13. DCO_SDM_EN + //bit 12. BGP_EN. + //bit 11:8. GPB_C +#define AM_DDR_PLL_STS 0xc8836814 + //bit 31. DDR_PLL lock. + //bit 8:1. DPLL_OUT_RSV + //bit 0. AFC DONE. + +#define DDR_CLK_CNTL 0xc8836818 + //bit 31 ddr_pll_clk enable. enable the clock from DDR_PLL to clock generateion. + // whenever change the DDR_PLL frequency, disable the clock, after the DDR_PLL locked, then enable it again. + //bit 30. ddr_pll_prod_test_en. enable the clock to clock/32 which to clock frequency measurement and production test pin. + //bit 29. ddr_phy_ctl_clk enable. + //bit 28. clock generation logic soft reset. 0 = reset. + //bit 27. phy_4xclk phase inverter.. + //bit 26. pll_freq divide/2. 1: use pll div/2 clock as the n_clk. 0: use pll clock as n_clk. this setting is used for the synopsys DDR PHY PLL fast lock mode. + +#define DDR0_CLK_CTRL 0xc8836c00 +//bit 3. force to disable PUB PCLK. +//bit 2. PUB auto ctrl n_clk clock gating enable. when the DFI_LP_REQ and DFI_LP_ACK detected , auto gated PUB n_clk. +//bit 1. force to disable PUB PCLK. +//bit 0. PUB pclk auto clock gating enable. when the IP detected PCTL enter power down mode, use this bit to gating pub pclk. +#define DDR0_SOFT_RESET 0xc8836c04 +//bit 3. pub n_clk domain soft reset. 1 active. +//bit 2. pub p_clk domain soft reset. + +#define DDR0_APD_CTRL 0xc8836c08 +//bit 15:8. power down enter latency. when IP checked the dfi_lp_req && dfi_lp_ack, give PCTL and pub additional latency let them settle down, then gating the clock. +//bit 7:0. no active latency. after c_active_in become to low, wait additional latency to check the pctl low power state. diff --git a/plat/gxb/ddr/sec_mmc_define.h b/plat/gxb/ddr/sec_mmc_define.h new file mode 100644 index 0000000..2d4508c --- /dev/null +++ b/plat/gxb/ddr/sec_mmc_define.h @@ -0,0 +1,712 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/ddr/sec_mmc_define.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#define DMC_SEC_REG_BASE 0xda838400 +#define DMC_SEC_CTRL (DMC_SEC_REG_BASE + (0x00 <<2)) + + //security range defination have to be atom option. all the range controll register will be shadowed. + //write bit 31 to 1 to update the setting in shadow register to be used. +#define DMC_SEC_RANGE0_CTRL (DMC_SEC_REG_BASE + (0x01 <<2)) + //bit 31:16 : range 0 end address higher 16bits. + //bit 15:0 : range 0 start address higher 16bits. +#define DMC_SEC_RANGE1_CTRL (DMC_SEC_REG_BASE + (0x02 <<2)) + //bit 31:16 : range 1 end address higher 16bits. + //bit 15:0 : range 1 start address higher 16bits. +#define DMC_SEC_RANGE2_CTRL (DMC_SEC_REG_BASE + (0x03 <<2)) + //bit 31:16 : range 2 end address higher 16bits. + //bit 15:0 : range 2 start address higher 16bits. +#define DMC_SEC_RANGE3_CTRL (DMC_SEC_REG_BASE + (0x04 <<2)) + //bit 31:16 : range 3 end address higher 16bits. + //bit 15:0 : range 3 start address higher 16bits. +#define DMC_SEC_RANGE4_CTRL (DMC_SEC_REG_BASE + (0x05 <<2)) + //bit 31:16 : range 4 end address higher 16bits. + //bit 15:0 : range 4 start address higher 16bits. +#define DMC_SEC_RANGE5_CTRL (DMC_SEC_REG_BASE + (0x06 <<2)) + //bit 31:16 : range 5 end address higher 16bits. + //bit 15:0 : range 5 start address higher 16bits. +#define DMC_SEC_RANGE_CTRL (DMC_SEC_REG_BASE + (0x07 <<2)) + //bit 31:7 : not used + //bit 6 : default range security level. 1 : secure region. 0 : non secure region. + //bit 5 : range 5 security level. 1 : secure region. 0 : non secure region. + //bit 4 : range 4 security level. 1 : secure region. 0 : non secure region. + //bit 3 : range 3 security level. 1 : secure region. 0 : non secure region. + //bit 2 : range 2 security level. 1 : secure region. 0 : non secure region. + //bit 1 : range 1 security level. 1 : secure region. 0 : non secure region. + //bit 0 : range 0 security level. 1 : secure region. 0 : non secure region. + +#define DMC_SEC_AXI_PORT_CTRL (DMC_SEC_REG_BASE + (0x0e <<2)) + //bit 31~24. not used. + //bit 23. AXI port3 (HDCP ) secure region write access enable bit. 1: enable. 0 : disable. + //bit 22. AXI port3 (HDCP ) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 21. AXI port2 (Mali 1) secure region write access enable bit. 1: enable. 0 : disable. + //bit 20. AXI port2 (Mali 1) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 19. AXI port1 (Mali 0) secure region write access enable bit. 1: enable. 0 : disable. + //bit 18. AXI port1 (Mali 0) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 17. AXI port0 (CPU) secure region write access enable bit. 1: enable. 0 : disable. + //bit 16. AXI port0 (CPU) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 15~8. not used. + //bit 7. AXI port3 (HDCP ) secure region read access enable bit. 1: enable. 0 : disable. + //bit 6. AXI port3 (HDCP ) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 5. AXI port2 (Mali 1) secure region read access enable bit. 1: enable. 0 : disable. + //bit 4. AXI port2 (Mali 1) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 3. AXI port1 (Mali 0) secure region read access enable bit. 1: enable. 0 : disable. + //bit 2. AXI port1 (Mali 0) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 1. AXI port0 (CPU) secure region read access enable bit. 1: enable. 0 : disable. + //bit 0. AXI port0 (CPU) non secure region read access enable bit. 1: enable. 0 : disable. + +#define DMC_VDEC_SEC_READ_CTRL (DMC_SEC_REG_BASE + (0x10 <<2)) + //bit 31. VDEC subID14 ( not used ) secure region read access enable bit. 1: enable. 0 : disable. + //bit 30. VDEC subID14 ( not used ) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 29. VDEC subID14 ( not used ) secure region read access enable bit. 1: enable. 0 : disable. + //bit 28. VDEC subID14 ( not used ) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 27. VDEC subID13 ( not used ) secure region read access enable bit. 1: enable. 0 : disable. + //bit 26. VDEC subID13 ( not used ) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 25. VDEC subID12 ( not used ) secure region read access enable bit. 1: enable. 0 : disable. + //bit 24. VDEC subID12 ( not used ) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 23. VDEC subID11 ( not used ) secure region read access enable bit. 1: enable. 0 : disable. + //bit 22. VDEC subID11 ( not used ) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 21. VDEC subID10 ( mbbot ) secure region read access enable bit. 1: enable. 0 : disable. + //bit 20. VDEC subID10 ( mbbot ) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 19. VDEC subID9 ( not used.) secure region read access enable bit. 1: enable. 0 : disable. + //bit 18. VDEC subID9 ( not used) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 17. VDEC subID8 ( not used.) secure region read access enable bit. 1: enable. 0 : disable. + //bit 16. VDEC subID8 ( not used) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 15. VDEC subID7 (dw) secure region read access enable bit. 1: enable. 0 : disable. + //bit 14. VDEC subID7 (dw) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 13. VDEC subID6 (comb) secure region read access enable bit. 1: enable. 0 : disable. + //bit 12. VDEC subID6 (comb) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 11. VDEC subID5 (lmem) secure region read access enable bit. 1: enable. 0 : disable. + //bit 10. VDEC subID5 (lmem) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 9. VDEC subID4 (imem) secure region read access enable bit. 1: enable. 0 : disable. + //bit 8. VDEC subID4 (imem) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 7. VDEC subID3 (picdc) secure region read access enable bit. 1: enable. 0 : disable. + //bit 6. VDEC subID3 (picdc) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 5. VDEC subID2 (psc) secure region read access enable bit. 1: enable. 0 : disable. + //bit 4. VDEC subID2 (psc) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 3. VDEC subID1 (dcac) secure region read access enable bit. 1: enable. 0 : disable. + //bit 2. VDEC subID1 (dcac) non secure region read access enable bit. 1: enable. 0 : disable. + //bit 1. VDEC subID0 (vld) secure region read access enable bit. 1: enable. 0 : disable. + //bit 0. VDEC subID0 (vld) non secure region read access enable bit. 1: enable. 0 : disable. +#define DMC_VDEC_SEC_WRITE_CTRL (DMC_SEC_REG_BASE + (0x11 <<2)) + //bit 31. VDEC subID14 ( not used ) secure region write access enable bit. 1: enable. 0 : disable. + //bit 30. VDEC subID14 ( not used ) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 29. VDEC subID14 ( not used ) secure region write access enable bit. 1: enable. 0 : disable. + //bit 28. VDEC subID14 ( not used ) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 27. VDEC subID13 ( not used ) secure region write access enable bit. 1: enable. 0 : disable. + //bit 26. VDEC subID13 ( not used ) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 25. VDEC subID12 ( not used ) secure region write access enable bit. 1: enable. 0 : disable. + //bit 24. VDEC subID12 ( not used ) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 23. VDEC subID11 ( not used ) secure region write access enable bit. 1: enable. 0 : disable. + //bit 22. VDEC subID11 ( not used ) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 21. VDEC subID10 ( mbbot ) secure region write access enable bit. 1: enable. 0 : disable. + //bit 20. VDEC subID10 ( mbbot ) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 19. VDEC subID9 ( not used.) secure region write access enable bit. 1: enable. 0 : disable. + //bit 18. VDEC subID9 ( not used) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 17. VDEC subID8 ( not used.) secure region write access enable bit. 1: enable. 0 : disable. + //bit 16. VDEC subID8 ( not used) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 15. VDEC subID7 (dw) secure region write access enable bit. 1: enable. 0 : disable. + //bit 14. VDEC subID7 (dw) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 13. VDEC subID6 (comb) secure region write access enable bit. 1: enable. 0 : disable. + //bit 12. VDEC subID6 (comb) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 11. VDEC subID5 (lmem) secure region write access enable bit. 1: enable. 0 : disable. + //bit 10. VDEC subID5 (lmem) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 9. VDEC subID4 (imem) secure region write access enable bit. 1: enable. 0 : disable. + //bit 8. VDEC subID4 (imem) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 7. VDEC subID3 (picdc) secure region write access enable bit. 1: enable. 0 : disable. + //bit 6. VDEC subID3 (picdc) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 5. VDEC subID2 (psc) secure region write access enable bit. 1: enable. 0 : disable. + //bit 4. VDEC subID2 (psc) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 3. VDEC subID1 (dcac) secure region write access enable bit. 1: enable. 0 : disable. + //bit 2. VDEC subID1 (dcac) non secure region write access enable bit. 1: enable. 0 : disable. + //bit 1. VDEC subID0 (vld) secure region write access enable bit. 1: enable. 0 : disable. + //bit 0. VDEC subID0 (vld) non secure region write access enable bit. 1: enable. 0 : disable. +#define DMC_VDEC_SEC_CFG (DMC_SEC_REG_BASE + (0x12 <<2)) + //DWC_VDEC_SEC_READ_CTRL and DMC_VDEC_SEC_WRITE_CTRL register APB bus configuation enable. 2 bit for each port. one for read, one for write. + //bit 31. VDEC subID15 () To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 30. VDEC subID14 () To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 29. VDEC subID13 () To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 28. VDEC subID12 () To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 27. VDEC subID11 () To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 26. VDEC subID10 (mbbot) To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 25. VDEC subID9 () To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 24. VDEC subID8 () To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 23. VDEC subID7 (dw) To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 22. VDEC subID6 (comb) To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 21. VDEC subID5 (lmem) To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 20. VDEC subID4 (imem) To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 19. VDEC subID3 (picdc) To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 18. VDEC subID2 (psc) To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 17. VDEC subID1 (dcac) To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 16. VDEC subID0 (vld) To enable APB bus modifiy the write security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 15. VDEC subID15 () To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 14. VDEC subID14 () To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 13. VDEC subID13 () To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 12. VDEC subID12 () To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 11. VDEC subID11 () To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 10. VDEC subID10 (mbbot) To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 9. VDEC subID9 () To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 8. VDEC subID8 () To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 7. VDEC subID7 (dw) To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 6. VDEC subID6 (comb) To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 5. VDEC subID5 (lmem) To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 4. VDEC subID4 (imem) To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 3. VDEC subID3 (picdc) To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 2. VDEC subID2 (psc) To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 1. VDEC subID1 (dcac) To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + //bit 0. VDEC subID0 (vld) To enable APB bus modifiy the read security control bits. 1 : eable the APB modify. 0 : disable APB bus modify. + +#define DMC_VDEC_EF_TRIG_CTRL (DMC_SEC_REG_BASE + (0x13 <<2)) + // VDEC Electronic fence trigger selection and trigger secure type. 1 bit for trigger select for one read port. 1 bit for trigger type for one read port. + //Electronic would be triggered by the read from defined secure level from selected subIDs. + //bit 31. trigger type selection for subID15 (). 1 = secure access. 0 : non secure access. + //bit 30. trigger type selection for subID14 (). 1 = secure access. 0 : non secure access. + //bit 29. trigger type selection for subID13 (). 1 = secure access. 0 : non secure access. + //bit 28. trigger type selection for subID12 (). 1 = secure access. 0 : non secure access. + //bit 27. trigger type selection for subID11 (). 1 = secure access. 0 : non secure access. + //bit 26. trigger type selection for subID10 (). 1 = secure access. 0 : non secure access. + //bit 25. trigger type selection for subID9 (). 1 = secure access. 0 : non secure access. + //bit 24. trigger type selection for subID8 (). 1 = secure access. 0 : non secure access. + //bit 23. trigger type selection for subID7 (dw). 1 = secure access. 0 : non secure access. + //bit 22. trigger type selection for subID6 (comb). 1 = secure access. 0 : non secure access. + //bit 21. trigger type selection for subID5 (lmem). 1 = secure access. 0 : non secure access. + //bit 20. trigger type selection for subID4 (imem). 1 = secure access. 0 : non secure access. + //bit 19. trigger type selection for subID3 (picdc). 1 = secure access. 0 : non secure access. + //bit 18. trigger type selection for subID2 (psc). 1 = secure access. 0 : non secure access. + //bit 17. trigger type selection for subID1 (dcac). 1 = secure access. 0 : non secure access. + //bit 16. trigger type selection for subID0 (vld). 1 = secure access. 0 : non secure access. + //bit 15. trigger source selection for subID15 (). 1 = selected. 0 : not selected. + //bit 14. trigger source selection for subID14 (). 1 = selected. 0 : not selected. + //bit 13. trigger source selection for subID13 (). 1 = selected. 0 : not selected. + //bit 12. trigger source selection for subID12 (). 1 = selected. 0 : not selected. + //bit 11. trigger source selection for subID11 (). 1 = selected. 0 : not selected. + //bit 10. trigger source selection for subID10 (). 1 = selected. 0 : not selected. + //bit 9. trigger source selection for subID9 (). 1 = selected. 0 : not selected. + //bit 8. trigger source selection for subID8 (). 1 = selected. 0 : not selected. + //bit 7. trigger source selection for subID7 (dw). 1 = selected. 0 : not selected. + //bit 6. trigger source selection for subID6 (comb). 1 = selected. 0 : not selected. + //bit 5. trigger source selection for subID5 (lmem). 1 = selected. 0 : not selected. + //bit 4. trigger source selection for subID4 (imem). 1 = selected. 0 : not selected. + //bit 3. trigger source selection for subID3 (picdc). 1 = selected. 0 : not selected. + //bit 2. trigger source selection for subID2 (psc). 1 = selected. 0 : not selected. + //bit 1. trigger source selection for subID1 (dcac). 1 = selected. 0 : not selected. + //bit 0. trigger source selection for subID0 (vld). 1 = selected. 0 : not selected. + +#define DMC_VDEC_EF_PROT (DMC_SEC_REG_BASE + (0x14 <<2)) + //to define which subID would be affected if the EF got triggered. + //bit 31. EF would affect subID15 () write access secure control. 1 = selected. 0 : not selected. + //bit 30. EF would affect subID14 () write access secure control. 1 = selected. 0 : not selected. + //bit 29. EF would affect subID13 () write access secure control. 1 = selected. 0 : not selected. + //bit 28. EF would affect subID12 () write access secure control. 1 = selected. 0 : not selected. + //bit 27. EF would affect subID11 () write access secure control. 1 = selected. 0 : not selected. + //bit 26. EF would affect subID10 () write access secure control. 1 = selected. 0 : not selected. + //bit 25. EF would affect subID9 () write access secure control. 1 = selected. 0 : not selected. + //bit 24. EF would affect subID8 () write access secure control. 1 = selected. 0 : not selected. + //bit 23. EF would affect subID7 (dw) write access secure control. 1 = selected. 0 : not selected. + //bit 22. EF would affect subID6 (comb) write access secure control. 1 = selected. 0 : not selected. + //bit 21. EF would affect subID5 (lmem) write access secure control. 1 = selected. 0 : not selected. + //bit 20. EF would affect subID4 (imem) write access secure control. 1 = selected. 0 : not selected. + //bit 19. EF would affect subID3 (picdc) write access secure control. 1 = selected. 0 : not selected. + //bit 18. EF would affect subID2 (psc) write access secure control. 1 = selected. 0 : not selected. + //bit 17. EF would affect subID1 (dcac) write access secure control. 1 = selected. 0 : not selected. + //bit 16. EF would affect subID0 (vld) write access secure control. 1 = selected. 0 : not selected. + //bit 15. EF would affect subID15 () read access secure control. 1 = selected. 0 : not selected. + //bit 14. EF would affect subID14 () read access secure control. 1 = selected. 0 : not selected. + //bit 13. EF would affect subID13 () read access secure control. 1 = selected. 0 : not selected. + //bit 12. EF would affect subID12 () read access secure control. 1 = selected. 0 : not selected. + //bit 11. EF would affect subID11 () read access secure control. 1 = selected. 0 : not selected. + //bit 10. EF would affect subID10 () read access secure control. 1 = selected. 0 : not selected. + //bit 9. EF would affect subID9 () read access secure control. 1 = selected. 0 : not selected. + //bit 8. EF would affect subID8 () read access secure control. 1 = selected. 0 : not selected. + //bit 7. EF would affect subID7 (dw) read access secure control. 1 = selected. 0 : not selected. + //bit 6. EF would affect subID6 (comb) read access secure control. 1 = selected. 0 : not selected. + //bit 5. EF would affect subID5 (lmem) read access secure control. 1 = selected. 0 : not selected. + //bit 4. EF would affect subID4 (imem) read access secure control. 1 = selected. 0 : not selected. + //bit 3. EF would affect subID3 (picdc) read access secure control. 1 = selected. 0 : not selected. + //bit 2. EF would affect subID2 (psc) read access secure control. 1 = selected. 0 : not selected. + //bit 1. EF would affect subID1 (dcac) read access secure control. 1 = selected. 0 : not selected. + //bit 0. EF would affect subID0 (vld) read access secure control. 1 = selected. 0 : not selected. +#define DMC_VDEC_EF_READ (DMC_SEC_REG_BASE + (0x15 <<2)) + //this register contains the vdec read security control bits after the EF got triggered. + //if the DMC_VDEC_EF_PROT register bit 15:0 related bit was enable, then the related secure control bits would be copied to DMC_VDEC_SEC_READ_CTRL related bits. + +#define DMC_VDEC_EF_WRITE (DMC_SEC_REG_BASE + (0x16 <<2)) + //this register contains the vdec write security control bits after the EF got triggered. + //if the DMC_VDEC_EF_PROT register bit 15:0 related bit was enable, then the related secure control bits would be copied to DMC_VDEC_SEC_READ_CTRL related bits. + + //HCODEC security and Electronic fence is same as VDEC with different SUBID define.. + //subID15:13 : not used. + //subID12 : ME. + //subID11 : mfdin + //subID10 : mcmbot + //subID9 : i_pred. + //subID8 : qdct + //subID7 : vlc + //subID6 : comb + //subID5 : LMEM + //subID4 : IMEM. + //subID3 : mcrcc + //subID2 : PSC + //subID1 : dcac + //subID0 : vld +#define DMC_HCODEC_SEC_READ_CTRL (DMC_SEC_REG_BASE + (0x17 <<2)) + //each subID with 2bits. one for secure region. one for unsecure region. + +#define DMC_HCODEC_SEC_WRITE_CTRL (DMC_SEC_REG_BASE + (0x18 <<2)) + //each subID with 2bits. one for secure region. one for unsecure region. + +#define DMC_HCODEC_SEC_CFG (DMC_SEC_REG_BASE + (0x19 <<2)) + //DWC_HCODEC_SEC_READ_CTRL and DMC_HCODEC_SEC_WRITE_CTRL register APB bus configuation enable. 2 bit for each port. one for read, one for write. + +#define DMC_HCODEC_EF_TRIG_CTRL (DMC_SEC_REG_BASE + (0x1a <<2)) + // HCODEC Electronic fence trigger selection and trigger secure type. 1 bit for trigger select for one read port. 1 bit for trigger type for one read port. + +#define DMC_HCODEC_EF_PROT (DMC_SEC_REG_BASE + (0x1b <<2)) + // HCODEC EF protected access control. each subID 2 bits. one for read one for write. +#define DMC_HCODEC_EF_READ (DMC_SEC_REG_BASE + (0x1c <<2)) + //the DWC_HCODEC_SEC_READ_CTRL value need to be changed after HCODEC EF fence triggered. once the trigger happens, the DMC_HCODEC_EF_PROT[15:0] bit enabled subIDs value will be copied to DWC_HCODEC_SEC_READ_CTRL register. +#define DMC_HCODEC_EF_WRITE (DMC_SEC_REG_BASE + (0x1d <<2)) + //the DWC_HCODEC_SEC_WRITE_CTRL value need to be changed after HCODEC EF fence triggered. once the trigger happens, the DMC_HCODEC_EF_PROT[31:16] bit enabled subIDs value will be copied to DWC_HCODEC_SEC_WRITE_CTRL register. + +//HEVC security and electronic fence control is similar with VDEC/HCODE. only difference is in HEVC, the LMEM/IMEM are shared in one SUBID. so we need to have seperate seting for them. + //subID 7 : mpred. + //subID 6 : dblk_d + //subID 5 : dblk_p + //subID 4 : ipp + //subID 3 : mpp + //subID 2 : SAO + //subID 1 : stream. + //subID 0 : AMRISC CPU. include IMEM and LMEM. AR/WID[3:0] == 0 IMEM. LMEM. + //HEVC ID 7. [6:4] for subID. +#define DMC_HEVC_SEC_READ_CTRL (DMC_SEC_REG_BASE + (0x1e <<2)) + //bit 31:18. not used. + //bit 17. READ secure area eable bit for HEVC subID0 CPU with IDbits 3:0 != 4'h0 read access. 1 : enable. 0 : disable. + //bit 16. READ non secure area eable bit for HEVC subID 0 CPU with IDbits 3:0 != 4'h0 read access. 1 : enable. 0 : disable. + //bit 15. READ secure area eable bit for HEVC subID 7 mpred read access. 1 : enable. 0 : disable. + //bit 14. READ non secure area eable bit for HEVC subID 7 mpred read access. 1 : enable. 0 : disable. + //bit 13. READ secure area eable bit for HEVC subID 6 dblk_d read access. 1 : enable. 0 : disable. + //bit 12. READ non secure area eable bit for HEVC subID 6 dblk_d read access. 1 : enable. 0 : disable. + //bit 11. READ secure area eable bit for HEVC subID 5 dblk_p read access. 1 : enable. 0 : disable. + //bit 10. READ non secure area eable bit for HEVC subID 5 dblk_p read access. 1 : enable. 0 : disable. + //bit 9. READ secure area eable bit for HEVC subID 4 ipp read access. 1 : enable. 0 : disable. + //bit 8. READ non secure area eable bit for HEVC subID 4 ipp read access. 1 : enable. 0 : disable. + //bit 7. READ secure area eable bit for HEVC subID 3 mpp read access. 1 : enable. 0 : disable. + //bit 6. READ non secure area eable bit for HEVC subID 3 mpp read access. 1 : enable. 0 : disable. + //bit 5. READ secure area eable bit for HEVC subID 2 SAO read access. 1 : enable. 0 : disable. + //bit 4. READ non secure area eable bit for HEVC subID 2 SAO read access. 1 : enable. 0 : disable. + //bit 3. READ secure area eable bit for HEVCsubID 1 stream read access. 1 : enable. 0 : disable. + //bit 2. READ non secure area eable bit for HEVC subID 1 stream read access. 1 : enable. 0 : disable. + //bit 1. READ secure area eable bit for HEVC CPU access with ID bit 3:0 = 4'h0. 1 : enable. 0 : disable. + //bit 0. READ non secure area eable bit for HEVC CPU access with ID bit 3:0 = 4'h0. 1 : enable. 0 : disable. + +#define DMC_HEVC_SEC_WRITE_CTRL (DMC_SEC_REG_BASE + (0x1f <<2)) + //bit 31:18. not used. + //bit 17. WRITE secure area eable bit for HEVC subID0 CPU with IDbits[7:4] == 4'h1 write access. 1 : enable. 0 : disable. + //bit 16. WRITE non secure area eable bit for HEVC subID 0 CPU IDbits[7:4] == 4'h1 write access. 1 : enable. 0 : disable. + //bit 15. WRITE secure area eable bit for HEVC subID [7:5] ==7 mpred write access. 1 : enable. 0 : disable. + //bit 14. WRITE non secure area eable bit for HEVC subID 7 mpred write access. 1 : enable. 0 : disable. + //bit 13. WRITE secure area eable bit for HEVC subID [7:5] == 6 dblk_d write access. 1 : enable. 0 : disable. + //bit 12. WRITE non secure area eable bit for HEVC subID [7:5] == 6 dblk_d write access. 1 : enable. 0 : disable. + //bit 11. WRITE secure area eable bit for HEVC subID [7:5] == 5 dblk_p write access. 1 : enable. 0 : disable. + //bit 10. WRITE non secure area eable bit for HEVC subID [7:5] == 5 dblk_p write access. 1 : enable. 0 : disable. + //bit 9. WRITE secure area eable bit for HEVC subID [7:5] == 4 ipp write access. 1 : enable. 0 : disable. + //bit 8. WRITE non secure area eable bit for HEVC subID [7:5] == 4 ipp write access. 1 : enable. 0 : disable. + //bit 7. WRITE secure area eable bit for HEVC subID [7:5] == 3 mpp write access. 1 : enable. 0 : disable. + //bit 6. WRITE non secure area eable bit for HEVC subID [7:5] == 3 mpp write access. 1 : enable. 0 : disable. + //bit 5. WRITE secure area eable bit for HEVC subID [7:5] == 2 SAO write access. 1 : enable. 0 : disable. + //bit 4. WRITE non secure area eable bit for HEVC subID 2 SAO write access. 1 : enable. 0 : disable. + //bit 3. WRITE secure area eable bit for HEVCsubID [7:5] == 1 stream write access. 1 : enable. 0 : disable. + //bit 2. WRITE non secure area eable bit for HEVC subID [7:5] == 1 stream write access. 1 : enable. 0 : disable. + //bit 1. WRITE secure area eable bit for HEVC CPU access with ID bit 7 :4 = 4'h0. 1 : enable. 0 : disable. + //bit 0. WRITE non secure area eable bit for HEVC CPU access with ID bit 7:4 = 4'h0. 1 : enable. 0 : disable. + +#define DMC_HEVC_SEC_CFG (DMC_SEC_REG_BASE + (0x20 <<2)) + //24:16 9 CBUS modfiy enable bit for 9 write secure cotnrol SUBIDs + // 8:0. 9 CBUS modify enable bit for 9 READ secure control SUBIDs. +#define DMC_HEVC_EF_TRIG_CTRL (DMC_SEC_REG_BASE + (0x21 <<2)) + //bit 24:16. 9 HEVC EF trigger selection type for 9 SUBID read access. + //bit 8:0. 9 HEVC EF trigger selection for 9 SUBID read acess. + +#define DMC_HEVC_EF_PROT (DMC_SEC_REG_BASE + (0x22 <<2)) + //bit 24:16. 9 HEVC EF controlled write subID selection. + //bit 8:0. 9 HEVC EF controlled read subIDs selection. + +#define DMC_HEVC_EF_READ (DMC_SEC_REG_BASE + (0x23 <<2)) + //bit 17:0. DWC_HEVC_SEC_READ_CTRL value need to be changed after HEVC EF fence triggered. +#define DMC_HEVC_EF_WRITE (DMC_SEC_REG_BASE + (0x24 <<2)) + //bit 17:0. DWC_HEVC_SEC_WRITE_CTRL value need to be changed after HEVC EF fence triggered. + + + +//there are upto 16 read subID inside VPU and dynamic allocated 3 VPU read ports. +//there are upto 16 write subIDs insdie VPU and dynamic allocated 2 VPU write ports +//there are 3 electronic fences for VPU domain. we can allocated any of those 16 read ports as the trigger of the 3 EF. +//the 3 EF also can control any of those read ports and write ports security levels. +//the Software should make sure there's no conflit setting between these 3 EFs. +#define DMC_VPU_SEC_READ_CTRL (DMC_SEC_REG_BASE + (0x32 <<2)) +//bit 31:0. each read subID have 2 bits securty control. one is for seucre area access. one is for unsecure aread access. + +#define DMC_VPU_SEC_WRITE_CTRL (DMC_SEC_REG_BASE + (0x33 <<2)) +//bit 31:0. each write subID have 2 bits securty control. one is for seucre area access. one is for unsecure aread access. + +#define DMC_VPU_SEC_CFG (DMC_SEC_REG_BASE + (0x25 <<2)) + //31:16 enable APB bus configure VPU write SubIDs security contrl register DMC_VPU_SEC_WRITE_CTRL. + //15:0 enable APB bus configure for VPU read SubIDs security control register. DMC_VPU_SEC_READ_CTRL +#define DMC_VPU_EF0_TRIG_CTRL (DMC_SEC_REG_BASE + (0x26 <<2)) + //31:16. VPU EF0 trigger selection read source type. + //15:0. VPU EF0 trigger selection read source select. +#define DMC_VPU_EF0_PROT (DMC_SEC_REG_BASE + (0x27 <<2)) + //bit 24:16. 16 VPU EF0 controlled write subIDs selection. + //bit 15:0. 16 VPU EF0 controlled read subIDs selection. +#define DMC_VPU_EF0_READ (DMC_SEC_REG_BASE + (0x28 <<2)) + //EF0 controlled DMC_VPU_SEC_READ_CTRL. +#define DMC_VPU_EF0_WRITE (DMC_SEC_REG_BASE + (0x29 <<2)) + //EF0 controlled DMC_VPU_SEC_WRITE_CTRL. + +#define DMC_VPU_EF1_TRIG_CTRL (DMC_SEC_REG_BASE + (0x2a <<2)) + //31:16. VPU EF1 trigger selection read source type. + //15:0. VPU EF1 trigger selection read source select. +#define DMC_VPU_EF1_PROT (DMC_SEC_REG_BASE + (0x2b <<2)) + //bit 24:16. 16 VPU EF1 controlled write subIDs selection. + //bit 15:0. 16 VPU EF1 controlled read subIDs selection. +#define DMC_VPU_EF1_READ (DMC_SEC_REG_BASE + (0x2c <<2)) + //EF1 controlled DMC_VPU_SEC_READ_CTRL. +#define DMC_VPU_EF1_WRITE (DMC_SEC_REG_BASE + (0x2d <<2)) + //EF1 controlled DMC_VPU_SEC_WRITE_CTRL. +#define DMC_VPU_EF2_TRIG_CTRL (DMC_SEC_REG_BASE + (0x2e <<2)) + //31:16. VPU EF2 trigger selection read source type. + //15:0. VPU EF2 trigger selection read source select. +#define DMC_VPU_EF2_PROT (DMC_SEC_REG_BASE + (0x2f <<2)) + //bit 24:16. 16 VPU EF2 controlled write subIDs selection. + //bit 15:0. 16 VPU EF2 controlled read subIDs selection. +#define DMC_VPU_EF2_READ (DMC_SEC_REG_BASE + (0x30 <<2)) + //EF2 controlled DMC_VPU_SEC_READ_CTRL. +#define DMC_VPU_EF2_WRITE (DMC_SEC_REG_BASE + (0x31 <<2)) + //EF2 controlled DMC_VPU_SEC_WRITE_CTRL. + + //GE2D is seperated port in GX. +#define DMC_GE2D_SEC_CTRL (DMC_SEC_REG_BASE + (0x34 <<2)) + //bit 31:22 NOT USED. + //bit 21:16. GE2D secure control after EF triggered. + //bit 14:12 GE2D EF proection selection after EF triggered.. + //bit 11:10 GE2D Electronic fence trigger read source secure type selection. + //bit 9:8 GE2D Electronic fence trigger read source selection. + //bit 5:4. GE2D write destination 2 secruity control bits. + //bit 3:2. GE2D read source 2 secruity control bits. + //bit 1:0. GE2D read source 1 secruity control bits. + +#define DMC_PARSER_SEC_CTRL (DMC_SEC_REG_BASE + (0x35 <<2)) + //bit 11:8. Pasrese write and read security contrl bits after EF triggered. + //bit 7:6. Parser EF trigger protection enable. + //bit 5. Parser EF trigger read source type. + //bit 4 Pasrer EF trigger read source enable. + //bit 3:2. Parser write security control bits. + //bit 1:0. Parser read security control bits. +#define DMC_DEV_SEC_READ_CTRL (DMC_SEC_REG_BASE + (0x36 <<2)) + //16 device subID read access security control bits. each subID 2 bits. +#define DMC_DEV_SEC_WRITE_CTRL (DMC_SEC_REG_BASE + (0x37 <<2)) + //16 device subID write access security control bits. each subID 2 bits. + + +//2 DES key one for secure region and one for non-secure region. +#define DMC_DES_KEY0_H (DMC_SEC_REG_BASE + (0x90 <<2)) +#define DMC_DES_KEY0_L (DMC_SEC_REG_BASE + (0x91 <<2)) + //64bits data descrable key for security level 0 ( DES key) + +#define DMC_DES_KEY1_H (DMC_SEC_REG_BASE + (0x92 <<2)) +#define DMC_DES_KEY1_L (DMC_SEC_REG_BASE + (0x93 <<2)) + //64bits data descrable key for security level 1( DES key) + +#define DMC_DES_PADDING (DMC_SEC_REG_BASE + (0x9a <<2)) + //32bits address padding used for DES data generation. + +#define DMC_CA_REMAP_L (DMC_SEC_REG_BASE + (0x9b <<2)) +#define DMC_CA_REMAP_H (DMC_SEC_REG_BASE + (0x9c <<2)) + //This is a 16x4 address remap look up table. + //the column address bit 7:4 would be the index input and be replace with the value stored in these register. + //{DMC_CA_REMAP_H, DMC_CA_REMAP_L} + //bit 63:60: new address for index 15 + //bit 59:56: new address for index 14 + //bit 55:52: new address for index 13 + //bit 51:48: new address for index 12 + //bit 47:44: new address for index 11 + //bit 43:40: new address for index 10 + //bit 39:36: new address for index 9 + //bit 35:32: new address for index 8 + //bit 31:28: new address for index 7 + //bit 27:24: new address for index 6 + //bit 23:20: new address for index 5 + //bit 19:16: new address for index 4 + //bit 15:12: new address for index 3 + //bit 11:8: new address for index 2 + //bit 7:4: new address for index 1 + //bit 3:0: new address for index 0 + + +// two range protection function. +#define DMC_PROT0_RANGE (DMC_SEC_REG_BASE + (0xa0 <<2)) + //protection 0 address range. the range define is 64Kbyte boundary. current address [31:16] >= start address && current address [31:16] <= end address. + //bit 31:16 : range end address. + //bit 15:0 : range start address +#define DMC_PROT0_CTRL (DMC_SEC_REG_BASE + (0xa1 <<2)) + //bit 19. protection 0 for write access enable bit. + //bit 18. protection 0 for read access enable bit. + //bit 17. protection 0 write access block function. if enabled, the access wouldn't write to the DDR SDRAM. if not enabled only generate a interrupt, but the access still wrote to DDR. + //bit 16. not used. + //bit 15:0 each bit to enable one of the 15 channel input for the protection function. + +#define DMC_PROT1_RANGE (DMC_SEC_REG_BASE + (0xa2 <<2)) + //protection 1 address range. the range define is 64Kbyte boundary. current address [31:16] >= start address && current address [31:16] <= end address. + //bit 31:16 : range end address. + //bit 15:0 : range start address +#define DMC_PROT1_CTRL (DMC_SEC_REG_BASE + (0xa3 <<2)) + //bit 19. protection 1 for write access enable bit. + //bit 18. protection 1 for read access enable bit. + //bit 17. protection 1 write access block function. if enabled, the access wouldn't write to the DDR SDRAM. if not enabled only generate a interrupt, but the access still wrote to DDR. +//two data point +#define DMC_WTCH0_D0 (DMC_SEC_REG_BASE + (0xa4 <<2)) + //WTCH0 will watch upto 128bits data access. +#define DMC_WTCH0_D1 (DMC_SEC_REG_BASE + (0xa5 <<2)) +#define DMC_WTCH0_D2 (DMC_SEC_REG_BASE + (0xa6 <<2)) +#define DMC_WTCH0_D3 (DMC_SEC_REG_BASE + (0xa7 <<2)) + // the watch point 0 data {d3, d2,d1,d0} +#define DMC_WTCH0_RANGE (DMC_SEC_REG_BASE + (0xa8 <<2)) + //address range. 64Kbyte boundary. + // 31:16 start address high 16. + // 15:0 start address high 16. +#define DMC_WTCH0_CTRL (DMC_SEC_REG_BASE + (0xa9 <<2)) + //bit 31:16. 16bits write data strb. + //bit 15:0. 16bits input channels select. +#define DMC_WTCH0_CTRL1 (DMC_SEC_REG_BASE + (0xaa <<2)) + //bit 2. watch point 0 enable. + //bit 1:0. watch point0 type. 2'b00 : double bytes. only watchpoint data 15:0 and data strb 1:0 is valid. 2'b01: 4 bytes. 2'b10: 8 bytes. 2'b11, all 16bytes. + +#define DMC_WTCH1_D0 (DMC_SEC_REG_BASE + (0xab <<2)) +#define DMC_WTCH1_D1 (DMC_SEC_REG_BASE + (0xac <<2)) +#define DMC_WTCH1_D2 (DMC_SEC_REG_BASE + (0xad <<2)) +#define DMC_WTCH1_D3 (DMC_SEC_REG_BASE + (0xae <<2)) + // the watch point 1 data {d3, d2,d1,d0} +#define DMC_WTCH1_RANGE (DMC_SEC_REG_BASE + (0xaf <<2)) + //address range. 64Kbyte boundary. + // 31:16 start address high 16. + // 15:0 start address high 16. +#define DMC_WTCH1_CTRL (DMC_SEC_REG_BASE + (0xb0 <<2)) + //bit 31:16. 16bits write data strb. + //bit 15:0. 16bits input channels select. +#define DMC_WTCH1_CTRL1 (DMC_SEC_REG_BASE + (0xb1 <<2)) + //bit 2. watch point 0 enable. + //bit 1:0. watch point0 type. 2'b00 : double bytes. only watchpoint data 15:0 and data strb 1:0 is valid. 2'b01: 4 bytes. 2'b10: 8 bytes. 2'b11, all 16bytes. + + +//trap function: all the enable the port ID read access or enable PORT ID and subID read access must be in the predefine range. otherwire the read access would be blocked. +// and an error will be generated. +#define DMC_TRAP0_RANGE (DMC_SEC_REG_BASE + (0xb2 <<2)) + // address trap0 range register. + //31:16. trap0 end address + //15:0 start0 address. +#define DMC_TRAP0_CTRL (DMC_SEC_REG_BASE + (0xb3 <<2)) + //bit 30 trap0 port ID 2 enable. + //bit 29 trap0 port ID 1 enable. + //bit 28 trap0 port ID 0 enable. + //bit 27 trap0 port ID 2 subid enable. + //bit 26 trap0 port ID 1 subid enable. + //bit 25 trap0 port ID 0 subid enable. + //bit 23:20. trap0 port port ID 2 channel ID number. + //bit 19:16. trap0 port port ID 2 subID ID number. + //bit 15:12. trap0 port ID 1 ID number. + //bit 11:8. trap0 port ID 1 subID ID number. + //bit 7:4. trap0 port ID 0 ID number. + //bit 3:0. trap0 port ID 0 subID ID number. + +#define DMC_TRAP1_RANGE (DMC_SEC_REG_BASE + (0xb4 <<2)) + //address trap range register. + //31:16. trap end address + //15:0 start address. +#define DMC_TRAP1_CTRL (DMC_SEC_REG_BASE + (0xb5 <<2)) + //bit 30 trap1 port ID 2 enable. + //bit 29 trap1 port ID 1 enable. + //bit 28 trap1 port ID 0 enable. + //bit 27 trap1 port ID 2 subid enable. + //bit 26 trap1 port ID 1 subid enable. + //bit 25 trap1 port ID 0 subid enable. + //bit 23:20. trap1 port port ID 2 channel ID number. + //bit 19:16. trap1 port port ID 2 subID ID number. + //bit 15:12. trap1 port ID 1 ID number. + //bit 11:8. trap1 port ID 1 subID ID number. + //bit 7:4. trap1 port ID 0 ID number. + //bit 3:0. trap1 port ID 0 subID ID number. + + + +//registers to check the security protection and watch point error information. +#define DMC_SEC_STATUS (DMC_SEC_REG_BASE + (0xb6 <<2)) + +#define DMC_VIO_ADDR0 (DMC_SEC_REG_BASE + (0xb7 <<2)) + //ddr0 write secure violation address. +#define DMC_VIO_ADDR1 (DMC_SEC_REG_BASE + (0xb8 <<2)) + //22 secure check violation. + //21 protection 1 vilation. + //20 protection 0 vilation. + //19:18. not use.d + //17 ddr0 write address overflow. write out of DDR size. + //16:14. ddr0 write violation AWPROT bits. + //13:0 ddr0_write violation ID. +#define DMC_VIO_ADDR2 (DMC_SEC_REG_BASE + (0xb9 <<2)) + //ddr1 write seure violation address +#define DMC_VIO_ADDR3 (DMC_SEC_REG_BASE + (0xba <<2)) + //22 ddr1 write secure check violation. + //21 ddr1 write protection 1 vilation. + //20 ddr1 write protection 0 vilation. + //19 ddr1 watch 1 catch + //18. ddr1 watch 0 catch. + //17 ddr1 write address overflow. write out of DDR size. + //16:14. ddr1 write violation AWPROT bits. + //13:0 ddr1_write violation ID. + +#define DMC_VIO_ADDR4 (DMC_SEC_REG_BASE + (0xbb <<2)) + //ddr0 read seure violation address +#define DMC_VIO_ADDR5 (DMC_SEC_REG_BASE + (0xbc <<2)) + //22 ddr0 read secure check violation. + //21 ddr0 read protection 1 violation. + //20 ddr0 read protection 0 violation. + //19 ddr0 read trap1 violation + //18 ddr0 read trap0 violation + //17 ddr 0 read address overflow. write out of DDR size. + //16:14. ddr 0 read violation ARPROT bits. + //13:0 ddr 0 read violation ID. + +#define DMC_VIO_ADDR6 (DMC_SEC_REG_BASE + (0xbd <<2)) + //ddr1 read seure violation address + +#define DMC_VIO_ADDR7 (DMC_SEC_REG_BASE + (0xbe <<2)) + //22 ddr1 read secure check violation. + //21 ddr1 read protection 1 violation. + //20 ddr1 read protection 0 violation. + //19 ddr1 read trap1 violation + //18 ddr1 read trap0 violation + //17 ddr 1 read address overflow. write out of DDR size. + //16:14. ddr 1 read violation ARPROT bits. + //13:0 ddr 1 read violation ID. + + +//each row bank and rank address can be selected from any address. +#define DDR0_ADDRMAP_4 (DMC_SEC_REG_BASE + (0xd4 <<2)) + //29:25 rank select. + //24:20 ba3 //for bank group or 16banks.. + //19:15 ba2. + //14:10 ba1. + //9:5 ba0. + //4:0 ra15. +#define DDR0_ADDRMAP_3 (DMC_SEC_REG_BASE + (0xd3 <<2)) + //29:25 ra14. + //24:20 ra13. + //19:15 ra12. + //14:10 ra11. + //9:5 ra10. + //4:0 ra9. +#define DDR0_ADDRMAP_2 (DMC_SEC_REG_BASE + (0xd2 <<2)) + //29:25 ra8. + //24:20 ra7. + //19:15 ra6. + //14:10 ra5. + //9:5 ra4. + //4:0 ra3. +#define DDR0_ADDRMAP_1 (DMC_SEC_REG_BASE + (0xd1 <<2)) + //29:25 ra2. + //24:20 ra1. + //19:15 ra0. + //14:10 ca11. + //9:5 ca10. + //4:0 ca9. + +#define DDR0_ADDRMAP_0 (DMC_SEC_REG_BASE + (0xd0 <<2)) + //29:25 ca8. + //24:20 ca7. + //19:15 ca6. + //14:10 ca5. + //9:5 ca4. + //4:0 ca3. + +#define DDR1_ADDRMAP_4 (DMC_SEC_REG_BASE + (0xd9 <<2)) + //29:25 rank select. + //24:20 ba3 //for bank group or 16banks.. + //19:15 ba2. + //14:10 ba1. + //9:5 ba0. + //4:0 ra15. +#define DDR1_ADDRMAP_3 (DMC_SEC_REG_BASE + (0xd8 <<2)) + //29:25 ra14. + //24:20 ra13. + //19:15 ra12. + //14:10 ra11. + //9:5 ra10. + //4:0 ra9. +#define DDR1_ADDRMAP_2 (DMC_SEC_REG_BASE + (0xd7 <<2)) + //29:25 ra8. + //24:20 ra7. + //19:15 ra6. + //14:10 ra5. + //9:5 ra4. + //4:0 ra3. +#define DDR1_ADDRMAP_1 (DMC_SEC_REG_BASE + (0xd6 <<2)) + //29:25 ra2. + //24:20 ra1. + //19:15 ra0. + //14:10 ca11. + //9:5 ca10. + //4:0 ca9. +#define DDR1_ADDRMAP_0 (DMC_SEC_REG_BASE + (0xd5 <<2)) + //29:25 ca8. + //24:20 ca7. + //19:15 ca6. + //14:10 ca5. + //9:5 ca4. + //4:0 ca3. + + +#define DMC_DDR_CTRL (DMC_SEC_REG_BASE + (0xda <<2)) + //bit 22. rank1 is same as rank0. only in not shared-AC mdoe. and chan0 second rank not selected. that's means still in rank0 32bits mode. + //bit 21. channel0 second rank selection enable. only in not shared-AC mode. + //bit 20. Shared AC mode. + //bit 19 :18 must be 0 always. becasue we'll use 32bits PHY data. + //bit 19: DDR channel 1 16bits data interface. 1 : 16bits data inteface. 0 : 32bits data interface + //bit 18: DDR channel 0 16bits data interface. 1 : 16bits data inteface. 0 : 32bits data interface + + //bit 17: for DDR channel 1. 1: only use 16bits data in a 32bits phy data interface. 0: normal 32bits data interface. + //bit 16. for DDR channel 0. 1: only use 16bits data in a 32bits phy data interface. 0: normal 32bits data interface. + //bit 10:8 channel bit selection in shared range. + //bit 7. DDR1_ONLY. 1: DDR channel 1 only. when both channel 0 and 1 in the design. 0 : normal. + //bit 6. DDR0_ONLY. 1: DDR channel 0 only. when both channel 0 and 1 in the design. 0 : normal. + //bit 5:3 : DDR channel 1 size. + //3'b000 : DDR channel 1 is 128MB. + //3'b001 : DDR channel 1 is 256MB. + //3'b010 : DDR channel 1 is 512MB. + //3'b011 : DDR channel 1 is 1GB. + //3'b100 : DDR channel 1 is 2GB. + //3'b101 : DDR channel 1 is 4GB. + //others : reserved. + //bit 2:0 : DDR channel 0 size. + //3'b000 : DDR channel 0 is 128MB. + //3'b001 : DDR channel 0 is 256MB. + //3'b010 : DDR channel 0 is 512MB. + //3'b011 : DDR channel 0 is 1GB. + //3'b100 : DDR channel 0 is 2GB. + //3'b101 : DDR channel 0 is 4GB. + //others : reserved.
\ No newline at end of file diff --git a/plat/gxb/efuse.c b/plat/gxb/efuse.c new file mode 100644 index 0000000..703c1d5 --- /dev/null +++ b/plat/gxb/efuse.c @@ -0,0 +1,48 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/efuse.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <io.h> +#include <asm/arch/cpu_config.h> +#include <stdio.h> +#include <string.h> +#include <efuse.h> + +#define EFUSE_READ_PRINT 0 + +void efuse_read(uint64_t offset, uint64_t length, const char * buffer){ + memcpy((void *)buffer, (void *)(P_SHARED_EFUSE_MIRROR+offset), length); +#if EFUSE_READ_PRINT + efuse_print(offset, length, buffer); +#endif +} + +void efuse_print(uint64_t offset, uint64_t length, const char * buffer){ + uint32_t loop = 0; + serial_puts("Efuse Read:"); + for (loop=0; loop<length; loop++) { + if (0 == (loop % 16)) + serial_puts("\n"); + serial_put_hex(buffer[loop], 8); + serial_puts(" "); + //printf("%2x ", buffer[loop]); + } + serial_puts("\n"); +}
\ No newline at end of file diff --git a/plat/gxb/include/arch.h b/plat/gxb/include/arch.h new file mode 100644 index 0000000..612ef63 --- /dev/null +++ b/plat/gxb/include/arch.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2015 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * AArch64 specific register defines + */ +#ifndef __ARCH_H__ +#define __ARCH_H__ + +/* AArch64 SPSR */ +#define AARCH64_SPSR_EL1h 0x5 +#define AARCH64_SPSR_F (1 << 6) +#define AARCH64_SPSR_I (1 << 7) +#define AARCH64_SPSR_A (1 << 8) + +/* CPSR/SPSR definitions */ +#define DAIF_FIQ_BIT (1 << 0) +#define DAIF_IRQ_BIT (1 << 1) +#define DAIF_ABT_BIT (1 << 2) +#define DAIF_DBG_BIT (1 << 3) +#define SPSR_DAIF_SHIFT 6 +#define SPSR_DAIF_MASK 0xf + +#define SPSR_AIF_SHIFT 6 +#define SPSR_AIF_MASK 0x7 + +#define SPSR_E_SHIFT 9 +#define SPSR_E_MASK 0x1 +#define SPSR_E_LITTLE 0x0 +#define SPSR_E_BIG 0x1 + +#define SPSR_T_SHIFT 5 +#define SPSR_T_MASK 0x1 +#define SPSR_T_ARM 0x0 +#define SPSR_T_THUMB 0x1 + +#define DISABLE_ALL_EXCEPTIONS \ + (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT) + + +#define MODE_EL_SHIFT 0x2 +#define MODE_EL_MASK 0x3 +#define MODE_EL3 0x3 +#define MODE_EL2 0x2 +#define MODE_EL1 0x1 +#define MODE_EL0 0x0 + +/* SCTLR definitions */ +#define SCTLR_EL2_RES1 ((1 << 29) | (1 << 28) | (1 << 23) | (1 << 22) | \ + (1 << 18) | (1 << 16) | (1 << 11) | (1 << 5) | \ + (1 << 4)) + +#define SCTLR_EL1_RES1 ((1 << 29) | (1 << 28) | (1 << 23) | (1 << 22) | \ + (1 << 11)) +#define SCTLR_AARCH32_EL1_RES1 \ + ((1 << 23) | (1 << 22) | (1 << 11) | (1 << 4) | \ + (1 << 3)) + +#define SCTLR_M_BIT (1 << 0) +#define SCTLR_A_BIT (1 << 1) +#define SCTLR_C_BIT (1 << 2) +#define SCTLR_SA_BIT (1 << 3) +#define SCTLR_I_BIT (1 << 12) +#define SCTLR_WXN_BIT (1 << 19) +#define SCTLR_EE_BIT (1 << 25) + + +/* Exception Syndrome register bits and bobs */ +#define ESR_EC_SHIFT 26 +#define ESR_EC_MASK 0x3f +#define ESR_EC_LENGTH 6 +#define EC_UNKNOWN 0x0 +#define EC_WFE_WFI 0x1 +#define EC_AARCH32_CP15_MRC_MCR 0x3 +#define EC_AARCH32_CP15_MRRC_MCRR 0x4 +#define EC_AARCH32_CP14_MRC_MCR 0x5 +#define EC_AARCH32_CP14_LDC_STC 0x6 +#define EC_FP_SIMD 0x7 +#define EC_AARCH32_CP10_MRC 0x8 +#define EC_AARCH32_CP14_MRRC_MCRR 0xc +#define EC_ILLEGAL 0xe +#define EC_AARCH32_SVC 0x11 +#define EC_AARCH32_HVC 0x12 +#define EC_AARCH32_SMC 0x13 +#define EC_AARCH64_SVC 0x15 +#define EC_AARCH64_HVC 0x16 +#define EC_AARCH64_SMC 0x17 +#define EC_AARCH64_SYS 0x18 +#define EC_IABORT_LOWER_EL 0x20 +#define EC_IABORT_CUR_EL 0x21 +#define EC_PC_ALIGN 0x22 +#define EC_DABORT_LOWER_EL 0x24 +#define EC_DABORT_CUR_EL 0x25 +#define EC_SP_ALIGN 0x26 +#define EC_AARCH32_FP 0x28 +#define EC_AARCH64_FP 0x2c +#define EC_SERROR 0x2f + +#define EC_BITS(x) ((x >> ESR_EC_SHIFT) & ESR_EC_MASK) + + +/****************************************************************************** + * Opcode passed in x0 to tell next EL that we want to run an image. + * Corresponds to the function ID of the only SMC that the BL1 exception + * handlers service. That's why the chosen value is the first function ID of + * the ARM SMC64 range. + *****************************************************************************/ +#define RUN_IMAGE 0xC0000000 + +/******************************************************************************* + * Constants that allow assembler code to access members of and the + * 'entry_point_info' structure at their correct offsets. + ******************************************************************************/ +#define ENTRY_POINT_INFO_PC_OFFSET 0x08 +#define ENTRY_POINT_INFO_ARGS_OFFSET 0x18 + +/* BL2 SMC parameter structre */ +#if 0 +/*************************************************************************** + * This structure provides version information and the size of the + * structure, attributes for the structure it represents + ***************************************************************************/ +/* typedef struct param_header { */ +/* uint8_t type; /* type of the structure */ */ +/* uint8_t version; /* version of this structure */ */ +/* uint16_t size; /* size of this structure in bytes */ */ +/* uint32_t attr; /* attributes: unused bits SBZ */ */ +/* } param_header_t; */ + +/***************************************************************************** + * This structure represents the superset of information needed while + * switching exception levels. The only two mechanisms to do so are + * ERET & SMC. Security state is indicated using bit zero of header + * attribute + * NOTE: BL1 expects entrypoint followed by spsr while processing + * SMC to jump to BL31 from the start of entry_point_info + *****************************************************************************/ +/* typedef struct entry_point_info { */ +/* param_header_t h; */ +/* uintptr_t pc; */ +/* uint32_t spsr; */ +/* aapcs64_params_t args; */ +/* } entry_point_info_t; */ + +/* BL2 SMC: MUST fill entry_point_info: +* pc, spsr(must be el3), arg0,..(BL2 pass to BL31 parameters) */ +#endif + +/******************************************************************************* + * CPU Extended Control register specific definitions. + ******************************************************************************/ +#define CPUECTLR_EL1 S3_1_C15_C2_1 /* Instruction def. */ +#define CPUECTLR_SMP_BIT (1 << 6) + +#endif diff --git a/plat/gxb/include/bignum.h b/plat/gxb/include/bignum.h new file mode 100644 index 0000000..0a84519 --- /dev/null +++ b/plat/gxb/include/bignum.h @@ -0,0 +1,640 @@ +/** + * \file bignum.h + * + * \brief Multi-precision integer library + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_BIGNUM_H +#define POLARSSL_BIGNUM_H + +#include "rsa_config.h" + +#ifdef _MSC_VER +#include <basetsd.h> +#if (_MSC_VER <= 1200) +typedef signed short int16_t; +typedef unsigned short uint16_t; +#else +typedef INT16 int16_t; +typedef UINT16 uint16_t; +#endif +typedef INT32 int32_t; +typedef INT64 int64_t; +typedef UINT32 uint32_t; +typedef UINT64 uint64_t; +#else +#ifdef CONFIG_EMU_BUILD +#include <inttypes.h> +#endif /* CONFIG_EMU_BUILD */ +#endif + +#define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */ +#define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */ +#define POLARSSL_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */ +#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */ +#define POLARSSL_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */ +#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */ +#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */ +#define POLARSSL_ERR_MPI_MALLOC_FAILED -0x0010 /**< Memory allocation failed. */ + +#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup + +/* + * Maximum size MPIs are allowed to grow to in number of limbs. + */ +#define POLARSSL_MPI_MAX_LIMBS 10000 + +/* + * Maximum window size used for modular exponentiation. Default: 6 + * Minimum value: 1. Maximum value: 6. + * + * Result is an array of ( 2 << POLARSSL_MPI_WINDOW_SIZE ) MPIs used + * for the sliding window calculation. (So 64 by default) + * + * Reduction in size, reduces speed. + */ +#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ + +/* + * Maximum size of MPIs allowed in bits and bytes for user-MPIs. + * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits ) + * + * Note: Calculations can results temporarily in larger MPIs. So the number + * of limbs required (POLARSSL_MPI_MAX_LIMBS) is higher. + */ +#define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */ +#define POLARSSL_MPI_MAX_BITS ( 8 * POLARSSL_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */ + +/* + * When reading from files with mpi_read_file() and writing to files with + * mpi_write_file() the buffer should have space + * for a (short) label, the MPI (in the provided radix), the newline + * characters and the '\0'. + * + * By default we assume at least a 10 char label, a minimum radix of 10 + * (decimal) and a maximum of 4096 bit numbers (1234 decimal chars). + * Autosized at compile time for at least a 10 char label, a minimum radix + * of 10 (decimal) for a number of POLARSSL_MPI_MAX_BITS size. + * + * This used to be statically sized to 1250 for a maximum of 4096 bit + * numbers (1234 decimal chars). + * + * Calculate using the formula: + * POLARSSL_MPI_RW_BUFFER_SIZE = ceil(POLARSSL_MPI_MAX_BITS / ln(10) * ln(2)) + + * LabelSize + 6 + */ +#define POLARSSL_MPI_MAX_BITS_SCALE100 ( 100 * POLARSSL_MPI_MAX_BITS ) +#define LN_2_DIV_LN_10_SCALE100 332 +#define POLARSSL_MPI_RW_BUFFER_SIZE ( ((POLARSSL_MPI_MAX_BITS_SCALE100 + LN_2_DIV_LN_10_SCALE100 - 1) / LN_2_DIV_LN_10_SCALE100) + 10 + 6 ) + +/* + * Define the base integer type, architecture-wise + */ +typedef int64_t t_sint; +typedef uint64_t t_uint; + +/** + * \brief MPI structure + */ +typedef struct +{ + int s; /*!< integer sign */ + size_t n; /*!< total # of limbs */ + t_uint *p; /*!< pointer to limbs */ +} +mpi; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Initialize one MPI + * + * \param X One MPI to initialize. + */ +void mpi_init( mpi *X ); + +/** + * \brief Unallocate one MPI + * + * \param X One MPI to unallocate. + */ +void mpi_free( mpi *X ); + +/** + * \brief Enlarge to the specified number of limbs + * + * \param X MPI to grow + * \param nblimbs The target number of limbs + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_grow( mpi *X, size_t nblimbs ); + +/** + * \brief Copy the contents of Y into X + * + * \param X Destination MPI + * \param Y Source MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_copy( mpi *X, const mpi *Y ); + +/** + * \brief Swap the contents of X and Y + * + * \param X First MPI value + * \param Y Second MPI value + */ +void mpi_swap( mpi *X, mpi *Y ); + +/** + * \brief Set value from integer + * + * \param X MPI to set + * \param z Value to use + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_lset( mpi *X, t_sint z ); + +/** + * \brief Get a specific bit from X + * + * \param X MPI to use + * \param pos Zero-based index of the bit in X + * + * \return Either a 0 or a 1 + */ +int mpi_get_bit( const mpi *X, size_t pos ); + +/** + * \brief Set a bit of X to a specific value of 0 or 1 + * + * \note Will grow X if necessary to set a bit to 1 in a not yet + * existing limb. Will not grow if bit should be set to 0 + * + * \param X MPI to use + * \param pos Zero-based index of the bit in X + * \param val The value to set the bit to (0 or 1) + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1 + */ +int mpi_set_bit( mpi *X, size_t pos, unsigned char val ); + +/** + * \brief Return the number of zero-bits before the least significant + * '1' bit + * + * Note: Thus also the zero-based index of the least significant '1' bit + * + * \param X MPI to use + */ +size_t mpi_lsb( const mpi *X ); + +/** + * \brief Return the number of bits up to and including the most + * significant '1' bit' + * + * Note: Thus also the one-based index of the most significant '1' bit + * + * \param X MPI to use + */ +size_t mpi_msb( const mpi *X ); + +/** + * \brief Return the total size in bytes + * + * \param X MPI to use + */ +size_t mpi_size( const mpi *X ); + +/** + * \brief Import from an ASCII string + * + * \param X Destination MPI + * \param radix Input numeric base + * \param s Null-terminated string buffer + * + * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code + */ +int mpi_read_string( mpi *X, int radix, const char *s ); + +/** + * \brief Export into an ASCII string + * + * \param X Source MPI + * \param radix Output numeric base + * \param s String buffer + * \param slen String buffer size + * + * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code. + * *slen is always updated to reflect the amount + * of data that has (or would have) been written. + * + * \note Call this function with *slen = 0 to obtain the + * minimum required buffer size in *slen. + */ +int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen ); + +#if defined(POLARSSL_FS_IO) +/** + * \brief Read X from an opened file + * + * \param X Destination MPI + * \param radix Input numeric base + * \param fin Input file handle + * + * \return 0 if successful, POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if + * the file read buffer is too small or a + * POLARSSL_ERR_MPI_XXX error code + */ +int mpi_read_file( mpi *X, int radix, FILE *fin ); + +/** + * \brief Write X into an opened file, or stdout if fout is NULL + * + * \param p Prefix, can be NULL + * \param X Source MPI + * \param radix Output numeric base + * \param fout Output file handle (can be NULL) + * + * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code + * + * \note Set fout == NULL to print X on the console. + */ +int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout ); +#endif /* POLARSSL_FS_IO */ + +/** + * \brief Import X from unsigned binary data, big endian + * + * \param X Destination MPI + * \param buf Input buffer + * \param buflen Input buffer size + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen ); + +/** + * \brief Export X into unsigned binary data, big endian + * + * \param X Source MPI + * \param buf Output buffer + * \param buflen Output buffer size + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough + */ +int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen ); + +/** + * \brief Left-shift: X <<= count + * + * \param X MPI to shift + * \param count Amount to shift + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_shift_l( mpi *X, size_t count ); + +/** + * \brief Right-shift: X >>= count + * + * \param X MPI to shift + * \param count Amount to shift + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_shift_r( mpi *X, size_t count ); + +/** + * \brief Compare unsigned values + * + * \param X Left-hand MPI + * \param Y Right-hand MPI + * + * \return 1 if |X| is greater than |Y|, + * -1 if |X| is lesser than |Y| or + * 0 if |X| is equal to |Y| + */ +int mpi_cmp_abs( const mpi *X, const mpi *Y ); + +/** + * \brief Compare signed values + * + * \param X Left-hand MPI + * \param Y Right-hand MPI + * + * \return 1 if X is greater than Y, + * -1 if X is lesser than Y or + * 0 if X is equal to Y + */ +int mpi_cmp_mpi( const mpi *X, const mpi *Y ); + +/** + * \brief Compare signed values + * + * \param X Left-hand MPI + * \param z The integer value to compare to + * + * \return 1 if X is greater than z, + * -1 if X is lesser than z or + * 0 if X is equal to z + */ +int mpi_cmp_int( const mpi *X, t_sint z ); + +/** + * \brief Unsigned addition: X = |A| + |B| + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_add_abs( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Unsigned substraction: X = |A| - |B| + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A + */ +int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Signed addition: X = A + B + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Signed substraction: X = A - B + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Signed addition: X = A + b + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param b The integer value to add + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_add_int( mpi *X, const mpi *A, t_sint b ); + +/** + * \brief Signed substraction: X = A - b + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param b The integer value to subtract + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_sub_int( mpi *X, const mpi *A, t_sint b ); + +/** + * \brief Baseline multiplication: X = A * B + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Baseline multiplication: X = A * b + * Note: b is an unsigned integer type, thus + * Negative values of b are ignored. + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param b The integer value to multiply with + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_mul_int( mpi *X, const mpi *A, t_sint b ); + +/** + * \brief Division by mpi: A = Q * B + R + * + * \param Q Destination MPI for the quotient + * \param R Destination MPI for the rest value + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0 + * + * \note Either Q or R can be NULL. + */ +int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ); + +/** + * \brief Division by int: A = Q * b + R + * + * \param Q Destination MPI for the quotient + * \param R Destination MPI for the rest value + * \param A Left-hand MPI + * \param b Integer to divide by + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0 + * + * \note Either Q or R can be NULL. + */ +int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b ); + +/** + * \brief Modulo: R = A mod B + * + * \param R Destination MPI for the rest value + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0, + * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0 + */ +int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B ); + +/** + * \brief Modulo: r = A mod b + * + * \param r Destination t_uint + * \param A Left-hand MPI + * \param b Integer to divide by + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0, + * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0 + */ +int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ); + +/** + * \brief Sliding-window exponentiation: X = A^E mod N + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param E Exponent MPI + * \param N Modular MPI + * \param _RR Speed-up MPI used for recalculations + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even or if + * E is negative + * + * \note _RR is used to avoid re-computing R*R mod N across + * multiple calls, which speeds up things a bit. It can + * be set to NULL if the extra performance is unneeded. + */ +int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ); + +/** + * \brief Fill an MPI X with size bytes of random + * + * \param X Destination MPI + * \param size Size in bytes + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_fill_random( mpi *X, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Greatest common divisor: G = gcd(A, B) + * + * \param G Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_gcd( mpi *G, const mpi *A, const mpi *B ); + +/** + * \brief Modular inverse: X = A^-1 mod N + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param N Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil + POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N + */ +int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N ); + +/** + * \brief Miller-Rabin primality test + * + * \param X MPI to check + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful (probably prime), + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime + */ +int mpi_is_prime( mpi *X, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Prime number generation + * + * \param X Destination MPI + * \param nbits Required size of X in bits ( 3 <= nbits <= POLARSSL_MPI_MAX_BITS ) + * \param dh_flag If 1, then (X-1)/2 will be prime too + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful (probably prime), + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3 + */ +int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mpi_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* bignum.h */ diff --git a/plat/gxb/include/bn_mul.h b/plat/gxb/include/bn_mul.h new file mode 100644 index 0000000..400ca74 --- /dev/null +++ b/plat/gxb/include/bn_mul.h @@ -0,0 +1,865 @@ +/** + * \file bn_mul.h + * + * \brief Multi-precision integer library + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * Multiply source vector [s] with b, add result + * to destination vector [d] and set carry c. + * + * Currently supports: + * + * . IA-32 (386+) . AMD64 / EM64T + * . IA-32 (SSE2) . Motorola 68000 + * . PowerPC, 32-bit . MicroBlaze + * . PowerPC, 64-bit . TriCore + * . SPARC v8 . ARM v3+ + * . Alpha . MIPS32 + * . C, longlong . C, generic + */ +#ifndef POLARSSL_BN_MUL_H +#define POLARSSL_BN_MUL_H + +#include "bignum.h" + +#if defined(POLARSSL_HAVE_ASM) + +#if defined(__GNUC__) +#if defined(__i386__) + +#define MULADDC_INIT \ + asm( " \ + movl %%ebx, %0; \ + movl %5, %%esi; \ + movl %6, %%edi; \ + movl %7, %%ecx; \ + movl %8, %%ebx; \ + " + +#define MULADDC_CORE \ + " \ + lodsl; \ + mull %%ebx; \ + addl %%ecx, %%eax; \ + adcl $0, %%edx; \ + addl (%%edi), %%eax; \ + adcl $0, %%edx; \ + movl %%edx, %%ecx; \ + stosl; \ + " + +#if defined(POLARSSL_HAVE_SSE2) + +#define MULADDC_HUIT \ + " \ + movd %%ecx, %%mm1; \ + movd %%ebx, %%mm0; \ + movd (%%edi), %%mm3; \ + paddq %%mm3, %%mm1; \ + movd (%%esi), %%mm2; \ + pmuludq %%mm0, %%mm2; \ + movd 4(%%esi), %%mm4; \ + pmuludq %%mm0, %%mm4; \ + movd 8(%%esi), %%mm6; \ + pmuludq %%mm0, %%mm6; \ + movd 12(%%esi), %%mm7; \ + pmuludq %%mm0, %%mm7; \ + paddq %%mm2, %%mm1; \ + movd 4(%%edi), %%mm3; \ + paddq %%mm4, %%mm3; \ + movd 8(%%edi), %%mm5; \ + paddq %%mm6, %%mm5; \ + movd 12(%%edi), %%mm4; \ + paddq %%mm4, %%mm7; \ + movd %%mm1, (%%edi); \ + movd 16(%%esi), %%mm2; \ + pmuludq %%mm0, %%mm2; \ + psrlq $32, %%mm1; \ + movd 20(%%esi), %%mm4; \ + pmuludq %%mm0, %%mm4; \ + paddq %%mm3, %%mm1; \ + movd 24(%%esi), %%mm6; \ + pmuludq %%mm0, %%mm6; \ + movd %%mm1, 4(%%edi); \ + psrlq $32, %%mm1; \ + movd 28(%%esi), %%mm3; \ + pmuludq %%mm0, %%mm3; \ + paddq %%mm5, %%mm1; \ + movd 16(%%edi), %%mm5; \ + paddq %%mm5, %%mm2; \ + movd %%mm1, 8(%%edi); \ + psrlq $32, %%mm1; \ + paddq %%mm7, %%mm1; \ + movd 20(%%edi), %%mm5; \ + paddq %%mm5, %%mm4; \ + movd %%mm1, 12(%%edi); \ + psrlq $32, %%mm1; \ + paddq %%mm2, %%mm1; \ + movd 24(%%edi), %%mm5; \ + paddq %%mm5, %%mm6; \ + movd %%mm1, 16(%%edi); \ + psrlq $32, %%mm1; \ + paddq %%mm4, %%mm1; \ + movd 28(%%edi), %%mm5; \ + paddq %%mm5, %%mm3; \ + movd %%mm1, 20(%%edi); \ + psrlq $32, %%mm1; \ + paddq %%mm6, %%mm1; \ + movd %%mm1, 24(%%edi); \ + psrlq $32, %%mm1; \ + paddq %%mm3, %%mm1; \ + movd %%mm1, 28(%%edi); \ + addl $32, %%edi; \ + addl $32, %%esi; \ + psrlq $32, %%mm1; \ + movd %%mm1, %%ecx; \ + " + +#define MULADDC_STOP \ + " \ + emms; \ + movl %4, %%ebx; \ + movl %%ecx, %1; \ + movl %%edi, %2; \ + movl %%esi, %3; \ + " \ + : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ + : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ + : "eax", "ecx", "edx", "esi", "edi" \ + ); + +#else + +#define MULADDC_STOP \ + " \ + movl %4, %%ebx; \ + movl %%ecx, %1; \ + movl %%edi, %2; \ + movl %%esi, %3; \ + " \ + : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ + : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ + : "eax", "ecx", "edx", "esi", "edi" \ + ); +#endif /* SSE2 */ +#endif /* i386 */ + +#if defined(__amd64__) || defined (__x86_64__) + +#define MULADDC_INIT \ + asm( "movq %0, %%rsi " :: "m" (s)); \ + asm( "movq %0, %%rdi " :: "m" (d)); \ + asm( "movq %0, %%rcx " :: "m" (c)); \ + asm( "movq %0, %%rbx " :: "m" (b)); \ + asm( "xorq %r8, %r8 " ); + +#define MULADDC_CORE \ + asm( "movq (%rsi),%rax " ); \ + asm( "mulq %rbx " ); \ + asm( "addq $8, %rsi " ); \ + asm( "addq %rcx, %rax " ); \ + asm( "movq %r8, %rcx " ); \ + asm( "adcq $0, %rdx " ); \ + asm( "nop " ); \ + asm( "addq %rax, (%rdi) " ); \ + asm( "adcq %rdx, %rcx " ); \ + asm( "addq $8, %rdi " ); + +#define MULADDC_STOP \ + asm( "movq %%rcx, %0 " : "=m" (c)); \ + asm( "movq %%rdi, %0 " : "=m" (d)); \ + asm( "movq %%rsi, %0 " : "=m" (s) :: \ + "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" ); + +#endif /* AMD64 */ + +#if defined(__mc68020__) || defined(__mcpu32__) + +#define MULADDC_INIT \ + asm( "movl %0, %%a2 " :: "m" (s)); \ + asm( "movl %0, %%a3 " :: "m" (d)); \ + asm( "movl %0, %%d3 " :: "m" (c)); \ + asm( "movl %0, %%d2 " :: "m" (b)); \ + asm( "moveq #0, %d0 " ); + +#define MULADDC_CORE \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "moveq #0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "addxl %d4, %d3 " ); + +#define MULADDC_STOP \ + asm( "movl %%d3, %0 " : "=m" (c)); \ + asm( "movl %%a3, %0 " : "=m" (d)); \ + asm( "movl %%a2, %0 " : "=m" (s) :: \ + "d0", "d1", "d2", "d3", "d4", "a2", "a3" ); + +#define MULADDC_HUIT \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addxl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d3:%d1 " ); \ + asm( "addxl %d4, %d1 " ); \ + asm( "addxl %d0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addxl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d3:%d1 " ); \ + asm( "addxl %d4, %d1 " ); \ + asm( "addxl %d0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addxl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d3:%d1 " ); \ + asm( "addxl %d4, %d1 " ); \ + asm( "addxl %d0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addxl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d3:%d1 " ); \ + asm( "addxl %d4, %d1 " ); \ + asm( "addxl %d0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "addxl %d0, %d3 " ); + +#endif /* MC68000 */ + +#if defined(__powerpc__) || defined(__ppc__) +#if defined(__powerpc64__) || defined(__ppc64__) + +#if defined(__MACH__) && defined(__APPLE__) + +#define MULADDC_INIT \ + asm( "ld r3, %0 " :: "m" (s)); \ + asm( "ld r4, %0 " :: "m" (d)); \ + asm( "ld r5, %0 " :: "m" (c)); \ + asm( "ld r6, %0 " :: "m" (b)); \ + asm( "addi r3, r3, -8 " ); \ + asm( "addi r4, r4, -8 " ); \ + asm( "addic r5, r5, 0 " ); + +#define MULADDC_CORE \ + asm( "ldu r7, 8(r3) " ); \ + asm( "mulld r8, r7, r6 " ); \ + asm( "mulhdu r9, r7, r6 " ); \ + asm( "adde r8, r8, r5 " ); \ + asm( "ld r7, 8(r4) " ); \ + asm( "addze r5, r9 " ); \ + asm( "addc r8, r8, r7 " ); \ + asm( "stdu r8, 8(r4) " ); + +#define MULADDC_STOP \ + asm( "addze r5, r5 " ); \ + asm( "addi r4, r4, 8 " ); \ + asm( "addi r3, r3, 8 " ); \ + asm( "std r5, %0 " : "=m" (c)); \ + asm( "std r4, %0 " : "=m" (d)); \ + asm( "std r3, %0 " : "=m" (s) :: \ + "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); + +#else + +#define MULADDC_INIT \ + asm( "ld %%r3, %0 " :: "m" (s)); \ + asm( "ld %%r4, %0 " :: "m" (d)); \ + asm( "ld %%r5, %0 " :: "m" (c)); \ + asm( "ld %%r6, %0 " :: "m" (b)); \ + asm( "addi %r3, %r3, -8 " ); \ + asm( "addi %r4, %r4, -8 " ); \ + asm( "addic %r5, %r5, 0 " ); + +#define MULADDC_CORE \ + asm( "ldu %r7, 8(%r3) " ); \ + asm( "mulld %r8, %r7, %r6 " ); \ + asm( "mulhdu %r9, %r7, %r6 " ); \ + asm( "adde %r8, %r8, %r5 " ); \ + asm( "ld %r7, 8(%r4) " ); \ + asm( "addze %r5, %r9 " ); \ + asm( "addc %r8, %r8, %r7 " ); \ + asm( "stdu %r8, 8(%r4) " ); + +#define MULADDC_STOP \ + asm( "addze %r5, %r5 " ); \ + asm( "addi %r4, %r4, 8 " ); \ + asm( "addi %r3, %r3, 8 " ); \ + asm( "std %%r5, %0 " : "=m" (c)); \ + asm( "std %%r4, %0 " : "=m" (d)); \ + asm( "std %%r3, %0 " : "=m" (s) :: \ + "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); + +#endif + +#else /* PPC32 */ + +#if defined(__MACH__) && defined(__APPLE__) + +#define MULADDC_INIT \ + asm( "lwz r3, %0 " :: "m" (s)); \ + asm( "lwz r4, %0 " :: "m" (d)); \ + asm( "lwz r5, %0 " :: "m" (c)); \ + asm( "lwz r6, %0 " :: "m" (b)); \ + asm( "addi r3, r3, -4 " ); \ + asm( "addi r4, r4, -4 " ); \ + asm( "addic r5, r5, 0 " ); + +#define MULADDC_CORE \ + asm( "lwzu r7, 4(r3) " ); \ + asm( "mullw r8, r7, r6 " ); \ + asm( "mulhwu r9, r7, r6 " ); \ + asm( "adde r8, r8, r5 " ); \ + asm( "lwz r7, 4(r4) " ); \ + asm( "addze r5, r9 " ); \ + asm( "addc r8, r8, r7 " ); \ + asm( "stwu r8, 4(r4) " ); + +#define MULADDC_STOP \ + asm( "addze r5, r5 " ); \ + asm( "addi r4, r4, 4 " ); \ + asm( "addi r3, r3, 4 " ); \ + asm( "stw r5, %0 " : "=m" (c)); \ + asm( "stw r4, %0 " : "=m" (d)); \ + asm( "stw r3, %0 " : "=m" (s) :: \ + "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); + +#else + +#define MULADDC_INIT \ + asm( "lwz %%r3, %0 " :: "m" (s)); \ + asm( "lwz %%r4, %0 " :: "m" (d)); \ + asm( "lwz %%r5, %0 " :: "m" (c)); \ + asm( "lwz %%r6, %0 " :: "m" (b)); \ + asm( "addi %r3, %r3, -4 " ); \ + asm( "addi %r4, %r4, -4 " ); \ + asm( "addic %r5, %r5, 0 " ); + +#define MULADDC_CORE \ + asm( "lwzu %r7, 4(%r3) " ); \ + asm( "mullw %r8, %r7, %r6 " ); \ + asm( "mulhwu %r9, %r7, %r6 " ); \ + asm( "adde %r8, %r8, %r5 " ); \ + asm( "lwz %r7, 4(%r4) " ); \ + asm( "addze %r5, %r9 " ); \ + asm( "addc %r8, %r8, %r7 " ); \ + asm( "stwu %r8, 4(%r4) " ); + +#define MULADDC_STOP \ + asm( "addze %r5, %r5 " ); \ + asm( "addi %r4, %r4, 4 " ); \ + asm( "addi %r3, %r3, 4 " ); \ + asm( "stw %%r5, %0 " : "=m" (c)); \ + asm( "stw %%r4, %0 " : "=m" (d)); \ + asm( "stw %%r3, %0 " : "=m" (s) :: \ + "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); + +#endif + +#endif /* PPC32 */ +#endif /* PPC64 */ + +#if defined(__sparc__) && defined(__sparc64__) + +#define MULADDC_INIT \ + asm( \ + " \ + ldx %3, %%o0; \ + ldx %4, %%o1; \ + ld %5, %%o2; \ + ld %6, %%o3; \ + " + +#define MULADDC_CORE \ + " \ + ld [%%o0], %%o4; \ + inc 4, %%o0; \ + ld [%%o1], %%o5; \ + umul %%o3, %%o4, %%o4; \ + addcc %%o4, %%o2, %%o4; \ + rd %%y, %%g1; \ + addx %%g1, 0, %%g1; \ + addcc %%o4, %%o5, %%o4; \ + st %%o4, [%%o1]; \ + addx %%g1, 0, %%o2; \ + inc 4, %%o1; \ + " + +#define MULADDC_STOP \ + " \ + st %%o2, %0; \ + stx %%o1, %1; \ + stx %%o0, %2; \ + " \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "g1", "o0", "o1", "o2", "o3", "o4", \ + "o5" \ + ); +#endif /* SPARCv9 */ + +#if defined(__sparc__) && !defined(__sparc64__) + +#define MULADDC_INIT \ + asm( \ + " \ + ld %3, %%o0; \ + ld %4, %%o1; \ + ld %5, %%o2; \ + ld %6, %%o3; \ + " + +#define MULADDC_CORE \ + " \ + ld [%%o0], %%o4; \ + inc 4, %%o0; \ + ld [%%o1], %%o5; \ + umul %%o3, %%o4, %%o4; \ + addcc %%o4, %%o2, %%o4; \ + rd %%y, %%g1; \ + addx %%g1, 0, %%g1; \ + addcc %%o4, %%o5, %%o4; \ + st %%o4, [%%o1]; \ + addx %%g1, 0, %%o2; \ + inc 4, %%o1; \ + " + +#define MULADDC_STOP \ + " \ + st %%o2, %0; \ + st %%o1, %1; \ + st %%o0, %2; \ + " \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "g1", "o0", "o1", "o2", "o3", "o4", \ + "o5" \ + ); + +#endif /* SPARCv8 */ + +#if defined(__microblaze__) || defined(microblaze) + +#define MULADDC_INIT \ + asm( "lwi r3, %0 " :: "m" (s)); \ + asm( "lwi r4, %0 " :: "m" (d)); \ + asm( "lwi r5, %0 " :: "m" (c)); \ + asm( "lwi r6, %0 " :: "m" (b)); \ + asm( "andi r7, r6, 0xffff" ); \ + asm( "bsrli r6, r6, 16 " ); + +#define MULADDC_CORE \ + asm( "lhui r8, r3, 0 " ); \ + asm( "addi r3, r3, 2 " ); \ + asm( "lhui r9, r3, 0 " ); \ + asm( "addi r3, r3, 2 " ); \ + asm( "mul r10, r9, r6 " ); \ + asm( "mul r11, r8, r7 " ); \ + asm( "mul r12, r9, r7 " ); \ + asm( "mul r13, r8, r6 " ); \ + asm( "bsrli r8, r10, 16 " ); \ + asm( "bsrli r9, r11, 16 " ); \ + asm( "add r13, r13, r8 " ); \ + asm( "add r13, r13, r9 " ); \ + asm( "bslli r10, r10, 16 " ); \ + asm( "bslli r11, r11, 16 " ); \ + asm( "add r12, r12, r10 " ); \ + asm( "addc r13, r13, r0 " ); \ + asm( "add r12, r12, r11 " ); \ + asm( "addc r13, r13, r0 " ); \ + asm( "lwi r10, r4, 0 " ); \ + asm( "add r12, r12, r10 " ); \ + asm( "addc r13, r13, r0 " ); \ + asm( "add r12, r12, r5 " ); \ + asm( "addc r5, r13, r0 " ); \ + asm( "swi r12, r4, 0 " ); \ + asm( "addi r4, r4, 4 " ); + +#define MULADDC_STOP \ + asm( "swi r5, %0 " : "=m" (c)); \ + asm( "swi r4, %0 " : "=m" (d)); \ + asm( "swi r3, %0 " : "=m" (s) :: \ + "r3", "r4" , "r5" , "r6" , "r7" , "r8" , \ + "r9", "r10", "r11", "r12", "r13" ); + +#endif /* MicroBlaze */ + +#if defined(__tricore__) + +#define MULADDC_INIT \ + asm( "ld.a %%a2, %0 " :: "m" (s)); \ + asm( "ld.a %%a3, %0 " :: "m" (d)); \ + asm( "ld.w %%d4, %0 " :: "m" (c)); \ + asm( "ld.w %%d1, %0 " :: "m" (b)); \ + asm( "xor %d5, %d5 " ); + +#define MULADDC_CORE \ + asm( "ld.w %d0, [%a2+] " ); \ + asm( "madd.u %e2, %e4, %d0, %d1 " ); \ + asm( "ld.w %d0, [%a3] " ); \ + asm( "addx %d2, %d2, %d0 " ); \ + asm( "addc %d3, %d3, 0 " ); \ + asm( "mov %d4, %d3 " ); \ + asm( "st.w [%a3+], %d2 " ); + +#define MULADDC_STOP \ + asm( "st.w %0, %%d4 " : "=m" (c)); \ + asm( "st.a %0, %%a3 " : "=m" (d)); \ + asm( "st.a %0, %%a2 " : "=m" (s) :: \ + "d0", "d1", "e2", "d4", "a2", "a3" ); + +#endif /* TriCore */ + +#if defined(__arm__) + +#if defined(__thumb__) + +#define MULADDC_INIT \ + asm( \ + " \ + ldr r0, %3; \ + ldr r1, %4; \ + ldr r2, %5; \ + ldr r3, %6; \ + lsr r7, r3, #16; \ + mov r9, r7; \ + lsl r7, r3, #16; \ + lsr r7, r7, #16; \ + mov r8, r7; \ + " + +#define MULADDC_CORE \ + " \ + ldmia r0!, {r6}; \ + lsr r7, r6, #16; \ + lsl r6, r6, #16; \ + lsr r6, r6, #16; \ + mov r4, r8; \ + mul r4, r6; \ + mov r3, r9; \ + mul r6, r3; \ + mov r5, r9; \ + mul r5, r7; \ + mov r3, r8; \ + mul r7, r3; \ + lsr r3, r6, #16; \ + add r5, r5, r3; \ + lsr r3, r7, #16; \ + add r5, r5, r3; \ + add r4, r4, r2; \ + mov r2, #0; \ + adc r5, r2; \ + lsl r3, r6, #16; \ + add r4, r4, r3; \ + adc r5, r2; \ + lsl r3, r7, #16; \ + add r4, r4, r3; \ + adc r5, r2; \ + ldr r3, [r1]; \ + add r4, r4, r3; \ + adc r2, r5; \ + stmia r1!, {r4}; \ + " + +#define MULADDC_STOP \ + " \ + str r2, %0; \ + str r1, %1; \ + str r0, %2; \ + " \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r0", "r1", "r2", "r3", "r4", "r5", \ + "r6", "r7", "r8", "r9" \ + ); + +#else + +#define MULADDC_INIT \ + asm( \ + " \ + ldr r0, %3; \ + ldr r1, %4; \ + ldr r2, %5; \ + ldr r3, %6; \ + " + +#define MULADDC_CORE \ + " \ + ldr r4, [r0], #4; \ + mov r5, #0; \ + ldr r6, [r1]; \ + umlal r2, r5, r3, r4; \ + adds r7, r6, r2; \ + adc r2, r5, #0; \ + str r7, [r1], #4; \ + " + +#define MULADDC_STOP \ + " \ + str r2, %0; \ + str r1, %1; \ + str r0, %2; \ + " \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r0", "r1", "r2", "r3", "r4", "r5", \ + "r6", "r7" \ + ); + +#endif /* Thumb */ + +#endif /* ARMv3 */ + +#if defined(__alpha__) + +#define MULADDC_INIT \ + asm( "ldq $1, %0 " :: "m" (s)); \ + asm( "ldq $2, %0 " :: "m" (d)); \ + asm( "ldq $3, %0 " :: "m" (c)); \ + asm( "ldq $4, %0 " :: "m" (b)); + +#define MULADDC_CORE \ + asm( "ldq $6, 0($1) " ); \ + asm( "addq $1, 8, $1 " ); \ + asm( "mulq $6, $4, $7 " ); \ + asm( "umulh $6, $4, $6 " ); \ + asm( "addq $7, $3, $7 " ); \ + asm( "cmpult $7, $3, $3 " ); \ + asm( "ldq $5, 0($2) " ); \ + asm( "addq $7, $5, $7 " ); \ + asm( "cmpult $7, $5, $5 " ); \ + asm( "stq $7, 0($2) " ); \ + asm( "addq $2, 8, $2 " ); \ + asm( "addq $6, $3, $3 " ); \ + asm( "addq $5, $3, $3 " ); + +#define MULADDC_STOP \ + asm( "stq $3, %0 " : "=m" (c)); \ + asm( "stq $2, %0 " : "=m" (d)); \ + asm( "stq $1, %0 " : "=m" (s) :: \ + "$1", "$2", "$3", "$4", "$5", "$6", "$7" ); + +#endif /* Alpha */ + +#if defined(__mips__) + +#define MULADDC_INIT \ + asm( "lw $10, %0 " :: "m" (s)); \ + asm( "lw $11, %0 " :: "m" (d)); \ + asm( "lw $12, %0 " :: "m" (c)); \ + asm( "lw $13, %0 " :: "m" (b)); + +#define MULADDC_CORE \ + asm( "lw $14, 0($10) " ); \ + asm( "multu $13, $14 " ); \ + asm( "addi $10, $10, 4 " ); \ + asm( "mflo $14 " ); \ + asm( "mfhi $9 " ); \ + asm( "addu $14, $12, $14 " ); \ + asm( "lw $15, 0($11) " ); \ + asm( "sltu $12, $14, $12 " ); \ + asm( "addu $15, $14, $15 " ); \ + asm( "sltu $14, $15, $14 " ); \ + asm( "addu $12, $12, $9 " ); \ + asm( "sw $15, 0($11) " ); \ + asm( "addu $12, $12, $14 " ); \ + asm( "addi $11, $11, 4 " ); + +#define MULADDC_STOP \ + asm( "sw $12, %0 " : "=m" (c)); \ + asm( "sw $11, %0 " : "=m" (d)); \ + asm( "sw $10, %0 " : "=m" (s) :: \ + "$9", "$10", "$11", "$12", "$13", "$14", "$15" ); + +#endif /* MIPS */ +#endif /* GNUC */ + +#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) + +#define MULADDC_INIT \ + __asm mov esi, s \ + __asm mov edi, d \ + __asm mov ecx, c \ + __asm mov ebx, b + +#define MULADDC_CORE \ + __asm lodsd \ + __asm mul ebx \ + __asm add eax, ecx \ + __asm adc edx, 0 \ + __asm add eax, [edi] \ + __asm adc edx, 0 \ + __asm mov ecx, edx \ + __asm stosd + +#if defined(POLARSSL_HAVE_SSE2) + +#define EMIT __asm _emit + +#define MULADDC_HUIT \ + EMIT 0x0F EMIT 0x6E EMIT 0xC9 \ + EMIT 0x0F EMIT 0x6E EMIT 0xC3 \ + EMIT 0x0F EMIT 0x6E EMIT 0x1F \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x6E EMIT 0x16 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ + EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xDC \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xEE \ + EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \ + EMIT 0x0F EMIT 0xD4 EMIT 0xFC \ + EMIT 0x0F EMIT 0x7E EMIT 0x0F \ + EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCD \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCF \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCC \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \ + EMIT 0x0F EMIT 0xD4 EMIT 0xDD \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCE \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \ + EMIT 0x83 EMIT 0xC7 EMIT 0x20 \ + EMIT 0x83 EMIT 0xC6 EMIT 0x20 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x7E EMIT 0xC9 + +#define MULADDC_STOP \ + EMIT 0x0F EMIT 0x77 \ + __asm mov c, ecx \ + __asm mov d, edi \ + __asm mov s, esi \ + +#else + +#define MULADDC_STOP \ + __asm mov c, ecx \ + __asm mov d, edi \ + __asm mov s, esi \ + +#endif /* SSE2 */ +#endif /* MSVC */ + +#endif /* POLARSSL_HAVE_ASM */ + +#if !defined(MULADDC_CORE) +#if defined(POLARSSL_HAVE_UDBL) + +#define MULADDC_INIT \ +{ \ + t_udbl r; \ + t_uint r0, r1; + +#define MULADDC_CORE \ + r = *(s++) * (t_udbl) b; \ + r0 = r; \ + r1 = r >> biL; \ + r0 += c; r1 += (r0 < c); \ + r0 += *d; r1 += (r0 < *d); \ + c = r1; *(d++) = r0; + +#define MULADDC_STOP \ +} + +#else + +#define MULADDC_INIT \ +{ \ + t_uint s0, s1, b0, b1; \ + t_uint r0, r1, rx, ry; \ + b0 = ( b << biH ) >> biH; \ + b1 = ( b >> biH ); + +#define MULADDC_CORE \ + s0 = ( *s << biH ) >> biH; \ + s1 = ( *s >> biH ); s++; \ + rx = s0 * b1; r0 = s0 * b0; \ + ry = s1 * b0; r1 = s1 * b1; \ + r1 += ( rx >> biH ); \ + r1 += ( ry >> biH ); \ + rx <<= biH; ry <<= biH; \ + r0 += rx; r1 += (r0 < rx); \ + r0 += ry; r1 += (r0 < ry); \ + r0 += c; r1 += (r0 < c); \ + r0 += *d; r1 += (r0 < *d); \ + c = r1; *(d++) = r0; + +#define MULADDC_STOP \ +} + +#endif /* C (generic) */ +#endif /* C (longlong) */ + +#endif /* bn_mul.h */ diff --git a/plat/gxb/include/cache.h b/plat/gxb/include/cache.h new file mode 100644 index 0000000..9f186f5 --- /dev/null +++ b/plat/gxb/include/cache.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2015 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + */ + +#ifndef __BL2_CACHE_H_ +#define __BL2_CACHE_H_ + +void disable_mmu_el1(void); /*disable mmu dcache*/ +void disable_mmu_icache_el1(void); /*disable mmu dcache icache*/ + +#endif /*__BL2_CACHE_H_*/
\ No newline at end of file diff --git a/plat/gxb/include/common.h b/plat/gxb/include/common.h new file mode 100644 index 0000000..68874ff --- /dev/null +++ b/plat/gxb/include/common.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * Common defines + */ + +#ifndef _BOOT_ROM_COMMON_H +#define _BOOT_ROM_COMMON_H + +#include <stdint.h> +#include <stddef.h> +#include "rsa_config.h" + +#ifdef CONFIG_EMU_BUILD +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#endif /* CONFIG_EMU_BUILD */ + +#define setbits_le32(reg, val) (*((volatile uint32_t *)((uintptr_t)(reg)))) |= (val) +#define clrbits_le32(reg, val) (*((volatile uint32_t *)((uintptr_t)(reg)))) &= (~(val)) +#define writel32(val, reg) (*((volatile uint32_t *)((uintptr_t)(reg)))) = (val) +#define readl32(reg) (*((volatile uint32_t *)((uintptr_t)(reg)))) + +#if 0 +static inline void writel32(uint32_t value, uintptr_t addr) +{ + *(volatile uint32_t*)addr = value; +} + +static inline uint32_t readl32(uintptr_t addr) +{ + return *(volatile uint32_t*)addr; +} +#endif + +#define writel writel32 +#define readl readl32 + +void print_str(const char *str); +void print_u32(unsigned int data); + +#undef DEBUG +#ifdef DEBUG +#define print_error print_str +#define print_out print_str +#define print_info print_str +#define print_dbg print_str +#define print_dbg_u32 print_u32 +#else +#define dummy_print(a) do{} while(0); +#define print_error print_str +#define print_out print_str +#define print_info(a) dummy_print(a) +#define print_dbg(a) dummy_print(a) +#define print_dbg_u32(a) dummy_print(a) +#endif + +#ifdef CONFIG_EMU_BUILD +#define ss_printf printf +#else +#define ss_printf(...) +#endif /* CONFIG_EMU_BUILD */ + +#endif /* _BOOT_ROM_COMMON_H */ diff --git a/plat/gxb/include/efuse.h b/plat/gxb/include/efuse.h new file mode 100644 index 0000000..bb32c23 --- /dev/null +++ b/plat/gxb/include/efuse.h @@ -0,0 +1,30 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/include/efuse.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __BL2_EFUSE_H__ +#define __BL2_EFUSE_H__ + +#include <stdint.h> + +void efuse_read(uint64_t offset, uint64_t length, const char * buffer); +void efuse_print(uint64_t offset, uint64_t length, const char * buffer); + +#endif /* __BL2_EFUSE_H__ */ diff --git a/plat/gxb/include/mailbox.h b/plat/gxb/include/mailbox.h new file mode 100644 index 0000000..7422e87 --- /dev/null +++ b/plat/gxb/include/mailbox.h @@ -0,0 +1,40 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/include/mailbox.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __BL2_MAILBOX_H_ +#define __BL2_MAILBOX_H_ + +#define MB_SRAM_BASE 0xd9013800 + +#define CMD_SHA 0xc0de0001 +#define CMD_OP_SHA 0xc0de0002 +#define CMD_DATA_LEN 0xc0dec0d0 +#define CMD_DATA 0xc0dec0de +#define CMD_END 0xe00de00d + +void *memcpy_t(void *dest, const void *src, size_t len); +void mb_send_data(uint32_t val, uint32_t port); +uint32_t mb_read_data(uint32_t port); +void mb_clear_data(uint32_t val, uint32_t port); +void send_bl30x(uint32_t addr, uint32_t size, const uint8_t * sha2, + uint32_t sha2_length, const char * name); + +#endif /*__BL2_MAILBOX_H_*/
\ No newline at end of file diff --git a/plat/gxb/include/ndma_utils.h b/plat/gxb/include/ndma_utils.h new file mode 100644 index 0000000..a0ff93a --- /dev/null +++ b/plat/gxb/include/ndma_utils.h @@ -0,0 +1,33 @@ + +#ifndef NDMA_UTILS_H +#define NDMA_UTILS_H +void NDMA_set_table_position( uint32_t thread_num, uint32_t table_start, uint32_t table_end ); +void NDMA_set_table_position_secure( uint32_t thread_num, uint32_t table_start, uint32_t table_end ); +void NDMA_start(uint32_t thread_num); +void NDMA_stop(uint32_t thread_num); +void NDMA_wait_for_completion(uint32_t thread_num); +void NDMA_add_descriptor_aes( + uint32_t thread_num, + uint32_t irq, + uint32_t cbc_enable, + uint32_t cbc_reset, + uint32_t encrypt, // 0 = decrypt, 1 = encrypt + uint32_t aes_type, // 00 = 128, 01 = 192, 10 = 256 + uint32_t pre_endian, + uint32_t post_endian, + uint32_t bytes_to_move, + uint32_t src_addr, + uint32_t dest_addr, + uint32_t ctr_endian, + uint32_t ctr_limit ); + + +void NDMA_add_descriptor_sha( + uint32_t thread_num, + uint32_t irq, + uint32_t sha_type, // 0 = sha1, 1 = sha2-224, 2 = sha2-256 + uint32_t pre_endian, + uint32_t bytes_to_move, + uint32_t src_addr, + uint32_t last_block ); +#endif diff --git a/plat/gxb/include/plat_init.h b/plat/gxb/include/plat_init.h new file mode 100644 index 0000000..a6ee99b --- /dev/null +++ b/plat/gxb/include/plat_init.h @@ -0,0 +1,27 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/include/plat_init.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __ARCH_INIT_H +#define __ARCH_INIT_H + +void pinmux_init(void); + +#endif /* __ARCH_INIT_H */ diff --git a/plat/gxb/include/plat_macros.S b/plat/gxb/include/plat_macros.S new file mode 100644 index 0000000..71f4264 --- /dev/null +++ b/plat/gxb/include/plat_macros.S @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <gic_v2.h> +#include "../plat_def.h" + +.section .rodata.gic_reg_name, "aS" +gic_regs: .asciz "gic_iar", "gic_ctlr", "" + +/* Currently we have only 2 GIC registers to report */ +#define GIC_REG_SIZE (2 * 8) + /* --------------------------------------------- + * The below macro prints out relevant GIC + * registers whenever an unhandled exception is + * taken in BL3-1. + * --------------------------------------------- + */ + .macro plat_print_gic_regs + ldr x0, =GICC_BASE + ldr w1, [x0, #GICC_IAR] + ldr w2, [x0, #GICC_CTLR] + sub sp, sp, #GIC_REG_SIZE + stp x1, x2, [sp] /* we store the gic registers as 64 bit */ + adr x0, gic_regs + mov x1, sp + bl print_string_value + add sp, sp, #GIC_REG_SIZE + .endm diff --git a/plat/gxb/include/platform_def.h b/plat/gxb/include/platform_def.h new file mode 100644 index 0000000..386baa3 --- /dev/null +++ b/plat/gxb/include/platform_def.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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_DEF_H__ +#define __PLATFORM_DEF_H__ + +#include <arch.h> + +/******************************************************************************* + * Platform binary types for linking + ******************************************************************************/ +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +/******************************************************************************* + * Generic platform constants + ******************************************************************************/ + +/* Size of cacheable stacks */ +#define PLATFORM_STACK_SIZE 0xE00 + +/* Size of coherent stacks for debug and release builds */ +#if DEBUG +#define PCPU_DV_MEM_STACK_SIZE 0x400 +#else +#define PCPU_DV_MEM_STACK_SIZE 0x300 +#endif + +#define FIRMWARE_WELCOME_STR "Booting trusted firmware boot loader stage 1\n\r" + +/* Trusted Boot Firmware BL2 */ +#define BL2_IMAGE_NAME "bl2.bin" +#define BL2_IMAGE_SIZE 0xC000 /*48KB*/ +#define BL2_IMAGE_OFFSET 0x1000 /*4KB, header of bl2*/ + +/* EL3 Runtime Firmware BL3-1 */ +#define BL31_IMAGE_NAME "bl31.bin" + +/* SCP Firmware BL3-0 */ +#define BL30_IMAGE_NAME "bl30.bin" + +/* Secure Payload BL3-2 (Trusted OS) */ +#define BL32_IMAGE_NAME "bl32.bin" + +/* Non-Trusted Firmware BL3-3 */ +#define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */ + +/* Firmware Image Package */ +#define FIP_IMAGE_NAME "fip.bin" + +#define PLATFORM_CACHE_LINE_SIZE 64 +#define PLATFORM_CORE_COUNT 6 +#define PRIMARY_CPU 0x0 +#define MAX_IO_DEVICES 3 +#define MAX_IO_HANDLES 4 + +/******************************************************************************* + * Platform memory map related constants + ******************************************************************************/ +#define FLASH_BASE 0x08000000 +#define FLASH_SIZE 0x04000000 + +/* Bypass offset from start of NOR flash */ +#define BL1_ROM_BYPASS_OFFSET 0x03EC0000 + +//#ifndef TZROM_BASE +/* Use the bypass address */ +//#define TZROM_BASE FLASH_BASE + BL1_ROM_BYPASS_OFFSET +//#endif +#define TZROM_BASE 0xD9040000 +#define TZROM_SIZE 0x00010000 + +//#define TZRAM_BASE 0x04001000 +//#define TZRAM_SIZE 0x0003F000 +#define TZRAM_BASE 0xD9000000 +#define TZRAM_SIZE 0x00020000 + +#define TZRAM_BL2_FREE_BASE TZRAM_BASE + BL2_IMAGE_SIZE +#define TZRAM_BL2_FREE_SIZE TZRAM_SIZE - BL2_IMAGE_SIZE + +/******************************************************************************* + * BL1 specific defines. + * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 base + * addresses. + ******************************************************************************/ +#define BL1_RO_BASE TZROM_BASE +#define BL1_RO_LIMIT (TZROM_BASE + TZROM_SIZE) +#define BL1_RW_BASE TZRAM_BASE +#define BL1_RW_LIMIT BL31_BASE + +/******************************************************************************* + * BL2 specific defines. + ******************************************************************************/ +//#define BL2_BASE (TZRAM_BASE + TZRAM_SIZE - 0xd000) +#define BL2_BASE TZRAM_BASE + BL2_IMAGE_OFFSET +//#define BL2_LIMIT (TZRAM_BASE + TZRAM_SIZE) +#define BL2_LIMIT (TZRAM_BASE + 0XC000) //48KB + +#define BL2_ALIGN (16) //default 4K +//#define BL2_ENABLE_MMU + +/******************************************************************************* + * Load address of BL3-0 in the ${PLAT} port + * BL3-0 is loaded to the same place as BL3-1. Once BL3-0 is transferred to the + * SCP, it is discarded and BL3-1 is loaded over the top. + ******************************************************************************/ +#define BL30_BASE BL31_BASE + +/******************************************************************************* + * BL3-1 specific defines. + ******************************************************************************/ +#define BL31_BASE (TZRAM_BASE + 0x8000) +#define BL31_LIMIT BL32_BASE + +/******************************************************************************* + * BL3-2 specific defines. + ******************************************************************************/ +#define TSP_SEC_MEM_BASE TZRAM_BASE +#define TSP_SEC_MEM_SIZE TZRAM_SIZE +#define BL32_BASE (TZRAM_BASE + TZRAM_SIZE - 0x1d000) +#define BL32_LIMIT BL2_BASE + +/******************************************************************************* + * Load address of BL3-3 in the ${PLAT} port + ******************************************************************************/ +#define NS_IMAGE_OFFSET 0xE0000000 + +/******************************************************************************* + * Platform specific page table and MMU setup constants + ******************************************************************************/ +#define ADDR_SPACE_SIZE (1ull << 32) +#define MAX_XLAT_TABLES 5 +#define MAX_MMAP_REGIONS 16 + +/******************************************************************************* + * ID of the secure physical generic timer interrupt. + ******************************************************************************/ +#define IRQ_SEC_PHY_TIMER 29 + +/******************************************************************************* + * CCI-400 related constants + ******************************************************************************/ +#define CCI400_BASE 0x2c090000 +#define CCI400_SL_IFACE_CLUSTER0 4 +#define CCI400_SL_IFACE_CLUSTER1 3 +#define CCI400_SL_IFACE_INDEX(mpidr) (mpidr & MPIDR_CLUSTER_MASK ? \ + CCI400_SL_IFACE_CLUSTER1 : \ + CCI400_SL_IFACE_CLUSTER0) +/******************************************************************************* + * Declarations and constants to access the mailboxes safely. Each mailbox is + * aligned on the biggest cache line size in the platform. This is known only + * to the platform as it might have a combination of integrated and external + * caches. Such alignment ensures that two maiboxes do not sit on the same cache + * line at any cache level. They could belong to different cpus/clusters & + * get written while being protected by different locks causing corruption of + * a valid mailbox address. + ******************************************************************************/ +#define CACHE_WRITEBACK_SHIFT 6 +#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) + +#endif /* __PLATFORM_DEF_H__ */ diff --git a/plat/gxb/include/pll.h b/plat/gxb/include/pll.h new file mode 100644 index 0000000..1e71b7e --- /dev/null +++ b/plat/gxb/include/pll.h @@ -0,0 +1,61 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/include/pll.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <stdint.h> +#include <io.h> + +#ifndef __BL2_PLL_H_ +#define __BL2_PLL_H_ + +#define PLL_lOCK_CHECK_LOOP 10 +#define PLL_LOCK_BIT_OFFSET 31 + +#define Wr(reg, val) writel(val, reg) +#define Rd(reg) readl(reg) + +#define CFG_SYS_PLL_CNTL_2 (0x5ac80000) +#define CFG_SYS_PLL_CNTL_3 (0x8e452015) +#define CFG_SYS_PLL_CNTL_4 (0x0401d40c) +#define CFG_SYS_PLL_CNTL_5 (0x00000870) + +#define CFG_MPLL_CNTL_2 (0x59C80000) +#define CFG_MPLL_CNTL_3 (0xCA45B822) +#define CFG_MPLL_CNTL_4 (0x00010007) +#define CFG_MPLL_CNTL_5 (0xB5500E1A) +#define CFG_MPLL_CNTL_6 (0xFC454545) +#define CFG_MPLL_CNTL_7 (0) +#define CFG_MPLL_CNTL_8 (0) +#define CFG_MPLL_CNTL_9 (0) + +//DDR PLL +#define CFG_DDR_PLL_CNTL_1 (0x69c80000) +#define CFG_DDR_PLL_CNTL_2 (0xca463823) +#define CFG_DDR_PLL_CNTL_3 (0x00c00023) +#define CFG_DDR_PLL_CNTL_4 (0x00303500) + +unsigned int pll_init(void); +void clocks_set_sys_cpu_clk(uint32_t freq, \ + uint32_t pclk_ratio, \ + uint32_t aclkm_ratio, \ + uint32_t atclk_ratio ); +unsigned pll_lock_check(unsigned long pll_reg, const char *pll_name); + +#endif /*__BL2_PLL_H_*/
\ No newline at end of file diff --git a/plat/gxb/include/rsa.h b/plat/gxb/include/rsa.h new file mode 100644 index 0000000..c6c91c5 --- /dev/null +++ b/plat/gxb/include/rsa.h @@ -0,0 +1,598 @@ +/** + * \file rsa.h + * + * \brief The RSA public-key cryptosystem + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_RSA_H +#define POLARSSL_RSA_H + +#include "common.h" +#include "bignum.h" + +/* + * RSA Error codes + */ +#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x4080 /**< Bad input parameters to function. */ +#define POLARSSL_ERR_RSA_INVALID_PADDING -0x4100 /**< Input data contains invalid padding and is rejected. */ +#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x4180 /**< Something failed during generation of a key. */ +#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x4200 /**< Key failed to pass the libraries validity check. */ +#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x4280 /**< The public key operation failed. */ +#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x4300 /**< The private key operation failed. */ +#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x4380 /**< The PKCS#1 verification failed. */ +#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE -0x4400 /**< The output buffer for decryption is not large enough. */ +#define POLARSSL_ERR_RSA_RNG_FAILED -0x4480 /**< The random generator failed to generate non-zeros. */ + +/* + * PKCS#1 constants + */ +#define SIG_RSA_RAW 0 +#define SIG_RSA_MD2 2 +#define SIG_RSA_MD4 3 +#define SIG_RSA_MD5 4 +#define SIG_RSA_SHA1 5 +#define SIG_RSA_SHA224 14 +#define SIG_RSA_SHA256 11 +#define SIG_RSA_SHA384 12 +#define SIG_RSA_SHA512 13 + +#define RSA_PUBLIC 0 +#define RSA_PRIVATE 1 + +#define RSA_PKCS_V15 0 +#define RSA_PKCS_V21 1 + +#define RSA_SIGN 1 +#define RSA_CRYPT 2 + +#define ASN1_STR_CONSTRUCTED_SEQUENCE "\x30" +#define ASN1_STR_NULL "\x05" +#define ASN1_STR_OID "\x06" +#define ASN1_STR_OCTET_STRING "\x04" + +#define OID_DIGEST_ALG_MDX "\x2A\x86\x48\x86\xF7\x0D\x02\x00" +#define OID_HASH_ALG_SHA1 "\x2b\x0e\x03\x02\x1a" +#define OID_HASH_ALG_SHA2X "\x60\x86\x48\x01\x65\x03\x04\x02\x00" + +#define OID_ISO_MEMBER_BODIES "\x2a" +#define OID_ISO_IDENTIFIED_ORG "\x2b" + +/* + * ISO Member bodies OID parts + */ +#define OID_COUNTRY_US "\x86\x48" +#define OID_RSA_DATA_SECURITY "\x86\xf7\x0d" + +/* + * ISO Identified organization OID parts + */ +#define OID_OIW_SECSIG_SHA1 "\x0e\x03\x02\x1a" + +/* + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithmIdentifier, + * digest Digest } + * + * DigestAlgorithmIdentifier ::= AlgorithmIdentifier + * + * Digest ::= OCTET STRING + */ +#define ASN1_HASH_MDX \ +( \ + ASN1_STR_CONSTRUCTED_SEQUENCE "\x20" \ + ASN1_STR_CONSTRUCTED_SEQUENCE "\x0C" \ + ASN1_STR_OID "\x08" \ + OID_DIGEST_ALG_MDX \ + ASN1_STR_NULL "\x00" \ + ASN1_STR_OCTET_STRING "\x10" \ +) + +#define ASN1_HASH_SHA1 \ + ASN1_STR_CONSTRUCTED_SEQUENCE "\x21" \ + ASN1_STR_CONSTRUCTED_SEQUENCE "\x09" \ + ASN1_STR_OID "\x05" \ + OID_HASH_ALG_SHA1 \ + ASN1_STR_NULL "\x00" \ + ASN1_STR_OCTET_STRING "\x14" + +#define ASN1_HASH_SHA1_ALT \ + ASN1_STR_CONSTRUCTED_SEQUENCE "\x1F" \ + ASN1_STR_CONSTRUCTED_SEQUENCE "\x07" \ + ASN1_STR_OID "\x05" \ + OID_HASH_ALG_SHA1 \ + ASN1_STR_OCTET_STRING "\x14" + +#define ASN1_HASH_SHA2X \ + ASN1_STR_CONSTRUCTED_SEQUENCE "\x11" \ + ASN1_STR_CONSTRUCTED_SEQUENCE "\x0d" \ + ASN1_STR_OID "\x09" \ + OID_HASH_ALG_SHA2X \ + ASN1_STR_NULL "\x00" \ + ASN1_STR_OCTET_STRING "\x00" + +/** + * \brief RSA context structure + */ +typedef struct +{ + int ver; /*!< always 0 */ + size_t len; /*!< size(N) in chars */ + + mpi N; /*!< public modulus */ + mpi E; /*!< public exponent */ + + mpi D; /*!< private exponent */ + mpi P; /*!< 1st prime factor */ + mpi Q; /*!< 2nd prime factor */ + mpi DP; /*!< D % (P - 1) */ + mpi DQ; /*!< D % (Q - 1) */ + mpi QP; /*!< 1 / (Q % P) */ + + mpi RN; /*!< cached R^2 mod N */ + mpi RP; /*!< cached R^2 mod P */ + mpi RQ; /*!< cached R^2 mod Q */ + + int padding; /*!< RSA_PKCS_V15 for 1.5 padding and + RSA_PKCS_v21 for OAEP/PSS */ + int hash_id; /*!< Hash identifier of md_type_t as + specified in the md.h header file + for the EME-OAEP and EMSA-PSS + encoding */ +} +rsa_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Initialize an RSA context + * + * Note: Set padding to RSA_PKCS_V21 for the RSAES-OAEP + * encryption scheme and the RSASSA-PSS signature scheme. + * + * \param ctx RSA context to be initialized + * \param padding RSA_PKCS_V15 or RSA_PKCS_V21 + * \param hash_id RSA_PKCS_V21 hash identifier + * + * \note The hash_id parameter is actually ignored + * when using RSA_PKCS_V15 padding. + */ +void rsa_init( rsa_context *ctx, + int padding, + int hash_id); + +/** + * \brief Generate an RSA keypair + * + * \param ctx RSA context that will hold the key + * \param f_rng RNG function + * \param p_rng RNG parameter + * \param nbits size of the public key in bits + * \param exponent public exponent (e.g., 65537) + * + * \note rsa_init() must be called beforehand to setup + * the RSA context. + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + */ +int rsa_gen_key( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + unsigned int nbits, int exponent ); + +/** + * \brief Check a public RSA key + * + * \param ctx RSA context to be checked + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + */ +int rsa_check_pubkey( const rsa_context *ctx ); + +/** + * \brief Check a private RSA key + * + * \param ctx RSA context to be checked + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + */ +int rsa_check_privkey( const rsa_context *ctx ); + +/** + * \brief Do an RSA public key operation + * + * \param ctx RSA context + * \param input input buffer + * \param output output buffer + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note This function does NOT take care of message + * padding. Also, be sure to set input[0] = 0 or assure that + * input is smaller than N. + * + * \note The input and output buffers must be large + * enough (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_public( rsa_context *ctx, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief Do an RSA private key operation + * + * \param ctx RSA context + * \param input input buffer + * \param output output buffer + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The input and output buffers must be large + * enough (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_private( rsa_context *ctx, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief Generic wrapper to perform a PKCS#1 encryption using the + * mode from the context. Add the message padding, then do an + * RSA operation. + * + * \param ctx RSA context + * \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param ilen contains the plaintext length + * \param input buffer holding the data to be encrypted + * \param output buffer that will hold the ciphertext + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_pkcs1_encrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t ilen, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief Perform a PKCS#1 v1.5 encryption (RSAES-PKCS1-v1_5-ENCRYPT) + * + * \param ctx RSA context + * \param f_rng RNG function (Needed for padding) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param ilen contains the plaintext length + * \param input buffer holding the data to be encrypted + * \param output buffer that will hold the ciphertext + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t ilen, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief Perform a PKCS#1 v2.1 OAEP encryption (RSAES-OAEP-ENCRYPT) + * + * \param ctx RSA context + * \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param label buffer holding the custom label to use + * \param label_len contains the label length + * \param ilen contains the plaintext length + * \param input buffer holding the data to be encrypted + * \param output buffer that will hold the ciphertext + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_rsaes_oaep_encrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + const unsigned char *label, size_t label_len, + size_t ilen, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief Generic wrapper to perform a PKCS#1 decryption using the + * mode from the context. Do an RSA operation, then remove + * the message padding + * + * \param ctx RSA context + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param olen will contain the plaintext length + * \param input buffer holding the encrypted data + * \param output buffer that will hold the plaintext + * \param output_max_len maximum length of the output buffer + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise + * an error is thrown. + */ +int rsa_pkcs1_decrypt( rsa_context *ctx, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ); + +/** + * \brief Perform a PKCS#1 v1.5 decryption (RSAES-PKCS1-v1_5-DECRYPT) + * + * \param ctx RSA context + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param olen will contain the plaintext length + * \param input buffer holding the encrypted data + * \param output buffer that will hold the plaintext + * \param output_max_len maximum length of the output buffer + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise + * an error is thrown. + */ +int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ); + +/** + * \brief Perform a PKCS#1 v2.1 OAEP decryption (RSAES-OAEP-DECRYPT) + * + * \param ctx RSA context + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param label buffer holding the custom label to use + * \param label_len contains the label length + * \param olen will contain the plaintext length + * \param input buffer holding the encrypted data + * \param output buffer that will hold the plaintext + * \param output_max_len maximum length of the output buffer + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise + * an error is thrown. + */ +int rsa_rsaes_oaep_decrypt( rsa_context *ctx, + int mode, + const unsigned char *label, size_t label_len, + size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ); + +/** + * \brief Generic wrapper to perform a PKCS#1 signature using the + * mode from the context. Do a private RSA operation to sign + * a message digest + * + * \param ctx RSA context + * \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512} + * \param hashlen message digest length (for SIG_RSA_RAW only) + * \param hash buffer holding the message digest + * \param sig buffer that will hold the ciphertext + * + * \return 0 if the signing operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * + * \note In case of PKCS#1 v2.1 encoding keep in mind that + * the hash_id in the RSA context is the one used for the + * encoding. hash_id in the function call is the type of hash + * that is encoded. According to RFC 3447 it is advised to + * keep both hashes the same. + */ +int rsa_pkcs1_sign( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + int hash_id, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ); + +/** + * \brief Perform a PKCS#1 v1.5 signature (RSASSA-PKCS1-v1_5-SIGN) + * + * \param ctx RSA context + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512} + * \param hashlen message digest length (for SIG_RSA_RAW only) + * \param hash buffer holding the message digest + * \param sig buffer that will hold the ciphertext + * + * \return 0 if the signing operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx, + int mode, + int hash_id, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ); + +/** + * \brief Perform a PKCS#1 v2.1 PSS signature (RSASSA-PSS-SIGN) + * + * \param ctx RSA context + * \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512} + * \param hashlen message digest length (for SIG_RSA_RAW only) + * \param hash buffer holding the message digest + * \param sig buffer that will hold the ciphertext + * + * \return 0 if the signing operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * + * \note In case of PKCS#1 v2.1 encoding keep in mind that + * the hash_id in the RSA context is the one used for the + * encoding. hash_id in the function call is the type of hash + * that is encoded. According to RFC 3447 it is advised to + * keep both hashes the same. + */ +int rsa_rsassa_pss_sign( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + int hash_id, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ); + +/** + * \brief Generic wrapper to perform a PKCS#1 verification using the + * mode from the context. Do a public RSA operation and check + * the message digest + * + * \param ctx points to an RSA public key + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512} + * \param hashlen message digest length (for SIG_RSA_RAW only) + * \param hash buffer holding the message digest + * \param sig buffer holding the ciphertext + * + * \return 0 if the verify operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * + * \note In case of PKCS#1 v2.1 encoding keep in mind that + * the hash_id in the RSA context is the one used for the + * verification. hash_id in the function call is the type of hash + * that is verified. According to RFC 3447 it is advised to + * keep both hashes the same. + */ +int rsa_pkcs1_verify( rsa_context *ctx, + int mode, + int hash_id, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ); + +/** + * \brief Perform a PKCS#1 v1.5 verification (RSASSA-PKCS1-v1_5-VERIFY) + * + * \param ctx points to an RSA public key + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512} + * \param hashlen message digest length (for SIG_RSA_RAW only) + * \param hash buffer holding the message digest + * \param sig buffer holding the ciphertext + * + * \return 0 if the verify operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx, + int mode, + int hash_id, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ); + +/** + * \brief Perform a PKCS#1 v2.1 PSS verification (RSASSA-PSS-VERIFY) + * \brief Do a public RSA and check the message digest + * + * \param ctx points to an RSA public key + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512} + * \param hashlen message digest length (for SIG_RSA_RAW only) + * \param hash buffer holding the message digest + * \param sig buffer holding the ciphertext + * + * \return 0 if the verify operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * + * \note In case of PKCS#1 v2.1 encoding keep in mind that + * the hash_id in the RSA context is the one used for the + * verification. hash_id in the function call is the type of hash + * that is verified. According to RFC 3447 it is advised to + * keep both hashes the same. + */ +int rsa_rsassa_pss_verify( rsa_context *ctx, + int mode, + int hash_id, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ); + +/** + * \brief Free the components of an RSA key + * + * \param ctx RSA Context to free + */ +void rsa_free( rsa_context *ctx ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int rsa_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* rsa.h */ diff --git a/plat/gxb/include/rsa_config.h b/plat/gxb/include/rsa_config.h new file mode 100644 index 0000000..6425e11 --- /dev/null +++ b/plat/gxb/include/rsa_config.h @@ -0,0 +1,892 @@ +/** + * \file config.h + * + * \brief Configuration options (set of defines) + * + * Copyright (C) 2006-2012, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ +#ifndef POLARSSL_CONFIG_H +#define POLARSSL_CONFIG_H + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def POLARSSL_HAVE_INT8 + * + * The system uses 8-bit wide native integers. + * + * Uncomment if native integers are 8-bit wide. +#define POLARSSL_HAVE_INT8 + */ + +/** + * \def POLARSSL_HAVE_INT16 + * + * The system uses 16-bit wide native integers. + * + * Uncomment if native integers are 16-bit wide. +#define POLARSSL_HAVE_INT16 + */ + +/** + * \def POLARSSL_HAVE_LONGLONG + * + * The compiler supports the 'long long' type. + * (Only used on 32-bit platforms) + */ +#define POLARSSL_HAVE_LONGLONG + +/** + * \def POLARSSL_HAVE_ASM + * + * The compiler has support for asm() + * + * Uncomment to enable the use of assembly code. + * + * Requires support for asm() in compiler. + * + * Used in: + * library/timing.c + * library/padlock.c + * include/polarssl/bn_mul.h + * + */ +#define POLARSSL_HAVE_ASM + +/** + * \def POLARSSL_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + * +#define POLARSSL_HAVE_SSE2 + */ +/* \} name */ + +/** + * \name SECTION: PolarSSL feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def POLARSSL_AES_ROM_TABLES + * + * Store the AES tables in ROM. + * + * Uncomment this macro to store the AES tables in ROM. + * +#define POLARSSL_AES_ROM_TABLES + */ + +/** + * \def POLARSSL_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CFB + +/** + * \def POLARSSL_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CTR + +/** + * \def POLARSSL_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * Requires POLARSSL_ENABLE_WEAK_CIPHERSUITES as well to enable + * the following ciphersuites: + * TLS_RSA_WITH_NULL_MD5 + * TLS_RSA_WITH_NULL_SHA + * TLS_RSA_WITH_NULL_SHA256 + * + * Uncomment this macro to enable the NULL cipher and ciphersuites +#define POLARSSL_CIPHER_NULL_CIPHER + */ + +/** + * \def POLARSSL_ENABLE_WEAK_CIPHERSUITES + * + * Enable weak ciphersuites in SSL / TLS + * Warning: Only do so when you know what you are doing. This allows for + * channels with virtually no security at all! + * + * This enables the following ciphersuites: + * TLS_RSA_WITH_DES_CBC_SHA + * TLS_DHE_RSA_WITH_DES_CBC_SHA + * + * Uncomment this macro to enable weak ciphersuites +#define POLARSSL_ENABLE_WEAK_CIPHERSUITES + */ + +/** + * \def POLARSSL_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of error_strerror() in + * third party libraries easier. + * + * Disable if you run into name conflicts and want to really remove the + * error_strerror() + */ +#define POLARSSL_ERROR_STRERROR_DUMMY + +/** + * \def POLARSSL_GENPRIME + * + * Requires: POLARSSL_BIGNUM_C, POLARSSL_RSA_C + * + * Enable the RSA prime-number generation code. +#define POLARSSL_GENPRIME + */ + +/** + * \def POLARSSL_FS_IO + * + * Enable functions that use the filesystem. +#define POLARSSL_FS_IO + */ + +/** + * \def POLARSSL_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources. These are the platform specific, + * hardclock and HAVEGE based poll functions. + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. +#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES + */ + +/** + * \def POLARSSL_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. +#define POLARSSL_NO_PLATFORM_ENTROPY + */ + +/** + * \def POLARSSL_PKCS1_V21 + * + * Requires: POLARSSL_MD_C, POLARSSL_RSA_C + * + * Enable support for PKCS#1 v2.1 encoding. + * This enables support for RSAES-OAEP and RSASSA-PSS operations. +#define POLARSSL_PKCS1_V21 + */ + +/** + * \def POLARSSL_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * +#define POLARSSL_RSA_NO_CRT + */ + +/** + * \def POLARSSL_SELF_TEST + * + * Enable the checkup functions (*_self_test). +#define POLARSSL_SELF_TEST + */ + +/** + * \def POLARSSL_SSL_ALL_ALERT_MESSAGES + * + * Enable sending of alert messages in case of encountered errors as per RFC. + * If you choose not to send the alert messages, PolarSSL can still communicate + * with other servers, only debugging of failures is harder. + * + * The advantage of not sending alert messages, is that no information is given + * about reasons for failures thus preventing adversaries of gaining intel. + * + * Enable sending of all alert messages + */ +#define POLARSSL_SSL_ALERT_MESSAGES + +/** + * \def POLARSSL_SSL_DEBUG_ALL + * + * Enable the debug messages in SSL module for all issues. + * Debug messages have been disabled in some places to prevent timing + * attacks due to (unbalanced) debugging function calls. + * + * If you need all error reporting you should enable this during debugging, + * but remove this for production servers that should log as well. + * + * Uncomment this macro to report all debug messages on errors introducing + * a timing side-channel. + * +#define POLARSSL_SSL_DEBUG_ALL + */ + +/** + * \def POLARSSL_SSL_HW_RECORD_ACCEL + * + * Enable hooking functions in SSL module for hardware acceleration of + * individual records. + * + * Uncomment this macro to enable hooking functions. +#define POLARSSL_SSL_HW_RECORD_ACCEL + */ + +/** + * \def POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + * + * Enable support for receiving and parsing SSLv2 Client Hello messages for the + * SSL Server module (POLARSSL_SSL_SRV_C) + * + * Comment this macro to disable support for SSLv2 Client Hello messages. + */ +#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + +/** + * \def POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an unknown critical extension. + * + * Uncomment to prevent an error. + * +#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + */ + +/** + * \def POLARSSL_ZLIB_SUPPORT + * + * If set, the SSL/TLS module uses ZLIB to support compression and + * decompression of packet data. + * + * Used in: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This feature requires zlib library and headers to be present. + * + * Uncomment to enable use of ZLIB +#define POLARSSL_ZLIB_SUPPORT + */ +/* \} name */ + +/** + * \name SECTION: PolarSSL modules + * + * This section enables or disables entire modules in PolarSSL + * \{ + */ + +/** + * \def POLARSSL_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/ssl_tls.c + * library/pem.c + * library/ctr_drbg.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_RSA_WITH_AES_128_CBC_SHA + * TLS_RSA_WITH_AES_256_CBC_SHA + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * TLS_RSA_WITH_AES_128_CBC_SHA256 + * TLS_RSA_WITH_AES_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * TLS_RSA_WITH_AES_128_GCM_SHA256 + * TLS_RSA_WITH_AES_256_GCM_SHA384 + * + * PEM uses AES for decrypting encrypted keys. +#define POLARSSL_AES_C + */ + +/** + * \def POLARSSL_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites: + * TLS_RSA_WITH_RC4_128_MD5 + * TLS_RSA_WITH_RC4_128_SHA +#define POLARSSL_ARC4_C + */ + +/** + * \def POLARSSL_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/x509parse.c + */ +#define POLARSSL_ASN1_PARSE_C + +/** + * \def POLARSSL_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + */ +#define POLARSSL_ASN1_WRITE_C + +/** + * \def POLARSSL_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +#define POLARSSL_BASE64_C + +/** + * \def POLARSSL_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/rsa.c + * library/ssl_tls.c + * library/x509parse.c + * + * This module is required for RSA and DHM support. + */ +#define POLARSSL_BIGNUM_C + +/** + * \def POLARSSL_BLOWFISH_C + * + * Enable the Blowfish block cipher. + * + * Module: library/blowfish.c + */ +#define POLARSSL_BLOWFISH_C + +/** + * \def POLARSSL_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + */ +#define POLARSSL_CAMELLIA_C + +/** + * \def POLARSSL_CERTS_C + * + * Enable the test certificates. + * + * Module: library/certs.c + * Caller: + * + * This module is used for testing (ssl_client/server). + */ +#define POLARSSL_CERTS_C + +/** + * \def POLARSSL_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * Caller: + * + * Uncomment to enable generic cipher wrappers. + */ +#define POLARSSL_CIPHER_C + +/** + * \def POLARSSL_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-256-based random generator + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: POLARSSL_AES_C + * + * This module provides the CTR_DRBG AES-256 random number generator. + */ +#define POLARSSL_CTR_DRBG_C + +/** + * \def POLARSSL_DEBUG_C + * + * Enable the debug functions. + * + * Module: library/debug.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module provides debugging functions. + */ +#define POLARSSL_DEBUG_C + +/** + * \def POLARSSL_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + * + * PEM uses DES/3DES for decrypting encrypted keys. + */ +#define POLARSSL_DES_C + +/** + * \def POLARSSL_DHM_C + * + * Enable the Diffie-Hellman-Merkle key exchange. + * + * Module: library/dhm.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_DHE_RSA_WITH_DES_CBC_SHA + * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + */ +#define POLARSSL_DHM_C + +/** + * \def POLARSSL_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: POLARSSL_SHA4_C + * + * This module provides a generic entropy pool + */ +#define POLARSSL_ENTROPY_C + +/** + * \def POLARSSL_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables err_strerror(). + */ +#define POLARSSL_ERROR_C + +/** + * \def POLARSSL_GCM_C + * + * Enable the Galois/Counter Mode (GCM) for AES + * + * Module: library/gcm.c + * + * Requires: POLARSSL_AES_C + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_RSA_WITH_AES_128_GCM_SHA256 + * TLS_RSA_WITH_AES_256_GCM_SHA384 + */ +#define POLARSSL_GCM_C + +/** + * \def POLARSSL_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Module: library/havege.c + * Caller: + * + * Requires: POLARSSL_TIMING_C + * + * This module enables the HAVEGE random number generator. + */ +#define POLARSSL_HAVEGE_C + +/** + * \def POLARSSL_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +#define POLARSSL_MD_C + +/** + * \def POLARSSL_MD2_C + * + * Enable the MD2 hash algorithm + * + * Module: library/md2.c + * Caller: library/x509parse.c + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + * +#define POLARSSL_MD2_C + */ + +/** + * \def POLARSSL_MD4_C + * + * Enable the MD4 hash algorithm + * + * Module: library/md4.c + * Caller: library/x509parse.c + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + * +#define POLARSSL_MD4_C + */ + +/** + * \def POLARSSL_MD5_C + * + * Enable the MD5 hash algorithm + * + * Module: library/md5.c + * Caller: library/pem.c + * library/ssl_tls.c + * library/x509parse.c + * + * This module is required for SSL/TLS and X.509. + * PEM uses MD5 for decrypting encrypted keys. + */ +#define POLARSSL_MD5_C + +/** + * \def POLARSSL_NET_C + * + * Enable the TCP/IP networking routines. + * + * Module: library/net.c + * Caller: + * + * This module provides TCP/IP networking routines. + */ +#define POLARSSL_NET_C + +/** + * \def POLARSSL_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * This modules adds support for the VIA PadLock on x86. +#define POLARSSL_PADLOCK_C + */ + +/** + * \def POLARSSL_PBKDF2_C + * + * Enable PKCS#5 PBKDF2 key derivation function + * + * Module: library/pbkdf2.c + * + * Requires: POLARSSL_MD_C + * + * This module adds support for the PKCS#5 PBKDF2 key derivation function. +#define POLARSSL_PBKDF2_C + */ + +/** + * \def POLARSSL_PEM_C + * + * Enable PEM decoding + * + * Module: library/pem.c + * Caller: library/x509parse.c + * + * Requires: POLARSSL_BASE64_C + * + * This modules adds support for decoding PEM files. + */ +#define POLARSSL_PEM_C + +/** + * \def POLARSSL_PKCS11_C + * + * Enable wrapper for PKCS#11 smartcard support. + * + * Module: library/ssl_srv.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module enables SSL/TLS PKCS #11 smartcard support. + * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) +#define POLARSSL_PKCS11_C + */ + +/** + * \def POLARSSL_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509.c + * + * Requires: POLARSSL_BIGNUM_C + * + * This module is required for SSL/TLS and MD5-signed certificates. + */ +#define POLARSSL_RSA_C + +/** + * \def POLARSSL_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509parse.c + * + * This module is required for SSL/TLS and SHA1-signed certificates. +#define POLARSSL_SHA1_C + */ + +/** + * \def POLARSSL_SHA2_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * + * Module: library/sha2.c + * Caller: library/md_wrap.c + * library/x509parse.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#define POLARSSL_SHA2_C + +/** + * \def POLARSSL_SHA4_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * + * Module: library/sha4.c + * Caller: library/md_wrap.c + * library/x509parse.c + * + * This module adds support for SHA-384 and SHA-512. + */ +#define POLARSSL_SHA4_C + +/** + * \def POLARSSL_SSL_CACHE_C + * + * Enable simple SSL cache implementation. + * + * Module: library/ssl_cache.c + * Caller: + * + * Requires: POLARSSL_SSL_CACHE_C + */ +#define POLARSSL_SSL_CACHE_C + +/** + * \def POLARSSL_SSL_CLI_C + * + * Enable the SSL/TLS client code. + * + * Module: library/ssl_cli.c + * Caller: + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module is required for SSL/TLS client support. + */ +#define POLARSSL_SSL_CLI_C + +/** + * \def POLARSSL_SSL_SRV_C + * + * Enable the SSL/TLS server code. + * + * Module: library/ssl_srv.c + * Caller: + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module is required for SSL/TLS server support. + */ +#define POLARSSL_SSL_SRV_C + +/** + * \def POLARSSL_SSL_TLS_C + * + * Enable the generic SSL/TLS code. + * + * Module: library/ssl_tls.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: POLARSSL_MD5_C, POLARSSL_SHA1_C, POLARSSL_X509_PARSE_C + * + * This module is required for SSL/TLS. + */ +#define POLARSSL_SSL_TLS_C + +/** + * \def POLARSSL_TIMING_C + * + * Enable the portable timing interface. + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +#define POLARSSL_TIMING_C + +/** + * \def POLARSSL_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +#define POLARSSL_VERSION_C + +/** + * \def POLARSSL_X509_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/x509parse.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_BIGNUM_C, POLARSSL_RSA_C + * + * This module is required for X.509 certificate parsing. + */ +#define POLARSSL_X509_PARSE_C + +/** + * \def POLARSSL_X509_WRITE_C + * + * Enable X.509 buffer writing. + * + * Module: library/x509write.c + * + * Requires: POLARSSL_BIGNUM_C, POLARSSL_RSA_C + * + * This module is required for X.509 certificate request writing. + */ +#define POLARSSL_X509_WRITE_C + +/** + * \def POLARSSL_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +#define POLARSSL_XTEA_C +/* \} name */ + +#endif /* config.h */ diff --git a/plat/gxb/include/saradc.h b/plat/gxb/include/saradc.h new file mode 100644 index 0000000..ca6becf --- /dev/null +++ b/plat/gxb/include/saradc.h @@ -0,0 +1,48 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/include/pll.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <stdint.h> +#include <io.h> + +#ifndef __SARADC_H_ +#define __SARADC_H_ + +#define Wr(reg, val) writel(val, reg) +#define Rd(reg) readl(reg) + +#define P_SAR_SAR_ADC_REG0 (volatile unsigned int *)0xc1108680 +#define P_SAR_ADC_CHAN_LIST (volatile unsigned int *)0xc1108684 +#define P_SAR_ADC_AVG_CNTL (volatile unsigned int *)0xc1108688 +#define P_SAR_ADC_REG3 (volatile unsigned int *)0xc110868c +#define P_SAR_ADC_DELAY (volatile unsigned int *)0xc1108690 +#define P_SAR_ADC_AUX_SW (volatile unsigned int *)0xc110869c +#define P_SAR_ADC_CHAN_10_SW (volatile unsigned int *)0xc11086a0 +#define P_SAR_ADC_DETECT_IDLE_SW (volatile unsigned int *)0xc11086a4 +#define P_SAR_ADC_DELTA_11 (volatile unsigned int *)0xc11086a8 +#define P_SAR_ADC_TEMP_SES (volatile unsigned int *)0xc11086ac +#define P_SAR_ADC_CLOCK (volatile unsigned int *)0xc883c3d8 +#define P_SAR_FIFO_READ (volatile unsigned int *)0xc1108698 + + +unsigned int saradc_ch1_get(void); + + +#endif /*__BL2_PLL_H_*/ diff --git a/plat/gxb/include/sha2.h b/plat/gxb/include/sha2.h new file mode 100644 index 0000000..f63f2c0 --- /dev/null +++ b/plat/gxb/include/sha2.h @@ -0,0 +1,48 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/include/sha2.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <stdint.h> + +#ifndef __PLAT_SHA2_H_ +#define __PLAT_SHA2_H_ + + +#define SHA224_DIGEST_SIZE 28 + +#define SHA256_DIGEST_SIZE 32 +#define SHA256_BLOCK_SIZE 64 + +/* SHA2 context */ +typedef struct { + uint32_t h[8]; + uint32_t tot_len; + uint32_t len; + uint32_t digest_len; + uint8_t block[2 * SHA256_BLOCK_SIZE]; + uint8_t buf[SHA256_DIGEST_SIZE]; /* Used to store the final digest. */ +}sha2_ctx ; + +void SHA2_init(sha2_ctx *, unsigned int ); +void SHA2_update(sha2_ctx *, const uint8_t *, unsigned int); +void SHA2_final(sha2_ctx *,const unsigned char *, unsigned int ); +void sha2(const unsigned char *, unsigned int , unsigned char output[32], unsigned int); +int aml_data_check(unsigned long ,unsigned long ,unsigned int ,unsigned int ); +#endif /*__PLAT_SHA2_H_*/
\ No newline at end of file diff --git a/plat/gxb/include/storage.h b/plat/gxb/include/storage.h new file mode 100644 index 0000000..ac01e44 --- /dev/null +++ b/plat/gxb/include/storage.h @@ -0,0 +1,77 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/include/storage.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __BL2_STORAGE_H_ +#define __BL2_STORAGE_H_ + +#include <asm/arch/cpu_sdio.h> + +/*boot device defines*/ +#define BOOT_DEVICE_RESERVED 0 +#define BOOT_DEVICE_EMMC 1 +#define BOOT_DEVICE_NAND 2 +#define BOOT_DEVICE_SPI 3 +#define BOOT_DEVICE_SD 4 +#define BOOT_DEVICE_USB 5 +#define BOOT_DEVICE_USB_FORCEMODE 6//force booting from usb mode + +/*sdio defines*/ +#define MAX_DESC_NUM 8 +#define MAX_BLOCK_COUNTS 128 +uint64_t storage_init(void); +uint64_t storage_load(uint64_t src, uint64_t des, uint64_t size, const char * image_name); +uint64_t get_boot_device(void); +uint64_t spi_read(uint64_t src, uint64_t des, uint64_t size); +uint64_t sdio_read_blocks(struct sd_emmc_global_regs *sd_emmc_regs, uint64_t src, uint64_t des, uint64_t size,uint64_t mode); +uint64_t sdio_read_data(uint64_t boot_device, uint64_t src, uint64_t des, uint64_t size); +uint64_t usb_boot(uint64_t src, uint64_t des, uint64_t size); +uint64_t get_boot_device(void); +uint64_t get_ddr_size(void); +void dump_ddr_data(void); +uint64_t sdio_write_data(uint64_t boot_device, uint64_t src, uint64_t des, uint64_t size); +uint64_t sdio_write_blocks(struct sd_emmc_global_regs *sd_emmc_regs, + uint64_t src, uint64_t des, uint64_t size, uint64_t mode); + +/*SIZE defines*/ +#define SIZE_1K 0x400 +#define SIZE_2K 0x800 +#define SIZE_4K 0x1000 +#define SIZE_8K 0x2000 +#define SIZE_16K 0x4000 +#define SIZE_32K 0x8000 +#define SIZE_64K 0x10000 +#define SIZE_128K 0x20000 +#define SIZE_256K 0x40000 +#define SIZE_512K 0x80000 +#define SIZE_1M 0x100000 +#define SIZE_2M 0x200000 +#define SIZE_4M 0x400000 +#define SIZE_8M 0x800000 +#define SIZE_16M 0x1000000 +#define SIZE_32M 0x2000000 +#define SIZE_64M 0x4000000 +#define SIZE_128M 0x8000000 +#define SIZE_256M 0x10000000 +#define SIZE_512M 0x20000000 +#define SIZE_1G 0x40000000 +#define SIZE_2G 0x80000000 + +#endif /*__BL2_STORAGE_H_*/ diff --git a/plat/gxb/include/timer.h b/plat/gxb/include/timer.h new file mode 100644 index 0000000..f477ce1 --- /dev/null +++ b/plat/gxb/include/timer.h @@ -0,0 +1,48 @@ + +/* + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __TIMER_H +#define __TIMER_H + +#include <stdint.h> + +/** + * Get the current timestamp from the system timer. + */ +uint32_t get_time(void); + +/** + * Busy-wait. + * + * @param us Number of microseconds to delay. + */ +void _udelay(unsigned int us); + +/** + * time counter + * usage: + * timer_start(); + * func(); //func that you want measure time consumption + * timer_end("func"); //will print "func Time: xxxx us" + */ +void timer_start(void); +void timer_end(const char * name); + +#endif /* __TIMER_H */ diff --git a/plat/gxb/mailbox.c b/plat/gxb/mailbox.c new file mode 100644 index 0000000..eadc2f1 --- /dev/null +++ b/plat/gxb/mailbox.c @@ -0,0 +1,135 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/mailbox.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <stdio.h> +#include <string.h> +#include <io.h> +#include <stdint.h> +#include <asm/arch/romboot.h> +#include <mailbox.h> +#include <asm/arch/secure_apb.h> + +void mb_send_data(uint32_t val, uint32_t port) +{ + unsigned long base_addr = SEC_HIU_MAILBOX_SET_0; + unsigned long set_addr; + + if (port > 5) { + serial_puts("Error: Use the error port num!\n"); + return; + } + + set_addr = base_addr + port*3*4; + + if (!val) { + serial_puts("Error: mailbox try to send zero val!\n"); + return; + } + + writel(val, set_addr); + + return; +} + +uint32_t mb_read_data(uint32_t port) +{ + unsigned long base_addr = SEC_HIU_MAILBOX_STAT_0; + uint32_t val; + + if (port > 5) { + serial_puts("Error: Use the error port num!\n"); + return 0; + } + + val = readl(base_addr + port*3*4); + + if (val) + return val; + else { +// print_out("Warning: read mailbox val=0.\n"); + return 0; + } +} + +void mb_clear_data(uint32_t val, uint32_t port) +{ + uint32_t base_addr = SEC_HIU_MAILBOX_CLR_0; + + unsigned long clean_addr = base_addr + port*3*4; + + if (port > 5) { + serial_puts("Error: Use the error port num!\n"); + return; + } + + if (!val) { + serial_puts("Warning: clean val=0.\n"); + return; + } + + writel(val,clean_addr); + + return; +} + +void send_bl30x(uint32_t addr, uint32_t size, const uint8_t * sha2, \ + uint32_t sha2_length, const char * name) +{ + int i; + *(unsigned int *)MB_SRAM_BASE = size; + + if (0 == strcmp("bl301", name)) { + /*bl301 must wait bl30 run*/ + serial_puts("Wait bl30..."); + while (0x3 != ((readl(AO_SEC_SD_CFG15) >> 20) & 0x3)) {} + serial_puts("Done\n"); + } + + serial_puts("Sending "); + serial_puts(name); + //serial_puts("time=0x%x size=0x%x\n", readl(0xc1109988),size); + + mb_send_data(CMD_DATA_LEN, 3); + do {} while(mb_read_data(3)); + memcpy((void *)MB_SRAM_BASE, (const void *)sha2, sha2_length); + mb_send_data(CMD_SHA, 3); + do {} while(mb_read_data(3)); + + for (i = 0; i < size; i+=1024) { + serial_puts("."); + if (size >= i + 1024) + memcpy((void *)MB_SRAM_BASE,(const void *)(unsigned long)(addr+i),1024); + else if(size > i) + memcpy((void *)MB_SRAM_BASE,(const void *)(unsigned long)(addr+i),(size-i)); + + mb_send_data(CMD_DATA, 3); + do {} while(mb_read_data(3)); + } + mb_send_data(CMD_OP_SHA, 3); + + do {} while(mb_read_data(3)); + serial_puts("OK. \nRun "); + serial_puts(name); + serial_puts("...\n"); + + /* The BL31 will run after this command */ + mb_send_data(CMD_END,3);//code transfer end. +} diff --git a/plat/gxb/mhu.c b/plat/gxb/mhu.c new file mode 100644 index 0000000..ba9baff --- /dev/null +++ b/plat/gxb/mhu.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <bakery_lock.h> +#include <mmio.h> +#include "plat_def.h" +#include "mhu.h" + +/* SCP MHU secure channel registers */ +#define SCP_INTR_S_STAT 0x200 +#define SCP_INTR_S_SET 0x208 +#define SCP_INTR_S_CLEAR 0x210 + +/* CPU MHU secure channel registers */ +#define CPU_INTR_S_STAT 0x300 +#define CPU_INTR_S_SET 0x308 +#define CPU_INTR_S_CLEAR 0x310 + + +static bakery_lock_t mhu_secure_lock __attribute__ ((section("tzfw_coherent_mem"))); + + +void mhu_secure_message_start(void) +{ + bakery_lock_get(read_mpidr(), &mhu_secure_lock); + + /* Make sure any previous command has finished */ + while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0) + ; +} + +void mhu_secure_message_send(uint32_t command) +{ + /* Send command to SCP and wait for it to pick it up */ + mmio_write_32(MHU_BASE + CPU_INTR_S_SET, command); + while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0) + ; +} + +uint32_t mhu_secure_message_wait(void) +{ + /* Wait for response from SCP */ + uint32_t response; + while (!(response = mmio_read_32(MHU_BASE + SCP_INTR_S_STAT))) + ; + + return response; +} + +void mhu_secure_message_end(void) +{ + /* Clear any response we got by writing all ones to the CLEAR register */ + mmio_write_32(MHU_BASE + SCP_INTR_S_CLEAR, 0xffffffffu); + + bakery_lock_release(read_mpidr(), &mhu_secure_lock); +} + +void mhu_secure_init(void) +{ + bakery_lock_init(&mhu_secure_lock); + + /* + * Clear the CPU's INTR register to make sure we don't see a stale + * or garbage value and think it's a message we've already sent. + */ + mmio_write_32(MHU_BASE + CPU_INTR_S_CLEAR, 0xffffffffu); +} diff --git a/plat/gxb/mhu.h b/plat/gxb/mhu.h new file mode 100644 index 0000000..5149c82 --- /dev/null +++ b/plat/gxb/mhu.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __MHU_H__ +#define __MHU_H__ + +#include <stdint.h> + +extern void mhu_secure_message_start(void); +extern void mhu_secure_message_send(uint32_t command); +extern uint32_t mhu_secure_message_wait(void); +extern void mhu_secure_message_end(void); + +extern void mhu_secure_init(void); + +#endif /* __MHU_H__ */ diff --git a/plat/gxb/nand.c b/plat/gxb/nand.c new file mode 100644 index 0000000..5813c47 --- /dev/null +++ b/plat/gxb/nand.c @@ -0,0 +1,775 @@ +/* + * Copyright (c) 2015 Amlogic, Inc. All rights reserved. + * + * This source code is subject to the terms and conditions defined in the + * file 'LICENSE' which is part of this source code package. + * + * + * Amlogic nand spl module + * Author: nand team @amlogic.com + * Created time: 2015.04.28 + * + */ + +#include <config.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <io.h> +#include <platform_def.h> +#include <asm/arch/io.h> +#include <asm/arch/nand.h> +#include <efuse.h> +#include <asm/arch/secure_apb.h> +#include <asm/arch/romboot.h> +#include <arch_helpers.h> + +//#define NFIO_LINE do { printf("%s %d\n", __func__, __LINE__); } while(0); +#define NFIO_LINE + +/* global */ +nand_setup_t glb_setup; // 8 bytes + +ext_info_t glb_ext_info = { + .read_info = 0, + .new_type = 0, + .xlc = 0, +}; + +unsigned char page_list_hynix_1y[128] = { + 0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0d, + 0x0f, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, + 0x1f, 0x21, 0x23, 0x25, 0x27, 0x29, 0x2b, 0x2d, + 0x2f, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3b, 0x3d, + + 0x3f, 0x41, 0x43, 0x45, 0x47, 0x49, 0x4b, 0x4d, + 0x4f, 0x51, 0x53, 0x55, 0x57, 0x59, 0x5b, 0x5d, + 0x5f, 0x61, 0x63, 0x65, 0x67, 0x69, 0x6b, 0x6d, + 0x6f, 0x71, 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7d, + + 0x7f, 0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d, + 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, + 0x9f, 0xa1, 0xA3, 0xA5, 0xA7, 0xA9, 0xAb, 0xAd, + 0xAf, 0xb1, 0xB3, 0xB5, 0xB7, 0xB9, 0xBb, 0xBd, + + 0xBf, 0xc1, 0xC3, 0xC5, 0xC7, 0xC9, 0xCb, 0xCd, + 0xCf, 0xd1, 0xD3, 0xD5, 0xD7, 0xD9, 0xDb, 0xDd, + 0xDf, 0xe1, 0xE3, 0xE5, 0xE7, 0xE9, 0xEb, 0xEd, + 0xEf, 0xf1, 0xF3, 0xF5, 0xF7, 0xF9, 0xFb, 0xFd, +}; + +unsigned char page_list_hynix_2x[128] = { + 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, + 0x0E, 0x0F, 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, + 0x1E, 0x1F, 0x22, 0x23, 0x26, 0x27, 0x2A, 0x2B, + 0x2E, 0x2F, 0x32, 0x33, 0x36, 0x37, 0x3A, 0x3B, + + 0x3E, 0x3F, 0x42, 0x43, 0x46, 0x47, 0x4A, 0x4B, + 0x4E, 0x4F, 0x52, 0x53, 0x56, 0x57, 0x5A, 0x5B, + 0x5E, 0x5F, 0x62, 0x63, 0x66, 0x67, 0x6A, 0x6B, + 0x6E, 0x6F, 0x72, 0x73, 0x76, 0x77, 0x7A, 0x7B, + + 0x7E, 0x7F, 0x82, 0x83, 0x86, 0x87, 0x8A, 0x8B, + 0x8E, 0x8F, 0x92, 0x93, 0x96, 0x97, 0x9A, 0x9B, + 0x9E, 0x9F, 0xA2, 0xA3, 0xA6, 0xA7, 0xAA, 0xAB, + 0xAE, 0xAF, 0xB2, 0xB3, 0xB6, 0xB7, 0xBA, 0xBB, + + 0xBE, 0xBF, 0xC2, 0xC3, 0xC6, 0xC7, 0xCA, 0xCB, + 0xCE, 0xCF, 0xD2, 0xD3, 0xD6, 0xD7, 0xDA, 0xDB, + 0xDE, 0xDF, 0xE2, 0xE3, 0xE6, 0xE7, 0xEA, 0xEB, + 0xEE, 0xEF, 0xF2, 0xF3, 0xF6, 0xF7, 0xFA, 0xFB, +}; + +//#define PRINT printf +#if 0 +static void _dump_mem_u8(uint8_t * buf, uint32_t len) +{ + uint32_t i; + PRINT("%s, %p, %d", __func__, buf, len); + for (i = 0; i < len/sizeof(uint8_t); i++) { + + if ( i % 16 == 0) + PRINT("\n0x%p: ", buf+i); + PRINT("%02x ", buf[i]); + } + PRINT("\n"); + return; +} +#endif //0 + +void nfio_pin_mux(void) +{ + *P_PAD_PULL_UP_EN_REG2 = 0xffff87ff; + *P_PAD_PULL_UP_REG2 = 0xffff8700; + *P_PERIPHS_PIN_MUX_4 = (1<<31) | (1<<30) | (0x3ff<<20); +} + +uint32_t nfio_reset(void) +{ + uint32_t tmp; + + // Reset NAND controller + (*P_NAND_CMD) = (1<<31); + + // Reset NAND + (*P_NAND_CMD) = (CE0 | IDLE); + (*P_NAND_CMD) = (CE0 | CLE | 0xff); + (*P_NAND_CMD) = (CE0 | IDLE | 10); + + // nand cycle = 200ns. + // Set time out 2^13* nand cycle, 1.7ms + if ( glb_setup.cfg.b.no_rb ) { // without RB + (*P_NAND_CMD) = (CE0 | CLE | 0x70); + (*P_NAND_CMD) = (CE0 | IDLE | 2); + (*P_NAND_CMD) = (IO6 | RB | 13); + } + else { // with RB + *P_NAND_CMD = (CE0 | RB | 13); + } + + (*P_NAND_CMD) = (CE0 | IDLE); + (*P_NAND_CMD) = (CE0 | IDLE); + + // if NAND is not installed or Reset failed, + // the RB time out is set. + while (((tmp = (*P_NAND_CMD))>>22&0x1f) > 0) { + if (tmp>>27&1) { // time out + (*P_NAND_CMD) = (1<<31); + return ERROR_NAND_TIMEOUT; + } + } + + return 0; +} + +/* + * read nand manufactor id into retry info. + */ +static uint16_t _read_id(void) +{ + uint16_t id; + + (*P_NAND_CMD) = (CE0 | IDLE); + (*P_NAND_CMD) = (CE0 | CLE | 0x90); + (*P_NAND_CMD) = (CE0 | IDLE | 3); + (*P_NAND_CMD) = (CE0 | ALE | 0); + (*P_NAND_CMD) = (CE0 | IDLE | 3); + (*P_NAND_CMD) = (CE0 | DRD | 3); + + (*P_NAND_CMD) = (CE0 | IDLE); + (*P_NAND_CMD) = (CE0 | IDLE); + while (((*P_NAND_CMD)>>22&0x1f) > 0); + + id = (*P_NAND_BUF)&0xff; + + return id; +} + +static void _set_retry(uint16_t id) +{ + switch (glb_setup.id) { + case NAND_MFR_MICRON : + glb_setup.max = 8; + break; + case NAND_MFR_TOSHIBA : + glb_setup.max = 8; + break; + case NAND_MFR_SAMSUNG : + glb_setup.max = 15; + break; + case NAND_MFR_SANDISK : + glb_setup.max = 22; + break; + case NAND_MFR_HYNIX : + case NAND_MFR_FUJITSU : + case NAND_MFR_NATIONAL : + case NAND_MFR_RENESAS : + case NAND_MFR_STMICRO : + case NAND_MFR_AMD : + case NAND_MFR_INTEL : + glb_setup.max = 0; + break; + default : + glb_setup.max = 0; + break; + } +} +// toshiba retry ------------------------------------------ +// 0 : pre condition + retry 0. +// 1~6 : valid retry, otherwise no action. +// 7, 0xff : exit, back to normal. +// loop from 0 to 7, total 8. +void read_retry_toshiba(uint32_t retry, uint32_t *cmd) +{ + unsigned char val[] = { + 0x04, 0x04, 0x7C, 0x7E, + 0x00, 0x7C, 0x78, 0x78, + 0x7C, 0x76, 0x74, 0x72, + 0x08, 0x08, 0x00, 0x00, + 0x0B, 0x7E, 0x76, 0x74, + 0x10, 0x76, 0x72, 0x70, + 0x02, 0x00, 0x7E, 0x7C, + 0x00, 0x00, 0x00, 0x00}; + uint32_t i, k, retry_val_idx; + + i = 0; + if (retry == 7) retry = 0xff; + retry_val_idx = retry == 0xff ? 7 : retry; + + if (retry_val_idx < 8) { + // pre condition, send before first. + if (retry == 0) { + cmd[i++] = (CE0 | CLE | 0x5c); + cmd[i++] = (CE0 | CLE | 0xc5); + cmd[i++] = (CE0 | IDLE); + } + + for (k=4; k<8; k++) { + cmd[i++] = (CE0 | CLE | 0x55); + cmd[i++] = (CE0 | IDLE | 2); //Tcalsv + cmd[i++] = (CE0 | ALE | k); + cmd[i++] = (CE0 | IDLE | 2); //Tcalsv + cmd[i++] = (CE0 | DWR | val[retry_val_idx*4 + k-4]); + cmd[i++] = (CE0 | IDLE); + } + + cmd[i++] = (CE0 | CLE | 0x55); + cmd[i++] = (CE0 | IDLE | 2); //Tcalsv + cmd[i++] = (CE0 | ALE | 0xd); + cmd[i++] = (CE0 | IDLE | 2); //Tcalsv + cmd[i++] = (CE0 | DWR | 0); + cmd[i++] = (CE0 | IDLE); + + if (retry == 6) { + cmd[i++] = (CE0 | CLE | 0xb3); + cmd[i++] = (CE0 | IDLE); + } + + if (retry != 0xff) { + cmd[i++] = (CE0 | CLE | 0x26); + cmd[i++] = (CE0 | CLE | 0x5d); + cmd[i++] = (CE0 | IDLE); + } + } + + // exit and check rb + if (retry == 0xff) { + cmd[i++] = (CE0 | CLE | 0xff); + cmd[i++] = (CE0 | IDLE | 2); //Twb + + if (glb_setup.cfg.b.no_rb) { + cmd[i++] = (CE0 | CLE | 0x70); + cmd[i++] = (CE0 | IDLE | 2); + cmd[i++] = (IO6 | RB | 13); + } + else{ + cmd[i++] = (CE0 | RB | 13); + } + } + + cmd[i] = 0; +} + +// sandisk retry ------------------------------------------ +// 0 : activation + retry 0. +// 1~20 : valid retry, otherwise no action. +// 21, 0xff : exit +// loop from 0 to 21, total 22. +void read_retry_sandisk(uint32_t retry, uint32_t *cmd) +{ + uint32_t i, k; + unsigned char val[] = { + 0x00, 0x00, 0x00, + 0xf0, 0xf0, 0xf0, + 0xef, 0xe0, 0xe0, + 0xdf, 0xd0, 0xd0, + 0x1e, 0xe0, 0x10, + 0x2e, 0xd0, 0x20, + 0x3d, 0xf0, 0x30, + 0xcd, 0xe0, 0xd0, + 0x0d, 0xd0, 0x10, + 0x01, 0x10, 0x20, + 0x12, 0x20, 0x20, + 0xb2, 0x10, 0xd0, + 0xa3, 0x20, 0xd0, + 0x9f, 0x00, 0xd0, + 0xbe, 0xf0, 0xc0, + 0xad, 0xc0, 0xc0, + 0x9f, 0xf0, 0xc0, + 0x01, 0x00, 0x00, + 0x02, 0x00, 0x00, + 0x0d, 0xb0, 0x00, + 0x0c, 0xa0, 0x00}; + + i = 0; + if (retry == 21) retry = 0xff; + + if (retry == 0) { // activation and init, entry 0. + cmd[i++] = (CE0 | CLE | 0x3b); + cmd[i++] = (CE0 | CLE | 0xb9); + for (k=4; k<13; k++) { + cmd[i++] = (CE0 | CLE | 0x54); + cmd[i++] = (CE0 | ALE | k); + cmd[i++] = (CE0 | DWR | 0); + } + cmd[i++] = (CE0 | CLE | 0xb6); + } + else if (retry < 21) { // entry: 1~20 + cmd[i++] = (CE0 | CLE | 0x3b); + cmd[i++] = (CE0 | CLE | 0xb9); + for (k=0; k<3; k++) { + cmd[i++] = (CE0 | CLE | 0x54); + cmd[i++] = (CE0 | ALE | (k==0?4:k==1?5:7)); + cmd[i++] = (CE0 | DWR | val[retry*3+k]); + } + cmd[i++] = (CE0 | CLE | 0xb6); + } + else if (retry == 255) { + cmd[i++] = (CE0 | CLE | 0x3b); + cmd[i++] = (CE0 | CLE | 0xb9); + for (k=0; k<3; k++) { + cmd[i++] = (CE0 | CLE | 0x54); + cmd[i++] = (CE0 | ALE | (k==0?4:k==1?5:7)); + cmd[i++] = (CE0 | DWR | 0); + } + cmd[i++] = (CE0 | CLE | 0xd6); + } + cmd[i] = 0; +} + +// micron retry ------------------------------------------ +// 0 : disable +// 1~7 : valid retry, otherwise no action. +// 0xff : same as 0. +// loop from 0 to 7, total 8. +void read_retry_micron(uint32_t retry, uint32_t *cmd) +{ + uint32_t i; + + i = 0; + if (retry == 0xff) retry = 0; + + if (retry < 8) { + cmd[i++] = (CE0 | CLE | 0xef); + cmd[i++] = (CE0 | ALE | 0x89); + cmd[i++] = (CE0 | IDLE | 3); //Tadl + cmd[i++] = (CE0 | DWR | retry); + cmd[i++] = (CE0 | DWR | 0); + cmd[i++] = (CE0 | DWR | 0); + cmd[i++] = (CE0 | DWR | 0); + cmd[i++] = (CE0 | IDLE | 2); //Twb + + //check rb for Tfeat + if (glb_setup.cfg.b.no_rb) { + cmd[i++] = (CE0 | CLE | 0x70); + cmd[i++] = (CE0 | IDLE | 2); + cmd[i++] = (IO6 | RB | 13); + } + else{ + cmd[i++] = (CE0 | RB | 13); + } + } + + cmd[i] = 0; +} + +void read_retry_hynix(uint32_t retry, uint32_t *cmd) +{ + // use SLC mode. +} + +// samsung retry ------------------------------------------ +// 0 : disable +// 1~14 : valid retry, otherwise no action. +// 0xff : same as 0. +// loop from 0 to 14, total 15. +void read_retry_samsung(uint32_t retry, uint32_t *cmd) +{ + uint32_t i, k; + unsigned char adr[] = { + 0xa7, 0xa4, 0xa5, 0xa6}; + unsigned char val[] = { + 0x00, 0x00, 0x00, 0x00, + 0x05, 0x0A, 0x00, 0x00, + 0x28, 0x00, 0xEC, 0xD8, + 0xED, 0xF5, 0xED, 0xE6, + 0x0A, 0x0F, 0x05, 0x00, + 0x0F, 0x0A, 0xFB, 0xEC, + 0xE8, 0xEF, 0xE8, 0xDC, + 0xF1, 0xFB, 0xFE, 0xF0, + 0x0A, 0x00, 0xFB, 0xEC, + 0xD0, 0xE2, 0xD0, 0xC2, + 0x14, 0x0F, 0xFB, 0xEC, + 0xE8, 0xFB, 0xE8, 0xDC, + 0x1E, 0x14, 0xFB, 0xEC, + 0xFB, 0xFF, 0xFB, 0xF8, + 0x07, 0x0C, 0x02, 0x00}; + + i = 0; + if (retry == 0xff) retry = 0; + if (retry < 15) { + for (k=0; k<4; k++) { + cmd[i++] = (CE0 | CLE | 0xa1); + cmd[i++] = (CE0 | ALE | 0); + cmd[i++] = (CE0 | ALE | adr[k]); + cmd[i++] = (CE0 | IDLE | 2); //Tadl + cmd[i++] = (CE0 | DWR | val[retry*4+k]); + cmd[i++] = (CE0 | IDLE | 8); //over 300ns before next cmd + } + } + cmd[i] = 0; +} + + +void nfio_read_retry(uint32_t mode) +{ + static uint32_t retry = 0; + uint32_t i, cmd[128]; + + if (glb_setup.max == 0) + return; + + switch (glb_setup.id) { + case NAND_MFR_MICRON: + NFIO_LINE + read_retry_micron(retry, cmd); + break; + + case NAND_MFR_TOSHIBA: + read_retry_toshiba(retry, cmd); + break; + + case NAND_MFR_HYNIX: + read_retry_hynix(retry, cmd); + break; + + case NAND_MFR_SAMSUNG: + read_retry_samsung(retry, cmd); + break; + + case NAND_MFR_SANDISK: + read_retry_sandisk(retry, cmd); + break; + + /* todo, add other read retry here! */ + } + + retry = retry+1 < glb_setup.max ? retry+1 : 0; + + i = 0; + while (((*P_NAND_CMD)>>22&0x1f)<0x1f && cmd[i] != 0) { + (*P_NAND_CMD) = cmd[i++]; + } +} + +// read one page +uint32_t nfio_page_read(uint32_t src, uint32_t mem) +{ + uint32_t k, ecc_pages; + uint32_t info; + uint64_t mem_addr; + + uint32_t info_adr = NAND_INFO_BUF; //use romboot's buffer. + uint64_t info_adr64; + uint64_t * p_info_buf; + volatile uint64_t dma_done; + + ecc_pages = glb_setup.cfg.b.cmd&0x3f; + + NFIO_LINE + info_adr64 = (uint64_t) info_adr; + p_info_buf = (uint64_t *)info_adr64; + + memset(p_info_buf, 0, ecc_pages * INFO_BYTE_PER_ECCPAGE); + flush_dcache_range((uint64_t)p_info_buf, (uint64_t)(ecc_pages * sizeof(uint64_t))); + + while (((*P_NAND_CMD)>>22&0x1f) > 0); + NFIO_LINE + + // add A2H command for SLC read + if ( glb_setup.cfg.b.a2 ) { + (*P_NAND_CMD) = (CE0 | IDLE); + (*P_NAND_CMD) = (CE0 | CLE | 0xa2); + (*P_NAND_CMD) = (CE0 | IDLE); + } + NFIO_LINE + // send cmds + (*P_NAND_CMD) = CE0 | IDLE; + (*P_NAND_CMD) = CE0 | CLE | 0; + (*P_NAND_CMD) = CE0 | ALE | 0; + if ( glb_setup.cfg.b.large_page ) { + NFIO_LINE + (*P_NAND_CMD) = CE0 | ALE | 0; + } + (*P_NAND_CMD) = CE0 | ALE | ((src)&0xff); + (*P_NAND_CMD) = CE0 | ALE | ((src>>8)&0xff); + (*P_NAND_CMD) = CE0 | ALE | 0; + if ( glb_setup.cfg.b.large_page ) { + NFIO_LINE + (*P_NAND_CMD) = CE0 | CLE | 0x30; + } + NFIO_LINE + if ( glb_setup.cfg.b.no_rb ) { // without RB + NFIO_LINE + (*P_NAND_CMD) = CE0 | IDLE; + (*P_NAND_CMD) = CE0 | CLE | 0x70; + (*P_NAND_CMD) = CE0 | IDLE | 2; + (*P_NAND_CMD) = IO6 | RB | 13; + (*P_NAND_CMD) = CE0 | IDLE | 2; + (*P_NAND_CMD) = CE0 | CLE | 0; //switch to read mode. + (*P_NAND_CMD) = CE0 | IDLE | 2; + }else{ // with RB + (*P_NAND_CMD) = CE0 | IDLE | 40; + (*P_NAND_CMD) = CE0 | RB | 13; + } + /* new way to set address. */ + (*P_NAND_CMD) = ADL | (mem & 0xFFFF); //data address. + (*P_NAND_CMD) = ADH | ((mem >> 16) & 0xFFFF); + (*P_NAND_CMD) = AIL | (info_adr & 0xFFFF); //set info address. + (*P_NAND_CMD) = AIH | ((info_adr >> 16) & 0xFFFF); + + + /* set seed, start dma*/ + (*P_NAND_CMD) = SEED | (0xc2 + (src&0x7fff)); + //printf("cmd 0x%x\n", glb_setup.cfg.b.cmd); + //printf("P_NAND_CFG 0x%x\n", (*P_NAND_CFG)); + (*P_NAND_CMD) = glb_setup.cfg.b.cmd; + + (*P_NAND_CMD) = (CE0 | IDLE); + (*P_NAND_CMD) = (CE0 | IDLE); + NFIO_LINE + /* wait I/F ready*/ + while (((*P_NAND_CMD)>>22&0x1f) > 0); + NFIO_LINE + /* wait info dma ready */ + do { + inv_dcache_range((uint64_t)p_info_buf, (uint64_t)(ecc_pages * sizeof(uint64_t))); + dma_done = p_info_buf[ecc_pages-1]; + } while (dma_done == 0); + NFIO_LINE + // random only, old oob! + // blank page: ecc uncorr, zero_cnt<10. + // ecc error: ecc uncorr, zero_cnt>10. + // no magic: ecc OK, no magic word. + // return the first error. + for (k=0; k<ecc_pages; k++) { + //printf("ecc page %d\n", k); + mem_addr = info_adr; + info = *(volatile uint32_t *)mem_addr; + if ((info>>24 & 0x3f) == 0x3f) { // uncorrectable + if ( glb_setup.cfg.b.a2 ) nfio_reset(); + + // check blank page + if ((info>>16&0x3f) < 0xa) { + //PRINT("blank @ page 0x%08x\n", src); + return ERROR_NAND_BLANK_PAGE; + } + else { + //PRINT("ecc fail @ page 0x%08x\n", src); + return ERROR_NAND_ECC; + } + } + + if (k == 0 && (info & 0xc000ffff) != 0xc000aa55) { //magic word error + //PRINT("magic fail @ page 0x%08x\n", src); + return ERROR_NAND_MAGIC_WORD; + } + info_adr += 8; + } + NFIO_LINE + return 0; +} + +static uint32_t page_2_addr(uint32_t page) +{ + uint32_t addr = page; + uint32_t new_type = glb_ext_info.new_type; + uint32_t page_per_blk = glb_ext_info.page_per_blk; + + if (new_type) { + uint32_t blk_addr; + blk_addr = (page / page_per_blk) * page_per_blk; + /* hynix */ + if (new_type < 10) { + if (new_type == 6) + addr = page_list_hynix_1y[page % page_per_blk] + blk_addr; + else + addr = page_list_hynix_2x[page % page_per_blk] + blk_addr; + } else if (new_type == 40) { + addr = (page % page_per_blk) * 2 + blk_addr; + } + } + return addr; +} + +// read multiple nand pages. fixme, may cause overflow... +uint32_t nfio_read(uint32_t src, uint32_t mem, uint32_t size) +{ + uint32_t ret; + uint32_t ecc_mode, short_mode, short_size, ecc_pages, page_size; + uint32_t page_base, page_addr, retry_cnt, read_size; + + // ecc page size, unit: 8 bytes + ecc_mode = glb_setup.cfg.b.cmd>>14&7; + short_mode = glb_setup.cfg.b.cmd>>13&1; + short_size = glb_setup.cfg.b.cmd>>6&0x7f; + ecc_pages = glb_setup.cfg.b.cmd&0x3f; + + page_size = (short_mode ? short_size : ecc_mode < 2 ? 64 : 128) * 8 * ecc_pages; + NFIO_LINE + flush_dcache_range((uint64_t)mem, (uint64_t)(size)); + // read one nand page per loop. + for (read_size=0; read_size<size; read_size+=page_size) { + page_addr = page_2_addr(src++); + //printf("page_addr 0x%x\n", page_addr); + retry_cnt = 0; + + do { + for (page_base=0; page_base<0x400; page_base+=0x100) { + NFIO_LINE + ret = nfio_page_read(page_base + page_addr, + mem + read_size); + if (ret != ERROR_NAND_ECC) { // good, blank, no magic + break; + } + } + + // read retry + if (ret == ERROR_NAND_ECC) { + if (retry_cnt < glb_setup.max) { + retry_cnt++; + nfio_read_retry(1); + } + else + break; + } + } while (ret == ERROR_NAND_ECC); + + if (ret) return ret; + } + + return 0; +} + +uint32_t nfio_init() +{ + uint32_t ret; + nand_page0_t *page0 = (nand_page0_t *)NAND_PAGE0_BUF; + nand_setup_t *nand_setup; + ext_info_t * p_ext_info; + char e_cfg[8]; + + nand_setup = &page0->nand_setup; + p_ext_info = &page0->ext_info; + + efuse_read(0, 8, e_cfg); + // from default + glb_setup.cfg.d32 = DEFAULT_ECC_MODE; + glb_setup.cfg.b.active = 1; + + // from efuse + glb_setup.cfg.b.no_rb = 1; //defaut + //glb_setup.cfg.b.sync_mode = efuse->tg_nd_bm_e ? 2 : 0; + glb_setup.cfg.b.sync_mode = 0; //fixme, + glb_setup.cfg.b.size = 0; + NFIO_LINE + // get pin + nfio_pin_mux(); + + // set clk to 24MHz + (*P_CLK_CNTL) = ( 1<< 31 | 1<<28 | 1 << 21 | 2 << 8 | 1); + + // nand cfg register: + // sync[11:10] : 0:aync, 1:micron(started from sync, don't need to set), + // 2: samsung/toshiba toggle, need to set when read. + // Nand cycle = 200ns, timing at 3rd clock. + (*P_NAND_CFG) = + 4 | (3<<5) // Please see main.c for detailed timing info + |(glb_setup.cfg.b.sync_mode<<10) // async mode + |(0<<12) // disable cmd_start + |(0<<13) // disable cmd_auto + |(0<<14) // disable apb_mode + |(1<<31);// disable NAND bus gated clock. + + if (e_cfg[6] & (1 << 5)) + (*P_NAND_CFG) = (*P_NAND_CFG) |(1<<17); // enable encrypt mode. + + // reset + ret = nfio_reset(); + if (ret) return ret; + NFIO_LINE + //read ID + glb_setup.id = _read_id(); + //printf("MID, %x\n", glb_setup.id); + // set retry parameter. + _set_retry(glb_setup.id); + NFIO_LINE + + //_dump_mem_u8((uint8_t *)page0, 384); + /* fixme, use the memory filled by romboot nfdrv.*/ + ret = nfio_read(0, NAND_PAGE0_BUF, 384); + if (ret == ERROR_NAND_ECC) { + if (glb_setup.id == NAND_MFR_SANDISK) { + glb_setup.cfg.b.a2 = 1; + glb_setup.max = 0; + ret = nfio_read(0, NAND_PAGE0_BUF, 384); + } + else if (glb_setup.cfg.b.sync_mode == 0 && (glb_setup.id == NAND_MFR_TOSHIBA || + glb_setup.id == NAND_MFR_SAMSUNG)) { + glb_setup.cfg.b.sync_mode = 2; + (*P_NAND_CFG) |= (glb_setup.cfg.b.sync_mode<<10); + *P_PAD_PULL_UP_REG2 &= ~(1<<15); + ret = nfio_read(0, NAND_PAGE0_BUF, 384); + } + } + // override + glb_setup.cfg.d32 = nand_setup->cfg.d32; //get cfg! + glb_setup.id = nand_setup->id; + glb_setup.max = nand_setup->max; + glb_setup.cfg.b.size = 0; // efuse size + + glb_ext_info.new_type = p_ext_info->new_type; + glb_ext_info.page_per_blk = p_ext_info->page_per_blk; + + //printf("cfg %x, new %x, pages %x\n", glb_setup.cfg.d32, glb_ext_info.new_type, glb_ext_info.page_per_blk); + NFIO_LINE + + return ret; +} + +/* + *interface for spl. + * + * src, offset bytes in storage + * dst, ram address + * size, reada bytes count. + **/ +uint32_t nf_read(uint32_t boot_device, uint32_t src, uint32_t des, uint32_t size) +{ + uint32_t _page_size, _page, _cnt; + uint32_t ecc_mode, ecc_pages; + uint32_t ret = 0; + + ecc_mode = glb_setup.cfg.b.cmd>>14&7; + ecc_pages = glb_setup.cfg.b.cmd&0x3f; + _page_size = (ecc_mode < 2 ? 64 : 128) * 8 * ecc_pages; + //printf("ecc_mode %d, ecc_pages %d, pagesize %d\n", ecc_mode, ecc_pages, _page_size); + if (src % SRC_ALIGN_SIZE) { + //PRINT("%s(), unaligned src 0x%08x\n", __func__, src); + ret = ERROR_NAND_UNALIGN_SRC; + goto _out; + } + NFIO_LINE + _page = src / _page_size; + _cnt = size; + ret = nfio_read(_page + 1, des, _cnt); /*skip page0 */ + // des64 = (uint64_t) des; + // _dump_mem_u8((uint8_t *)des64, size); +_out: + return ret; +} + + + + + diff --git a/plat/gxb/plat-tsp.ld.S b/plat/gxb/plat-tsp.ld.S new file mode 100644 index 0000000..16d6c17 --- /dev/null +++ b/plat/gxb/plat-tsp.ld.S @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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. + */ + + ASSERT(__BL32_END__ <= BL2_BASE, "BL3-2 image overlaps BL2 image.") diff --git a/plat/gxb/plat_def.h b/plat/gxb/plat_def.h new file mode 100644 index 0000000..13f0fdf --- /dev/null +++ b/plat/gxb/plat_def.h @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __PLAT_DEF_H__ +#define __PLAT_DEF_H__ + +/* Special value used to verify platform parameters from BL2 to BL3-1 */ +#define PLAT_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL + +/******************************************************************************* + * ${PLAT} memory map related constants + ******************************************************************************/ +#define MHU_SECURE_BASE 0x04000000 +#define MHU_SECURE_SIZE 0x00001000 + +#define MHU_PAYLOAD_CACHED 0 + +#define TRUSTED_MAILBOXES_BASE MHU_SECURE_BASE +#define TRUSTED_MAILBOX_SHIFT 4 + +#define EMMC_BASE 0x0c000000 +#define EMMC_SIZE 0x04000000 + +#define PSRAM_BASE 0x14000000 +#define PSRAM_SIZE 0x02000000 + +#define IOFPGA_BASE 0x1c000000 +#define IOFPGA_SIZE 0x03000000 + +#define NSROM_BASE 0x1f000000 +#define NSROM_SIZE 0x00001000 + +#define SPI_BASE 0xCC000000 +#define SPI_SIZE 0x00400000 + +#define MAILBOX_START 0xd9013000 +#define MAILBOX_SIZE 0x00001000 + +/* Following covers Columbus Peripherals excluding NSROM and NSRAM */ +#define DEVICE0_BASE 0x20000000 +#define DEVICE0_SIZE 0x0e000000 +#define MHU_BASE 0x2b1f0000 + +#define DEVICEC_BASE 0xC0000000 +#define DEVICEC_SIZE 0x0C000000 + +#define DEVICED_BASE 0xDA100000 +#define DEVICED_SIZE 0x02000000 + +#define DEVICEE_BASE 0xD0000000 +#define DEVICEE_SIZE 0x01000000 + +#define NSRAM_BASE 0x2e000000 +#define NSRAM_SIZE 0x00008000 + +/* Following covers ${PLAT} Peripherals and PCIe expansion area */ +#define DEVICE1_BASE 0x40000000 +#define DEVICE1_SIZE 0x40000000 +#define PCIE_CONTROL_BASE 0x7ff20000 + +//#define DRAM_ROM_SPACE 0x01000000 /*16MB*/ +#define DRAM_BASE 0x01000000 +#define DRAM_SIZE 0x7f000000 + +/* Memory mapped Generic timer interfaces */ +#define SYS_CNTCTL_BASE 0x2a430000 +#define SYS_CNTREAD_BASE 0x2a800000 +#define SYS_TIMCTL_BASE 0x2a810000 + +/* V2M motherboard system registers & offsets */ +#define VE_SYSREGS_BASE 0x1c010000 +#define V2M_SYS_LED 0x8 + +/* + * V2M sysled bit definitions. The values written to this + * register are defined in arch.h & runtime_svc.h. Only + * used by the primary cpu to diagnose any cold boot issues. + * + * SYS_LED[0] - Security state (S=0/NS=1) + * SYS_LED[2:1] - Exception Level (EL3-EL0) + * SYS_LED[7:3] - Exception Class (Sync/Async & origin) + * + */ +#define SYS_LED_SS_SHIFT 0x0 +#define SYS_LED_EL_SHIFT 0x1 +#define SYS_LED_EC_SHIFT 0x3 + +/******************************************************************************* + * GIC-400 & interrupt handling related constants + ******************************************************************************/ +#define GICD_BASE 0x2c010000 +#define GICC_BASE 0x2c02f000 +#define GICH_BASE 0x2c04f000 +#define GICV_BASE 0x2c06f000 + +#define IRQ_MHU 69 +#define IRQ_GPU_SMMU_0 71 +#define IRQ_GPU_SMMU_1 73 +#define IRQ_ETR_SMMU 75 +#define IRQ_TZC400 80 +#define IRQ_TZ_WDOG 86 + +#define IRQ_SEC_SGI_0 8 +#define IRQ_SEC_SGI_1 9 +#define IRQ_SEC_SGI_2 10 +#define IRQ_SEC_SGI_3 11 +#define IRQ_SEC_SGI_4 12 +#define IRQ_SEC_SGI_5 13 +#define IRQ_SEC_SGI_6 14 +#define IRQ_SEC_SGI_7 15 +#define IRQ_SEC_SGI_8 16 + +/******************************************************************************* + * PL011 related constants + ******************************************************************************/ +/* FPGA UART0 */ +#define PL011_UART0_BASE 0x1c090000 +/* FPGA UART1 */ +#define PL011_UART1_BASE 0x1c0a0000 +/* SoC UART0 */ +#define PL011_UART2_BASE 0x7ff80000 +/* SoC UART1 */ +#define PL011_UART3_BASE 0x7ff70000 + +/******************************************************************************* + * NIC-400 related constants + ******************************************************************************/ + +/* CSS NIC-400 Global Programmers View (GPV) */ +#define CSS_NIC400_BASE 0x2a000000 + +/* The slave_bootsecure controls access to GPU, DMC and CS. */ +#define CSS_NIC400_SLAVE_BOOTSECURE 8 + +/* SoC NIC-400 Global Programmers View (GPV) */ +#define SOC_NIC400_BASE 0x7fd00000 + +#define SOC_NIC400_USB_EHCI 0 +#define SOC_NIC400_TLX_MASTER 1 +#define SOC_NIC400_USB_OHCI 2 +#define SOC_NIC400_PL354_SMC 3 +/* + * The apb4_bridge controls access to: + * - the PCIe configuration registers + * - the MMU units for USB, HDLCD and DMA + */ +#define SOC_NIC400_APB4_BRIDGE 4 +/* + * The bootsec_bridge controls access to a bunch of peripherals, e.g. the UARTs. + */ +#define SOC_NIC400_BOOTSEC_BRIDGE 5 +#define SOC_NIC400_BOOTSEC_BRIDGE_UART1 (1 << 12) + +/******************************************************************************* + * TZC-400 related constants + ******************************************************************************/ +#define TZC400_BASE 0x2a4a0000 + +#define TZC400_NSAID_CCI400 0 /* Note: Same as default NSAID!! */ +#define TZC400_NSAID_PCIE 1 +#define TZC400_NSAID_HDLCD0 2 +#define TZC400_NSAID_HDLCD1 3 +#define TZC400_NSAID_USB 4 +#define TZC400_NSAID_DMA330 5 +#define TZC400_NSAID_THINLINKS 6 +#define TZC400_NSAID_AP 9 +#define TZC400_NSAID_GPU 10 +#define TZC400_NSAID_SCP 11 +#define TZC400_NSAID_CORESIGHT 12 + +#endif /* __FVP_DEF_H__ */ diff --git a/plat/gxb/plat_gic.c b/plat/gxb/plat_gic.c new file mode 100644 index 0000000..874077c --- /dev/null +++ b/plat/gxb/plat_gic.c @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <gic_v2.h> +#include <interrupt_mgmt.h> +#include <platform.h> +#include "plat_def.h" +#include "plat_private.h" + + +/* Value used to initialise Non-Secure irq priorities four at a time */ +#define DEFAULT_NS_PRIORITY_X4 \ + (GIC_HIGHEST_NS_PRIORITY | \ + (GIC_HIGHEST_NS_PRIORITY << 8) | \ + (GIC_HIGHEST_NS_PRIORITY << 16) | \ + (GIC_HIGHEST_NS_PRIORITY << 24)) + + +/******************************************************************************* + * Enable secure interrupts and use FIQs to route them. Disable legacy bypass + * and set the priority mask register to allow all interrupts to trickle in. + ******************************************************************************/ +void gic_cpuif_setup(unsigned int gicc_base) +{ + unsigned int val; + + gicc_write_pmr(gicc_base, GIC_PRI_MASK); + + val = ENABLE_GRP0 | FIQ_EN; + val |= FIQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP0; + val |= FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1; + gicc_write_ctlr(gicc_base, val); +} + +/******************************************************************************* + * Place the cpu interface in a state where it can never make a cpu exit wfi as + * as result of an asserted interrupt. This is critical for powering down a cpu + ******************************************************************************/ +void gic_cpuif_deactivate(unsigned int gicc_base) +{ + unsigned int val; + + /* Disable secure, non-secure interrupts and disable their bypass */ + val = gicc_read_ctlr(gicc_base); + val &= ~(ENABLE_GRP0 | ENABLE_GRP1); + val |= FIQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP0; + val |= IRQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP1; + gicc_write_ctlr(gicc_base, val); +} + +static void gic_set_secure(unsigned int gicd_base, unsigned id) +{ + /* Set interrupt as Group 0 */ + gicd_clr_igroupr(gicd_base, id); + + /* Set priority to max */ + gicd_set_ipriorityr(gicd_base, id, GIC_HIGHEST_SEC_PRIORITY); +} + +/******************************************************************************* + * Per cpu gic distributor setup which will be done by all cpus after a cold + * boot/hotplug. This marks out the secure interrupts & enables them. + ******************************************************************************/ +void gic_pcpu_distif_setup(unsigned int gicd_base) +{ + unsigned i; + + /* Mark all 32 PPI interrupts as Group 1 (non-secure) */ + mmio_write_32(gicd_base + GICD_IGROUPR, 0xffffffffu); + + /* Setup PPI priorities doing four at a time */ + for (i = 0; i < 32; i += 4) + mmio_write_32(gicd_base + GICD_IPRIORITYR + i, DEFAULT_NS_PRIORITY_X4); + + /* Configure those PPIs we want as secure, and enable them. */ + static const char sec_irq[] = { + IRQ_SEC_PHY_TIMER, + IRQ_SEC_SGI_0, + IRQ_SEC_SGI_1, + IRQ_SEC_SGI_2, + IRQ_SEC_SGI_3, + IRQ_SEC_SGI_4, + IRQ_SEC_SGI_5, + IRQ_SEC_SGI_6, + IRQ_SEC_SGI_7 + }; + for (i = 0; i < sizeof(sec_irq) / sizeof(sec_irq[0]); i++) { + gic_set_secure(gicd_base, sec_irq[i]); + gicd_set_isenabler(gicd_base, sec_irq[i]); + } +} + +/******************************************************************************* + * Global gic distributor setup which will be done by the primary cpu after a + * cold boot. It marks out the secure SPIs, PPIs & SGIs and enables them. It + * then enables the secure GIC distributor interface. + ******************************************************************************/ +static void gic_distif_setup(unsigned int gicd_base) +{ + unsigned int i, ctlr; + const unsigned int ITLinesNumber = + gicd_read_typer(gicd_base) & IT_LINES_NO_MASK; + + /* Disable the distributor before going further */ + ctlr = gicd_read_ctlr(gicd_base); + ctlr &= ~(ENABLE_GRP0 | ENABLE_GRP1); + gicd_write_ctlr(gicd_base, ctlr); + + /* Mark all lines of SPIs as Group 1 (non-secure) */ + for (i = 0; i < ITLinesNumber; i++) + mmio_write_32(gicd_base + GICD_IGROUPR + 4 + i * 4, 0xffffffffu); + + /* Setup SPI priorities doing four at a time */ + for (i = 0; i < ITLinesNumber * 32; i += 4) + mmio_write_32(gicd_base + GICD_IPRIORITYR + 32 + i, DEFAULT_NS_PRIORITY_X4); + + /* Configure the SPIs we want as secure */ + static const char sec_irq[] = { + IRQ_MHU, + IRQ_GPU_SMMU_0, + IRQ_GPU_SMMU_1, + IRQ_ETR_SMMU, + IRQ_TZC400, + IRQ_TZ_WDOG + }; + for (i = 0; i < sizeof(sec_irq) / sizeof(sec_irq[0]); i++) + gic_set_secure(gicd_base, sec_irq[i]); + + /* Route watchdog interrupt to this CPU and enable it. */ + gicd_set_itargetsr(gicd_base, IRQ_TZ_WDOG, + platform_get_core_pos(read_mpidr())); + gicd_set_isenabler(gicd_base, IRQ_TZ_WDOG); + + /* Now setup the PPIs */ + gic_pcpu_distif_setup(gicd_base); + + /* Enable Group 0 (secure) interrupts */ + gicd_write_ctlr(gicd_base, ctlr | ENABLE_GRP0); +} + +void gic_setup(void) +{ + gic_cpuif_setup(GICC_BASE); + gic_distif_setup(GICD_BASE); +} + +/******************************************************************************* + * An ARM processor signals interrupt exceptions through the IRQ and FIQ pins. + * The interrupt controller knows which pin/line it uses to signal a type of + * interrupt. The platform knows which interrupt controller type is being used + * in a particular security state e.g. with an ARM GIC, normal world could use + * the GICv2 features while the secure world could use GICv3 features and vice + * versa. + * This function is exported by the platform to let the interrupt management + * framework determine for a type of interrupt and security state, which line + * should be used in the SCR_EL3 to control its routing to EL3. The interrupt + * line is represented as the bit position of the IRQ or FIQ bit in the SCR_EL3. + ******************************************************************************/ +uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state) +{ + assert(type == INTR_TYPE_S_EL1 || + type == INTR_TYPE_EL3 || + type == INTR_TYPE_NS); + + assert(security_state == NON_SECURE || security_state == SECURE); + + /* + * We ignore the security state parameter because ${PLAT} is GICv2 only + * so both normal and secure worlds are using ARM GICv2. + */ + return gicv2_interrupt_type_to_line(GICC_BASE, type); +} + +/******************************************************************************* + * This function returns the type of the highest priority pending interrupt at + * the GIC cpu interface. INTR_TYPE_INVAL is returned when there is no + * interrupt pending. + ******************************************************************************/ +uint32_t plat_ic_get_pending_interrupt_type(void) +{ + uint32_t id; + + id = gicc_read_hppir(GICC_BASE); + + /* Assume that all secure interrupts are S-EL1 interrupts */ + if (id < 1022) + return INTR_TYPE_S_EL1; + + if (id == GIC_SPURIOUS_INTERRUPT) + return INTR_TYPE_INVAL; + + return INTR_TYPE_NS; +} + +/******************************************************************************* + * This function returns the id of the highest priority pending interrupt at + * the GIC cpu interface. INTR_ID_UNAVAILABLE is returned when there is no + * interrupt pending. + ******************************************************************************/ +uint32_t plat_ic_get_pending_interrupt_id(void) +{ + uint32_t id; + + id = gicc_read_hppir(GICC_BASE); + + if (id < 1022) + return id; + + if (id == 1023) + return INTR_ID_UNAVAILABLE; + + /* + * Find out which non-secure interrupt it is under the assumption that + * the GICC_CTLR.AckCtl bit is 0. + */ + return gicc_read_ahppir(GICC_BASE); +} + +/******************************************************************************* + * This functions reads the GIC cpu interface Interrupt Acknowledge register + * to start handling the pending interrupt. It returns the contents of the IAR. + ******************************************************************************/ +uint32_t plat_ic_acknowledge_interrupt(void) +{ + return gicc_read_IAR(GICC_BASE); +} + +/******************************************************************************* + * This functions writes the GIC cpu interface End Of Interrupt register with + * the passed value to finish handling the active interrupt + ******************************************************************************/ +void plat_ic_end_of_interrupt(uint32_t id) +{ + gicc_write_EOIR(GICC_BASE, id); +} + +/******************************************************************************* + * This function returns the type of the interrupt id depending upon the group + * this interrupt has been configured under by the interrupt controller i.e. + * group0 or group1. + ******************************************************************************/ +uint32_t plat_ic_get_interrupt_type(uint32_t id) +{ + uint32_t group; + + group = gicd_get_igroupr(GICD_BASE, id); + + /* Assume that all secure interrupts are S-EL1 interrupts */ + if (group == GRP0) + return INTR_TYPE_S_EL1; + else + return INTR_TYPE_NS; +} diff --git a/plat/gxb/plat_init.c b/plat/gxb/plat_init.c new file mode 100644 index 0000000..a19e1f7 --- /dev/null +++ b/plat/gxb/plat_init.c @@ -0,0 +1,44 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/plat_init.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <io.h> +#include <stdio.h> +#include <stdint.h> +#include <timer.h> +#include <asm/arch/secure_apb.h> + +void pinmux_init(void) { + //detect sdio debug board + unsigned pinmux_2 = readl(P_PERIPHS_PIN_MUX_2); + // clear sdio pinmux + setbits_le32(P_PREG_PAD_GPIO2_O,0x3f<<20); + setbits_le32(P_PREG_PAD_GPIO2_EN_N,0x3f<<20); + clrbits_le32(P_PERIPHS_PIN_MUX_2,7<<12); //clear sd d1~d3 pinmux + if (!(readl(P_PREG_PAD_GPIO2_I)&(1<<24))) { //sd_d3 low, debug board in + clrbits_le32(P_AO_RTI_PIN_MUX_REG,3<<11); //clear AO uart pinmux + setbits_le32(P_PERIPHS_PIN_MUX_8,3<<9); + serial_puts("\nsdio debug board detected "); + } + else{ + writel(pinmux_2,P_PERIPHS_PIN_MUX_2); + serial_puts("\nno sdio debug board detected "); + } +}
\ No newline at end of file diff --git a/plat/gxb/plat_io_storage.c b/plat/gxb/plat_io_storage.c new file mode 100644 index 0000000..b1b0532 --- /dev/null +++ b/plat/gxb/plat_io_storage.c @@ -0,0 +1,203 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/plat_io_storage.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <assert.h> +#include <string.h> +#include <platform.h> +#include <io_storage.h> +#include <io_driver.h> +#include <semihosting.h> /* For FOPEN_MODE_... */ +#include <io_fip.h> +#include <io_memmap.h> +#include <debug.h> +#include "plat_def.h" + +/* IO devices */ +static io_plat_data_t io_data; +static const io_dev_connector_t *fip_dev_con; +static uintptr_t fip_dev_spec; +static uintptr_t fip_dev_handle; +static const io_dev_connector_t *memmap_dev_con; +static uintptr_t memmap_dev_spec; +static uintptr_t memmap_init_params; +static uintptr_t memmap_dev_handle; + +static const io_block_spec_t fip_block_spec = { + .offset = FLASH_BASE, + .length = FLASH_SIZE +}; + +static const io_file_spec_t bl2_file_spec = { + .path = BL2_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl30_file_spec = { + .path = BL30_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl31_file_spec = { + .path = BL31_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl32_file_spec = { + .path = BL32_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl33_file_spec = { + .path = BL33_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static int open_fip(const uintptr_t spec); +static int open_memmap(const uintptr_t spec); + +struct plat_io_policy { + const char *image_name; + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +static const struct plat_io_policy policies[] = { + { + FIP_IMAGE_NAME, + &memmap_dev_handle, + (uintptr_t)&fip_block_spec, + open_memmap + }, { + BL2_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl2_file_spec, + open_fip + }, { + BL30_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl30_file_spec, + open_fip + }, { + BL31_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl31_file_spec, + open_fip + }, { + BL32_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl32_file_spec, + open_fip + }, { + BL33_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl33_file_spec, + open_fip + }, { + 0, 0, 0 + } +}; + + +static int open_fip(const uintptr_t spec) +{ + int result = IO_FAIL; + + /* See if a Firmware Image Package is available */ + result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_NAME); + if (result == IO_SUCCESS) { + INFO("Using FIP\n"); + /*TODO: Check image defined in spec is present in FIP. */ + } + return result; +} + + +static int open_memmap(const uintptr_t spec) +{ + int result = IO_FAIL; + uintptr_t local_image_handle; + + result = io_dev_init(memmap_dev_handle, memmap_init_params); + if (result == IO_SUCCESS) { + result = io_open(memmap_dev_handle, spec, &local_image_handle); + if (result == IO_SUCCESS) { + /* INFO("Using Memmap IO\n"); */ + io_close(local_image_handle); + } + } + return result; +} + +void io_setup (void) +{ + int io_result = IO_FAIL; + + /* Initialise the IO layer */ + io_init(&io_data); + + /* Register the IO devices on this platform */ + io_result = register_io_dev_fip(&fip_dev_con); + assert(io_result == IO_SUCCESS); + + io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == IO_SUCCESS); + + /* Open connections to devices and cache the handles */ + io_result = io_dev_open(fip_dev_con, fip_dev_spec, &fip_dev_handle); + assert(io_result == IO_SUCCESS); + + io_result = io_dev_open(memmap_dev_con, memmap_dev_spec, + &memmap_dev_handle); + assert(io_result == IO_SUCCESS); + + /* Ignore improbable errors in release builds */ + (void)io_result; +} + + +/* Return an IO device handle and specification which can be used to access + * an image. Use this to enforce platform load policy */ +int plat_get_image_source(const char *image_name, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int result = IO_FAIL; + const struct plat_io_policy *policy; + + if ((image_name != NULL) && (dev_handle != NULL) && + (image_spec != NULL)) { + policy = policies; + while (policy->image_name != NULL) { + if (strcmp(policy->image_name, image_name) == 0) { + result = policy->check(policy->image_spec); + if (result == IO_SUCCESS) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + break; + } + } + policy++; + } + } else { + result = IO_FAIL; + } + return result; +} diff --git a/plat/gxb/plat_pm.c b/plat/gxb/plat_pm.c new file mode 100644 index 0000000..c3248eb --- /dev/null +++ b/plat/gxb/plat_pm.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2013, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <arch_helpers.h> +#include <cci400.h> +#include <platform.h> +#include <platform_def.h> +#include <psci.h> +#include "plat_def.h" +#include "plat_private.h" +#include "scpi.h" + +typedef struct { + /* Align the suspend level to allow per-cpu lockless access */ + uint32_t state[MPIDR_MAX_AFFLVL] __aligned(CACHE_WRITEBACK_GRANULE); +} scp_pstate; + +static scp_pstate target_pstate[PLATFORM_CORE_COUNT]; + +int pm_on(unsigned long mpidr, + unsigned long sec_entrypoint, + unsigned long ns_entrypoint, + unsigned int afflvl, + unsigned int state) +{ + /* + * SCP takes care of powering up higher affinity levels so we + * only need to care about level 0 + */ + if (afflvl != MPIDR_AFFLVL0) + return PSCI_E_SUCCESS; + + /* + * Setup mailbox with address for CPU entrypoint when it next powers up + */ + unsigned long *mbox = (unsigned long *)(unsigned long)( + TRUSTED_MAILBOXES_BASE + + (platform_get_core_pos(mpidr) << TRUSTED_MAILBOX_SHIFT) + ); + *mbox = sec_entrypoint; + flush_dcache_range((unsigned long)mbox, sizeof(*mbox)); + + scpi_set_css_power_state(mpidr, scpi_power_on, scpi_power_on, + scpi_power_on); + + return PSCI_E_SUCCESS; +} + +int pm_on_finish(unsigned long mpidr, unsigned int afflvl, unsigned int state) +{ + switch (afflvl) { + + case MPIDR_AFFLVL1: + /* Enable coherency if this cluster was off */ + if (state == PSCI_STATE_OFF) + cci_enable_coherency(mpidr); + break; + + case MPIDR_AFFLVL0: + /* + * Ignore the state passed for a cpu. It could only have + * been off if we are here. + */ + + /* Turn on intra-cluster coherency. */ + write_cpuectlr(read_cpuectlr() | CPUECTLR_SMP_BIT); + + /* Enable the gic cpu interface */ + gic_cpuif_setup(GICC_BASE); + /* ${PLAT} todo: Is this setup only needed after a cold boot? */ + gic_pcpu_distif_setup(GICD_BASE); + + /* + * Clear the mailbox for each cpu + */ + unsigned long *mbox = (unsigned long *)(unsigned long)( + TRUSTED_MAILBOXES_BASE + + (platform_get_core_pos(mpidr) << TRUSTED_MAILBOX_SHIFT) + ); + *mbox = 0; + flush_dcache_range((unsigned long)mbox, sizeof(*mbox)); + + break; + } + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * Common function called while turning a cpu off or suspending it. It is called + * for each affinity level until the target affinity level. It keeps track of + * the power state that needs to be programmed through the SCP firmware for each + * affinity level. Once the target affinity level is reached it uses the MHU + * channel to ask the SCP to perform the power operations for each affinity + * level accumulated so far. + * + * CAUTION: This function is called with coherent stacks so that caches can be + * turned off, flushed and coherency disabled. There is no guarantee that caches + * will remain turned on across calls to this function as each affinity level is + * dealt with. So do not write & read global variables across calls. It will be + * wise to do flush a write to the global to prevent unpredictable results. + ******************************************************************************/ +static int plat_power_down_common(unsigned long mpidr, + unsigned int linear_id, + unsigned int cur_afflvl, + unsigned int tgt_afflvl, + unsigned int state) +{ + /* Record which power state this affinity level is supposed to enter */ + if (state == PSCI_STATE_OFF) { + target_pstate[linear_id].state[cur_afflvl] = scpi_power_off; + } else { + assert(cur_afflvl != MPIDR_AFFLVL0); + target_pstate[linear_id].state[cur_afflvl] = scpi_power_on; + goto exit; + } + + switch (cur_afflvl) { + case MPIDR_AFFLVL1: + /* Cluster is to be turned off, so disable coherency */ + cci_disable_coherency(mpidr); + + break; + + case MPIDR_AFFLVL0: + /* Turn off intra-cluster coherency */ + write_cpuectlr(read_cpuectlr() & ~CPUECTLR_SMP_BIT); + + /* Prevent interrupts from spuriously waking up this cpu */ + gic_cpuif_deactivate(GICC_BASE); + + break; + } + +exit: + /* + * If this is the target affinity level then we need to ask the SCP + * to power down the appropriate components depending upon their state + */ + if (cur_afflvl == tgt_afflvl) { + scpi_set_css_power_state(mpidr, + target_pstate[linear_id].state[MPIDR_AFFLVL0], + target_pstate[linear_id].state[MPIDR_AFFLVL1], + scpi_power_on); + + /* Reset the states */ + target_pstate[linear_id].state[MPIDR_AFFLVL0] = scpi_power_on; + target_pstate[linear_id].state[MPIDR_AFFLVL1] = scpi_power_on; + } + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * Handler called when an affinity instance is about to be turned off. The + * level and mpidr determine the affinity instance. The 'state' arg. allows the + * platform to decide whether the cluster is being turned off and take apt + * actions. + * + * CAUTION: This function is called with coherent stacks so that caches can be + * turned off, flushed and coherency disabled. There is no guarantee that caches + * will remain turned on across calls to this function as each affinity level is + * dealt with. So do not write & read global variables across calls. It will be + * wise to do flush a write to the global to prevent unpredictable results. + ******************************************************************************/ +int pm_off(unsigned long mpidr, unsigned int afflvl, unsigned int state) +{ + return plat_power_down_common(mpidr, + platform_get_core_pos(mpidr), + afflvl, + plat_get_max_afflvl(), + state); +} + +/******************************************************************************* + * Handler called when an affinity instance is about to be suspended. The + * level and mpidr determine the affinity instance. The 'state' arg. allows the + * platform to decide whether the cluster is being turned off and take apt + * actions. The 'sec_entrypoint' determines the address in BL3-1 from where + * execution should resume. + * + * CAUTION: This function is called with coherent stacks so that caches can be + * turned off, flushed and coherency disabled. There is no guarantee that caches + * will remain turned on across calls to this function as each affinity level is + * dealt with. So do not write & read global variables across calls. It will be + * wise to do flush a write to the global to prevent unpredictable results. + ******************************************************************************/ +int pm_suspend(unsigned long mpidr, + unsigned long sec_entrypoint, + unsigned long ns_entrypoint, + unsigned int afflvl, + unsigned int state) +{ + uint32_t tgt_afflvl; + + tgt_afflvl = psci_get_suspend_afflvl(mpidr); + assert(tgt_afflvl != PSCI_INVALID_DATA); + + /* + * Setup mailbox with address for CPU entrypoint when it next powers up + */ + if (afflvl == MPIDR_AFFLVL0) { + unsigned long *mbox = (unsigned long *)(unsigned long)( + TRUSTED_MAILBOXES_BASE + + (platform_get_core_pos(mpidr) << TRUSTED_MAILBOX_SHIFT) + ); + *mbox = sec_entrypoint; + flush_dcache_range((unsigned long)mbox, sizeof(*mbox)); + } + + return plat_power_down_common(mpidr, + platform_get_core_pos(mpidr), + afflvl, + tgt_afflvl, + state); +} + +int pm_suspend_finish(unsigned long mpidr, + unsigned int afflvl, + unsigned int state) +{ + return pm_on_finish(mpidr, afflvl, state); +} + +/******************************************************************************* + * Export the platform handlers to enable psci to invoke them + ******************************************************************************/ +static const plat_pm_ops_t pm_ops = { + .affinst_on = pm_on, + .affinst_on_finish = pm_on_finish, + .affinst_off = pm_off, + .affinst_suspend = pm_suspend, + .affinst_suspend_finish = pm_suspend_finish +}; + +/******************************************************************************* + * Export the platform specific power ops & initialize the fvp power controller + ******************************************************************************/ +int platform_setup_pm(const plat_pm_ops_t **plat_ops) +{ + *plat_ops = &pm_ops; + return 0; +} diff --git a/plat/gxb/plat_private.h b/plat/gxb/plat_private.h new file mode 100644 index 0000000..ec552e7 --- /dev/null +++ b/plat/gxb/plat_private.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __PLAT_PRIVATE_H__ +#define __PLAT_PRIVATE_H__ + +#include <bl_common.h> +#include <stdint.h> +#include <platform_def.h> + +/******************************************************************************* + * Forward declarations + ******************************************************************************/ +struct plat_pm_ops; +struct meminfo; +struct bl31_params; +struct image_info; +struct entry_point_info; + +/******************************************************************************* + * This structure represents the superset of information that is passed to + * BL3-1 e.g. while passing control to it from BL2 which is bl31_params + * and other platform specific params + ******************************************************************************/ +typedef struct bl2_to_bl31_params_mem { + struct bl31_params bl31_params; + struct image_info bl31_image_info; + struct image_info bl32_image_info; + struct image_info bl33_image_info; + struct entry_point_info bl33_ep_info; + struct entry_point_info bl32_ep_info; + struct entry_point_info bl31_ep_info; +} bl2_to_bl31_params_mem_t; + +/******************************************************************************* + * Function and variable prototypes + ******************************************************************************/ +void bl1_plat_arch_setup(void); +void bl2_plat_arch_setup(void); +void bl31_plat_arch_setup(void); +int platform_setup_pm(const struct plat_pm_ops **plat_ops); +unsigned int platform_get_core_pos(unsigned long mpidr); +void configure_mmu_el1(unsigned long total_base, + unsigned long total_size, + unsigned long ro_start, + unsigned long ro_limit, + unsigned long coh_start, + unsigned long coh_limit); +void configure_mmu_el3(unsigned long total_base, + unsigned long total_size, + unsigned long ro_start, + unsigned long ro_limit, + unsigned long coh_start, + unsigned long coh_limit); +void plat_report_exception(unsigned long type); +unsigned long plat_get_ns_image_entrypoint(void); +unsigned long platform_get_stack(unsigned long mpidr); +uint64_t plat_get_syscnt_freq(void); + +/* Declarations for plat_gic.c */ +uint32_t ic_get_pending_interrupt_id(void); +uint32_t ic_get_pending_interrupt_type(void); +uint32_t ic_acknowledge_interrupt(void); +uint32_t ic_get_interrupt_type(uint32_t id); +void ic_end_of_interrupt(uint32_t id); +void gic_cpuif_deactivate(unsigned int gicc_base); +void gic_cpuif_setup(unsigned int gicc_base); +void gic_pcpu_distif_setup(unsigned int gicd_base); +void gic_setup(void); +uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state); + +/* Declarations for plat_topology.c */ +int plat_setup_topology(void); +int plat_get_max_afflvl(void); +unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr); +unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr); + +/* Declarations for plat_io_storage.c */ +void io_setup(void); +int plat_get_image_source(const char *image_name, + uintptr_t *dev_handle, + uintptr_t *image_spec); + +/* + * Before calling this function BL2 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL2 and set SPSR and security state. + * On ${PLAT} we are only setting the security state, entrypoint + */ +void bl1_plat_set_bl2_ep_info(struct image_info *image, + struct entry_point_info *ep); + +/* + * Before calling this function BL3-1 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL3-1 and set SPSR and security state. + * On ${PLAT} we are only setting the security state, entrypoint + */ +void bl2_plat_set_bl31_ep_info(struct image_info *image, + struct entry_point_info *ep); + +/* + * Before calling this function BL3-2 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL3-2 and set SPSR and security state. + * On ${PLAT} we are only setting the security state, entrypoint + */ +void bl2_plat_set_bl32_ep_info(struct image_info *image, + struct entry_point_info *ep); + +/* + * Before calling this function BL3-3 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL3-3 and set SPSR and security state. + * On ${PLAT} we are only setting the security state, entrypoint + */ +void bl2_plat_set_bl33_ep_info(struct image_info *image, + struct entry_point_info *ep); + +/* Gets the memory layout for BL3-2 */ +void bl2_plat_get_bl32_meminfo(struct meminfo *mem_info); + +/* Gets the memory layout for BL3-3 */ +void bl2_plat_get_bl33_meminfo(struct meminfo *mem_info); + +#endif /* __PLAT_PRIVATE_H__ */ diff --git a/plat/gxb/plat_topology.c b/plat/gxb/plat_topology.c new file mode 100644 index 0000000..b4b3711 --- /dev/null +++ b/plat/gxb/plat_topology.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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_def.h> +#include <psci.h> + +unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr) +{ + /* Report 1 (absent) instance at levels higher that the cluster level */ + if (aff_lvl > MPIDR_AFFLVL1) + return 1; + + if (aff_lvl == MPIDR_AFFLVL1) + return 2; /* We have two clusters */ + + return mpidr & 0x100 ? 4 : 2; /* 4 cpus in cluster 1, 2 in cluster 0 */ +} + +unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr) +{ + return aff_lvl <= MPIDR_AFFLVL1 ? PSCI_AFF_PRESENT : PSCI_AFF_ABSENT; +} + +int plat_get_max_afflvl() +{ + return MPIDR_AFFLVL1; +} + +int plat_setup_topology() +{ + /* ${PLAT} todo: Make topology configurable via SCC */ + return 0; +} diff --git a/plat/gxb/platform.mk b/plat/gxb/platform.mk new file mode 100644 index 0000000..8caffd4 --- /dev/null +++ b/plat/gxb/platform.mk @@ -0,0 +1,97 @@ +# +# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 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. +# +# Neither the name of ARM nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific +# prior written permission. +# +# 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. +# + +PLAT_INCLUDES := -Iplat/${PLAT}/include/ + +PLAT_BL_COMMON_SOURCES := drivers/arm/serial/serial.c \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + lib/mmio.c \ + lib/aarch64/sysreg_helpers.S \ + plat/common/aarch64/plat_common.c \ + plat/${PLAT}/plat_io_storage.c + +BL1_SOURCES += drivers/arm/cci400/cci400.c \ + plat/common/aarch64/platform_up_stack.S \ + plat/${PLAT}/bl1_plat_setup.c \ + plat/${PLAT}/aarch64/bl1_plat_helpers.S \ + plat/${PLAT}/aarch64/plat_helpers.S \ + plat/${PLAT}/aarch64/common.c + +BL2_SOURCES += lib/locks/bakery/bakery_lock.c \ + plat/common/aarch64/platform_up_stack.S \ + plat/${PLAT}/bl2_plat_setup.c \ + plat/${PLAT}/mhu.c \ + plat/${PLAT}/aarch64/plat_helpers.S \ + plat/${PLAT}/aarch64/cache.S \ + plat/${PLAT}/aarch64/common.c \ + plat/${PLAT}/scp_bootloader.c \ + plat/${PLAT}/scpi.c \ + plat/${PLAT}/storage.c \ + plat/${PLAT}/sha2.c \ + plat/${PLAT}/mailbox.c \ + plat/${PLAT}/watchdog.c \ + plat/${PLAT}/efuse.c \ + plat/${PLAT}/pll.c \ + plat/${PLAT}/power_init.c \ + plat/${PLAT}/saradc.c \ + plat/${PLAT}/timer.c \ + plat/${PLAT}/crypto/secureboot.c \ + plat/${PLAT}/ddr/ddr.c \ + plat/${PLAT}/plat_init.c \ + plat/${PLAT}/crypto/ndma_utils.c + +BL31_SOURCES += drivers/arm/cci400/cci400.c \ + drivers/arm/gic/gic_v2.c \ + plat/common/aarch64/platform_mp_stack.S \ + plat/${PLAT}/bl31_plat_setup.c \ + plat/${PLAT}/mhu.c \ + plat/${PLAT}/aarch64/plat_helpers.S \ + plat/${PLAT}/aarch64/common.c \ + plat/${PLAT}/plat_pm.c \ + plat/${PLAT}/plat_topology.c \ + plat/${PLAT}/plat_gic.c \ + plat/${PLAT}/scpi.c \ + plat/${PLAT}/smc_arm.c + +ifeq ($(CONFIG_AML_SECURE_UBOOT),y) + BL2_SOURCES += plat/${PLAT}/crypto/rsa.c \ + plat/${PLAT}/crypto/bignum.c +endif + +ifeq ($(CONFIG_AML_NAND),y) + BL2_SOURCES += plat/${PLAT}/nand.c +endif + + +ifneq (${RESET_TO_BL31},0) + $(error "Using BL3-1 as the reset vector is not supported on PLAT. \ + Please set RESET_TO_BL31 to 0.") +endif diff --git a/plat/gxb/pll.c b/plat/gxb/pll.c new file mode 100644 index 0000000..5dd5bb8 --- /dev/null +++ b/plat/gxb/pll.c @@ -0,0 +1,271 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/pll.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <pll.h> +#include <string.h> +#include <asm/arch/watchdog.h> +#include <stdio.h> +#include <asm/arch/secure_apb.h> +#include <timer.h> +#include <stdio.h> +#include <asm/arch/timing.h> + +unsigned lock_check_loop = 0; +extern pll_set_t __pll_setting; +static pll_set_t * p_pll_set = &__pll_setting; + +unsigned int pll_init(void){ + // Switch clk81 to the oscillator input + // romcode might have already programmed clk81 to a PLL + Wr( HHI_MPEG_CLK_CNTL, Rd(HHI_MPEG_CLK_CNTL) & ~(1 << 8) ); + // Switch sys clk to oscillator, the SYS CPU might have already been programmed + clocks_set_sys_cpu_clk( 0, 0, 0, 0); + + //SYS PLL,FIX PLL bangap + Wr(HHI_MPLL_CNTL6, Rd(HHI_MPLL_CNTL6)|(1<<26)); + _udelay(100); + + unsigned int sys_pll_cntl = 0; + if ((p_pll_set->cpu_clk >= 600) && (p_pll_set->cpu_clk <= 1200)) { + sys_pll_cntl = (1<<16/*OD*/) | (1<<9/*N*/) | (p_pll_set->cpu_clk / 12/*M*/); + } + else if ((p_pll_set->cpu_clk > 1200) && (p_pll_set->cpu_clk <= 2000)) { + sys_pll_cntl = (0<<16/*OD*/) | (1<<9/*N*/) | (p_pll_set->cpu_clk / 24/*M*/); + } + //Init SYS pll + do { + Wr(HHI_SYS_PLL_CNTL, Rd(HHI_SYS_PLL_CNTL)|(1<<29)); + Wr(HHI_SYS_PLL_CNTL2, CFG_SYS_PLL_CNTL_2); + Wr(HHI_SYS_PLL_CNTL3, CFG_SYS_PLL_CNTL_3); + Wr(HHI_SYS_PLL_CNTL4, CFG_SYS_PLL_CNTL_4); + Wr(HHI_SYS_PLL_CNTL5, CFG_SYS_PLL_CNTL_5); + Wr(HHI_SYS_PLL_CNTL, ((1<<30)|(1<<29)|sys_pll_cntl)); // A9 clock + Wr(HHI_SYS_PLL_CNTL, Rd(HHI_SYS_PLL_CNTL)&(~(1<<29))); + _udelay(20); + } while(pll_lock_check(HHI_SYS_PLL_CNTL, "SYS PLL")); + clocks_set_sys_cpu_clk( 1, 0, 0, 0); // Connect SYS CPU to the PLL divider output + + sys_pll_cntl = Rd(HHI_SYS_PLL_CNTL); + unsigned cpu_clk = (24/ \ + ((sys_pll_cntl>>9)&0x1F)* \ + (sys_pll_cntl&0x1FF)/ \ + (1<<((sys_pll_cntl>>16)&0x3))); + /* cpu clk = 24/N*M/2^OD */ + serial_puts("CPU clk: "); + serial_put_dec(cpu_clk); + serial_puts("MHz\n"); + + //FIXED PLL + Wr(HHI_MPLL_CNTL4, CFG_MPLL_CNTL_4); + Wr(HHI_MPLL_CNTL, Rd(HHI_MPLL_CNTL)|(1<<29)); + _udelay(200); + Wr(HHI_MPLL_CNTL2, CFG_MPLL_CNTL_2); + Wr(HHI_MPLL_CNTL3, CFG_MPLL_CNTL_3); + //Wr(HHI_MPLL_CNTL4, CFG_MPLL_CNTL_4); + Wr(HHI_MPLL_CNTL5, CFG_MPLL_CNTL_5); + Wr(HHI_MPLL_CNTL6, CFG_MPLL_CNTL_6); + Wr(HHI_MPLL_CNTL, ((1 << 30) | (1<<29) | (3 << 9) | (250 << 0)) ); + Wr(HHI_MPLL_CNTL, Rd(HHI_MPLL_CNTL)&(~(1<<29))); //set reset bit to 0 + _udelay(800); + Wr(HHI_MPLL_CNTL4, Rd(HHI_MPLL_CNTL4)|(1<<14)); + do { + if ((Rd(HHI_MPLL_CNTL)&(1<<31)) != 0) + break; + Wr(HHI_MPLL_CNTL,Rd(HHI_MPLL_CNTL) | (1<<29)); + _udelay(1000); + Wr(HHI_MPLL_CNTL, Rd(HHI_MPLL_CNTL)&(~(1<<29))); + _udelay(1000); + }while(pll_lock_check(HHI_MPLL_CNTL, "FIX PLL")); + + // Enable the separate fclk_div2 and fclk_div3 + // .MPLL_CLK_OUT_DIV2_EN ( hi_mpll_cntl10[7:0] ), + // .MPLL_CLK_OUT_DIV3_EN ( hi_mpll_cntl10[11:8] ), + Wr( HHI_MPLL_CNTL10, (0xFFF << 16) ); + + // ------------------------------- + // Set Multi-Phase PLL0 = 350Mhz + // ------------------------------- + Wr( HHI_MPLL_CNTL7, ((7 << 16) | (1 << 15) | (1 << 14) | (4681 << 0)) ); + + // ------------------------- + // set CLK81 to 166.6Mhz Fixed + // ------------------------- + Wr( HHI_MPEG_CLK_CNTL, ((Rd(HHI_MPEG_CLK_CNTL) & (~((0x7 << 12) | (1 << 7) | (0x7F << 0)))) | ((5 << 12) | (1 << 7) | (2 << 0))) ); + // Connect clk81 to the PLL divider output + Wr( HHI_MPEG_CLK_CNTL, Rd(HHI_MPEG_CLK_CNTL) | (1 << 8) ); + + // ------------------------------- + // Set Multi-Phase PLL1 = 442.368 Mhz + // ------------------------------- + // +----------------------------------------+ + // | <<< Clock Reset Test >>> | + // +-------------------------------------+ +------+-----------+---------------------+ +------------ + // | Multi-Phase PLL | | CRT | Final | Ideal | | HIU Reg + // | FIn | N2 SDM_IN | CLKMP | | XD | Clock | Error Clock | | 0x10a7 + // +---------+--------------+------------| |------+-----------+---------------------+ +------------ + // | 24.0000 | 5 12524 | 442.3701 | | 1 | 442.3701 | 0.000% ( 442.368) | | 0x0005f0ec + // .MPLL_SDM_IN1 ( hi_mpll_cntl8[13:0] ), + // .MPLL_CH1_EN ( hi_mpll_cntl8[14] ), + // .MPLL_SDM_EN1 ( hi_mpll_cntl8[15] ), + // .MPLL_N_IN1 ( hi_mpll_cntl8[22:16] ), + // .MPLL_I160CTR1 ( hi_mpll_cntl8[25:24] ), + // .MPLL_R_SW1 ( hi_mpll_cntl8[27:26] ), + Wr( HHI_MPLL_CNTL8, ((5 << 16) | (1 << 15) | (1 << 14) | (12524 << 0)) ); + + return 0; +} + +// -------------------------------------------------- +// clocks_set_sys_cpu_clk +// -------------------------------------------------- +// This function sets the System CPU clock muxing and the +// sub-clocks related to the System CPU (AXI, PCLK,...) +// +// Parameters: +// freq: +// 0: 24Mhz Crystal +// 1: System PLL +// 1275, 850, 637,.... +// pclk_ratio: 0 = no change to the existing setting. 2,3,...8 = the clock ratio relative to the system CPU clock +// aclkm_ratio: 0 = no change to the existing setting. 2,3,...8 = the clock ratio relative to the system CPU clock +// atclk_ratio: 0 = no change to the existing setting. 2,3,...8 = the clock ratio relative to the system CPU clock +// -------------------------------- +// freq = 0: 24Mhz Crystal +// freq = 1: System PLL +// freq = 1000, 667, 500, 333, 250... +// Pass 0 to pclk_ratio or aclkm_ratio or atclk_ratio if nothing changes +void clocks_set_sys_cpu_clk(uint32_t freq, uint32_t pclk_ratio, uint32_t aclkm_ratio, uint32_t atclk_ratio ) +{ + uint32_t control = 0; + uint32_t dyn_pre_mux = 0; + uint32_t dyn_post_mux = 0; + uint32_t dyn_div = 0; + + // Make sure not busy from last setting and we currently match the last setting + do { + control = Rd(HHI_SYS_CPU_CLK_CNTL); + } while( (control & (1 << 28)) ); + + control = control | (1 << 26); // Enable + + // Switching to System PLL...just change the final mux + if ( freq == 1 ) { + // wire cntl_final_mux_sel = control[11]; + control = control | (1 << 11); + } else { + switch ( freq ) { + case 0: // If Crystal + dyn_pre_mux = 0; + dyn_post_mux = 0; + dyn_div = 0; // divide by 1 + break; + case 1000: // fclk_div2 + dyn_pre_mux = 1; + dyn_post_mux = 0; + dyn_div = 0; // divide by 1 + break; + case 667: // fclk_div3 + dyn_pre_mux = 2; + dyn_post_mux = 0; + dyn_div = 0; // divide by 1 + break; + case 500: // fclk_div2/2 + dyn_pre_mux = 1; + dyn_post_mux = 1; + dyn_div = 1; // Divide by 2 + break; + case 333: // fclk_div3/2 + dyn_pre_mux = 2; + dyn_post_mux = 1; + dyn_div = 1; // divide by 2 + break; + case 250: // fclk_div2/4 + dyn_pre_mux = 1; + dyn_post_mux = 1; + dyn_div = 3; // divide by 4 + break; + } + if ( control & (1 << 10) ) { // if using Dyn mux1, set dyn mux 0 + // Toggle bit[10] indicating a dynamic mux change + control = (control & ~((1 << 10) | (0x3f << 4) | (1 << 2) | (0x3 << 0))) + | ((0 << 10) + | (dyn_div << 4) + | (dyn_post_mux << 2) + | (dyn_pre_mux << 0)); + } else { + // Toggle bit[10] indicating a dynamic mux change + control = (control & ~((1 << 10) | (0x3f << 20) | (1 << 18) | (0x3 << 16))) + | ((1 << 10) + | (dyn_div << 20) + | (dyn_post_mux << 18) + | (dyn_pre_mux << 16)); + } + // Select Dynamic mux + control = control & ~(1 << 11); + } + Wr(HHI_SYS_CPU_CLK_CNTL,control); + // + // Now set the divided clocks related to the System CPU + // + // This function changes the clock ratios for the + // PCLK, ACLKM (AXI) and ATCLK + // .clk_clken0_i ( {clk_div2_en,clk_div2} ), + // .clk_clken1_i ( {clk_div3_en,clk_div3} ), + // .clk_clken2_i ( {clk_div4_en,clk_div4} ), + // .clk_clken3_i ( {clk_div5_en,clk_div5} ), + // .clk_clken4_i ( {clk_div6_en,clk_div6} ), + // .clk_clken5_i ( {clk_div7_en,clk_div7} ), + // .clk_clken6_i ( {clk_div8_en,clk_div8} ), + + uint32_t control1 = Rd(HHI_SYS_CPU_CLK_CNTL1); + + // .cntl_PCLK_mux ( hi_sys_cpu_clk_cntl1[5:3] ), + if ( (pclk_ratio >= 2) && (pclk_ratio <= 8) ) { control1 = (control1 & ~(0x7 << 3)) | ((pclk_ratio-2) << 3) ; } + // .cntl_ACLKM_clk_mux ( hi_sys_cpu_clk_cntl1[11:9] ), // AXI matrix + if ( (aclkm_ratio >= 2) && (aclkm_ratio <= 8) ) { control1 = (control1 & ~(0x7 << 9)) | ((aclkm_ratio-2) << 9) ; } + // .cntl_ATCLK_clk_mux ( hi_sys_cpu_clk_cntl1[8:6] ), + if ( (atclk_ratio >= 2) && (atclk_ratio <= 8) ) { control1 = (control1 & ~(0x7 << 6)) | ((atclk_ratio-2) << 6) ; } + Wr( HHI_SYS_CPU_CLK_CNTL1, control1 ); +} + +unsigned pll_lock_check(unsigned long pll_reg, const char *pll_name){ + /*locked: return 0, else return 1*/ + unsigned lock = ((Rd(pll_reg) >> PLL_LOCK_BIT_OFFSET) & 0x1); + if (lock) { + lock_check_loop = 0; + //serial_puts(pll_name); + //serial_puts("" lock ok!\n"); + } + else{ + lock_check_loop++; + serial_puts(pll_name); + serial_puts(" lock check "); + serial_put_dec(lock_check_loop); + serial_puts("\n"); + if (lock_check_loop >= PLL_lOCK_CHECK_LOOP) { + serial_puts(pll_name); + serial_puts(" lock failed! reset...\n"); + reset_system(); + while (1) ; + } + } + return !lock; +}
\ No newline at end of file diff --git a/plat/gxb/power_init.c b/plat/gxb/power_init.c new file mode 100644 index 0000000..2098361 --- /dev/null +++ b/plat/gxb/power_init.c @@ -0,0 +1,16 @@ + +#ifdef CONFIG_PLATFORM_POWER_INIT +#include "power.c" +#else +void __attribute__((weak)) power_init(int mode) +{ + /* + * fake function for platform without power init + */ +} +#endif + +void platform_power_init(int mode) +{ + power_init(mode); +} diff --git a/plat/gxb/saradc.c b/plat/gxb/saradc.c new file mode 100644 index 0000000..1e5bfd3 --- /dev/null +++ b/plat/gxb/saradc.c @@ -0,0 +1,73 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/saradc.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <string.h> +#include <stdio.h> +#include <saradc.h> +#include <asm/arch/secure_apb.h> +#include <timer.h> + +#define SAMP_COUNT 9 +const unsigned int sam_val[SAMP_COUNT] = {0, 0x80, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400}; + +unsigned int saradc_ch1_get(void) +{ + unsigned int val = 0; + unsigned int cnt=0; + unsigned int idx=0; + + Wr(P_SAR_ADC_CHAN_LIST, 0x00000001); // + Wr(P_SAR_ADC_AVG_CNTL, 0x00003000); + Wr(P_SAR_ADC_REG3, 0xc3a8500a); + Wr(P_SAR_ADC_DELAY, 0x010a000a); + Wr(P_SAR_ADC_AUX_SW, 0x03eb1a0c); + Wr(P_SAR_ADC_CHAN_10_SW, 0x008c000c); + Wr(P_SAR_ADC_DETECT_IDLE_SW, 0x008e038c); + Wr(P_SAR_ADC_DELTA_11, 0x0c00c400); + Wr(P_SAR_ADC_CLOCK, 0x00000114); + Wr(P_SAR_ADC_TEMP_SES, 0x00002000); + Wr(P_SAR_SAR_ADC_REG0, 0x84064040); + _udelay(20); + Wr(P_SAR_SAR_ADC_REG0, 0x84064041); + _udelay(20); + Wr(P_SAR_SAR_ADC_REG0, 0x84064045); + _udelay(20); + + while ( ( Rd(P_SAR_SAR_ADC_REG0)& 0x70000000) && (cnt++ <100)) ; + if (cnt >= 100) { + serial_puts(" Get saradc sample Error. Cnt_"); + serial_put_dec(cnt); + serial_puts("\n"); + } + val = Rd(P_SAR_FIFO_READ) & 0x3ff; + for (idx=0; idx<SAMP_COUNT; idx++) + { + if (val <= sam_val[idx]+0x3f) + break; + } + + Wr(SEC_AO_SEC_GP_CFG0, ((Rd(SEC_AO_SEC_GP_CFG0) & 0xFFFF00ff) | (idx << 8))); + serial_puts("Board ID = "); + serial_put_dec(idx); + serial_puts("\n"); + return idx; +} + diff --git a/plat/gxb/scp_bootloader.c b/plat/gxb/scp_bootloader.c new file mode 100644 index 0000000..305029f --- /dev/null +++ b/plat/gxb/scp_bootloader.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <platform.h> +#include "plat_def.h" +#include "mhu.h" +#include "scp_bootloader.h" +#include "scpi.h" + +/* Boot commands sent from AP -> SCP */ +#define BOOT_CMD_START 0x01 +#define BOOT_CMD_DATA 0x02 + +typedef struct { + uint32_t image_size; +} cmd_start_payload; + +typedef struct { + uint32_t sequence_num; + uint32_t offset; + uint32_t size; +} cmd_data_payload; + +#define BOOT_DATA_MAX_SIZE 0x1000 + +/* Boot commands sent from SCP -> AP */ +#define BOOT_CMD_ACK 0x03 +#define BOOT_CMD_NACK 0x04 + +typedef struct { + uint32_t sequence_num; +} cmd_ack_payload; + +/* + * Unlike the runtime protocol, the boot protocol uses the same memory region + * for both AP -> SCP and SCP -> AP transfers; define the address of this... + */ +static void * const cmd_payload = (void *)(MHU_SECURE_BASE + 0x0080); + +static void *scp_boot_message_start(void) +{ + mhu_secure_message_start(); + + return cmd_payload; +} + +static void scp_boot_message_send(unsigned command, size_t size) +{ + /* Make sure payload can be seen by SCP */ + if (MHU_PAYLOAD_CACHED) + flush_dcache_range((unsigned long)cmd_payload, size); + + /* Send command to SCP */ + mhu_secure_message_send(command | (size << 8)); +} + +static uint32_t scp_boot_message_wait(size_t size) +{ + uint32_t response = mhu_secure_message_wait(); + + /* Make sure we see the reply from the SCP and not any stale data */ + if (MHU_PAYLOAD_CACHED) + inv_dcache_range((unsigned long)cmd_payload, size); + + return response & 0xff; +} + +static void scp_boot_message_end(void) +{ + mhu_secure_message_end(); +} + +static int transfer_block(uint32_t sequence_num, uint32_t offset, uint32_t size) +{ + cmd_data_payload *cmd_data = scp_boot_message_start(); + cmd_data->sequence_num = sequence_num; + cmd_data->offset = offset; + cmd_data->size = size; + + scp_boot_message_send(BOOT_CMD_DATA, sizeof(*cmd_data)); + + cmd_ack_payload *cmd_ack = cmd_payload; + int ok = scp_boot_message_wait(sizeof(*cmd_ack)) == BOOT_CMD_ACK + && cmd_ack->sequence_num == sequence_num; + + scp_boot_message_end(); + + return ok; +} + +int scp_bootloader_transfer(void *image, unsigned int image_size) +{ + uintptr_t offset = (uintptr_t)image - MHU_SECURE_BASE; + uintptr_t end = offset + image_size; + uint32_t response; + + mhu_secure_init(); + + /* Initiate communications with SCP */ + do { + cmd_start_payload *cmd_start = scp_boot_message_start(); + cmd_start->image_size = image_size; + + scp_boot_message_send(BOOT_CMD_START, sizeof(*cmd_start)); + + response = scp_boot_message_wait(0); + + scp_boot_message_end(); + } while (response != BOOT_CMD_ACK); + + /* Transfer image to SCP a block at a time */ + uint32_t sequence_num = 1; + size_t size; + while ((size = end - offset) != 0) { + if (size > BOOT_DATA_MAX_SIZE) + size = BOOT_DATA_MAX_SIZE; + while (!transfer_block(sequence_num, offset, size)) + ; /* Retry forever */ + offset += size; + sequence_num++; + } + + /* Wait for SCP to signal it's ready */ + return scpi_wait_ready(); +} diff --git a/plat/gxb/scp_bootloader.h b/plat/gxb/scp_bootloader.h new file mode 100644 index 0000000..e872513 --- /dev/null +++ b/plat/gxb/scp_bootloader.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __SCP_BOOTLOADER_H__ +#define __SCP_BOOTLOADER_H__ + +int scp_bootloader_transfer(void *image, unsigned int image_size); + +#endif diff --git a/plat/gxb/scpi.c b/plat/gxb/scpi.c new file mode 100644 index 0000000..07f1f66 --- /dev/null +++ b/plat/gxb/scpi.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <platform.h> +#include "plat_def.h" +#include "mhu.h" +#include "scpi.h" + +#define MHU_SECURE_SCP_TO_AP_PAYLOAD (MHU_SECURE_BASE+0x0080) +#define MHU_SECURE_AP_TO_SCP_PAYLOAD (MHU_SECURE_BASE+0x0280) + +#define SIZE_SHIFT 20 /* Bit position for size value in MHU header */ +#define SIZE_MASK 0x1ff /* Mask to extract size value in MHU header*/ + + +void *scpi_secure_message_start(void) +{ + mhu_secure_message_start(); + + /* Return address of payload area. */ + return (void *)MHU_SECURE_AP_TO_SCP_PAYLOAD; +} + +void scpi_secure_message_send(unsigned command, size_t size) +{ + /* Make sure payload can be seen by SCP */ + if (MHU_PAYLOAD_CACHED) + flush_dcache_range(MHU_SECURE_AP_TO_SCP_PAYLOAD, size); + + mhu_secure_message_send(command | (size << SIZE_SHIFT)); +} + +unsigned scpi_secure_message_receive(void **message_out, size_t *size_out) +{ + uint32_t response = mhu_secure_message_wait(); + + /* Get size of payload */ + size_t size = (response >> SIZE_SHIFT) & SIZE_MASK; + + /* Clear size from response */ + response &= ~(SIZE_MASK << SIZE_SHIFT); + + /* Make sure we don't read stale data */ + if (MHU_PAYLOAD_CACHED) + inv_dcache_range(MHU_SECURE_SCP_TO_AP_PAYLOAD, size); + + if (size_out) + *size_out = size; + + if (message_out) + *message_out = (void *)MHU_SECURE_SCP_TO_AP_PAYLOAD; + + return response; +} + +void scpi_secure_message_end(void) +{ + mhu_secure_message_end(); +} + +static void scpi_secure_send32(unsigned command, uint32_t message) +{ + *(__typeof__(message) *)scpi_secure_message_start() = message; + scpi_secure_message_send(command, sizeof(message)); + scpi_secure_message_end(); +} + +int scpi_wait_ready(void) + { + /* Get a message from the SCP */ + scpi_secure_message_start(); + size_t size; + unsigned command = scpi_secure_message_receive(NULL, &size); + scpi_secure_message_end(); + + /* We are expecting 'SCP Ready', produce correct error if it's not */ + spci_status response = SCP_OK; + if (command != SCPI_CMD_SCP_READY) + response = SCP_E_SUPPORT; + else if (size != 0) + response = SCP_E_SIZE; + + /* Send our response back to SCP */ + scpi_secure_send32(command, response); + + return response == SCP_OK ? 0 : -1; + } + +void scpi_set_css_power_state(unsigned mpidr, scpi_power_state cpu_state, + scpi_power_state cluster_state, scpi_power_state css_state) +{ + uint32_t state = mpidr & 0x0f; /* CPU ID */ + state |= (mpidr & 0xf00) >> 4; /* Cluster ID */ + state |= cpu_state << 8; + state |= cluster_state << 12; + state |= css_state << 16; + scpi_secure_send32(SCPI_CMD_SET_CSS_POWER_STATE, state); +} diff --git a/plat/gxb/scpi.h b/plat/gxb/scpi.h new file mode 100644 index 0000000..4ddbeea --- /dev/null +++ b/plat/gxb/scpi.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __SCPI_H__ +#define __SCPI_H__ + +#include <stddef.h> +#include <stdint.h> + +extern void *scpi_secure_message_start(void); +extern void scpi_secure_message_send(unsigned command, size_t size); +extern unsigned scpi_secure_message_receive(void ** message_out, size_t *size_out); +extern void scpi_secure_message_end(void); + + +enum { + SCP_OK = 0, /* Success */ + SCP_E_PARAM, /* Invalid parameter(s) */ + SCP_E_ALIGN, /* Invalid alignment */ + SCP_E_SIZE, /* Invalid size */ + SCP_E_HANDLER, /* Invalid handler or callback */ + SCP_E_ACCESS, /* Invalid access or permission denied */ + SCP_E_RANGE, /* Value out of range */ + SCP_E_TIMEOUT, /* Time out has ocurred */ + SCP_E_NOMEM, /* Invalid memory area or pointer */ + SCP_E_PWRSTATE, /* Invalid power state */ + SCP_E_SUPPORT, /* Feature not supported or disabled */ +}; + +typedef uint32_t spci_status; + +typedef enum { + SCPI_CMD_SCP_READY = 0x01, + SCPI_CMD_SET_CSS_POWER_STATE = 0x04, +} spci_command; + +typedef enum { + scpi_power_on = 0, + scpi_power_retention = 1, + scpi_power_off = 3, +} scpi_power_state; + +extern int scpi_wait_ready(void); +extern void scpi_set_css_power_state(unsigned mpidr, scpi_power_state cpu_state, + scpi_power_state cluster_state, scpi_power_state css_state); + +#endif /* __SCPI_H__ */ diff --git a/plat/gxb/sha2.c b/plat/gxb/sha2.c new file mode 100644 index 0000000..0ccf5bd --- /dev/null +++ b/plat/gxb/sha2.c @@ -0,0 +1,416 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/sha2.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <stdio.h> +#include <asm/arch/romboot.h> +#include <string.h> +#include <io.h> +#include <platform_def.h> +#include <sha2.h> +#include <asm/arch/secure_apb.h> +#include <ndma_utils.h> + +#define CONFIG_AML_SHA2_HW_DMA + +static sha2_ctx *cur_ctx; +static void hw_init(uint32_t is224) +{ + uint32_t i, tmp; + uint32_t state[10]; + if (is224 == 0) { + /* SHA-256 */ + state[7] = 0x6A09E667; + state[6] = 0xBB67AE85; + state[5] = 0x3C6EF372; + state[4] = 0xA54FF53A; + state[3] = 0x510E527F; + state[2] = 0x9B05688C; + state[1] = 0x1F83D9AB; + state[0] = 0x5BE0CD19; + } + else { + /* SHA-224 */ + state[7] = 0xC1059ED8; + state[6] = 0x367CD507; + state[5] = 0x3070DD17; + state[4] = 0xF70E5939; + state[3] = 0xFFC00B31; + state[2] = 0x68581511; + state[1] = 0x64F98FA7; + state[0] = 0xBEFA4FA4; + } + + state[8] = 0; + state[9] = 0; + + tmp = readl(SEC_SEC_BLKMV_GEN_REG0); + tmp &= ~((3 << 12) | (0xf << 8) | (0xf << 4)); + tmp |= (1 << 12) | (0xa << 8) | (4 << 4); + writel(tmp, (int *)SEC_SEC_BLKMV_GEN_REG0); + + writel((0 << 21) | // last wdata + (0 << 20) | // last block + (3 << 18) | // byte transfer count + ((is224 ? 3 : 2) << 16) | // SHA mode + (0 << 12) | // out endian + (0 << 8) | // in endian + (0 << 4) | // + (0 << 4) | // + (1 << 3) | // enable + (0 << 2) | // + (0 << 1) | // + (1 << 0), // enable SHA PIO data engine + SEC_SEC_BLKMV_SHA_CONTROL); + + // sha=5 + writel((1 << 4) | 5, SEC_SEC_BLKMV_PIO_CNTL0); + while (((readl(SEC_SEC_BLKMV_PIO_CNTL0) >> 31) & 1) == 0) + ; + + // initial + for (i = 0; i < 10; i++) + writel(state[i], (long)(SEC_SEC_BLKMV_PIO_DATA0 + i * 4)); +} + +static void hw_update(const uint8_t *input, uint32_t ilen, uint8_t last_update) +{ + uint32_t bytes, left, tmp; + uint32_t *p; + + if (!last_update && (ilen % 64)) { + serial_puts("Err:sha\n"); + // sha2 usage problem + return; + } + + // block + p = (uint32_t *)input; + while (ilen > 0) { + if (ilen >= 64) { + bytes = 64; + ilen -= 64; + } + else { + bytes = ilen; + ilen = 0; + } + + while (bytes > 0) { + if (bytes >= 4) { + left = 4; + bytes -= 4; + } + else { + left = bytes; + bytes = 0; + } + + if (left < 4) { // last write, last block + tmp = readl(SEC_SEC_BLKMV_SHA_CONTROL); + tmp &= ~(0xf << 18); + tmp |= ((left - 1) << 18) | (3 << 20); + writel(tmp, SEC_SEC_BLKMV_SHA_CONTROL); + } + else if (bytes == 0) { // last write, + tmp = readl(SEC_SEC_BLKMV_SHA_CONTROL); + tmp &= ~(3 << 20); + tmp |= (1 << 21); + + if (last_update && ilen == 0) + tmp |= (1 << 20); // last block + + writel(tmp, SEC_SEC_BLKMV_SHA_CONTROL); + } + + writel(*p++, SEC_SEC_BLKMV_SHA_PIO_WDATA); + + if (bytes == 0) { + while ((readl(SEC_SEC_BLKMV_SHA_CONTROL) >> 31) & 1) + ; + + tmp = readl(SEC_SEC_BLKMV_SHA_CONTROL); + tmp &= ~(3 << 20); + tmp |= (1 << 22); + writel(tmp, SEC_SEC_BLKMV_SHA_CONTROL); + } + } + } +} + +static void hw_final(uint8_t output[32]) +{ + uint32_t *p; + uint32_t i; + setbits_le32(SEC_SEC_BLKMV_PIO_CNTL0, 1 << 6); + clrbits_le32(SEC_SEC_BLKMV_PIO_CNTL0, 1 << 6); + + for (p = (uint32_t *)(output), i = 0; i < 8; i++) + *p++ = readl((long)(SEC_SEC_BLKMV_PIO_DATA0 + i * 4)); +} + +/** + * SHA-2 Family Hash Init + * + * @param ctx context + * @param digest_len digest length in bits (224 or 256) + */ +void SHA2_HW_init(sha2_ctx *ctx, uint32_t digest_len) +{ + if (cur_ctx != NULL) { + serial_puts("Err:sha\n"); + // sha2 usage problem + return; + } + cur_ctx = ctx; + + hw_init(digest_len == 224); + + ctx->len = 0; +} + +/** + * SHA-2 Family Hash Update + */ +void SHA2_HW_update(sha2_ctx *ctx, const uint8_t *data, uint32_t len) +{ + unsigned int fill_len, data_len, rem_len,offset; + + if (cur_ctx != ctx) { + serial_puts("Err:sha\n"); + // sha2 usage problem + return; + } + /* This method updates the hash for the input data in blocks, except the last + * partial|full block, which is saved in ctx->block. The last partial|full + * block will be added to the hash in SHA2_final. + */ + data_len = len; + offset = 0; + /* fill saved block from beginning of input data */ + if (ctx->len) { + fill_len = SHA256_BLOCK_SIZE - ctx->len; + memcpy(&ctx->block[ctx->len], data, fill_len); + data_len -= fill_len; + offset = fill_len; + ctx->len += fill_len; + } + if (ctx->len == SHA256_BLOCK_SIZE && data_len > 0) { + /* saved block is full and is not last block, hash it */ + hw_update(ctx->block, SHA256_BLOCK_SIZE, 0); + ctx->len = 0; + } + if (data_len > SHA256_BLOCK_SIZE) { + /* still have more than 1 block. hash up until last [partial|full] block */ + rem_len = data_len % SHA256_BLOCK_SIZE; + if (rem_len == 0) { + rem_len = SHA256_BLOCK_SIZE; + } + + data_len -= rem_len; + hw_update(&data[offset], data_len, 0); + offset += data_len; + } else { + rem_len = data_len; + } + + if (rem_len) { + /* save the remaining data */ + memcpy(ctx->block, &data[offset], rem_len); + ctx->len = rem_len; + } +} + +/** + * SHA-2 Family Hash Update + * + * Returns pointer to ctx->buf containing hash. + */ +uint8_t *SHA2_HW_final(sha2_ctx *ctx) +{ + if (cur_ctx != ctx) { + serial_puts("Err:sha\n"); + // sha2 usage problem + return ctx->buf; + } + if (ctx->len == 0 || ctx->len > SHA256_BLOCK_SIZE) { + serial_puts("Err:sha\n"); + // internal sha2 problem + return ctx->buf; + } + hw_update(ctx->block, ctx->len, 1); + hw_final(ctx->buf); + cur_ctx = NULL; + return ctx->buf; +} + +#if defined(CONFIG_AML_SHA2_HW_DMA) +#define THREAD1_TABLE_LOC 0x5510000 +#define SHA_Wr(addr, data) *(volatile uint32_t *)(addr)=(data) +#define SHA_Rd(addr) *(volatile uint32_t *)(addr) +#define SEC_ALLOWED_MASK 0xa // thread 3 and thread 1 are allowed non-secure +int g_n_sha_Start_flag = 0; +int g_n_sha_thread_num = 0; +#endif + +void SHA2_init(sha2_ctx *ctx, unsigned int digest_len) +{ +#if defined(CONFIG_AML_SHA2_HW_DMA) + + unsigned int sha2_256_msg_in[8] = { + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + + g_n_sha_thread_num = 0; //fixed SHA2 with thread 0 + + + // Setup secure and non-secure transfers + // Also set up the general readback of crypto outputs to the SHA engine + // assign sec_allowed_mask = sec_gen_reg0[11:8]; + // wire [1:0] sec_read_sel = sec_gen_reg0[13:12]; + SHA_Wr(SEC_SEC_BLKMV_GEN_REG0, ((SHA_Rd(SEC_SEC_BLKMV_GEN_REG0) & ~((0x3 << 12) | (0xf << 8))) | (1 << 12) | (SEC_ALLOWED_MASK << 8)) ); + // Allow secure DDR tranfers for the Secure domains + // wire [3:0] sec_ddr_sec_id_en = sec_gen_reg0[7:4]; // Even though a thread is secure, we may not want it to use the DDR secure ID (just in case); + SHA_Wr(SEC_SEC_BLKMV_GEN_REG0, ((SHA_Rd(SEC_SEC_BLKMV_GEN_REG0) & ~(0xf << 4)) | (0x4 << 4)) ); // only thread 2 can issue Secure transfers + + // Enable the SHA engine + // wire sec_sha_dma_enable = sec_sha_control[3]; + SHA_Wr( SEC_SEC_BLKMV_SHA_CONTROL, SHA_Rd(SEC_SEC_BLKMV_SHA_CONTROL) | (1 << 3) ); + + // For DMA modes, pretend there is a PIO request for the AES (not SHA) + // reg pio_granted; // pio_control[31]; + // wire pio_hold_all = pio_control[5]; // set to 1 to block all in-line processing regardless of the PIO being used + // wire pio_request = pio_control[4]; + // wire [2:0] pio_inline_type = pio_control[2:0]; + SHA_Wr( SEC_SEC_BLKMV_PIO_CNTL0, (SHA_Rd(SEC_SEC_BLKMV_PIO_CNTL0) & ~((1 << 4) | (0x7 << 0))) | ((1 << 4) | (4 << 0)) ); // Request for AES + + // + // Write the initial message and datatlen + // + // initial the internal CPU fifo write counter for the save/restore engine + // wire sec_sha_cpu_save_init = sec_sha_control[6]; // Pulsed + // wire [1:0] sec_sha_thread = sec_sha_control[5:4]; + SHA_Wr( SEC_SEC_BLKMV_SHA_CONTROL, (SHA_Rd(SEC_SEC_BLKMV_SHA_CONTROL) & ~(3 << 4)) | (1 << 6) | (g_n_sha_thread_num << 4) ); // pulse bit (init cpu counters) + SHA_Wr( SEC_SEC_BLKMV_SHA_DMA_MSG_IN, sha2_256_msg_in[7] ); + SHA_Wr( SEC_SEC_BLKMV_SHA_DMA_MSG_IN, sha2_256_msg_in[6] ); + SHA_Wr( SEC_SEC_BLKMV_SHA_DMA_MSG_IN, sha2_256_msg_in[5] ); + SHA_Wr( SEC_SEC_BLKMV_SHA_DMA_MSG_IN, sha2_256_msg_in[4] ); + SHA_Wr( SEC_SEC_BLKMV_SHA_DMA_MSG_IN, sha2_256_msg_in[3] ); + SHA_Wr( SEC_SEC_BLKMV_SHA_DMA_MSG_IN, sha2_256_msg_in[2] ); + SHA_Wr( SEC_SEC_BLKMV_SHA_DMA_MSG_IN, sha2_256_msg_in[1] ); + SHA_Wr( SEC_SEC_BLKMV_SHA_DMA_MSG_IN, sha2_256_msg_in[0] ); + SHA_Wr( SEC_SEC_BLKMV_SHA_DMA_DATALEN_IN, 0 ); + SHA_Wr( SEC_SEC_BLKMV_SHA_DMA_DATALEN_IN, 0 ); + + memset((void*)THREAD1_TABLE_LOC,0,10*32); + + NDMA_set_table_position_secure( g_n_sha_thread_num, THREAD1_TABLE_LOC, THREAD1_TABLE_LOC + (10*32) ); // 2 thread entries + g_n_sha_Start_flag = 0; +#else + SHA2_HW_init(ctx, digest_len); +#endif +} + +void SHA2_update(sha2_ctx *ctx, const unsigned char *data, unsigned int len) +{ + +#if defined(CONFIG_AML_SHA2_HW_DMA) + + if (!len) + return; + + NDMA_add_descriptor_sha( g_n_sha_thread_num, // uint32_t thread_num, + 1, // uint32_t irq, + 2, // uint32_t sha_mode, // 1:sha1;2:sha2-256;3:sha2_224 + 0, // uint32_t pre_endian, + len, // uint32_t bytes_to_move, + (uint32_t)(unsigned long)data, // uint32_t src_addr, + 0 ); // uint32_t last_block, + if (!g_n_sha_Start_flag) + { + NDMA_start(g_n_sha_thread_num); + g_n_sha_Start_flag = 1; + } +#else + SHA2_HW_update(ctx, data, len); +#endif +} + +void SHA2_final(sha2_ctx *ctx,const unsigned char *data, unsigned int len) +{ +#if defined(CONFIG_AML_SHA2_HW_DMA) + unsigned int *pOUT = (unsigned int *)(unsigned char *)ctx->buf; + + NDMA_add_descriptor_sha( g_n_sha_thread_num, // uint32_t thread_num, + 1, // uint32_t irq, + 2, // uint32_t sha_mode, // 1:sha1;2:sha2-256;3:sha2_224 + 0, // uint32_t pre_endian, + len, // uint32_t bytes_to_move, + (uint32_t)(unsigned long)data, // uint32_t src_addr, + 1 ); // uint32_t last_block, + + if (!g_n_sha_Start_flag) + { + NDMA_start(g_n_sha_thread_num); + g_n_sha_Start_flag = 1; + } + + NDMA_wait_for_completion(g_n_sha_thread_num); + NDMA_stop(g_n_sha_thread_num); + g_n_sha_Start_flag = 0; + + pOUT[0] = SHA_Rd(SEC_SEC_BLKMV_PIO_DATA0); + pOUT[1] = SHA_Rd(SEC_SEC_BLKMV_PIO_DATA1); + pOUT[2] = SHA_Rd(SEC_SEC_BLKMV_PIO_DATA2); + pOUT[3] = SHA_Rd(SEC_SEC_BLKMV_PIO_DATA3); + pOUT[4] = SHA_Rd(SEC_SEC_BLKMV_PIO_DATA4); + pOUT[5] = SHA_Rd(SEC_SEC_BLKMV_PIO_DATA5); + pOUT[6] = SHA_Rd(SEC_SEC_BLKMV_PIO_DATA6); + pOUT[7] = SHA_Rd(SEC_SEC_BLKMV_PIO_DATA7); + +#else + SHA2_HW_update(ctx, data, len); + SHA2_HW_final(ctx); +#endif + +} + + +void sha2(const uint8_t *input, unsigned int ilen, unsigned char output[32], unsigned int is224) +{ + sha2_ctx sha_ctx; + unsigned long nSRCAddr = (unsigned long)input; + + if (((nSRCAddr >> 24) & (0xFF)) == 0xD9) + { + //serial_puts("aml log : PIO SHA\n"); + SHA2_HW_init(&sha_ctx, is224 ? 224: 256); + SHA2_HW_update(&sha_ctx, input, ilen); + SHA2_HW_final(&sha_ctx); + + } + else + { + //serial_puts("aml log : DMA SHA\n"); + SHA2_init( &sha_ctx, is224 ? 224: 256); + SHA2_final( &sha_ctx, input,ilen); + } + memcpy(output,sha_ctx.buf,32); +} diff --git a/plat/gxb/smc_arm.c b/plat/gxb/smc_arm.c new file mode 100644 index 0000000..c6b3c9b --- /dev/null +++ b/plat/gxb/smc_arm.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <psci.h> +#include <runtime_svc.h> + +#define ARM_SMC_ARM_CPU_SUSPEND 0x80100001 +#define ARM_SMC_ARM_CPU_OFF 0x80100002 +#define ARM_SMC_ARM_CPU_ON 0x80100003 +#define ARM_SMC_ARM_MIGRATE 0x80100004 + +#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_PRESENCE 0x80FFFF00 +#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_UID 0x80FFFF10 + +#define ARM_TRUSTZONE_UID_4LETTERID 0x1 +#define ARM_TRUSTZONE_ARM_UID 0x40524d48 /* "ARMH" */ + + +static uint64_t smc_arm_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, + uint64_t x3, uint64_t x4, void *cookie, + void *handle, uint64_t flags) +{ + switch (smc_fid) { + + /* + * HACK WARNING: Below we use SMC_RET4 to return the original contents + * of x1-x3. We do this because UEFI is expecting these values to be + * preserved across the SMC call. + */ + + case ARM_TRUSTZONE_ARM_FAST_SMC_ID_PRESENCE: + SMC_RET4(handle, 1, x1, x2, x3); + break; + + case ARM_TRUSTZONE_ARM_FAST_SMC_ID_UID + 0: + SMC_RET4(handle, ARM_TRUSTZONE_UID_4LETTERID, x1, x2, x3); + break; + + case ARM_TRUSTZONE_ARM_FAST_SMC_ID_UID + 1: + SMC_RET4(handle, ARM_TRUSTZONE_ARM_UID, x1, x2, x3); + break; + + /* The following 3 cases translate functions into the PSCI equivalent */ + + case ARM_SMC_ARM_CPU_OFF: + smc_fid = PSCI_CPU_OFF; + break; + + case ARM_SMC_ARM_CPU_SUSPEND: + smc_fid = PSCI_CPU_SUSPEND_AARCH64; + break; + + case ARM_SMC_ARM_CPU_ON: + smc_fid = PSCI_CPU_ON_AARCH64; + break; + + } + + return psci_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); +} + +static int32_t smc_arm_setup(void) +{ + return 0; +} + +DECLARE_RT_SVC(arm, OEN_ARM_START, OEN_ARM_END, SMC_TYPE_FAST, + smc_arm_setup, smc_arm_handler); diff --git a/plat/gxb/storage.c b/plat/gxb/storage.c new file mode 100644 index 0000000..2227b70 --- /dev/null +++ b/plat/gxb/storage.c @@ -0,0 +1,497 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/storage.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <arch_helpers.h> +#include <stdio.h> +#include <stdint.h> +#include <asm/arch/romboot.h> +#include <string.h> +#include <io.h> +#include <platform_def.h> +#include <storage.h> +#include <asm/arch/io.h> +#include <asm/arch/secure_apb.h> +#include <asm/arch/cpu_sdio.h> +#include <asm/arch/nand.h> +#include <fip.h> +#include <asm/arch/watchdog.h> + +void dump_ddr_data(void) +{ +#ifdef CONFIG_SPL_DDR_DUMP + if (CONFIG_SPL_DDR_DUMP_FLAG == readl(P_PREG_STICKY_REG0)) { + serial_puts("Dump ddr[0x"); + serial_put_hex(CONFIG_SPL_DDR_DUMP_ADDR, 32); + serial_puts("-0x"); + serial_put_hex((CONFIG_SPL_DDR_DUMP_ADDR+CONFIG_SPL_DDR_DUMP_SIZE), 32); + serial_puts("] to "); + serial_puts((CONFIG_SPL_DDR_DUMP_DEV_TYPE==BOOT_DEVICE_SD)?"External":"Internal"); + serial_puts(" device[0x"); + serial_put_hex(CONFIG_SPL_DDR_DUMP_DEV_OFFSET, 32); + serial_puts("-0x"); + serial_put_hex((CONFIG_SPL_DDR_DUMP_DEV_OFFSET+CONFIG_SPL_DDR_DUMP_SIZE), 32); + serial_puts("]\n\n"); + + writel(0, P_PREG_STICKY_REG0); + watchdog_disable(); + sdio_write_data(CONFIG_SPL_DDR_DUMP_DEV_TYPE, CONFIG_SPL_DDR_DUMP_ADDR, \ + CONFIG_SPL_DDR_DUMP_DEV_OFFSET, CONFIG_SPL_DDR_DUMP_SIZE); + reset_system(); + } +#endif + return; +} + +uint64_t storage_init(void) +{ + uint64_t boot_device = 0; + boot_device = get_boot_device(); + switch (boot_device) { +#if defined(CONFIG_AML_NAND) + case BOOT_DEVICE_NAND: + serial_puts( "NAND init\n"); + nfio_init(); + break; +#endif //CONFIG_AML_NAND + default: + //serial_puts("do nothing!\n"); + break; + } + return 0; +} +uint64_t storage_load(uint64_t src, uint64_t des, uint64_t size, const char * image_name) +{ + char * device_name = "UNKNOWN"; + uint64_t boot_device = 0; + + boot_device = get_boot_device(); + //boot_device = BOOT_DEVICE_SPI; + switch (boot_device) { + case BOOT_DEVICE_RESERVED: + device_name = "Rsv"; + break; + case BOOT_DEVICE_EMMC: + device_name = "eMMC"; + break; +#if defined(CONFIG_AML_NAND) + case BOOT_DEVICE_NAND: + device_name = "NAND"; + break; +#endif //CONFIG_AML_NAND + case BOOT_DEVICE_SPI: + device_name = "SPI"; + break; + case BOOT_DEVICE_SD: + device_name = "SD"; + src += 512; //sd boot must add 512 offset + break; + case BOOT_DEVICE_USB: + case BOOT_DEVICE_USB_FORCEMODE: + device_name = "USB"; + break; + default: + break; + } + //printf("Load %s from %s, src: 0x%x, dst: 0x%x, size: 0x%x\n", + // image_name, device_name, src, des, size); + serial_puts("Load "); + serial_puts(image_name); + serial_puts(" from "); + serial_puts(device_name); + serial_puts(", src: 0x"); + serial_put_hex(src, 32); + serial_puts(", des: 0x"); + serial_put_hex(des, 32); + serial_puts(", size: 0x"); + serial_put_hex(size, 32); + serial_puts("\n"); + switch (boot_device) { + case BOOT_DEVICE_RESERVED: + break; + case BOOT_DEVICE_EMMC: + sdio_read_data(boot_device,src, des, size); + break; +#if defined(CONFIG_AML_NAND) + case BOOT_DEVICE_NAND: + nf_read(boot_device, src, des, size); + break; +#endif //CONFIG_AML_NAND + case BOOT_DEVICE_SPI: + spi_read(src, des, size); + break; + case BOOT_DEVICE_SD: + sdio_read_data(boot_device, src, des, size); + break; + case BOOT_DEVICE_USB: + case BOOT_DEVICE_USB_FORCEMODE: + usb_boot(src, des, size); + break; + default: + break; + } +#ifdef BL2_ENABLE_MMU + inv_dcache_range(des, size); +#endif + return 0; +} + +uint64_t spi_read(uint64_t src, uint64_t des, uint64_t size) +{ + /*spi pin mux*/ + *P_PAD_PULL_UP_EN_REG2 = 0xffff87ff; + *P_PAD_PULL_UP_REG2 = 0xffff8700; + // deselect nand/emmc, select spi. + *P_PERIPHS_PIN_MUX_4 &= ~((1<<31) | (7<<22) | (1<<20)); + *P_PERIPHS_PIN_MUX_5 |= 0xf; + + /*spi init*/ + /* use sys_clock_freq: 0x002ab000 //24:0x002ab313 + * use sys_clock_freq/2: 0x002aa101 + * use sys_clock_freq/4: 0x002aa313 + * use sys_clock_freq/8: 0x002aa737 + * use sys_clock_freq/10: 0x002aa949 + * use sys_clock_freq/16: 0x002aaf7f + */ +#ifndef CONFIG_PXP_EMULATOR + writel(0x2aa949,P_SPI_FLASH_CTRL); +#else + writel(0x002ab000,P_SPI_FLASH_CTRL); +#endif + + /*load data*/ + uint64_t des64, src64; + des64 = des; + src64 = src; + memcpy((void *)des64, (void *)(src64 | (uint64_t)P_SPI_START_ADDR), size); + return 0; +} + +uint64_t sdio_read_blocks(struct sd_emmc_global_regs *sd_emmc_regs, + uint64_t src, uint64_t des, uint64_t size, uint64_t mode) +{ + unsigned ret = 0; + unsigned read_start; + unsigned vstart = 0; + unsigned status_irq = 0; + unsigned response[4]; + struct cmd_cfg *des_cmd_cur = NULL; + struct sd_emmc_desc_info desc[MAX_DESC_NUM]; + struct sd_emmc_desc_info *desc_cur; + struct sd_emmc_start *desc_start = (struct sd_emmc_start*)&vstart; + struct sd_emmc_status *status_irq_reg = (void *)&status_irq; + + memset(desc,0,MAX_DESC_NUM*sizeof(struct sd_emmc_desc_info)); + desc_cur = desc; + + if (mode) + read_start = src>>9; + else + read_start = src; + + des_cmd_cur = (struct cmd_cfg *)&(desc_cur->cmd_info); + //starting reading...... + des_cmd_cur->cmd_index = 18; //read data command + if (mode) { + des_cmd_cur->block_mode = 1; + des_cmd_cur->length = size; + }else{ + des_cmd_cur->block_mode = 0; + des_cmd_cur->length = size; + } + + des_cmd_cur->data_io = 1; + des_cmd_cur->data_wr = 0; + des_cmd_cur->data_num = 0; + des_cmd_cur->no_resp = 0; + des_cmd_cur->resp_num = 0; + des_cmd_cur->timeout = 7; + des_cmd_cur->owner = 1; + des_cmd_cur->end_of_chain = 1; + + desc_cur->cmd_arg = read_start; + desc_cur->data_addr = des; + desc_cur->data_addr &= ~(1<<0); //DDR + desc_cur->resp_addr = (unsigned long)response; + + desc_start->init = 0; + desc_start->busy = 1; + desc_start->addr = (unsigned long)desc >> 2; + sd_emmc_regs->gstatus = 0x3fff; + //sd_emmc_regs->gstart = vstart; + sd_emmc_regs->gcmd_cfg = desc_cur->cmd_info; + sd_emmc_regs->gcmd_dat = desc_cur->data_addr; + sd_emmc_regs->gcmd_arg = desc_cur->cmd_arg; + + + while (1) { + status_irq = sd_emmc_regs->gstatus; + if (status_irq_reg->end_of_chain) + break; + } + //send stop cmd + desc_cur = &desc[1]; + des_cmd_cur = (struct cmd_cfg *)&(desc_cur->cmd_info); + des_cmd_cur->cmd_index = 12; + des_cmd_cur->data_io = 0; + des_cmd_cur->no_resp = 0; + des_cmd_cur->r1b = 1; + des_cmd_cur->owner = 1; + des_cmd_cur->end_of_chain = 1; + + desc_start->init = 0; + desc_start->busy = 1; + desc_start->addr = (unsigned long)desc_cur >> 2; + sd_emmc_regs->gstatus = 0x3fff; + //sd_emmc_regs->gstart = vstart; + sd_emmc_regs->gcmd_cfg = desc_cur->cmd_info; + sd_emmc_regs->gcmd_dat = desc_cur->data_addr; + sd_emmc_regs->gcmd_arg = desc_cur->cmd_arg; + + while (1) { + status_irq = sd_emmc_regs->gstatus; + //printf("status_irq=0x%x\n",status_irq); + if (status_irq_reg->end_of_chain) + break; + } + + if (status_irq_reg->rxd_err) + ret |= SD_EMMC_RXD_ERROR; + if (status_irq_reg->txd_err) + ret |= SD_EMMC_TXD_ERROR; + if (status_irq_reg->desc_err) + ret |= SD_EMMC_DESC_ERROR; + if (status_irq_reg->resp_err) + ret |= SD_EMMC_RESP_CRC_ERROR; + if (status_irq_reg->resp_timeout) + ret |= SD_EMMC_RESP_TIMEOUT_ERROR; + if (status_irq_reg->desc_timeout) + ret |= SD_EMMC_DESC_TIMEOUT_ERROR; + if (ret) { + serial_puts("sd/emmc read data error: ret="); + serial_put_dec(ret); + serial_puts("\n"); + } + //else + //serial_puts("read data success!\n"); + return ret; +} + +#ifdef CONFIG_SPL_DDR_DUMP +uint64_t sdio_write_blocks(struct sd_emmc_global_regs *sd_emmc_regs, + uint64_t src, uint64_t des, uint64_t size, uint64_t mode) +{ + unsigned ret = 0; + unsigned write_start; + unsigned vstart = 0; + unsigned status_irq = 0; + unsigned response[4]; + struct cmd_cfg *des_cmd_cur = NULL; + struct sd_emmc_desc_info desc[MAX_DESC_NUM]; + struct sd_emmc_desc_info *desc_cur; + struct sd_emmc_start *desc_start = (struct sd_emmc_start*)&vstart; + struct sd_emmc_status *status_irq_reg = (void *)&status_irq; + + memset(desc,0,MAX_DESC_NUM*sizeof(struct sd_emmc_desc_info)); + desc_cur = desc; + + if (mode) + write_start = des>>9; + else + write_start = des; + + des_cmd_cur = (struct cmd_cfg *)&(desc_cur->cmd_info); + //starting reading...... + des_cmd_cur->cmd_index = 25; //muti write data command + if (mode) { + des_cmd_cur->block_mode = 1; + des_cmd_cur->length = size; + }else{ + des_cmd_cur->block_mode = 0; + des_cmd_cur->length = size; + } + + des_cmd_cur->data_io = 1; + des_cmd_cur->data_wr = 1; + des_cmd_cur->data_num = 0; + des_cmd_cur->no_resp = 0; + des_cmd_cur->resp_num = 0; + des_cmd_cur->timeout = 7; + des_cmd_cur->owner = 1; + des_cmd_cur->end_of_chain = 1; + + desc_cur->cmd_arg = write_start; + desc_cur->data_addr = src; + desc_cur->data_addr &= ~(1<<0); //DDR + desc_cur->resp_addr = (unsigned long)response; + + desc_start->init = 0; + desc_start->busy = 1; + desc_start->addr = (unsigned long)desc >> 2; + sd_emmc_regs->gstatus = 0x3fff; + //sd_emmc_regs->gstart = vstart; + sd_emmc_regs->gcmd_cfg = desc_cur->cmd_info; + sd_emmc_regs->gcmd_dat = desc_cur->data_addr; + sd_emmc_regs->gcmd_arg = desc_cur->cmd_arg; + + + while (1) { + status_irq = sd_emmc_regs->gstatus; + if (status_irq_reg->end_of_chain) + break; + } + //send stop cmd + desc_cur = &desc[1]; + des_cmd_cur = (struct cmd_cfg *)&(desc_cur->cmd_info); + des_cmd_cur->cmd_index = 12; + des_cmd_cur->data_io = 0; + des_cmd_cur->no_resp = 0; + des_cmd_cur->r1b = 1; + des_cmd_cur->owner = 1; + des_cmd_cur->end_of_chain = 1; + + desc_start->init = 0; + desc_start->busy = 1; + desc_start->addr = (unsigned long)desc_cur >> 2; + sd_emmc_regs->gstatus = 0x3fff; + //sd_emmc_regs->gstart = vstart; + sd_emmc_regs->gcmd_cfg = desc_cur->cmd_info; + sd_emmc_regs->gcmd_dat = desc_cur->data_addr; + sd_emmc_regs->gcmd_arg = desc_cur->cmd_arg; + + while (1) { + status_irq = sd_emmc_regs->gstatus; + //printf("status_irq=0x%x\n",status_irq); + if (status_irq_reg->end_of_chain) + break; + } + + if (status_irq_reg->rxd_err) + ret |= SD_EMMC_RXD_ERROR; + if (status_irq_reg->txd_err) + ret |= SD_EMMC_TXD_ERROR; + if (status_irq_reg->desc_err) + ret |= SD_EMMC_DESC_ERROR; + if (status_irq_reg->resp_err) + ret |= SD_EMMC_RESP_CRC_ERROR; + if (status_irq_reg->resp_timeout) + ret |= SD_EMMC_RESP_TIMEOUT_ERROR; + if (status_irq_reg->desc_timeout) + ret |= SD_EMMC_DESC_TIMEOUT_ERROR; + if (ret) { + serial_puts("sd/emmc write data error: ret="); + serial_put_dec(ret); + serial_puts("\n"); + } + //else + //serial_puts("write data success!\n"); + return ret; +} +#endif // #ifdef CONFIG_SPL_DDR_DUMP + +uint64_t sdio_read_data(uint64_t boot_device, uint64_t src, uint64_t des, uint64_t size) +{ + unsigned mode,blk_cnt,ret; + struct sd_emmc_global_regs *sd_emmc_regs=0; + union sd_emmc_setup *s_setup = (union sd_emmc_setup *)SEC_AO_SEC_GP_CFG1; + + if (boot_device == BOOT_DEVICE_EMMC) + sd_emmc_regs = (struct sd_emmc_global_regs *)SD_EMMC_BASE_C; + else if(boot_device == BOOT_DEVICE_SD) + sd_emmc_regs = (struct sd_emmc_global_regs *)SD_EMMC_BASE_B; + else + serial_puts("sd/emmc boot device error\n"); + + mode = s_setup->b.sdhc | s_setup->b.hcs ? 1 : 0; + +#if 0 + if (mode) + serial_puts("sd/emmc is lba mode\n"); + else + serial_puts("sd/emmc is byte mode\n"); +#endif + + blk_cnt = ((size+511)&(~(511)))>>9; + do { + ret = sdio_read_blocks(sd_emmc_regs,src,des,(blk_cnt>MAX_BLOCK_COUNTS)?MAX_BLOCK_COUNTS:blk_cnt,mode); + if (ret) + return ret; + if (blk_cnt>MAX_BLOCK_COUNTS) { + src += MAX_BLOCK_COUNTS<<9; + des += MAX_BLOCK_COUNTS<<9; + blk_cnt -= MAX_BLOCK_COUNTS; + }else + break; + }while(1); + + return ret; +} + +#ifdef CONFIG_SPL_DDR_DUMP +uint64_t sdio_write_data(uint64_t boot_device, uint64_t src, uint64_t des, uint64_t size) +{ + unsigned mode,blk_cnt,ret; + struct sd_emmc_global_regs *sd_emmc_regs=0; + union sd_emmc_setup *s_setup = (union sd_emmc_setup *)SEC_AO_SEC_GP_CFG1; + + if (boot_device == BOOT_DEVICE_EMMC) + sd_emmc_regs = (struct sd_emmc_global_regs *)SD_EMMC_BASE_C; + else if(boot_device == BOOT_DEVICE_SD) + sd_emmc_regs = (struct sd_emmc_global_regs *)SD_EMMC_BASE_B; + else + serial_puts("sd/emmc boot device error\n"); + + mode = s_setup->b.sdhc | s_setup->b.hcs ? 1 : 0; + +#if 0 + if (mode) + serial_puts("sd/emmc is lba mode\n"); + else + serial_puts("sd/emmc is byte mode\n"); +#endif + + blk_cnt = ((size+511)&(~(511)))>>9; + do { + ret = sdio_write_blocks(sd_emmc_regs,src,des,(blk_cnt>MAX_BLOCK_COUNTS)?MAX_BLOCK_COUNTS:blk_cnt,mode); + if (ret) + return ret; + if (blk_cnt>MAX_BLOCK_COUNTS) { + src += MAX_BLOCK_COUNTS<<9; + des += MAX_BLOCK_COUNTS<<9; + blk_cnt -= MAX_BLOCK_COUNTS; + }else + break; + }while(1); + + return ret; +} +#endif // #ifdef CONFIG_SPL_DDR_DUMP + +uint64_t get_boot_device(void) { + const unsigned forceUsbRegVal = readl(SEC_AO_RTI_STATUS_REG3); + const unsigned forceUsbBootFlag = ( forceUsbRegVal>>12 ) & 0xF; + if ( 2 == forceUsbBootFlag) return BOOT_DEVICE_USB_FORCEMODE; + + return (readl(SEC_AO_SEC_GP_CFG0) & 0xf); +} + +uint64_t get_ddr_size(void) { + return ((readl(SEC_AO_SEC_GP_CFG0) >> 16) & 0xffff); +} diff --git a/plat/gxb/timer.c b/plat/gxb/timer.c new file mode 100644 index 0000000..e8f076d --- /dev/null +++ b/plat/gxb/timer.c @@ -0,0 +1,59 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/timer.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <io.h> +#include <stdio.h> +#include <asm/arch/romboot.h> +#include <timer.h> + +#define P_EE_TIMER_E P_ISA_TIMERE + +uint32_t time_start = 0; +uint32_t time_end = 0; + +uint32_t get_time(void) +{ + return readl(P_EE_TIMER_E); +} + +void _udelay(unsigned int us) +{ +#ifndef CONFIG_PXP_EMULATOR + uint32_t t0 = get_time(); + + while (get_time() - t0 <= us) + ; +#endif +} + +void timer_start(void) +{ + time_start = get_time(); +} + +void timer_end(const char * name) +{ + time_end = get_time(); + serial_puts(name); + serial_puts(" Time: "); + serial_put_dec(time_end - time_start); + serial_puts(" us\n"); +}
\ No newline at end of file diff --git a/plat/gxb/watchdog.c b/plat/gxb/watchdog.c new file mode 100644 index 0000000..e77e358 --- /dev/null +++ b/plat/gxb/watchdog.c @@ -0,0 +1,72 @@ + +/* + * arch/arm/cpu/armv8/common/firmware/plat/gxb/watchdog.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <stdint.h> +#include <asm/arch/romboot.h> +#include <asm/arch/watchdog.h> +#include <io.h> +#include <asm/arch/io.h> +#include <timer.h> + +void watchdog_init(uint32_t msec) +{ + // src: 24MHz + // div: 24000 for 1ms + // reset ao-22 and ee-21 + *P_WATCHDOG_CNTL = (1<<24)|(1<<25)|(1<<22)|(1<<21)|(24000-1); + + // set timeout + *P_WATCHDOG_TCNT = msec; + *P_WATCHDOG_RESET = 0; + + // enable + *P_WATCHDOG_CNTL |= (1<<18); +} + +void watchdog_reset(void) +{ + *P_WATCHDOG_RESET = 0; +} + +void watchdog_disable(void) +{ + // turn off internal counter and disable + *P_WATCHDOG_CNTL &= ~((1<<18)|(1<<25)); +} +void reset_system(void) +{ + int i; + _udelay(10000); //wait print + while (1) { + writel( 0x3 | (1 << 21) // sys reset en + | (1 << 23) // interrupt en + | (1 << 24) // clk en + | (1 << 25) // clk div en + | (1 << 26) // sys reset now + , P_WATCHDOG_CNTL); + writel(0, P_WATCHDOG_RESET); + + writel(readl(P_WATCHDOG_CNTL) | (1<<18), // watchdog en + P_WATCHDOG_CNTL); + for (i=0; i<100; i++) + readl(P_WATCHDOG_CNTL);/*Deceive gcc for waiting some cycles */ + } +} diff --git a/plat/juno/aarch64/bl1_plat_helpers.S b/plat/juno/aarch64/bl1_plat_helpers.S new file mode 100644 index 0000000..785aa15 --- /dev/null +++ b/plat/juno/aarch64/bl1_plat_helpers.S @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> +#include "../juno_def.h" + + .globl platform_get_entrypoint + .globl platform_cold_boot_init + .globl plat_secondary_cold_boot_setup + + + /* ----------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset e.g + * mark the cpu's presence, mechanism to place it in a + * holding pen etc. + * ----------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + /* Juno todo: Implement secondary CPU cold boot setup on Juno */ +cb_panic: + b cb_panic + + + /* ----------------------------------------------------- + * void platform_get_entrypoint (unsigned int mpid); + * + * Main job of this routine is to distinguish between + * a cold and warm boot. + * On a cold boot the secondaries first wait for the + * platform to be initialized after which they are + * hotplugged in. The primary proceeds to perform the + * platform initialization. + * On a warm boot, each cpu jumps to the address in its + * mailbox. + * + * TODO: Not a good idea to save lr in a temp reg + * ----------------------------------------------------- + */ +func platform_get_entrypoint + mov x9, x30 // lr + bl platform_get_core_pos + ldr x1, =TRUSTED_MAILBOXES_BASE + lsl x0, x0, #TRUSTED_MAILBOX_SHIFT + ldr x0, [x1, x0] + ret x9 + + + /* ----------------------------------------------------- + * void platform_cold_boot_init (bl1_main function); + * + * Routine called only by the primary cpu after a cold + * boot to perform early platform initialization + * ----------------------------------------------------- + */ +func platform_cold_boot_init + mov x20, x0 + + /* --------------------------------------------- + * Give ourselves a small coherent stack to + * ease the pain of initializing the MMU and + * CCI in assembler + * --------------------------------------------- + */ + mrs x0, mpidr_el1 + bl platform_set_coherent_stack + + /* --------------------------------------------- + * Architectural init. can be generic e.g. + * enabling stack alignment and platform spec- + * ific e.g. MMU & page table setup as per the + * platform memory map. Perform the latter here + * and the former in bl1_main. + * --------------------------------------------- + */ + bl bl1_early_platform_setup + bl bl1_plat_arch_setup + + /* --------------------------------------------- + * Give ourselves a stack allocated in Normal + * -IS-WBWA memory + * --------------------------------------------- + */ + mrs x0, mpidr_el1 + bl platform_set_stack + + /* --------------------------------------------- + * Jump to the main function. Returning from it + * is a terminal error. + * --------------------------------------------- + */ + blr x20 + +cb_init_panic: + b cb_init_panic diff --git a/plat/juno/aarch64/juno_common.c b/plat/juno/aarch64/juno_common.c new file mode 100644 index 0000000..1aaf189 --- /dev/null +++ b/plat/juno/aarch64/juno_common.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <mmio.h> +#include <platform.h> +#include <platform_def.h> +#include <xlat_tables.h> +#include "../juno_def.h" +#include <runtime_svc.h> +#include <arch_helpers.h> + +extern int console_puts(const char *s); +extern void console_put_hex(unsigned long data,unsigned int bitlen); + +/* + * Table of regions to map using the MMU. + * This doesn't include Trusted RAM as the 'mem_layout' argument passed to + * configure_mmu_elx() will give the available subset of that, + */ +static const mmap_region_t juno_mmap[] = { +#if 0 + { TZROM_BASE, TZROM_SIZE, MT_MEMORY | MT_RO | MT_SECURE }, + { MHU_SECURE_BASE, MHU_SECURE_SIZE, (MHU_PAYLOAD_CACHED ? MT_MEMORY : MT_DEVICE) + | MT_RW | MT_SECURE }, +// { TZRAM_BASE, TZRAM_SIZE, MT_MEMORY | MT_RW | MT_SECURE }, /* configure_mmu() meminfo arg sets subset of this */ + { FLASH_BASE, FLASH_SIZE, MT_MEMORY | MT_RO | MT_SECURE }, + { EMMC_BASE, EMMC_SIZE, MT_MEMORY | MT_RO | MT_SECURE }, + { PSRAM_BASE, PSRAM_SIZE, MT_MEMORY | MT_RW | MT_SECURE }, /* Used for 'TZDRAM' */ + { IOFPGA_BASE, IOFPGA_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, +// { NSROM_BASE, NSROM_SIZE, MT_MEMORY | MT_RW | MT_NS }, /* Eats a page table so leave it out for now */ + { DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, + { NSRAM_BASE, NSRAM_SIZE, MT_MEMORY | MT_RW | MT_NS }, + { DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, + { DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS }, +#endif + + { TZROM_BASE, TZROM_SIZE, MT_MEMORY | MT_RO | MT_SECURE }, + { DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS }, + { DEVICEG_BASE, DEVICEG_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, + + {0} +}; + +/******************************************************************************* + * Macro generating the code for the function setting up the pagetables as per + * the platform memory map & initialize the mmu, for the given exception level + ******************************************************************************/ +#define DEFINE_CONFIGURE_MMU_EL(_el) \ + void configure_mmu_el##_el(unsigned long total_base, \ + unsigned long total_size, \ + unsigned long ro_start, \ + unsigned long ro_limit, \ + unsigned long coh_start, \ + unsigned long coh_limit) \ + { \ + mmap_add_region(total_base, \ + total_size, \ + MT_MEMORY | MT_RW | MT_SECURE); \ + mmap_add_region(ro_start, ro_limit - ro_start, \ + MT_MEMORY | MT_RO | MT_SECURE); \ + mmap_add_region(coh_start, coh_limit - coh_start,\ + MT_DEVICE | MT_RW | MT_SECURE); \ + mmap_add(juno_mmap); \ + init_xlat_tables(); \ + \ + enable_mmu_el##_el(); \ + } + +/* Define EL1 and EL3 variants of the function initialising the MMU */ +DEFINE_CONFIGURE_MMU_EL(1) +DEFINE_CONFIGURE_MMU_EL(3) + + +unsigned long plat_get_ns_image_entrypoint(void) +{ + return NS_IMAGE_OFFSET; +} + +uint64_t plat_get_syscnt_freq(void) +{ + uint64_t counter_base_frequency; + + /* Read the frequency from Frequency modes table */ + counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF); + + /* The first entry of the frequency modes table must not be 0 */ + assert(counter_base_frequency != 0); + + return counter_base_frequency; +} + +void plat_report_exception(void){ + console_puts("Enter exception!\n"); + console_puts("Value: 0x"); + uint64_t esr_val = read_esr_el1(); + //__asm__ volatile("msr %0, esr_el1\n" : "=r"(esr_val)); + //__asm__ volatile("msr %0, esr_el1\n" :"=r"(esr_val)); + console_put_hex(esr_val, 32); + console_puts("\n"); + + /*never return*/ + while (1) ; +}
\ No newline at end of file diff --git a/plat/juno/aarch64/plat_helpers.S b/plat/juno/aarch64/plat_helpers.S new file mode 100644 index 0000000..c091b99 --- /dev/null +++ b/plat/juno/aarch64/plat_helpers.S @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> +#include <bl_common.h> +#include <platform_def.h> +#include "../juno_def.h" + + .globl platform_mem_init + + /* --------------------------------------------- + * void plat_report_exception(unsigned int type) + * Function to report an unhandled exception + * with platform-specific means. + * On Juno platform, it updates the LEDs + * to indicate where we are + * --------------------------------------------- + */ + + /* + * Return 0 to 3 for the A53s and 4 or 5 for the A57s + */ + .globl platform_get_core_pos +func platform_get_core_pos + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + eor x0, x0, #(1 << MPIDR_AFFINITY_BITS) // swap A53/A57 order + add x0, x1, x0, LSR #6 + ret + + + /* ----------------------------------------------------- + * void platform_is_primary_cpu (unsigned int mpid); + * + * Given the mpidr say whether this cpu is the primary + * cpu (applicable ony after a cold boot) + * ----------------------------------------------------- + */ + .globl platform_is_primary_cpu +func platform_is_primary_cpu + /* Warning: this function is called without a valid stack */ + /* Juno todo: allow configuration of primary CPU using SCC */ + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, #PRIMARY_CPU + cset x0, eq + ret + + + /* ----------------------------------------------------- + * void platform_mem_init(void); + * + * We don't need to carry out any memory initialization + * on Juno. The Secure RAM is accessible straight away. + * ----------------------------------------------------- + */ +func platform_mem_init + ret diff --git a/plat/juno/bl1_plat_setup.c b/plat/juno/bl1_plat_setup.c new file mode 100644 index 0000000..9f9583d --- /dev/null +++ b/plat/juno/bl1_plat_setup.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <cci400.h> +#include <console.h> +#include <mmio.h> +#include <platform.h> +#include <platform_def.h> +#include <tzc400.h> +#include "juno_def.h" +#include "juno_private.h" + +/******************************************************************************* + * Declarations of linker defined symbols which will help us find the layout + * of trusted RAM + ******************************************************************************/ +extern unsigned long __COHERENT_RAM_START__; +extern unsigned long __COHERENT_RAM_END__; + +extern unsigned long __BL1_RAM_START__; +extern unsigned long __BL1_RAM_END__; + +/* + * The next 2 constants identify the extents of the coherent memory region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to + * page-aligned addresses. + */ +#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) +#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) + +#define BL1_RAM_BASE (unsigned long)(&__BL1_RAM_START__) +#define BL1_RAM_LIMIT (unsigned long)(&__BL1_RAM_END__) + + +/* Data structure which holds the extents of the trusted RAM for BL1 */ +static meminfo_t bl1_tzram_layout; + +meminfo_t *bl1_plat_sec_mem_layout(void) +{ + return &bl1_tzram_layout; +} + +/******************************************************************************* + * Perform any BL1 specific platform actions. + ******************************************************************************/ +void bl1_early_platform_setup(void) +{ + const unsigned long bl1_ram_base = BL1_RAM_BASE; + const unsigned long bl1_ram_limit = BL1_RAM_LIMIT; + const unsigned long tzram_limit = TZRAM_BASE + TZRAM_SIZE; + + /* Initialize the console to provide early debug support */ + console_init(PL011_UART0_BASE); + + /* + * Calculate how much ram is BL1 using & how much remains free. + * This also includes a rudimentary mechanism to detect whether + * the BL1 data is loaded at the top or bottom of memory. + * TODO: add support for discontigous chunks of free ram if + * needed. Might need dynamic memory allocation support + * et al. + */ + bl1_tzram_layout.total_base = TZRAM_BASE; + bl1_tzram_layout.total_size = TZRAM_SIZE; + + if (bl1_ram_limit == tzram_limit) { + /* BL1 has been loaded at the top of memory. */ + bl1_tzram_layout.free_base = TZRAM_BASE; + bl1_tzram_layout.free_size = bl1_ram_base - TZRAM_BASE; + } else { + /* BL1 has been loaded at the bottom of memory. */ + bl1_tzram_layout.free_base = bl1_ram_limit; + bl1_tzram_layout.free_size = + tzram_limit - bl1_ram_limit; + } +} + + +/* + * Address of slave 'n' security setting in the NIC-400 address region + * control + * TODO: Ideally this macro should be moved in a "nic-400.h" header file but + * it would be the only thing in there so it's not worth it at the moment. + */ +#define NIC400_ADDR_CTRL_SECURITY_REG(n) (0x8 + (n) * 4) + +static void init_nic400(void) +{ + /* + * NIC-400 Access Control Initialization + * + * Define access privileges by setting each corresponding bit to: + * 0 = Secure access only + * 1 = Non-secure access allowed + */ + + /* + * Allow non-secure access to some SOC regions, excluding UART1, which + * remains secure. + * Note: This is the NIC-400 device on the SOC + */ + mmio_write_32(SOC_NIC400_BASE + + NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_USB_EHCI), ~0); + mmio_write_32(SOC_NIC400_BASE + + NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_TLX_MASTER), ~0); + mmio_write_32(SOC_NIC400_BASE + + NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_USB_OHCI), ~0); + mmio_write_32(SOC_NIC400_BASE + + NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_PL354_SMC), ~0); + mmio_write_32(SOC_NIC400_BASE + + NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_APB4_BRIDGE), ~0); + mmio_write_32(SOC_NIC400_BASE + + NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_BOOTSEC_BRIDGE), + ~SOC_NIC400_BOOTSEC_BRIDGE_UART1); + + /* + * Allow non-secure access to some CSS regions. + * Note: This is the NIC-400 device on the CSS + */ + mmio_write_32(CSS_NIC400_BASE + + NIC400_ADDR_CTRL_SECURITY_REG(CSS_NIC400_SLAVE_BOOTSECURE), + ~0); +} + + +static void init_tzc400(void) +{ + /* Enable all filter units available */ + mmio_write_32(TZC400_BASE + GATE_KEEPER_OFF, 0x0000000f); + + /* + * Secure read and write are enabled for region 0, and the background + * region (region 0) is enabled for all four filter units + */ + mmio_write_32(TZC400_BASE + REGION_ATTRIBUTES_OFF, 0xc0000000); + + /* + * Enable Non-secure read/write accesses for the Soc Devices from the + * Non-Secure World + */ + mmio_write_32(TZC400_BASE + REGION_ID_ACCESS_OFF, + TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CCI400) | + TZC_REGION_ACCESS_RDWR(TZC400_NSAID_PCIE) | + TZC_REGION_ACCESS_RDWR(TZC400_NSAID_HDLCD0) | + TZC_REGION_ACCESS_RDWR(TZC400_NSAID_HDLCD1) | + TZC_REGION_ACCESS_RDWR(TZC400_NSAID_USB) | + TZC_REGION_ACCESS_RDWR(TZC400_NSAID_DMA330) | + TZC_REGION_ACCESS_RDWR(TZC400_NSAID_THINLINKS) | + TZC_REGION_ACCESS_RDWR(TZC400_NSAID_AP) | + TZC_REGION_ACCESS_RDWR(TZC400_NSAID_GPU) | + TZC_REGION_ACCESS_RDWR(TZC400_NSAID_SCP) | + TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CORESIGHT) + ); +} + +#define PCIE_SECURE_REG 0x3000 +#define PCIE_SEC_ACCESS_MASK ((1 << 0) | (1 << 1)) /* REG and MEM access bits */ + +static void init_pcie(void) +{ + /* + * PCIE Root Complex Security settings to enable non-secure + * access to config registers. + */ + mmio_write_32(PCIE_CONTROL_BASE + PCIE_SECURE_REG, PCIE_SEC_ACCESS_MASK); +} + + +/******************************************************************************* + * Function which will perform any remaining platform-specific setup that can + * occur after the MMU and data cache have been enabled. + ******************************************************************************/ +void bl1_platform_setup(void) +{ + init_nic400(); + init_tzc400(); + init_pcie(); + + /* Initialise the IO layer and register platform IO devices */ + io_setup(); + + /* Enable and initialize the System level generic timer */ + mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN); +} + + +/******************************************************************************* + * Perform the very early platform specific architecture setup here. At the + * moment this only does basic initialization. Later architectural setup + * (bl1_arch_setup()) does not do anything platform specific. + ******************************************************************************/ +void bl1_plat_arch_setup(void) +{ + /* + * Enable CCI-400 for this cluster. No need + * for locks as no other cpu is active at the + * moment + */ + cci_enable_coherency(read_mpidr()); + + configure_mmu_el3(bl1_tzram_layout.total_base, + bl1_tzram_layout.total_size, + TZROM_BASE, + TZROM_BASE + TZROM_SIZE, + BL1_COHERENT_RAM_BASE, + BL1_COHERENT_RAM_LIMIT); +} + +/******************************************************************************* + * Before calling this function BL2 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL2 and set SPSR and security state. + * On Juno we are only setting the security state, entrypoint + ******************************************************************************/ +void bl1_plat_set_bl2_ep_info(image_info_t *bl2_image, + entry_point_info_t *bl2_ep) +{ + SET_SECURITY_STATE(bl2_ep->h.attr, SECURE); + bl2_ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); +} diff --git a/plat/juno/bl2_plat_setup.c b/plat/juno/bl2_plat_setup.c new file mode 100644 index 0000000..1a26e43 --- /dev/null +++ b/plat/juno/bl2_plat_setup.c @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <console.h> +#include <debug.h> +#include <platform.h> +#include <platform_def.h> +#include <string.h> +#include "juno_def.h" +#include "juno_private.h" +#include "scp_bootloader.h" +#include <xlat_tables.h> +/******************************************************************************* + * Declarations of linker defined symbols which will help us find the layout + * of trusted RAM + ******************************************************************************/ +extern unsigned long __RO_START__; +extern unsigned long __RO_END__; + +extern unsigned long __COHERENT_RAM_START__; +extern unsigned long __COHERENT_RAM_END__; + +/* + * The next 2 constants identify the extents of the code & RO data region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses. + */ +#define BL2_RO_BASE (unsigned long)(&__RO_START__) +#define BL2_RO_LIMIT (unsigned long)(&__RO_END__) + +/* + * The next 2 constants identify the extents of the coherent memory region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to + * page-aligned addresses. + */ +#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) +#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) + +/* Data structure which holds the extents of the trusted RAM for BL2 */ +static meminfo_t bl2_tzram_layout +__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE), + section("tzfw_coherent_mem"))); + +/******************************************************************************* + * Structure which holds the arguments which need to be passed to BL3-1 + ******************************************************************************/ +static bl2_to_bl31_params_mem_t bl31_params_mem; + +meminfo_t *bl2_plat_sec_mem_layout(void) +{ + return &bl2_tzram_layout; +} + +/******************************************************************************* + * This function assigns a pointer to the memory that the platform has kept + * aside to pass platform specific and trusted firmware related information + * to BL31. This memory is allocated by allocating memory to + * bl2_to_bl31_params_mem_t structure which is a superset of all the + * structure whose information is passed to BL31 + * NOTE: This function should be called only once and should be done + * before generating params to BL31 + ******************************************************************************/ +bl31_params_t *bl2_plat_get_bl31_params(void) +{ + bl31_params_t *bl2_to_bl31_params; + + /* + * Initialise the memory for all the arguments that needs to + * be passed to BL3-1 + */ + memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t)); + + /* Assign memory for TF related information */ + bl2_to_bl31_params = &bl31_params_mem.bl31_params; + SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0); + + /* Fill BL3-1 related information */ + bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY, + VERSION_1, 0); + + /* Fill BL3-2 related information if it exists */ +#if BL32_BASE + bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP, + VERSION_1, 0); + bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY, + VERSION_1, 0); +#endif + + /* Fill BL3-3 related information */ + bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info, + PARAM_EP, VERSION_1, 0); + /* UEFI expects to receive the primary CPU MPID (through x0) */ + bl2_to_bl31_params->bl33_ep_info->args.arg0 = PRIMARY_CPU; + + bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info; + SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY, + VERSION_1, 0); + + return bl2_to_bl31_params; +} + +/******************************************************************************* + * This function returns a pointer to the shared memory that the platform + * has kept to point to entry point information of BL31 to BL2 + ******************************************************************************/ +struct entry_point_info *bl2_plat_get_bl31_ep_info(void) +{ +#if DEBUG + bl31_params_mem.bl31_ep_info.args.arg1 = JUNO_BL31_PLAT_PARAM_VAL; +#endif + + return &bl31_params_mem.bl31_ep_info; +} + +/******************************************************************************* + * BL1 has passed the extents of the trusted RAM that should be visible to BL2 + * in x0. This memory layout is sitting at the base of the free trusted RAM. + * Copy it to a safe loaction before its reclaimed by later BL2 functionality. + ******************************************************************************/ +void bl2_early_platform_setup(meminfo_t *mem_layout) +{ + /* Initialize the console to provide early debug support */ + //console_init(PL011_UART0_BASE); + //char c; + console_init(52); //24M + +console_putc('h'); +console_putc('a'); +console_putc('h'); +console_putc('a'); + /* Setup the BL2 memory layout */ +#if 0 + bl2_tzram_layout.total_base = mem_layout->total_base; + bl2_tzram_layout.total_size = mem_layout->total_size; + bl2_tzram_layout.free_base = mem_layout->free_base; + bl2_tzram_layout.free_size = mem_layout->free_size; + bl2_tzram_layout.attr = mem_layout->attr; + bl2_tzram_layout.next = 0; +#endif + bl2_tzram_layout.total_base = TZRAM_BASE; + bl2_tzram_layout.total_size = TZRAM_SIZE; + bl2_tzram_layout.free_base = TZRAM_BASE; + bl2_tzram_layout.free_size = TZRAM_SIZE; + bl2_tzram_layout.attr = (unsigned long)0x0E939E2E8CF8EFFD; + bl2_tzram_layout.next = 0; +console_putc('h'); +console_putc('e'); +console_putc('h'); +console_putc('e'); +} + +/******************************************************************************* + * Load BL3-0 into Trusted RAM, then transfer it using the SCP Download + * protocol. The image is loaded into RAM in the same place that BL3-1 will be + * loaded later so here, we copy the RAM layout structure and use it to load + * the image into. When this function exits, the RAM layout remains untouched + * so the BL2 can load BL3-1 as normal. + ******************************************************************************/ +static int load_bl30(void) +{ + meminfo_t *bl2_tzram_layout; + meminfo_t tmp_tzram_layout; + uintptr_t bl30_base; + uint32_t bl30_size; + unsigned int bl2_load, bl30_load; + int ret; + int e; + image_info_t bl30_image_info; + + /* Find out how much free trusted ram remains after BL2 load */ + bl2_tzram_layout = bl2_plat_sec_mem_layout(); + + /* copy the TZRAM layout and use it */ + memcpy(&tmp_tzram_layout, bl2_tzram_layout, sizeof(meminfo_t)); + + /* Work out where to load BL3-0 before transferring to SCP */ + bl2_load = tmp_tzram_layout.attr & LOAD_MASK; + assert((bl2_load == TOP_LOAD) || (bl2_load == BOT_LOAD)); + bl30_load = (bl2_load == TOP_LOAD) ? BOT_LOAD : TOP_LOAD; + + SET_PARAM_HEAD(&bl30_image_info, PARAM_IMAGE_BINARY, VERSION_1, 0); + + /* Load the BL3-0 image */ + e = load_image(&tmp_tzram_layout, + BL30_IMAGE_NAME, + bl30_load, + BL30_BASE, + &bl30_image_info, + NULL); + + /* Panic if it has not been possible to load BL3-0 */ + if (e) { + ERROR("Failed to load BL3-0 image.\n"); + panic(); + } + + bl30_base = bl30_image_info.image_base; + bl30_size = bl30_image_info.image_size; + assert(bl30_base != 0); + assert(bl30_size != 0); + + INFO("BL2: BL3-0 loaded at 0x%lx, len=%d (0x%x)\n\r", bl30_base, + bl30_size, bl30_size); + flush_dcache_range(bl30_base, bl30_size); + ret = scp_bootloader_transfer((void *)bl30_base, bl30_size); + + if (ret == 0) + INFO("BL2: BL3-0 loaded and transferred to SCP\n\r"); + else + ERROR("BL2: BL3-0 load and transfer failure\n\r"); + + return ret; +} + +/******************************************************************************* + * Perform platform specific setup, i.e. initialize the IO layer, load BL3-0 + * image and initialise the memory location to use for passing arguments to + * BL3-1. + ******************************************************************************/ +void bl2_platform_setup(void) +{ + /* Initialise the IO layer and register platform IO devices */ + io_setup(); + + /* Load BL3-0 */ + if (load_bl30() != 0) + panic(); +} + +/* Flush the TF params and the TF plat params */ +void bl2_plat_flush_bl31_params(void) +{ + flush_dcache_range((unsigned long)&bl31_params_mem, + sizeof(bl2_to_bl31_params_mem_t)); +} + +/* + * Table of regions to map using the MMU. + * This doesn't include Trusted RAM as the 'mem_layout' argument passed to + * configure_mmu_elx() will give the available subset of that, + */ +static const mmap_region_t juno_mmap[] = { +#if 0 + { TZROM_BASE, TZROM_SIZE, MT_MEMORY | MT_RO | MT_SECURE }, + { MHU_SECURE_BASE, MHU_SECURE_SIZE, (MHU_PAYLOAD_CACHED ? MT_MEMORY : MT_DEVICE) + | MT_RW | MT_SECURE }, +// { TZRAM_BASE, TZRAM_SIZE, MT_MEMORY | MT_RW | MT_SECURE }, /* configure_mmu() meminfo arg sets subset of this */ + { FLASH_BASE, FLASH_SIZE, MT_MEMORY | MT_RO | MT_SECURE }, + { EMMC_BASE, EMMC_SIZE, MT_MEMORY | MT_RO | MT_SECURE }, + { PSRAM_BASE, PSRAM_SIZE, MT_MEMORY | MT_RW | MT_SECURE }, /* Used for 'TZDRAM' */ + { IOFPGA_BASE, IOFPGA_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, +// { NSROM_BASE, NSROM_SIZE, MT_MEMORY | MT_RW | MT_NS }, /* Eats a page table so leave it out for now */ + { DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, + { NSRAM_BASE, NSRAM_SIZE, MT_MEMORY | MT_RW | MT_NS }, + { DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, + { DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS }, +#endif + + { TZROM_BASE, TZROM_SIZE, MT_MEMORY | MT_RO | MT_SECURE }, + { DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS }, + { DEVICEG_BASE, DEVICEG_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, + + {0} +}; +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only intializes the mmu in a quick and dirty way. + ******************************************************************************/ +void bl2_plat_arch_setup(void) +{ +console_putc('a'); +console_putc('r'); +console_putc('c'); +console_putc('h'); +/* + configure_mmu_el1(bl2_tzram_layout.total_base, + bl2_tzram_layout.total_size, + BL2_RO_BASE, + BL2_RO_LIMIT, + BL2_COHERENT_RAM_BASE, + BL2_COHERENT_RAM_LIMIT); +*/ + +mmap_add_region(bl2_tzram_layout.total_base, + bl2_tzram_layout.total_size, + MT_MEMORY | MT_RW | MT_SECURE); +console_putc('1'); +mmap_add_region(BL2_RO_BASE, BL2_RO_LIMIT - BL2_RO_BASE, + MT_MEMORY | MT_RO | MT_SECURE); +console_putc('2'); +mmap_add_region(BL2_COHERENT_RAM_BASE, BL2_COHERENT_RAM_LIMIT - BL2_COHERENT_RAM_BASE, + MT_DEVICE | MT_RW | MT_SECURE); +console_putc('3'); +mmap_add(juno_mmap); +console_putc('4'); +init_xlat_tables(); +console_putc('5'); +//enable_mmu_el1(); + + +console_putc('o'); +console_putc('v'); +console_putc('e'); +console_putc('r'); +} + +/******************************************************************************* + * Before calling this function BL31 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL31 and set SPSR and security state. + * On Juno we are only setting the security state, entrypoint + ******************************************************************************/ +void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info, + entry_point_info_t *bl31_ep_info) +{ + SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE); + bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS); +} + + +/******************************************************************************* + * Before calling this function BL32 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL32 and set SPSR and security state. + * On Juno we are only setting the security state, entrypoint + ******************************************************************************/ +void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info, + entry_point_info_t *bl32_ep_info) +{ + SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE); + /* + * The Secure Payload Dispatcher service is responsible for + * setting the SPSR prior to entry into the BL32 image. + */ + bl32_ep_info->spsr = 0; +} + +/******************************************************************************* + * Before calling this function BL33 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL33 and set SPSR and security state. + * On Juno we are only setting the security state, entrypoint + ******************************************************************************/ +void bl2_plat_set_bl33_ep_info(image_info_t *image, + entry_point_info_t *bl33_ep_info) +{ + unsigned long el_status; + unsigned int mode; + + /* Figure out what mode we enter the non-secure world in */ + el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; + el_status &= ID_AA64PFR0_ELX_MASK; + + if (el_status) + mode = MODE_EL2; + else + mode = MODE_EL1; + + /* + * TODO: Consider the possibility of specifying the SPSR in + * the FIP ToC and allowing the platform to have a say as + * well. + */ + bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS); + SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE); +} + +/******************************************************************************* + * Populate the extents of memory available for loading BL3-2 + ******************************************************************************/ +void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo) +{ + /* + * Populate the extents of memory available for loading BL3-2. + */ + bl32_meminfo->total_base = BL32_BASE; + bl32_meminfo->free_base = BL32_BASE; + bl32_meminfo->total_size = + (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; + bl32_meminfo->free_size = + (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; + bl32_meminfo->attr = BOT_LOAD; + bl32_meminfo->next = 0; +} + + +/******************************************************************************* + * Populate the extents of memory available for loading BL3-3 + ******************************************************************************/ +void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo) +{ + bl33_meminfo->total_base = DRAM_BASE; + bl33_meminfo->total_size = DRAM_SIZE; + bl33_meminfo->free_base = DRAM_BASE; + bl33_meminfo->free_size = DRAM_SIZE; + bl33_meminfo->attr = 0; + bl33_meminfo->attr = 0; +} diff --git a/plat/juno/bl31_plat_setup.c b/plat/juno/bl31_plat_setup.c new file mode 100644 index 0000000..9489804 --- /dev/null +++ b/plat/juno/bl31_plat_setup.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <assert.h> +#include <bl31.h> +#include <bl_common.h> +#include <console.h> +#include <mmio.h> +#include <platform.h> +#include <stddef.h> +#include "juno_def.h" +#include "juno_private.h" +#include "mhu.h" + +/******************************************************************************* + * Declarations of linker defined symbols which will help us find the layout + * of trusted RAM + ******************************************************************************/ +extern unsigned long __RO_START__; +extern unsigned long __RO_END__; + +extern unsigned long __COHERENT_RAM_START__; +extern unsigned long __COHERENT_RAM_END__; + +/* + * The next 2 constants identify the extents of the code & RO data region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses. + */ +#define BL31_RO_BASE (unsigned long)(&__RO_START__) +#define BL31_RO_LIMIT (unsigned long)(&__RO_END__) + +/* + * The next 2 constants identify the extents of the coherent memory region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols + * refer to page-aligned addresses. + */ +#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) +#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) + +/****************************************************************************** + * Placeholder variables for copying the arguments that have been passed to + * BL3-1 from BL2. + ******************************************************************************/ +static entry_point_info_t bl32_ep_info; +static entry_point_info_t bl33_ep_info; + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL3-3 corresponds to the non-secure image type + * while BL3-2 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ******************************************************************************/ +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + entry_point_info_t *next_image_info; + + next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info; + + /* None of the images on this platform can have 0x0 as the entrypoint */ + if (next_image_info->pc) + return next_image_info; + else + return NULL; +} + +/******************************************************************************* + * Perform any BL3-1 specific platform actions. Here is an opportunity to copy + * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they + * are lost (potentially). This needs to be done before the MMU is initialized + * so that the memory layout can be used while creating page tables. Also, BL2 + * has flushed this information to memory, so we are guaranteed to pick up good + * data + ******************************************************************************/ +void bl31_early_platform_setup(bl31_params_t *from_bl2, + void *plat_params_from_bl2) +{ + /* Initialize the console to provide early debug support */ + console_init(PL011_UART0_BASE); + + /* + * Check params passed from BL2 should not be NULL, + */ + assert(from_bl2 != NULL); + assert(from_bl2->h.type == PARAM_BL31); + assert(from_bl2->h.version >= VERSION_1); + /* + * In debug builds, we pass a special value in 'plat_params_from_bl2' + * to verify platform parameters from BL2 to BL3-1. + * In release builds, it's not used. + */ + assert(((unsigned long long)plat_params_from_bl2) == + JUNO_BL31_PLAT_PARAM_VAL); + + /* + * Copy BL3-2 and BL3-3 entry point information. + * They are stored in Secure RAM, in BL2's address space. + */ + bl32_ep_info = *from_bl2->bl32_ep_info; + bl33_ep_info = *from_bl2->bl33_ep_info; +} + +/******************************************************************************* + * Initialize the MHU and the GIC. + ******************************************************************************/ +void bl31_platform_setup(void) +{ + unsigned int reg_val; + + mhu_secure_init(); + + /* Initialize the gic cpu and distributor interfaces */ + gic_setup(); + + /* Enable and initialize the System level generic timer */ + mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN); + + /* Allow access to the System counter timer module */ + reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT); + reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT); + reg_val |= (1 << CNTACR_RWVT_SHIFT) | (1 << CNTACR_RWPT_SHIFT); + mmio_write_32(SYS_TIMCTL_BASE + CNTACR_BASE(1), reg_val); + + reg_val = (1 << CNTNSAR_NS_SHIFT(1)); + mmio_write_32(SYS_TIMCTL_BASE + CNTNSAR, reg_val); + + /* Topologies are best known to the platform. */ + plat_setup_topology(); +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only intializes the mmu in a quick and dirty way. + ******************************************************************************/ +void bl31_plat_arch_setup() +{ + configure_mmu_el3(BL31_RO_BASE, + BL31_COHERENT_RAM_LIMIT - BL31_RO_BASE, + BL31_RO_BASE, + BL31_RO_LIMIT, + BL31_COHERENT_RAM_BASE, + BL31_COHERENT_RAM_LIMIT); +} diff --git a/plat/juno/bl32_plat_setup.c b/plat/juno/bl32_plat_setup.c new file mode 100644 index 0000000..d154add --- /dev/null +++ b/plat/juno/bl32_plat_setup.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <bl_common.h> +#include <console.h> +#include <platform.h> +#include "juno_def.h" +#include "juno_private.h" + +/******************************************************************************* + * Declarations of linker defined symbols which will help us find the layout + * of trusted SRAM + ******************************************************************************/ +extern unsigned long __RO_START__; +extern unsigned long __RO_END__; + +extern unsigned long __COHERENT_RAM_START__; +extern unsigned long __COHERENT_RAM_END__; + +/* + * The next 2 constants identify the extents of the code & RO data region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses. + */ +#define BL32_RO_BASE (unsigned long)(&__RO_START__) +#define BL32_RO_LIMIT (unsigned long)(&__RO_END__) + +/* + * The next 2 constants identify the extents of the coherent memory region. + * These addresses are used by the MMU setup code and therefore they must be + * page-aligned. It is the responsibility of the linker script to ensure that + * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to + * page-aligned addresses. + */ +#define BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) +#define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) + +/******************************************************************************* + * Initialize the UART + ******************************************************************************/ +void bl32_early_platform_setup(void) +{ + /* + * Initialize a different console than already in use to display + * messages from TSP + */ + console_init(PL011_UART1_BASE); +} + +/******************************************************************************* + * Perform platform specific setup placeholder + ******************************************************************************/ +void bl32_platform_setup(void) +{ +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this only intializes the MMU + ******************************************************************************/ +void bl32_plat_arch_setup(void) +{ + configure_mmu_el1(BL32_RO_BASE, + BL32_COHERENT_RAM_LIMIT - BL32_RO_BASE, + BL32_RO_BASE, + BL32_RO_LIMIT, + BL32_COHERENT_RAM_BASE, + BL32_COHERENT_RAM_LIMIT); +} diff --git a/plat/juno/include/plat_macros.S b/plat/juno/include/plat_macros.S new file mode 100644 index 0000000..30dc847 --- /dev/null +++ b/plat/juno/include/plat_macros.S @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <gic_v2.h> +#include "../juno_def.h" + +.section .rodata.gic_reg_name, "aS" +gic_regs: .asciz "gic_iar", "gic_ctlr", "" + +/* Currently we have only 2 GIC registers to report */ +#define GIC_REG_SIZE (2 * 8) + /* --------------------------------------------- + * The below macro prints out relevant GIC + * registers whenever an unhandled exception is + * taken in BL3-1. + * --------------------------------------------- + */ + .macro plat_print_gic_regs + ldr x0, =GICC_BASE + ldr w1, [x0, #GICC_IAR] + ldr w2, [x0, #GICC_CTLR] + sub sp, sp, #GIC_REG_SIZE + stp x1, x2, [sp] /* we store the gic registers as 64 bit */ + adr x0, gic_regs + mov x1, sp + bl print_string_value + add sp, sp, #GIC_REG_SIZE + .endm diff --git a/plat/juno/include/platform_def.h b/plat/juno/include/platform_def.h new file mode 100644 index 0000000..cb8a685 --- /dev/null +++ b/plat/juno/include/platform_def.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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_DEF_H__ +#define __PLATFORM_DEF_H__ + +#include <arch.h> + +/******************************************************************************* + * Platform binary types for linking + ******************************************************************************/ +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +/******************************************************************************* + * Generic platform constants + ******************************************************************************/ + +/* Size of cacheable stacks */ +#define PLATFORM_STACK_SIZE 0x800 + +/* Size of coherent stacks for debug and release builds */ +#if DEBUG +#define PCPU_DV_MEM_STACK_SIZE 0x400 +#else +#define PCPU_DV_MEM_STACK_SIZE 0x300 +#endif + +#define FIRMWARE_WELCOME_STR "Booting trusted firmware boot loader stage 1\n\r" + +/* Trusted Boot Firmware BL2 */ +#define BL2_IMAGE_NAME "bl2.bin" + +/* EL3 Runtime Firmware BL3-1 */ +#define BL31_IMAGE_NAME "bl31.bin" + +/* SCP Firmware BL3-0 */ +#define BL30_IMAGE_NAME "bl30.bin" + +/* Secure Payload BL3-2 (Trusted OS) */ +#define BL32_IMAGE_NAME "bl32.bin" + +/* Non-Trusted Firmware BL3-3 */ +#define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */ + +/* Firmware Image Package */ +#define FIP_IMAGE_NAME "fip.bin" + +#define PLATFORM_CACHE_LINE_SIZE 64 +#define PLATFORM_CORE_COUNT 6 +#define PRIMARY_CPU 0x0 +#define MAX_IO_DEVICES 3 +#define MAX_IO_HANDLES 4 + +/******************************************************************************* + * Platform memory map related constants + ******************************************************************************/ +#define FLASH_BASE 0x08000000 +#define FLASH_SIZE 0x04000000 + +/* Bypass offset from start of NOR flash */ +#define BL1_ROM_BYPASS_OFFSET 0x03EC0000 + +//#ifndef TZROM_BASE +/* Use the bypass address */ +//#define TZROM_BASE FLASH_BASE + BL1_ROM_BYPASS_OFFSET +//#endif +#define TZROM_BASE 0xD9040000 +#define TZROM_SIZE 0x00010000 + +//#define TZRAM_BASE 0x04001000 +//#define TZRAM_SIZE 0x0003F000 +#define TZRAM_BASE 0xD9000000 +#define TZRAM_SIZE 0x00020000 + +/******************************************************************************* + * BL1 specific defines. + * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 base + * addresses. + ******************************************************************************/ +#define BL1_RO_BASE TZROM_BASE +#define BL1_RO_LIMIT (TZROM_BASE + TZROM_SIZE) +#define BL1_RW_BASE TZRAM_BASE +#define BL1_RW_LIMIT BL31_BASE + +/******************************************************************************* + * BL2 specific defines. + ******************************************************************************/ +//#define BL2_BASE (TZRAM_BASE + TZRAM_SIZE - 0xd000) +#define BL2_BASE TZRAM_BASE +#define BL2_LIMIT (TZRAM_BASE + TZRAM_SIZE) + +/******************************************************************************* + * Load address of BL3-0 in the Juno port + * BL3-0 is loaded to the same place as BL3-1. Once BL3-0 is transferred to the + * SCP, it is discarded and BL3-1 is loaded over the top. + ******************************************************************************/ +#define BL30_BASE BL31_BASE + +/******************************************************************************* + * BL3-1 specific defines. + ******************************************************************************/ +#define BL31_BASE (TZRAM_BASE + 0x8000) +#define BL31_LIMIT BL32_BASE + +/******************************************************************************* + * BL3-2 specific defines. + ******************************************************************************/ +#define TSP_SEC_MEM_BASE TZRAM_BASE +#define TSP_SEC_MEM_SIZE TZRAM_SIZE +#define BL32_BASE (TZRAM_BASE + TZRAM_SIZE - 0x1d000) +#define BL32_LIMIT BL2_BASE + +/******************************************************************************* + * Load address of BL3-3 in the Juno port + ******************************************************************************/ +#define NS_IMAGE_OFFSET 0xE0000000 + +/******************************************************************************* + * Platform specific page table and MMU setup constants + ******************************************************************************/ +#define ADDR_SPACE_SIZE (1ull << 32) +#define MAX_XLAT_TABLES 5 +#define MAX_MMAP_REGIONS 16 + +/******************************************************************************* + * ID of the secure physical generic timer interrupt. + ******************************************************************************/ +#define IRQ_SEC_PHY_TIMER 29 + +/******************************************************************************* + * CCI-400 related constants + ******************************************************************************/ +#define CCI400_BASE 0x2c090000 +#define CCI400_SL_IFACE_CLUSTER0 4 +#define CCI400_SL_IFACE_CLUSTER1 3 +#define CCI400_SL_IFACE_INDEX(mpidr) (mpidr & MPIDR_CLUSTER_MASK ? \ + CCI400_SL_IFACE_CLUSTER1 : \ + CCI400_SL_IFACE_CLUSTER0) +/******************************************************************************* + * Declarations and constants to access the mailboxes safely. Each mailbox is + * aligned on the biggest cache line size in the platform. This is known only + * to the platform as it might have a combination of integrated and external + * caches. Such alignment ensures that two maiboxes do not sit on the same cache + * line at any cache level. They could belong to different cpus/clusters & + * get written while being protected by different locks causing corruption of + * a valid mailbox address. + ******************************************************************************/ +#define CACHE_WRITEBACK_SHIFT 6 +#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) + +#endif /* __PLATFORM_DEF_H__ */ diff --git a/plat/juno/juno_def.h b/plat/juno/juno_def.h new file mode 100644 index 0000000..bc9c8c1 --- /dev/null +++ b/plat/juno/juno_def.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __JUNO_DEF_H__ +#define __JUNO_DEF_H__ + +/* Special value used to verify platform parameters from BL2 to BL3-1 */ +#define JUNO_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL + +/******************************************************************************* + * Juno memory map related constants + ******************************************************************************/ +#define MHU_SECURE_BASE 0x04000000 +#define MHU_SECURE_SIZE 0x00001000 + +#define MHU_PAYLOAD_CACHED 0 + +#define TRUSTED_MAILBOXES_BASE MHU_SECURE_BASE +#define TRUSTED_MAILBOX_SHIFT 4 + +#define EMMC_BASE 0x0c000000 +#define EMMC_SIZE 0x04000000 + +#define PSRAM_BASE 0x14000000 +#define PSRAM_SIZE 0x02000000 + +#define IOFPGA_BASE 0x1c000000 +#define IOFPGA_SIZE 0x03000000 + +#define NSROM_BASE 0x1f000000 +#define NSROM_SIZE 0x00001000 + +/* Following covers Columbus Peripherals excluding NSROM and NSRAM */ +#define DEVICE0_BASE 0x20000000 +#define DEVICE0_SIZE 0x0e000000 +#define MHU_BASE 0x2b1f0000 +#define DEVICEG_BASE 0xC0000000 +#define DEVICEG_SIZE 0x08008000 + +#define NSRAM_BASE 0x2e000000 +#define NSRAM_SIZE 0x00008000 + +/* Following covers Juno Peripherals and PCIe expansion area */ +#define DEVICE1_BASE 0x40000000 +#define DEVICE1_SIZE 0x40000000 +#define PCIE_CONTROL_BASE 0x7ff20000 + +#define DRAM_BASE 0x00000000 +#define DRAM_SIZE 0xC0000000 + +/* Memory mapped Generic timer interfaces */ +#define SYS_CNTCTL_BASE 0x2a430000 +#define SYS_CNTREAD_BASE 0x2a800000 +#define SYS_TIMCTL_BASE 0x2a810000 + +/* V2M motherboard system registers & offsets */ +#define VE_SYSREGS_BASE 0x1c010000 +#define V2M_SYS_LED 0x8 + +/* + * V2M sysled bit definitions. The values written to this + * register are defined in arch.h & runtime_svc.h. Only + * used by the primary cpu to diagnose any cold boot issues. + * + * SYS_LED[0] - Security state (S=0/NS=1) + * SYS_LED[2:1] - Exception Level (EL3-EL0) + * SYS_LED[7:3] - Exception Class (Sync/Async & origin) + * + */ +#define SYS_LED_SS_SHIFT 0x0 +#define SYS_LED_EL_SHIFT 0x1 +#define SYS_LED_EC_SHIFT 0x3 + +/******************************************************************************* + * GIC-400 & interrupt handling related constants + ******************************************************************************/ +#define GICD_BASE 0x2c010000 +#define GICC_BASE 0x2c02f000 +#define GICH_BASE 0x2c04f000 +#define GICV_BASE 0x2c06f000 + +#define IRQ_MHU 69 +#define IRQ_GPU_SMMU_0 71 +#define IRQ_GPU_SMMU_1 73 +#define IRQ_ETR_SMMU 75 +#define IRQ_TZC400 80 +#define IRQ_TZ_WDOG 86 + +#define IRQ_SEC_SGI_0 8 +#define IRQ_SEC_SGI_1 9 +#define IRQ_SEC_SGI_2 10 +#define IRQ_SEC_SGI_3 11 +#define IRQ_SEC_SGI_4 12 +#define IRQ_SEC_SGI_5 13 +#define IRQ_SEC_SGI_6 14 +#define IRQ_SEC_SGI_7 15 +#define IRQ_SEC_SGI_8 16 + +/******************************************************************************* + * PL011 related constants + ******************************************************************************/ +/* FPGA UART0 */ +#define PL011_UART0_BASE 0x1c090000 +/* FPGA UART1 */ +#define PL011_UART1_BASE 0x1c0a0000 +/* SoC UART0 */ +#define PL011_UART2_BASE 0x7ff80000 +/* SoC UART1 */ +#define PL011_UART3_BASE 0x7ff70000 + +/******************************************************************************* + * NIC-400 related constants + ******************************************************************************/ + +/* CSS NIC-400 Global Programmers View (GPV) */ +#define CSS_NIC400_BASE 0x2a000000 + +/* The slave_bootsecure controls access to GPU, DMC and CS. */ +#define CSS_NIC400_SLAVE_BOOTSECURE 8 + +/* SoC NIC-400 Global Programmers View (GPV) */ +#define SOC_NIC400_BASE 0x7fd00000 + +#define SOC_NIC400_USB_EHCI 0 +#define SOC_NIC400_TLX_MASTER 1 +#define SOC_NIC400_USB_OHCI 2 +#define SOC_NIC400_PL354_SMC 3 +/* + * The apb4_bridge controls access to: + * - the PCIe configuration registers + * - the MMU units for USB, HDLCD and DMA + */ +#define SOC_NIC400_APB4_BRIDGE 4 +/* + * The bootsec_bridge controls access to a bunch of peripherals, e.g. the UARTs. + */ +#define SOC_NIC400_BOOTSEC_BRIDGE 5 +#define SOC_NIC400_BOOTSEC_BRIDGE_UART1 (1 << 12) + +/******************************************************************************* + * TZC-400 related constants + ******************************************************************************/ +#define TZC400_BASE 0x2a4a0000 + +#define TZC400_NSAID_CCI400 0 /* Note: Same as default NSAID!! */ +#define TZC400_NSAID_PCIE 1 +#define TZC400_NSAID_HDLCD0 2 +#define TZC400_NSAID_HDLCD1 3 +#define TZC400_NSAID_USB 4 +#define TZC400_NSAID_DMA330 5 +#define TZC400_NSAID_THINLINKS 6 +#define TZC400_NSAID_AP 9 +#define TZC400_NSAID_GPU 10 +#define TZC400_NSAID_SCP 11 +#define TZC400_NSAID_CORESIGHT 12 + +#endif /* __FVP_DEF_H__ */ diff --git a/plat/juno/juno_private.h b/plat/juno/juno_private.h new file mode 100644 index 0000000..924b679 --- /dev/null +++ b/plat/juno/juno_private.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __JUNO_PRIVATE_H__ +#define __JUNO_PRIVATE_H__ + +#include <bl_common.h> +#include <stdint.h> +#include <platform_def.h> + +/******************************************************************************* + * Forward declarations + ******************************************************************************/ +struct plat_pm_ops; +struct meminfo; +struct bl31_params; +struct image_info; +struct entry_point_info; + +/******************************************************************************* + * This structure represents the superset of information that is passed to + * BL3-1 e.g. while passing control to it from BL2 which is bl31_params + * and other platform specific params + ******************************************************************************/ +typedef struct bl2_to_bl31_params_mem { + struct bl31_params bl31_params; + struct image_info bl31_image_info; + struct image_info bl32_image_info; + struct image_info bl33_image_info; + struct entry_point_info bl33_ep_info; + struct entry_point_info bl32_ep_info; + struct entry_point_info bl31_ep_info; +} bl2_to_bl31_params_mem_t; + +/******************************************************************************* + * Function and variable prototypes + ******************************************************************************/ +void bl1_plat_arch_setup(void); +void bl2_plat_arch_setup(void); +void bl31_plat_arch_setup(void); +int platform_setup_pm(const struct plat_pm_ops **plat_ops); +unsigned int platform_get_core_pos(unsigned long mpidr); +void configure_mmu_el1(unsigned long total_base, + unsigned long total_size, + unsigned long ro_start, + unsigned long ro_limit, + unsigned long coh_start, + unsigned long coh_limit); +void configure_mmu_el3(unsigned long total_base, + unsigned long total_size, + unsigned long ro_start, + unsigned long ro_limit, + unsigned long coh_start, + unsigned long coh_limit); +void plat_report_exception(unsigned long type); +unsigned long plat_get_ns_image_entrypoint(void); +unsigned long platform_get_stack(unsigned long mpidr); +uint64_t plat_get_syscnt_freq(void); + +/* Declarations for plat_gic.c */ +uint32_t ic_get_pending_interrupt_id(void); +uint32_t ic_get_pending_interrupt_type(void); +uint32_t ic_acknowledge_interrupt(void); +uint32_t ic_get_interrupt_type(uint32_t id); +void ic_end_of_interrupt(uint32_t id); +void gic_cpuif_deactivate(unsigned int gicc_base); +void gic_cpuif_setup(unsigned int gicc_base); +void gic_pcpu_distif_setup(unsigned int gicd_base); +void gic_setup(void); +uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state); + +/* Declarations for plat_topology.c */ +int plat_setup_topology(void); +int plat_get_max_afflvl(void); +unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr); +unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr); + +/* Declarations for plat_io_storage.c */ +void io_setup(void); +int plat_get_image_source(const char *image_name, + uintptr_t *dev_handle, + uintptr_t *image_spec); + +/* + * Before calling this function BL2 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL2 and set SPSR and security state. + * On Juno we are only setting the security state, entrypoint + */ +void bl1_plat_set_bl2_ep_info(struct image_info *image, + struct entry_point_info *ep); + +/* + * Before calling this function BL3-1 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL3-1 and set SPSR and security state. + * On Juno we are only setting the security state, entrypoint + */ +void bl2_plat_set_bl31_ep_info(struct image_info *image, + struct entry_point_info *ep); + +/* + * Before calling this function BL3-2 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL3-2 and set SPSR and security state. + * On Juno we are only setting the security state, entrypoint + */ +void bl2_plat_set_bl32_ep_info(struct image_info *image, + struct entry_point_info *ep); + +/* + * Before calling this function BL3-3 is loaded in memory and its entrypoint + * is set by load_image. This is a placeholder for the platform to change + * the entrypoint of BL3-3 and set SPSR and security state. + * On Juno we are only setting the security state, entrypoint + */ +void bl2_plat_set_bl33_ep_info(struct image_info *image, + struct entry_point_info *ep); + +/* Gets the memory layout for BL3-2 */ +void bl2_plat_get_bl32_meminfo(struct meminfo *mem_info); + +/* Gets the memory layout for BL3-3 */ +void bl2_plat_get_bl33_meminfo(struct meminfo *mem_info); + +#endif /* __JUNO_PRIVATE_H__ */ diff --git a/plat/juno/mhu.c b/plat/juno/mhu.c new file mode 100644 index 0000000..89b8d00 --- /dev/null +++ b/plat/juno/mhu.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <bakery_lock.h> +#include <mmio.h> +#include "juno_def.h" +#include "mhu.h" + +/* SCP MHU secure channel registers */ +#define SCP_INTR_S_STAT 0x200 +#define SCP_INTR_S_SET 0x208 +#define SCP_INTR_S_CLEAR 0x210 + +/* CPU MHU secure channel registers */ +#define CPU_INTR_S_STAT 0x300 +#define CPU_INTR_S_SET 0x308 +#define CPU_INTR_S_CLEAR 0x310 + + +static bakery_lock_t mhu_secure_lock __attribute__ ((section("tzfw_coherent_mem"))); + + +void mhu_secure_message_start(void) +{ + bakery_lock_get(read_mpidr(), &mhu_secure_lock); + + /* Make sure any previous command has finished */ + while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0) + ; +} + +void mhu_secure_message_send(uint32_t command) +{ + /* Send command to SCP and wait for it to pick it up */ + mmio_write_32(MHU_BASE + CPU_INTR_S_SET, command); + while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0) + ; +} + +uint32_t mhu_secure_message_wait(void) +{ + /* Wait for response from SCP */ + uint32_t response; + while (!(response = mmio_read_32(MHU_BASE + SCP_INTR_S_STAT))) + ; + + return response; +} + +void mhu_secure_message_end(void) +{ + /* Clear any response we got by writing all ones to the CLEAR register */ + mmio_write_32(MHU_BASE + SCP_INTR_S_CLEAR, 0xffffffffu); + + bakery_lock_release(read_mpidr(), &mhu_secure_lock); +} + +void mhu_secure_init(void) +{ + bakery_lock_init(&mhu_secure_lock); + + /* + * Clear the CPU's INTR register to make sure we don't see a stale + * or garbage value and think it's a message we've already sent. + */ + mmio_write_32(MHU_BASE + CPU_INTR_S_CLEAR, 0xffffffffu); +} diff --git a/plat/juno/mhu.h b/plat/juno/mhu.h new file mode 100644 index 0000000..5149c82 --- /dev/null +++ b/plat/juno/mhu.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __MHU_H__ +#define __MHU_H__ + +#include <stdint.h> + +extern void mhu_secure_message_start(void); +extern void mhu_secure_message_send(uint32_t command); +extern uint32_t mhu_secure_message_wait(void); +extern void mhu_secure_message_end(void); + +extern void mhu_secure_init(void); + +#endif /* __MHU_H__ */ diff --git a/plat/juno/plat-tsp.ld.S b/plat/juno/plat-tsp.ld.S new file mode 100644 index 0000000..16d6c17 --- /dev/null +++ b/plat/juno/plat-tsp.ld.S @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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. + */ + + ASSERT(__BL32_END__ <= BL2_BASE, "BL3-2 image overlaps BL2 image.") diff --git a/plat/juno/plat_gic.c b/plat/juno/plat_gic.c new file mode 100644 index 0000000..b18890b --- /dev/null +++ b/plat/juno/plat_gic.c @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <gic_v2.h> +#include <interrupt_mgmt.h> +#include <platform.h> +#include "juno_def.h" +#include "juno_private.h" + + +/* Value used to initialise Non-Secure irq priorities four at a time */ +#define DEFAULT_NS_PRIORITY_X4 \ + (GIC_HIGHEST_NS_PRIORITY | \ + (GIC_HIGHEST_NS_PRIORITY << 8) | \ + (GIC_HIGHEST_NS_PRIORITY << 16) | \ + (GIC_HIGHEST_NS_PRIORITY << 24)) + + +/******************************************************************************* + * Enable secure interrupts and use FIQs to route them. Disable legacy bypass + * and set the priority mask register to allow all interrupts to trickle in. + ******************************************************************************/ +void gic_cpuif_setup(unsigned int gicc_base) +{ + unsigned int val; + + gicc_write_pmr(gicc_base, GIC_PRI_MASK); + + val = ENABLE_GRP0 | FIQ_EN; + val |= FIQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP0; + val |= FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1; + gicc_write_ctlr(gicc_base, val); +} + +/******************************************************************************* + * Place the cpu interface in a state where it can never make a cpu exit wfi as + * as result of an asserted interrupt. This is critical for powering down a cpu + ******************************************************************************/ +void gic_cpuif_deactivate(unsigned int gicc_base) +{ + unsigned int val; + + /* Disable secure, non-secure interrupts and disable their bypass */ + val = gicc_read_ctlr(gicc_base); + val &= ~(ENABLE_GRP0 | ENABLE_GRP1); + val |= FIQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP0; + val |= IRQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP1; + gicc_write_ctlr(gicc_base, val); +} + +static void gic_set_secure(unsigned int gicd_base, unsigned id) +{ + /* Set interrupt as Group 0 */ + gicd_clr_igroupr(gicd_base, id); + + /* Set priority to max */ + gicd_set_ipriorityr(gicd_base, id, GIC_HIGHEST_SEC_PRIORITY); +} + +/******************************************************************************* + * Per cpu gic distributor setup which will be done by all cpus after a cold + * boot/hotplug. This marks out the secure interrupts & enables them. + ******************************************************************************/ +void gic_pcpu_distif_setup(unsigned int gicd_base) +{ + unsigned i; + + /* Mark all 32 PPI interrupts as Group 1 (non-secure) */ + mmio_write_32(gicd_base + GICD_IGROUPR, 0xffffffffu); + + /* Setup PPI priorities doing four at a time */ + for (i = 0; i < 32; i += 4) + mmio_write_32(gicd_base + GICD_IPRIORITYR + i, DEFAULT_NS_PRIORITY_X4); + + /* Configure those PPIs we want as secure, and enable them. */ + static const char sec_irq[] = { + IRQ_SEC_PHY_TIMER, + IRQ_SEC_SGI_0, + IRQ_SEC_SGI_1, + IRQ_SEC_SGI_2, + IRQ_SEC_SGI_3, + IRQ_SEC_SGI_4, + IRQ_SEC_SGI_5, + IRQ_SEC_SGI_6, + IRQ_SEC_SGI_7 + }; + for (i = 0; i < sizeof(sec_irq) / sizeof(sec_irq[0]); i++) { + gic_set_secure(gicd_base, sec_irq[i]); + gicd_set_isenabler(gicd_base, sec_irq[i]); + } +} + +/******************************************************************************* + * Global gic distributor setup which will be done by the primary cpu after a + * cold boot. It marks out the secure SPIs, PPIs & SGIs and enables them. It + * then enables the secure GIC distributor interface. + ******************************************************************************/ +static void gic_distif_setup(unsigned int gicd_base) +{ + unsigned int i, ctlr; + const unsigned int ITLinesNumber = + gicd_read_typer(gicd_base) & IT_LINES_NO_MASK; + + /* Disable the distributor before going further */ + ctlr = gicd_read_ctlr(gicd_base); + ctlr &= ~(ENABLE_GRP0 | ENABLE_GRP1); + gicd_write_ctlr(gicd_base, ctlr); + + /* Mark all lines of SPIs as Group 1 (non-secure) */ + for (i = 0; i < ITLinesNumber; i++) + mmio_write_32(gicd_base + GICD_IGROUPR + 4 + i * 4, 0xffffffffu); + + /* Setup SPI priorities doing four at a time */ + for (i = 0; i < ITLinesNumber * 32; i += 4) + mmio_write_32(gicd_base + GICD_IPRIORITYR + 32 + i, DEFAULT_NS_PRIORITY_X4); + + /* Configure the SPIs we want as secure */ + static const char sec_irq[] = { + IRQ_MHU, + IRQ_GPU_SMMU_0, + IRQ_GPU_SMMU_1, + IRQ_ETR_SMMU, + IRQ_TZC400, + IRQ_TZ_WDOG + }; + for (i = 0; i < sizeof(sec_irq) / sizeof(sec_irq[0]); i++) + gic_set_secure(gicd_base, sec_irq[i]); + + /* Route watchdog interrupt to this CPU and enable it. */ + gicd_set_itargetsr(gicd_base, IRQ_TZ_WDOG, + platform_get_core_pos(read_mpidr())); + gicd_set_isenabler(gicd_base, IRQ_TZ_WDOG); + + /* Now setup the PPIs */ + gic_pcpu_distif_setup(gicd_base); + + /* Enable Group 0 (secure) interrupts */ + gicd_write_ctlr(gicd_base, ctlr | ENABLE_GRP0); +} + +void gic_setup(void) +{ + gic_cpuif_setup(GICC_BASE); + gic_distif_setup(GICD_BASE); +} + +/******************************************************************************* + * An ARM processor signals interrupt exceptions through the IRQ and FIQ pins. + * The interrupt controller knows which pin/line it uses to signal a type of + * interrupt. The platform knows which interrupt controller type is being used + * in a particular security state e.g. with an ARM GIC, normal world could use + * the GICv2 features while the secure world could use GICv3 features and vice + * versa. + * This function is exported by the platform to let the interrupt management + * framework determine for a type of interrupt and security state, which line + * should be used in the SCR_EL3 to control its routing to EL3. The interrupt + * line is represented as the bit position of the IRQ or FIQ bit in the SCR_EL3. + ******************************************************************************/ +uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state) +{ + assert(type == INTR_TYPE_S_EL1 || + type == INTR_TYPE_EL3 || + type == INTR_TYPE_NS); + + assert(security_state == NON_SECURE || security_state == SECURE); + + /* + * We ignore the security state parameter because Juno is GICv2 only + * so both normal and secure worlds are using ARM GICv2. + */ + return gicv2_interrupt_type_to_line(GICC_BASE, type); +} + +/******************************************************************************* + * This function returns the type of the highest priority pending interrupt at + * the GIC cpu interface. INTR_TYPE_INVAL is returned when there is no + * interrupt pending. + ******************************************************************************/ +uint32_t plat_ic_get_pending_interrupt_type(void) +{ + uint32_t id; + + id = gicc_read_hppir(GICC_BASE); + + /* Assume that all secure interrupts are S-EL1 interrupts */ + if (id < 1022) + return INTR_TYPE_S_EL1; + + if (id == GIC_SPURIOUS_INTERRUPT) + return INTR_TYPE_INVAL; + + return INTR_TYPE_NS; +} + +/******************************************************************************* + * This function returns the id of the highest priority pending interrupt at + * the GIC cpu interface. INTR_ID_UNAVAILABLE is returned when there is no + * interrupt pending. + ******************************************************************************/ +uint32_t plat_ic_get_pending_interrupt_id(void) +{ + uint32_t id; + + id = gicc_read_hppir(GICC_BASE); + + if (id < 1022) + return id; + + if (id == 1023) + return INTR_ID_UNAVAILABLE; + + /* + * Find out which non-secure interrupt it is under the assumption that + * the GICC_CTLR.AckCtl bit is 0. + */ + return gicc_read_ahppir(GICC_BASE); +} + +/******************************************************************************* + * This functions reads the GIC cpu interface Interrupt Acknowledge register + * to start handling the pending interrupt. It returns the contents of the IAR. + ******************************************************************************/ +uint32_t plat_ic_acknowledge_interrupt(void) +{ + return gicc_read_IAR(GICC_BASE); +} + +/******************************************************************************* + * This functions writes the GIC cpu interface End Of Interrupt register with + * the passed value to finish handling the active interrupt + ******************************************************************************/ +void plat_ic_end_of_interrupt(uint32_t id) +{ + gicc_write_EOIR(GICC_BASE, id); +} + +/******************************************************************************* + * This function returns the type of the interrupt id depending upon the group + * this interrupt has been configured under by the interrupt controller i.e. + * group0 or group1. + ******************************************************************************/ +uint32_t plat_ic_get_interrupt_type(uint32_t id) +{ + uint32_t group; + + group = gicd_get_igroupr(GICD_BASE, id); + + /* Assume that all secure interrupts are S-EL1 interrupts */ + if (group == GRP0) + return INTR_TYPE_S_EL1; + else + return INTR_TYPE_NS; +} diff --git a/plat/juno/plat_io_storage.c b/plat/juno/plat_io_storage.c new file mode 100644 index 0000000..16259af --- /dev/null +++ b/plat/juno/plat_io_storage.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include <platform.h> +#include <io_storage.h> +#include <io_driver.h> +#include <semihosting.h> /* For FOPEN_MODE_... */ +#include <io_fip.h> +#include <io_memmap.h> +#include <debug.h> +#include "juno_def.h" + +/* IO devices */ +static io_plat_data_t io_data; +static const io_dev_connector_t *fip_dev_con; +static uintptr_t fip_dev_spec; +static uintptr_t fip_dev_handle; +static const io_dev_connector_t *memmap_dev_con; +static uintptr_t memmap_dev_spec; +static uintptr_t memmap_init_params; +static uintptr_t memmap_dev_handle; + +static const io_block_spec_t fip_block_spec = { + .offset = FLASH_BASE, + .length = FLASH_SIZE +}; + +static const io_file_spec_t bl2_file_spec = { + .path = BL2_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl30_file_spec = { + .path = BL30_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl31_file_spec = { + .path = BL31_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl32_file_spec = { + .path = BL32_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl33_file_spec = { + .path = BL33_IMAGE_NAME, + .mode = FOPEN_MODE_RB +}; + +static int open_fip(const uintptr_t spec); +static int open_memmap(const uintptr_t spec); + +struct plat_io_policy { + const char *image_name; + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +static const struct plat_io_policy policies[] = { + { + FIP_IMAGE_NAME, + &memmap_dev_handle, + (uintptr_t)&fip_block_spec, + open_memmap + }, { + BL2_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl2_file_spec, + open_fip + }, { + BL30_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl30_file_spec, + open_fip + }, { + BL31_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl31_file_spec, + open_fip + }, { + BL32_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl32_file_spec, + open_fip + }, { + BL33_IMAGE_NAME, + &fip_dev_handle, + (uintptr_t)&bl33_file_spec, + open_fip + }, { + 0, 0, 0 + } +}; + + +static int open_fip(const uintptr_t spec) +{ + int result = IO_FAIL; + + /* See if a Firmware Image Package is available */ + result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_NAME); + if (result == IO_SUCCESS) { + INFO("Using FIP\n"); + /*TODO: Check image defined in spec is present in FIP. */ + } + return result; +} + + +static int open_memmap(const uintptr_t spec) +{ + int result = IO_FAIL; + uintptr_t local_image_handle; + + result = io_dev_init(memmap_dev_handle, memmap_init_params); + if (result == IO_SUCCESS) { + result = io_open(memmap_dev_handle, spec, &local_image_handle); + if (result == IO_SUCCESS) { + /* INFO("Using Memmap IO\n"); */ + io_close(local_image_handle); + } + } + return result; +} + +void io_setup (void) +{ + int io_result = IO_FAIL; + + /* Initialise the IO layer */ + io_init(&io_data); + + /* Register the IO devices on this platform */ + io_result = register_io_dev_fip(&fip_dev_con); + assert(io_result == IO_SUCCESS); + + io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == IO_SUCCESS); + + /* Open connections to devices and cache the handles */ + io_result = io_dev_open(fip_dev_con, fip_dev_spec, &fip_dev_handle); + assert(io_result == IO_SUCCESS); + + io_result = io_dev_open(memmap_dev_con, memmap_dev_spec, + &memmap_dev_handle); + assert(io_result == IO_SUCCESS); + + /* Ignore improbable errors in release builds */ + (void)io_result; +} + + +/* Return an IO device handle and specification which can be used to access + * an image. Use this to enforce platform load policy */ +int plat_get_image_source(const char *image_name, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int result = IO_FAIL; + const struct plat_io_policy *policy; + + if ((image_name != NULL) && (dev_handle != NULL) && + (image_spec != NULL)) { + policy = policies; + while (policy->image_name != NULL) { + if (strcmp(policy->image_name, image_name) == 0) { + result = policy->check(policy->image_spec); + if (result == IO_SUCCESS) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + break; + } + } + policy++; + } + } else { + result = IO_FAIL; + } + return result; +} diff --git a/plat/juno/plat_pm.c b/plat/juno/plat_pm.c new file mode 100644 index 0000000..4e85f7c --- /dev/null +++ b/plat/juno/plat_pm.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2013, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <arch_helpers.h> +#include <cci400.h> +#include <platform.h> +#include <platform_def.h> +#include <psci.h> +#include "juno_def.h" +#include "juno_private.h" +#include "scpi.h" + +typedef struct { + /* Align the suspend level to allow per-cpu lockless access */ + uint32_t state[MPIDR_MAX_AFFLVL] __aligned(CACHE_WRITEBACK_GRANULE); +} scp_pstate; + +static scp_pstate target_pstate[PLATFORM_CORE_COUNT]; + +int pm_on(unsigned long mpidr, + unsigned long sec_entrypoint, + unsigned long ns_entrypoint, + unsigned int afflvl, + unsigned int state) +{ + /* + * SCP takes care of powering up higher affinity levels so we + * only need to care about level 0 + */ + if (afflvl != MPIDR_AFFLVL0) + return PSCI_E_SUCCESS; + + /* + * Setup mailbox with address for CPU entrypoint when it next powers up + */ + unsigned long *mbox = (unsigned long *)(unsigned long)( + TRUSTED_MAILBOXES_BASE + + (platform_get_core_pos(mpidr) << TRUSTED_MAILBOX_SHIFT) + ); + *mbox = sec_entrypoint; + flush_dcache_range((unsigned long)mbox, sizeof(*mbox)); + + scpi_set_css_power_state(mpidr, scpi_power_on, scpi_power_on, + scpi_power_on); + + return PSCI_E_SUCCESS; +} + +int pm_on_finish(unsigned long mpidr, unsigned int afflvl, unsigned int state) +{ + switch (afflvl) { + + case MPIDR_AFFLVL1: + /* Enable coherency if this cluster was off */ + if (state == PSCI_STATE_OFF) + cci_enable_coherency(mpidr); + break; + + case MPIDR_AFFLVL0: + /* + * Ignore the state passed for a cpu. It could only have + * been off if we are here. + */ + + /* Turn on intra-cluster coherency. */ + write_cpuectlr(read_cpuectlr() | CPUECTLR_SMP_BIT); + + /* Enable the gic cpu interface */ + gic_cpuif_setup(GICC_BASE); + /* Juno todo: Is this setup only needed after a cold boot? */ + gic_pcpu_distif_setup(GICD_BASE); + + /* + * Clear the mailbox for each cpu + */ + unsigned long *mbox = (unsigned long *)(unsigned long)( + TRUSTED_MAILBOXES_BASE + + (platform_get_core_pos(mpidr) << TRUSTED_MAILBOX_SHIFT) + ); + *mbox = 0; + flush_dcache_range((unsigned long)mbox, sizeof(*mbox)); + + break; + } + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * Common function called while turning a cpu off or suspending it. It is called + * for each affinity level until the target affinity level. It keeps track of + * the power state that needs to be programmed through the SCP firmware for each + * affinity level. Once the target affinity level is reached it uses the MHU + * channel to ask the SCP to perform the power operations for each affinity + * level accumulated so far. + * + * CAUTION: This function is called with coherent stacks so that caches can be + * turned off, flushed and coherency disabled. There is no guarantee that caches + * will remain turned on across calls to this function as each affinity level is + * dealt with. So do not write & read global variables across calls. It will be + * wise to do flush a write to the global to prevent unpredictable results. + ******************************************************************************/ +static int juno_power_down_common(unsigned long mpidr, + unsigned int linear_id, + unsigned int cur_afflvl, + unsigned int tgt_afflvl, + unsigned int state) +{ + /* Record which power state this affinity level is supposed to enter */ + if (state == PSCI_STATE_OFF) { + target_pstate[linear_id].state[cur_afflvl] = scpi_power_off; + } else { + assert(cur_afflvl != MPIDR_AFFLVL0); + target_pstate[linear_id].state[cur_afflvl] = scpi_power_on; + goto exit; + } + + switch (cur_afflvl) { + case MPIDR_AFFLVL1: + /* Cluster is to be turned off, so disable coherency */ + cci_disable_coherency(mpidr); + + break; + + case MPIDR_AFFLVL0: + /* Turn off intra-cluster coherency */ + write_cpuectlr(read_cpuectlr() & ~CPUECTLR_SMP_BIT); + + /* Prevent interrupts from spuriously waking up this cpu */ + gic_cpuif_deactivate(GICC_BASE); + + break; + } + +exit: + /* + * If this is the target affinity level then we need to ask the SCP + * to power down the appropriate components depending upon their state + */ + if (cur_afflvl == tgt_afflvl) { + scpi_set_css_power_state(mpidr, + target_pstate[linear_id].state[MPIDR_AFFLVL0], + target_pstate[linear_id].state[MPIDR_AFFLVL1], + scpi_power_on); + + /* Reset the states */ + target_pstate[linear_id].state[MPIDR_AFFLVL0] = scpi_power_on; + target_pstate[linear_id].state[MPIDR_AFFLVL1] = scpi_power_on; + } + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * Handler called when an affinity instance is about to be turned off. The + * level and mpidr determine the affinity instance. The 'state' arg. allows the + * platform to decide whether the cluster is being turned off and take apt + * actions. + * + * CAUTION: This function is called with coherent stacks so that caches can be + * turned off, flushed and coherency disabled. There is no guarantee that caches + * will remain turned on across calls to this function as each affinity level is + * dealt with. So do not write & read global variables across calls. It will be + * wise to do flush a write to the global to prevent unpredictable results. + ******************************************************************************/ +int pm_off(unsigned long mpidr, unsigned int afflvl, unsigned int state) +{ + return juno_power_down_common(mpidr, + platform_get_core_pos(mpidr), + afflvl, + plat_get_max_afflvl(), + state); +} + +/******************************************************************************* + * Handler called when an affinity instance is about to be suspended. The + * level and mpidr determine the affinity instance. The 'state' arg. allows the + * platform to decide whether the cluster is being turned off and take apt + * actions. The 'sec_entrypoint' determines the address in BL3-1 from where + * execution should resume. + * + * CAUTION: This function is called with coherent stacks so that caches can be + * turned off, flushed and coherency disabled. There is no guarantee that caches + * will remain turned on across calls to this function as each affinity level is + * dealt with. So do not write & read global variables across calls. It will be + * wise to do flush a write to the global to prevent unpredictable results. + ******************************************************************************/ +int pm_suspend(unsigned long mpidr, + unsigned long sec_entrypoint, + unsigned long ns_entrypoint, + unsigned int afflvl, + unsigned int state) +{ + uint32_t tgt_afflvl; + + tgt_afflvl = psci_get_suspend_afflvl(mpidr); + assert(tgt_afflvl != PSCI_INVALID_DATA); + + /* + * Setup mailbox with address for CPU entrypoint when it next powers up + */ + if (afflvl == MPIDR_AFFLVL0) { + unsigned long *mbox = (unsigned long *)(unsigned long)( + TRUSTED_MAILBOXES_BASE + + (platform_get_core_pos(mpidr) << TRUSTED_MAILBOX_SHIFT) + ); + *mbox = sec_entrypoint; + flush_dcache_range((unsigned long)mbox, sizeof(*mbox)); + } + + return juno_power_down_common(mpidr, + platform_get_core_pos(mpidr), + afflvl, + tgt_afflvl, + state); +} + +int pm_suspend_finish(unsigned long mpidr, + unsigned int afflvl, + unsigned int state) +{ + return pm_on_finish(mpidr, afflvl, state); +} + +/******************************************************************************* + * Export the platform handlers to enable psci to invoke them + ******************************************************************************/ +static const plat_pm_ops_t pm_ops = { + .affinst_on = pm_on, + .affinst_on_finish = pm_on_finish, + .affinst_off = pm_off, + .affinst_suspend = pm_suspend, + .affinst_suspend_finish = pm_suspend_finish +}; + +/******************************************************************************* + * Export the platform specific power ops & initialize the fvp power controller + ******************************************************************************/ +int platform_setup_pm(const plat_pm_ops_t **plat_ops) +{ + *plat_ops = &pm_ops; + return 0; +} diff --git a/plat/juno/plat_topology.c b/plat/juno/plat_topology.c new file mode 100644 index 0000000..39d4dab --- /dev/null +++ b/plat/juno/plat_topology.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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_def.h> +#include <psci.h> + +unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr) +{ + /* Report 1 (absent) instance at levels higher that the cluster level */ + if (aff_lvl > MPIDR_AFFLVL1) + return 1; + + if (aff_lvl == MPIDR_AFFLVL1) + return 2; /* We have two clusters */ + + return mpidr & 0x100 ? 4 : 2; /* 4 cpus in cluster 1, 2 in cluster 0 */ +} + +unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr) +{ + return aff_lvl <= MPIDR_AFFLVL1 ? PSCI_AFF_PRESENT : PSCI_AFF_ABSENT; +} + +int plat_get_max_afflvl() +{ + return MPIDR_AFFLVL1; +} + +int plat_setup_topology() +{ + /* Juno todo: Make topology configurable via SCC */ + return 0; +} diff --git a/plat/juno/platform.mk b/plat/juno/platform.mk new file mode 100644 index 0000000..b1d0c77 --- /dev/null +++ b/plat/juno/platform.mk @@ -0,0 +1,74 @@ +# +# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 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. +# +# Neither the name of ARM nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific +# prior written permission. +# +# 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. +# + +PLAT_INCLUDES := -Iplat/juno/include/ + +PLAT_BL_COMMON_SOURCES := drivers/arm/serial/serial.c \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + lib/mmio.c \ + lib/aarch64/xlat_tables.c \ + lib/aarch64/sysreg_helpers.S \ + plat/common/aarch64/plat_common.c \ + plat/juno/plat_io_storage.c + +BL1_SOURCES += drivers/arm/cci400/cci400.c \ + plat/common/aarch64/platform_up_stack.S \ + plat/juno/bl1_plat_setup.c \ + plat/juno/aarch64/bl1_plat_helpers.S \ + plat/juno/aarch64/plat_helpers.S \ + plat/juno/aarch64/juno_common.c + +BL2_SOURCES += lib/locks/bakery/bakery_lock.c \ + plat/common/aarch64/platform_up_stack.S \ + plat/juno/bl2_plat_setup.c \ + plat/juno/mhu.c \ + plat/juno/aarch64/plat_helpers.S \ + plat/juno/aarch64/juno_common.c \ + plat/juno/scp_bootloader.c \ + plat/juno/scpi.c + +BL31_SOURCES += drivers/arm/cci400/cci400.c \ + drivers/arm/gic/gic_v2.c \ + plat/common/aarch64/platform_mp_stack.S \ + plat/juno/bl31_plat_setup.c \ + plat/juno/mhu.c \ + plat/juno/aarch64/plat_helpers.S \ + plat/juno/aarch64/juno_common.c \ + plat/juno/plat_pm.c \ + plat/juno/plat_topology.c \ + plat/juno/plat_gic.c \ + plat/juno/scpi.c \ + plat/juno/smc_arm.c + +ifneq (${RESET_TO_BL31},0) + $(error "Using BL3-1 as the reset vector is not supported on Juno. \ + Please set RESET_TO_BL31 to 0.") +endif diff --git a/plat/juno/scp_bootloader.c b/plat/juno/scp_bootloader.c new file mode 100644 index 0000000..a6d25d4 --- /dev/null +++ b/plat/juno/scp_bootloader.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <platform.h> +#include "juno_def.h" +#include "mhu.h" +#include "scp_bootloader.h" +#include "scpi.h" + +/* Boot commands sent from AP -> SCP */ +#define BOOT_CMD_START 0x01 +#define BOOT_CMD_DATA 0x02 + +typedef struct { + uint32_t image_size; +} cmd_start_payload; + +typedef struct { + uint32_t sequence_num; + uint32_t offset; + uint32_t size; +} cmd_data_payload; + +#define BOOT_DATA_MAX_SIZE 0x1000 + +/* Boot commands sent from SCP -> AP */ +#define BOOT_CMD_ACK 0x03 +#define BOOT_CMD_NACK 0x04 + +typedef struct { + uint32_t sequence_num; +} cmd_ack_payload; + +/* + * Unlike the runtime protocol, the boot protocol uses the same memory region + * for both AP -> SCP and SCP -> AP transfers; define the address of this... + */ +static void * const cmd_payload = (void *)(MHU_SECURE_BASE + 0x0080); + +static void *scp_boot_message_start(void) +{ + mhu_secure_message_start(); + + return cmd_payload; +} + +static void scp_boot_message_send(unsigned command, size_t size) +{ + /* Make sure payload can be seen by SCP */ + if (MHU_PAYLOAD_CACHED) + flush_dcache_range((unsigned long)cmd_payload, size); + + /* Send command to SCP */ + mhu_secure_message_send(command | (size << 8)); +} + +static uint32_t scp_boot_message_wait(size_t size) +{ + uint32_t response = mhu_secure_message_wait(); + + /* Make sure we see the reply from the SCP and not any stale data */ + if (MHU_PAYLOAD_CACHED) + inv_dcache_range((unsigned long)cmd_payload, size); + + return response & 0xff; +} + +static void scp_boot_message_end(void) +{ + mhu_secure_message_end(); +} + +static int transfer_block(uint32_t sequence_num, uint32_t offset, uint32_t size) +{ + cmd_data_payload *cmd_data = scp_boot_message_start(); + cmd_data->sequence_num = sequence_num; + cmd_data->offset = offset; + cmd_data->size = size; + + scp_boot_message_send(BOOT_CMD_DATA, sizeof(*cmd_data)); + + cmd_ack_payload *cmd_ack = cmd_payload; + int ok = scp_boot_message_wait(sizeof(*cmd_ack)) == BOOT_CMD_ACK + && cmd_ack->sequence_num == sequence_num; + + scp_boot_message_end(); + + return ok; +} + +int scp_bootloader_transfer(void *image, unsigned int image_size) +{ + uintptr_t offset = (uintptr_t)image - MHU_SECURE_BASE; + uintptr_t end = offset + image_size; + uint32_t response; + + mhu_secure_init(); + + /* Initiate communications with SCP */ + do { + cmd_start_payload *cmd_start = scp_boot_message_start(); + cmd_start->image_size = image_size; + + scp_boot_message_send(BOOT_CMD_START, sizeof(*cmd_start)); + + response = scp_boot_message_wait(0); + + scp_boot_message_end(); + } while (response != BOOT_CMD_ACK); + + /* Transfer image to SCP a block at a time */ + uint32_t sequence_num = 1; + size_t size; + while ((size = end - offset) != 0) { + if (size > BOOT_DATA_MAX_SIZE) + size = BOOT_DATA_MAX_SIZE; + while (!transfer_block(sequence_num, offset, size)) + ; /* Retry forever */ + offset += size; + sequence_num++; + } + + /* Wait for SCP to signal it's ready */ + return scpi_wait_ready(); +} diff --git a/plat/juno/scp_bootloader.h b/plat/juno/scp_bootloader.h new file mode 100644 index 0000000..e872513 --- /dev/null +++ b/plat/juno/scp_bootloader.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __SCP_BOOTLOADER_H__ +#define __SCP_BOOTLOADER_H__ + +int scp_bootloader_transfer(void *image, unsigned int image_size); + +#endif diff --git a/plat/juno/scpi.c b/plat/juno/scpi.c new file mode 100644 index 0000000..cdfc1f2 --- /dev/null +++ b/plat/juno/scpi.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <platform.h> +#include "juno_def.h" +#include "mhu.h" +#include "scpi.h" + +#define MHU_SECURE_SCP_TO_AP_PAYLOAD (MHU_SECURE_BASE+0x0080) +#define MHU_SECURE_AP_TO_SCP_PAYLOAD (MHU_SECURE_BASE+0x0280) + +#define SIZE_SHIFT 20 /* Bit position for size value in MHU header */ +#define SIZE_MASK 0x1ff /* Mask to extract size value in MHU header*/ + + +void *scpi_secure_message_start(void) +{ + mhu_secure_message_start(); + + /* Return address of payload area. */ + return (void *)MHU_SECURE_AP_TO_SCP_PAYLOAD; +} + +void scpi_secure_message_send(unsigned command, size_t size) +{ + /* Make sure payload can be seen by SCP */ + if (MHU_PAYLOAD_CACHED) + flush_dcache_range(MHU_SECURE_AP_TO_SCP_PAYLOAD, size); + + mhu_secure_message_send(command | (size << SIZE_SHIFT)); +} + +unsigned scpi_secure_message_receive(void **message_out, size_t *size_out) +{ + uint32_t response = mhu_secure_message_wait(); + + /* Get size of payload */ + size_t size = (response >> SIZE_SHIFT) & SIZE_MASK; + + /* Clear size from response */ + response &= ~(SIZE_MASK << SIZE_SHIFT); + + /* Make sure we don't read stale data */ + if (MHU_PAYLOAD_CACHED) + inv_dcache_range(MHU_SECURE_SCP_TO_AP_PAYLOAD, size); + + if (size_out) + *size_out = size; + + if (message_out) + *message_out = (void *)MHU_SECURE_SCP_TO_AP_PAYLOAD; + + return response; +} + +void scpi_secure_message_end(void) +{ + mhu_secure_message_end(); +} + +static void scpi_secure_send32(unsigned command, uint32_t message) +{ + *(__typeof__(message) *)scpi_secure_message_start() = message; + scpi_secure_message_send(command, sizeof(message)); + scpi_secure_message_end(); +} + +int scpi_wait_ready(void) + { + /* Get a message from the SCP */ + scpi_secure_message_start(); + size_t size; + unsigned command = scpi_secure_message_receive(NULL, &size); + scpi_secure_message_end(); + + /* We are expecting 'SCP Ready', produce correct error if it's not */ + spci_status response = SCP_OK; + if (command != SCPI_CMD_SCP_READY) + response = SCP_E_SUPPORT; + else if (size != 0) + response = SCP_E_SIZE; + + /* Send our response back to SCP */ + scpi_secure_send32(command, response); + + return response == SCP_OK ? 0 : -1; + } + +void scpi_set_css_power_state(unsigned mpidr, scpi_power_state cpu_state, + scpi_power_state cluster_state, scpi_power_state css_state) +{ + uint32_t state = mpidr & 0x0f; /* CPU ID */ + state |= (mpidr & 0xf00) >> 4; /* Cluster ID */ + state |= cpu_state << 8; + state |= cluster_state << 12; + state |= css_state << 16; + scpi_secure_send32(SCPI_CMD_SET_CSS_POWER_STATE, state); +} diff --git a/plat/juno/scpi.h b/plat/juno/scpi.h new file mode 100644 index 0000000..4ddbeea --- /dev/null +++ b/plat/juno/scpi.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __SCPI_H__ +#define __SCPI_H__ + +#include <stddef.h> +#include <stdint.h> + +extern void *scpi_secure_message_start(void); +extern void scpi_secure_message_send(unsigned command, size_t size); +extern unsigned scpi_secure_message_receive(void ** message_out, size_t *size_out); +extern void scpi_secure_message_end(void); + + +enum { + SCP_OK = 0, /* Success */ + SCP_E_PARAM, /* Invalid parameter(s) */ + SCP_E_ALIGN, /* Invalid alignment */ + SCP_E_SIZE, /* Invalid size */ + SCP_E_HANDLER, /* Invalid handler or callback */ + SCP_E_ACCESS, /* Invalid access or permission denied */ + SCP_E_RANGE, /* Value out of range */ + SCP_E_TIMEOUT, /* Time out has ocurred */ + SCP_E_NOMEM, /* Invalid memory area or pointer */ + SCP_E_PWRSTATE, /* Invalid power state */ + SCP_E_SUPPORT, /* Feature not supported or disabled */ +}; + +typedef uint32_t spci_status; + +typedef enum { + SCPI_CMD_SCP_READY = 0x01, + SCPI_CMD_SET_CSS_POWER_STATE = 0x04, +} spci_command; + +typedef enum { + scpi_power_on = 0, + scpi_power_retention = 1, + scpi_power_off = 3, +} scpi_power_state; + +extern int scpi_wait_ready(void); +extern void scpi_set_css_power_state(unsigned mpidr, scpi_power_state cpu_state, + scpi_power_state cluster_state, scpi_power_state css_state); + +#endif /* __SCPI_H__ */ diff --git a/plat/juno/smc_arm.c b/plat/juno/smc_arm.c new file mode 100644 index 0000000..c6b3c9b --- /dev/null +++ b/plat/juno/smc_arm.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <psci.h> +#include <runtime_svc.h> + +#define ARM_SMC_ARM_CPU_SUSPEND 0x80100001 +#define ARM_SMC_ARM_CPU_OFF 0x80100002 +#define ARM_SMC_ARM_CPU_ON 0x80100003 +#define ARM_SMC_ARM_MIGRATE 0x80100004 + +#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_PRESENCE 0x80FFFF00 +#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_UID 0x80FFFF10 + +#define ARM_TRUSTZONE_UID_4LETTERID 0x1 +#define ARM_TRUSTZONE_ARM_UID 0x40524d48 /* "ARMH" */ + + +static uint64_t smc_arm_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, + uint64_t x3, uint64_t x4, void *cookie, + void *handle, uint64_t flags) +{ + switch (smc_fid) { + + /* + * HACK WARNING: Below we use SMC_RET4 to return the original contents + * of x1-x3. We do this because UEFI is expecting these values to be + * preserved across the SMC call. + */ + + case ARM_TRUSTZONE_ARM_FAST_SMC_ID_PRESENCE: + SMC_RET4(handle, 1, x1, x2, x3); + break; + + case ARM_TRUSTZONE_ARM_FAST_SMC_ID_UID + 0: + SMC_RET4(handle, ARM_TRUSTZONE_UID_4LETTERID, x1, x2, x3); + break; + + case ARM_TRUSTZONE_ARM_FAST_SMC_ID_UID + 1: + SMC_RET4(handle, ARM_TRUSTZONE_ARM_UID, x1, x2, x3); + break; + + /* The following 3 cases translate functions into the PSCI equivalent */ + + case ARM_SMC_ARM_CPU_OFF: + smc_fid = PSCI_CPU_OFF; + break; + + case ARM_SMC_ARM_CPU_SUSPEND: + smc_fid = PSCI_CPU_SUSPEND_AARCH64; + break; + + case ARM_SMC_ARM_CPU_ON: + smc_fid = PSCI_CPU_ON_AARCH64; + break; + + } + + return psci_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); +} + +static int32_t smc_arm_setup(void) +{ + return 0; +} + +DECLARE_RT_SVC(arm, OEN_ARM_START, OEN_ARM_END, SMC_TYPE_FAST, + smc_arm_setup, smc_arm_handler); diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..357a969 --- /dev/null +++ b/readme.md @@ -0,0 +1,151 @@ +ARM Trusted Firmware - version 0.4 +================================== + +ARM Trusted Firmware provides a reference implementation of secure world +software for [ARMv8-A], including Exception Level 3 (EL3) software. This +release focuses on support for ARM's [Fixed Virtual Platforms (FVPs)] [FVP]. + +The intent is to provide a reference implementation of various ARM interface +standards, such as the Power State Coordination Interface ([PSCI]), Trusted +Board Boot Requirements (TBBR) and [Secure Monitor] [TEE-SMC] code. As far as +possible the code is designed for reuse or porting to other ARMv8-A model and +hardware platforms. + +This release builds on previous source code releases, supporting the Base and +Foundation FVP platform models from ARM. + +ARM will continue development in collaboration with interested parties to +provide a full reference implementation of PSCI, TBBR and Secure Monitor code +to the benefit of all developers working with ARMv8-A TrustZone technology. + + +License +------- + +The software is provided under a BSD 3-Clause [license]. Certain source files +are derived from FreeBSD code: the original license is included in these +source files. + + +This Release +------------ + +This release is a limited functionality implementation of the Trusted Firmware. +It provides a suitable starting point for productization. Future versions will +contain new features, optimizations and quality improvements. + +### Functionality + +* Initial implementation of a subset of the Trusted Board Boot Requirements + Platform Design Document (PDD). This includes packaging the various firmware + images into a Firmware Image Package (FIP) to be loaded from non-volatile + storage. + +* Initializes the secure world (for example, exception vectors, control + registers, GIC and interrupts for the platform), before transitioning into + the normal world. + +* Supports both GICv2 and GICv3 initialization for use by normal world + software. + +* Starts the normal world at the highest available Exception Level: EL2 + if available, otherwise EL1. + +* Handles SMCs (Secure Monitor Calls) conforming to the [SMC Calling + Convention PDD] [SMCCC] using an EL3 runtime services framework. + +* Handles SMCs relating to the [Power State Coordination Interface PDD] [PSCI] + for the Secondary CPU Boot, CPU hotplug and CPU idle use-cases. + +* A Test Secure-EL1 Payload and Dispatcher to demonstrate Secure Monitor + functionality such as world switching, EL1 context management and interrupt + routing. This also demonstrates Secure-EL1 interaction with PSCI. Some of + this functionality is provided in library form for re-use by other + Secure-EL1 Payload Dispatchers. + +* Support for alternative Trusted Boot Firmware. Some platforms have their own + Trusted Boot implementation and only require the Secure Monitor + functionality provided by ARM Trusted Firmware. + +* Isolation of memory accessible by the secure world from the normal world + through programming of a TrustZone controller. + +For a full description of functionality and implementation details, please +see the [Firmware Design] and supporting documentation. The [Change Log] +provides details of changes made since the last release. + +### Platforms + +This release of the Trusted Firmware has been tested on the following ARM +[FVP]s (64-bit versions only): + +* `Foundation_v8` (Version 2.0, Build 0.8.5206) +* `FVP_Base_AEMv8A-AEMv8A` (Version 5.6, Build 0.8.5602) +* `FVP_Base_Cortex-A57x4-A53x4` (Version 5.6, Build 0.8.5602) +* `FVP_Base_Cortex-A57x1-A53x1` (Version 5.6, Build 0.8.5602) +* `FVP_Base_Cortex-A57x2-A53x4` (Version 5.6, Build 0.8.5602) + +The Foundation FVP can be downloaded free of charge. The Base FVPs can be +licensed from ARM: see [www.arm.com/fvp] [FVP]. + +### Still to Come + +* Support for ARMv8-A development board as a reference platform. + +* Complete Trusted Boot implementation. + +* Complete implementation of the [PSCI] specification. + +* Support for alternative types of Secure-EL1 Payloads. + +* Completing the currently experimental GICv3 support. + +For a full list of detailed issues in the current code, please see the [Change +Log] and the [GitHub issue tracker]. + + +Getting Started +--------------- + +Get the Trusted Firmware source code from +[GitHub](https://www.github.com/ARM-software/arm-trusted-firmware). + +See the [User Guide] for instructions on how to install, build and use +the Trusted Firmware with the ARM [FVP]s. + +See the [Firmware Design] for information on how the ARM Trusted Firmware works. + +See the [Porting Guide] as well for information about how to use this +software on another ARMv8-A platform. + +See the [Contributing Guidelines] for information on how to contribute to this +project and the [Acknowledgments] file for a list of contributors to the +project. + +### Feedback and support + +ARM welcomes any feedback on the Trusted Firmware. Please send feedback using +the [GitHub issue tracker]. + +ARM licensees may contact ARM directly via their partner managers. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - + +_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._ + + +[License]: ./license.md "BSD license for ARM Trusted Firmware" +[Contributing Guidelines]: ./contributing.md "Guidelines for contributors" +[Acknowledgments]: ./acknowledgements.md "Contributor acknowledgments" +[Change Log]: ./docs/change-log.md +[User Guide]: ./docs/user-guide.md +[Firmware Design]: ./docs/firmware-design.md +[Porting Guide]: ./docs/porting-guide.md + +[ARMv8-A]: http://www.arm.com/products/processors/armv8-architecture.php "ARMv8-A Architecture" +[FVP]: http://www.arm.com/fvp "ARM's Fixed Virtual Platforms" +[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022b/index.html "Power State Coordination Interface PDD (ARM DEN 0022B.b)" +[SMCCC]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)" +[TEE-SMC]: http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php "Secure Monitor and TEEs" +[GitHub issue tracker]: https://github.com/ARM-software/tf-issues/issues diff --git a/services/spd/tspd/tspd.mk b/services/spd/tspd/tspd.mk new file mode 100644 index 0000000..a32f4c4 --- /dev/null +++ b/services/spd/tspd/tspd.mk @@ -0,0 +1,54 @@ +# +# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 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. +# +# Neither the name of ARM nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific +# prior written permission. +# +# 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. +# + +TSPD_DIR := services/spd/tspd +SPD_INCLUDES := -Iinclude/bl32/payloads + +SPD_SOURCES := services/spd/tspd/tspd_common.c \ + services/spd/tspd/tspd_helpers.S \ + services/spd/tspd/tspd_main.c \ + services/spd/tspd/tspd_pm.c + +# This dispatcher is paired with a Test Secure Payload source and we intend to +# build the Test Secure Payload along with this dispatcher. +# +# In cases where an associated Secure Payload lies outside this build +# system/source tree, the the dispatcher Makefile can either invoke an external +# build command or assume it pre-built + +BL32_ROOT := bl32/tsp + +# Include SP's Makefile. The assumption is that the TSP's build system is +# compatible with that of Trusted Firmware, and it'll add and populate necessary +# build targets and variables +include ${BL32_ROOT}/tsp.mk + +# Let the top-level Makefile know that we intend to build the SP from source +NEED_BL32 := yes diff --git a/services/spd/tspd/tspd_common.c b/services/spd/tspd/tspd_common.c new file mode 100644 index 0000000..6b3592e --- /dev/null +++ b/services/spd/tspd/tspd_common.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <context_mgmt.h> +#include <string.h> +#include "tspd_private.h" + +/******************************************************************************* + * Given a secure payload entrypoint, register width, cpu id & pointer to a + * context data structure, this function will create a secure context ready for + * programming an entry into the secure payload. + ******************************************************************************/ +int32_t tspd_init_secure_context(uint64_t entrypoint, + uint32_t rw, + uint64_t mpidr, + tsp_context_t *tsp_ctx) +{ + uint32_t scr, sctlr; + el1_sys_regs_t *el1_state; + uint32_t spsr; + + /* Passing a NULL context is a critical programming error */ + assert(tsp_ctx); + + /* + * We support AArch64 TSP for now. + * TODO: Add support for AArch32 TSP + */ + assert(rw == TSP_AARCH64); + + /* + * This might look redundant if the context was statically + * allocated but this function cannot make that assumption. + */ + memset(tsp_ctx, 0, sizeof(*tsp_ctx)); + + /* + * Set the right security state, register width and enable access to + * the secure physical timer for the SP. + */ + scr = read_scr(); + scr &= ~SCR_NS_BIT; + scr &= ~SCR_RW_BIT; + scr |= SCR_ST_BIT; + if (rw == TSP_AARCH64) + scr |= SCR_RW_BIT; + + /* Get a pointer to the S-EL1 context memory */ + el1_state = get_sysregs_ctx(&tsp_ctx->cpu_ctx); + + /* + * Program the SCTLR_EL1 such that upon entry in S-EL1, caches and MMU are + * disabled and exception endianess is set to be the same as EL3 + */ + sctlr = read_sctlr_el3(); + sctlr &= SCTLR_EE_BIT; + sctlr |= SCTLR_EL1_RES1; + write_ctx_reg(el1_state, CTX_SCTLR_EL1, sctlr); + + /* Set this context as ready to be initialised i.e OFF */ + set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_OFF); + + /* + * This context has not been used yet. It will become valid + * when the TSP is interrupted and wants the TSPD to preserve + * the context. + */ + clr_std_smc_active_flag(tsp_ctx->state); + + /* Associate this context with the cpu specified */ + tsp_ctx->mpidr = mpidr; + + cm_set_context(mpidr, &tsp_ctx->cpu_ctx, SECURE); + spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + cm_set_el3_eret_context(SECURE, entrypoint, spsr, scr); + + return 0; +} + +/******************************************************************************* + * This function takes an SP context pointer and: + * 1. Applies the S-EL1 system register context from tsp_ctx->cpu_ctx. + * 2. Saves the current C runtime state (callee saved registers) on the stack + * frame and saves a reference to this state. + * 3. Calls el3_exit() so that the EL3 system and general purpose registers + * from the tsp_ctx->cpu_ctx are used to enter the secure payload image. + ******************************************************************************/ +uint64_t tspd_synchronous_sp_entry(tsp_context_t *tsp_ctx) +{ + uint64_t rc; + + assert(tsp_ctx->c_rt_ctx == 0); + + /* Apply the Secure EL1 system register context and switch to it */ + assert(cm_get_context(read_mpidr(), SECURE) == &tsp_ctx->cpu_ctx); + cm_el1_sysregs_context_restore(SECURE); + cm_set_next_eret_context(SECURE); + + rc = tspd_enter_sp(&tsp_ctx->c_rt_ctx); +#if DEBUG + tsp_ctx->c_rt_ctx = 0; +#endif + + return rc; +} + + +/******************************************************************************* + * This function takes an SP context pointer and: + * 1. Saves the S-EL1 system register context tp tsp_ctx->cpu_ctx. + * 2. Restores the current C runtime state (callee saved registers) from the + * stack frame using the reference to this state saved in tspd_enter_sp(). + * 3. It does not need to save any general purpose or EL3 system register state + * as the generic smc entry routine should have saved those. + ******************************************************************************/ +void tspd_synchronous_sp_exit(tsp_context_t *tsp_ctx, uint64_t ret) +{ + /* Save the Secure EL1 system register context */ + assert(cm_get_context(read_mpidr(), SECURE) == &tsp_ctx->cpu_ctx); + cm_el1_sysregs_context_save(SECURE); + + assert(tsp_ctx->c_rt_ctx != 0); + tspd_exit_sp(tsp_ctx->c_rt_ctx, ret); + + /* Should never reach here */ + assert(0); +} diff --git a/services/spd/tspd/tspd_helpers.S b/services/spd/tspd/tspd_helpers.S new file mode 100644 index 0000000..dd3b07b --- /dev/null +++ b/services/spd/tspd/tspd_helpers.S @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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_macros.S> +#include "tspd_private.h" + + .global tspd_enter_sp + /* --------------------------------------------- + * This function is called with SP_EL0 as stack. + * Here we stash our EL3 callee-saved registers + * on to the stack as a part of saving the C + * runtime and enter the secure payload. + * 'x0' contains a pointer to the memory where + * the address of the C runtime context is to be + * saved. + * --------------------------------------------- + */ +func tspd_enter_sp + /* Make space for the registers that we're going to save */ + mov x3, sp + str x3, [x0, #0] + sub sp, sp, #TSPD_C_RT_CTX_SIZE + + /* Save callee-saved registers on to the stack */ + stp x19, x20, [sp, #TSPD_C_RT_CTX_X19] + stp x21, x22, [sp, #TSPD_C_RT_CTX_X21] + stp x23, x24, [sp, #TSPD_C_RT_CTX_X23] + stp x25, x26, [sp, #TSPD_C_RT_CTX_X25] + stp x27, x28, [sp, #TSPD_C_RT_CTX_X27] + stp x29, x30, [sp, #TSPD_C_RT_CTX_X29] + + /* --------------------------------------------- + * Everything is setup now. el3_exit() will + * use the secure context to restore to the + * general purpose and EL3 system registers to + * ERET into the secure payload. + * --------------------------------------------- + */ + b el3_exit + + /* --------------------------------------------- + * This function is called 'x0' pointing to a C + * runtime context saved in tspd_enter_sp(). It + * restores the saved registers and jumps to + * that runtime with 'x0' as the new sp. This + * destroys the C runtime context that had been + * built on the stack below the saved context by + * the caller. Later the second parameter 'x1' + * is passed as return value to the caller + * --------------------------------------------- + */ + .global tspd_exit_sp +func tspd_exit_sp + /* Restore the previous stack */ + mov sp, x0 + + /* Restore callee-saved registers on to the stack */ + ldp x19, x20, [x0, #(TSPD_C_RT_CTX_X19 - TSPD_C_RT_CTX_SIZE)] + ldp x21, x22, [x0, #(TSPD_C_RT_CTX_X21 - TSPD_C_RT_CTX_SIZE)] + ldp x23, x24, [x0, #(TSPD_C_RT_CTX_X23 - TSPD_C_RT_CTX_SIZE)] + ldp x25, x26, [x0, #(TSPD_C_RT_CTX_X25 - TSPD_C_RT_CTX_SIZE)] + ldp x27, x28, [x0, #(TSPD_C_RT_CTX_X27 - TSPD_C_RT_CTX_SIZE)] + ldp x29, x30, [x0, #(TSPD_C_RT_CTX_X29 - TSPD_C_RT_CTX_SIZE)] + + /* --------------------------------------------- + * This should take us back to the instruction + * after the call to the last tspd_enter_sp(). + * Place the second parameter to x0 so that the + * caller will see it as a return value from the + * original entry call + * --------------------------------------------- + */ + mov x0, x1 + ret diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c new file mode 100644 index 0000000..1a6913a --- /dev/null +++ b/services/spd/tspd/tspd_main.c @@ -0,0 +1,593 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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. + */ + + +/******************************************************************************* + * This is the Secure Payload Dispatcher (SPD). The dispatcher is meant to be a + * plug-in component to the Secure Monitor, registered as a runtime service. The + * SPD is expected to be a functional extension of the Secure Payload (SP) that + * executes in Secure EL1. The Secure Monitor will delegate all SMCs targeting + * the Trusted OS/Applications range to the dispatcher. The SPD will either + * handle the request locally or delegate it to the Secure Payload. It is also + * responsible for initialising and maintaining communication with the SP. + ******************************************************************************/ +#include <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <bl31.h> +#include <context_mgmt.h> +#include <debug.h> +#include <errno.h> +#include <platform.h> +#include <runtime_svc.h> +#include <stddef.h> +#include <tsp.h> +#include <uuid.h> +#include "tspd_private.h" + +/******************************************************************************* + * Address of the entrypoint vector table in the Secure Payload. It is + * initialised once on the primary core after a cold boot. + ******************************************************************************/ +tsp_vectors_t *tsp_vectors; + +/******************************************************************************* + * Array to keep track of per-cpu Secure Payload state + ******************************************************************************/ +tsp_context_t tspd_sp_context[TSPD_CORE_COUNT]; + + +/* TSP UID */ +DEFINE_SVC_UUID(tsp_uuid, + 0x5b3056a0, 0x3291, 0x427b, 0x98, 0x11, + 0x71, 0x68, 0xca, 0x50, 0xf3, 0xfa); + +int32_t tspd_init(void); + +/******************************************************************************* + * This function is the handler registered for S-EL1 interrupts by the TSPD. It + * validates the interrupt and upon success arranges entry into the TSP at + * 'tsp_fiq_entry()' for handling the interrupt. + ******************************************************************************/ +static uint64_t tspd_sel1_interrupt_handler(uint32_t id, + uint32_t flags, + void *handle, + void *cookie) +{ + uint32_t linear_id; + uint64_t mpidr; + tsp_context_t *tsp_ctx; + + /* Check the security state when the exception was generated */ + assert(get_interrupt_src_ss(flags) == NON_SECURE); + +#if IMF_READ_INTERRUPT_ID + /* Check the security status of the interrupt */ + assert(plat_ic_get_interrupt_type(id) == INTR_TYPE_S_EL1); +#endif + + /* Sanity check the pointer to this cpu's context */ + mpidr = read_mpidr(); + assert(handle == cm_get_context(mpidr, NON_SECURE)); + + /* Save the non-secure context before entering the TSP */ + cm_el1_sysregs_context_save(NON_SECURE); + + /* Get a reference to this cpu's TSP context */ + linear_id = platform_get_core_pos(mpidr); + tsp_ctx = &tspd_sp_context[linear_id]; + assert(&tsp_ctx->cpu_ctx == cm_get_context(mpidr, SECURE)); + + /* + * Determine if the TSP was previously preempted. Its last known + * context has to be preserved in this case. + * The TSP should return control to the TSPD after handling this + * FIQ. Preserve essential EL3 context to allow entry into the + * TSP at the FIQ entry point using the 'cpu_context' structure. + * There is no need to save the secure system register context + * since the TSP is supposed to preserve it during S-EL1 interrupt + * handling. + */ + if (get_std_smc_active_flag(tsp_ctx->state)) { + tsp_ctx->saved_spsr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx, + CTX_SPSR_EL3); + tsp_ctx->saved_elr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx, + CTX_ELR_EL3); + } + + SMC_SET_EL3(&tsp_ctx->cpu_ctx, + CTX_SPSR_EL3, + SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS)); + SMC_SET_EL3(&tsp_ctx->cpu_ctx, + CTX_ELR_EL3, + (uint64_t) &tsp_vectors->fiq_entry); + cm_el1_sysregs_context_restore(SECURE); + cm_set_next_eret_context(SECURE); + + /* + * Tell the TSP that it has to handle an FIQ synchronously. Also the + * instruction in normal world where the interrupt was generated is + * passed for debugging purposes. It is safe to retrieve this address + * from ELR_EL3 as the secure context will not take effect until + * el3_exit(). + */ + SMC_RET2(&tsp_ctx->cpu_ctx, TSP_HANDLE_FIQ_AND_RETURN, read_elr_el3()); +} + +/******************************************************************************* + * Secure Payload Dispatcher setup. The SPD finds out the SP entrypoint and type + * (aarch32/aarch64) if not already known and initialises the context for entry + * into the SP for its initialisation. + ******************************************************************************/ +int32_t tspd_setup(void) +{ + entry_point_info_t *image_info; + int32_t rc; + uint64_t mpidr = read_mpidr(); + uint32_t linear_id; + + linear_id = platform_get_core_pos(mpidr); + + /* + * Get information about the Secure Payload (BL32) image. Its + * absence is a critical failure. TODO: Add support to + * conditionally include the SPD service + */ + image_info = bl31_plat_get_next_image_ep_info(SECURE); + assert(image_info); + + /* + * If there's no valid entry point for SP, we return a non-zero value + * signalling failure initializing the service. We bail out without + * registering any handlers + */ + if (!image_info->pc) + return 1; + + /* + * We could inspect the SP image and determine it's execution + * state i.e whether AArch32 or AArch64. Assuming it's AArch64 + * for the time being. + */ + rc = tspd_init_secure_context(image_info->pc, + TSP_AARCH64, + mpidr, + &tspd_sp_context[linear_id]); + assert(rc == 0); + + /* + * All TSPD initialization done. Now register our init function with + * BL31 for deferred invocation + */ + bl31_register_bl32_init(&tspd_init); + + return rc; +} + +/******************************************************************************* + * This function passes control to the Secure Payload image (BL32) for the first + * time on the primary cpu after a cold boot. It assumes that a valid secure + * context has already been created by tspd_setup() which can be directly used. + * It also assumes that a valid non-secure context has been initialised by PSCI + * so it does not need to save and restore any non-secure state. This function + * performs a synchronous entry into the Secure payload. The SP passes control + * back to this routine through a SMC. + ******************************************************************************/ +int32_t tspd_init(void) +{ + uint64_t mpidr = read_mpidr(); + uint32_t linear_id = platform_get_core_pos(mpidr), flags; + uint64_t rc; + tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id]; + + /* + * Arrange for an entry into the test secure payload. We expect an array + * of vectors in return + */ + rc = tspd_synchronous_sp_entry(tsp_ctx); + assert(rc != 0); + if (rc) { + set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_ON); + + /* + * TSP has been successfully initialized. Register power + * managemnt hooks with PSCI + */ + psci_register_spd_pm_hook(&tspd_pm); + } + + /* + * Register an interrupt handler for S-EL1 interrupts when generated + * during code executing in the non-secure state. + */ + flags = 0; + set_interrupt_rm_flag(flags, NON_SECURE); + rc = register_interrupt_type_handler(INTR_TYPE_S_EL1, + tspd_sel1_interrupt_handler, + flags); + if (rc) + panic(); + + return rc; +} + + +/******************************************************************************* + * This function is responsible for handling all SMCs in the Trusted OS/App + * range from the non-secure state as defined in the SMC Calling Convention + * Document. It is also responsible for communicating with the Secure payload + * to delegate work and return results back to the non-secure state. Lastly it + * will also return any information that the secure payload needs to do the + * work assigned to it. + ******************************************************************************/ +uint64_t tspd_smc_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *cookie, + void *handle, + uint64_t flags) +{ + cpu_context_t *ns_cpu_context; + unsigned long mpidr = read_mpidr(); + uint32_t linear_id = platform_get_core_pos(mpidr), ns; + tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id]; + + /* Determine which security state this SMC originated from */ + ns = is_caller_non_secure(flags); + + switch (smc_fid) { + + /* + * This function ID is used by TSP to indicate that it was + * preempted by a normal world IRQ. + * + */ + case TSP_PREEMPTED: + if (ns) + SMC_RET1(handle, SMC_UNK); + + assert(handle == cm_get_context(mpidr, SECURE)); + cm_el1_sysregs_context_save(SECURE); + /* Get a reference to the non-secure context */ + ns_cpu_context = cm_get_context(mpidr, NON_SECURE); + assert(ns_cpu_context); + + /* + * Restore non-secure state. There is no need to save the + * secure system register context since the TSP was supposed + * to preserve it during S-EL1 interrupt handling. + */ + cm_el1_sysregs_context_restore(NON_SECURE); + cm_set_next_eret_context(NON_SECURE); + + SMC_RET1(ns_cpu_context, SMC_PREEMPTED); + + /* + * This function ID is used only by the TSP to indicate that it has + * finished handling a S-EL1 FIQ interrupt. Execution should resume + * in the normal world. + */ + case TSP_HANDLED_S_EL1_FIQ: + if (ns) + SMC_RET1(handle, SMC_UNK); + + assert(handle == cm_get_context(mpidr, SECURE)); + + /* + * Restore the relevant EL3 state which saved to service + * this SMC. + */ + if (get_std_smc_active_flag(tsp_ctx->state)) { + SMC_SET_EL3(&tsp_ctx->cpu_ctx, + CTX_SPSR_EL3, + tsp_ctx->saved_spsr_el3); + SMC_SET_EL3(&tsp_ctx->cpu_ctx, + CTX_ELR_EL3, + tsp_ctx->saved_elr_el3); + } + + /* Get a reference to the non-secure context */ + ns_cpu_context = cm_get_context(mpidr, NON_SECURE); + assert(ns_cpu_context); + + /* + * Restore non-secure state. There is no need to save the + * secure system register context since the TSP was supposed + * to preserve it during S-EL1 interrupt handling. + */ + cm_el1_sysregs_context_restore(NON_SECURE); + cm_set_next_eret_context(NON_SECURE); + + SMC_RET0((uint64_t) ns_cpu_context); + + + /* + * This function ID is used only by the TSP to indicate that it was + * interrupted due to a EL3 FIQ interrupt. Execution should resume + * in the normal world. + */ + case TSP_EL3_FIQ: + if (ns) + SMC_RET1(handle, SMC_UNK); + + assert(handle == cm_get_context(mpidr, SECURE)); + + /* Assert that standard SMC execution has been preempted */ + assert(get_std_smc_active_flag(tsp_ctx->state)); + + /* Save the secure system register state */ + cm_el1_sysregs_context_save(SECURE); + + /* Get a reference to the non-secure context */ + ns_cpu_context = cm_get_context(mpidr, NON_SECURE); + assert(ns_cpu_context); + + /* Restore non-secure state */ + cm_el1_sysregs_context_restore(NON_SECURE); + cm_set_next_eret_context(NON_SECURE); + + SMC_RET1(ns_cpu_context, TSP_EL3_FIQ); + + + /* + * This function ID is used only by the SP to indicate it has + * finished initialising itself after a cold boot + */ + case TSP_ENTRY_DONE: + if (ns) + SMC_RET1(handle, SMC_UNK); + + /* + * Stash the SP entry points information. This is done + * only once on the primary cpu + */ + assert(tsp_vectors == NULL); + tsp_vectors = (tsp_vectors_t *) x1; + + /* + * SP reports completion. The SPD must have initiated + * the original request through a synchronous entry + * into the SP. Jump back to the original C runtime + * context. + */ + tspd_synchronous_sp_exit(tsp_ctx, x1); + + /* + * These function IDs is used only by the SP to indicate it has + * finished: + * 1. turning itself on in response to an earlier psci + * cpu_on request + * 2. resuming itself after an earlier psci cpu_suspend + * request. + */ + case TSP_ON_DONE: + case TSP_RESUME_DONE: + + /* + * These function IDs is used only by the SP to indicate it has + * finished: + * 1. suspending itself after an earlier psci cpu_suspend + * request. + * 2. turning itself off in response to an earlier psci + * cpu_off request. + */ + case TSP_OFF_DONE: + case TSP_SUSPEND_DONE: + if (ns) + SMC_RET1(handle, SMC_UNK); + + /* + * SP reports completion. The SPD must have initiated the + * original request through a synchronous entry into the SP. + * Jump back to the original C runtime context, and pass x1 as + * return value to the caller + */ + tspd_synchronous_sp_exit(tsp_ctx, x1); + + /* + * Request from non-secure client to perform an + * arithmetic operation or response from secure + * payload to an earlier request. + */ + case TSP_FAST_FID(TSP_ADD): + case TSP_FAST_FID(TSP_SUB): + case TSP_FAST_FID(TSP_MUL): + case TSP_FAST_FID(TSP_DIV): + + case TSP_STD_FID(TSP_ADD): + case TSP_STD_FID(TSP_SUB): + case TSP_STD_FID(TSP_MUL): + case TSP_STD_FID(TSP_DIV): + if (ns) { + /* + * This is a fresh request from the non-secure client. + * The parameters are in x1 and x2. Figure out which + * registers need to be preserved, save the non-secure + * state and send the request to the secure payload. + */ + assert(handle == cm_get_context(mpidr, NON_SECURE)); + + /* Check if we are already preempted */ + if (get_std_smc_active_flag(tsp_ctx->state)) + SMC_RET1(handle, SMC_UNK); + + cm_el1_sysregs_context_save(NON_SECURE); + + /* Save x1 and x2 for use by TSP_GET_ARGS call below */ + store_tsp_args(tsp_ctx, x1, x2); + + /* + * We are done stashing the non-secure context. Ask the + * secure payload to do the work now. + */ + + /* + * Verify if there is a valid context to use, copy the + * operation type and parameters to the secure context + * and jump to the fast smc entry point in the secure + * payload. Entry into S-EL1 will take place upon exit + * from this function. + */ + assert(&tsp_ctx->cpu_ctx == cm_get_context(mpidr, SECURE)); + + /* Set appropriate entry for SMC. + * We expect the TSP to manage the PSTATE.I and PSTATE.F + * flags as appropriate. + */ + if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_FAST) { + cm_set_elr_el3(SECURE, (uint64_t) + &tsp_vectors->fast_smc_entry); + } else { + set_std_smc_active_flag(tsp_ctx->state); + cm_set_elr_el3(SECURE, (uint64_t) + &tsp_vectors->std_smc_entry); + } + + cm_el1_sysregs_context_restore(SECURE); + cm_set_next_eret_context(SECURE); + SMC_RET3(&tsp_ctx->cpu_ctx, smc_fid, x1, x2); + } else { + /* + * This is the result from the secure client of an + * earlier request. The results are in x1-x3. Copy it + * into the non-secure context, save the secure state + * and return to the non-secure state. + */ + assert(handle == cm_get_context(mpidr, SECURE)); + cm_el1_sysregs_context_save(SECURE); + + /* Get a reference to the non-secure context */ + ns_cpu_context = cm_get_context(mpidr, NON_SECURE); + assert(ns_cpu_context); + + /* Restore non-secure state */ + cm_el1_sysregs_context_restore(NON_SECURE); + cm_set_next_eret_context(NON_SECURE); + if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_STD) + clr_std_smc_active_flag(tsp_ctx->state); + SMC_RET3(ns_cpu_context, x1, x2, x3); + } + + break; + + /* + * Request from non secure world to resume the preempted + * Standard SMC call. + */ + case TSP_FID_RESUME: + /* RESUME should be invoked only by normal world */ + if (!ns) { + assert(0); + break; + } + + /* + * This is a resume request from the non-secure client. + * save the non-secure state and send the request to + * the secure payload. + */ + assert(handle == cm_get_context(mpidr, NON_SECURE)); + + /* Check if we are already preempted before resume */ + if (!get_std_smc_active_flag(tsp_ctx->state)) + SMC_RET1(handle, SMC_UNK); + + cm_el1_sysregs_context_save(NON_SECURE); + + /* + * We are done stashing the non-secure context. Ask the + * secure payload to do the work now. + */ + + /* We just need to return to the preempted point in + * TSP and the execution will resume as normal. + */ + cm_el1_sysregs_context_restore(SECURE); + cm_set_next_eret_context(SECURE); + SMC_RET0(&tsp_ctx->cpu_ctx); + + /* + * This is a request from the secure payload for more arguments + * for an ongoing arithmetic operation requested by the + * non-secure world. Simply return the arguments from the non- + * secure client in the original call. + */ + case TSP_GET_ARGS: + if (ns) + SMC_RET1(handle, SMC_UNK); + + get_tsp_args(tsp_ctx, x1, x2); + SMC_RET2(handle, x1, x2); + + case TOS_CALL_COUNT: + /* + * Return the number of service function IDs implemented to + * provide service to non-secure + */ + SMC_RET1(handle, TSP_NUM_FID); + + case TOS_UID: + /* Return TSP UID to the caller */ + SMC_UUID_RET(handle, tsp_uuid); + + case TOS_CALL_VERSION: + /* Return the version of current implementation */ + SMC_RET2(handle, TSP_VERSION_MAJOR, TSP_VERSION_MINOR); + + default: + break; + } + + SMC_RET1(handle, SMC_UNK); +} + +/* Define a SPD runtime service descriptor for fast SMC calls */ +DECLARE_RT_SVC( + tspd_fast, + + OEN_TOS_START, + OEN_TOS_END, + SMC_TYPE_FAST, + tspd_setup, + tspd_smc_handler +); + +/* Define a SPD runtime service descriptor for standard SMC calls */ +DECLARE_RT_SVC( + tspd_std, + + OEN_TOS_START, + OEN_TOS_END, + SMC_TYPE_STD, + NULL, + tspd_smc_handler +); diff --git a/services/spd/tspd/tspd_pm.c b/services/spd/tspd/tspd_pm.c new file mode 100644 index 0000000..ec4989d --- /dev/null +++ b/services/spd/tspd/tspd_pm.c @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <context_mgmt.h> +#include <debug.h> +#include <platform.h> +#include <tsp.h> +#include "tspd_private.h" + +/******************************************************************************* + * The target cpu is being turned on. Allow the TSPD/TSP to perform any actions + * needed. Nothing at the moment. + ******************************************************************************/ +static void tspd_cpu_on_handler(uint64_t target_cpu) +{ +} + +/******************************************************************************* + * This cpu is being turned off. Allow the TSPD/TSP to perform any actions + * needed + ******************************************************************************/ +static int32_t tspd_cpu_off_handler(uint64_t cookie) +{ + int32_t rc = 0; + uint64_t mpidr = read_mpidr(); + uint32_t linear_id = platform_get_core_pos(mpidr); + tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id]; + + assert(tsp_vectors); + assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_ON); + + /* Program the entry point and enter the TSP */ + cm_set_elr_el3(SECURE, (uint64_t) &tsp_vectors->cpu_off_entry); + rc = tspd_synchronous_sp_entry(tsp_ctx); + + /* + * Read the response from the TSP. A non-zero return means that + * something went wrong while communicating with the TSP. + */ + if (rc != 0) + panic(); + + /* + * Reset TSP's context for a fresh start when this cpu is turned on + * subsequently. + */ + set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_OFF); + + return 0; +} + +/******************************************************************************* + * This cpu is being suspended. S-EL1 state must have been saved in the + * resident cpu (mpidr format) if it is a UP/UP migratable TSP. + ******************************************************************************/ +static void tspd_cpu_suspend_handler(uint64_t power_state) +{ + int32_t rc = 0; + uint64_t mpidr = read_mpidr(); + uint32_t linear_id = platform_get_core_pos(mpidr); + tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id]; + + assert(tsp_vectors); + assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_ON); + + /* Program the entry point, power_state parameter and enter the TSP */ + write_ctx_reg(get_gpregs_ctx(&tsp_ctx->cpu_ctx), + CTX_GPREG_X0, + power_state); + cm_set_elr_el3(SECURE, (uint64_t) &tsp_vectors->cpu_suspend_entry); + rc = tspd_synchronous_sp_entry(tsp_ctx); + + /* + * Read the response from the TSP. A non-zero return means that + * something went wrong while communicating with the TSP. + */ + if (rc != 0) + panic(); + + /* Update its context to reflect the state the TSP is in */ + set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_SUSPEND); +} + +/******************************************************************************* + * This cpu has been turned on. Enter the TSP to initialise S-EL1 and other bits + * before passing control back to the Secure Monitor. Entry in S-El1 is done + * after initialising minimal architectural state that guarantees safe + * execution. + ******************************************************************************/ +static void tspd_cpu_on_finish_handler(uint64_t cookie) +{ + int32_t rc = 0; + uint64_t mpidr = read_mpidr(); + uint32_t linear_id = platform_get_core_pos(mpidr); + tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id]; + + assert(tsp_vectors); + assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_OFF); + + /* Initialise this cpu's secure context */ + tspd_init_secure_context((uint64_t) &tsp_vectors->cpu_on_entry, + TSP_AARCH64, + mpidr, + tsp_ctx); + + /* Enter the TSP */ + rc = tspd_synchronous_sp_entry(tsp_ctx); + + /* + * Read the response from the TSP. A non-zero return means that + * something went wrong while communicating with the SP. + */ + if (rc != 0) + panic(); + + /* Update its context to reflect the state the SP is in */ + set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_ON); +} + +/******************************************************************************* + * This cpu has resumed from suspend. The SPD saved the TSP context when it + * completed the preceding suspend call. Use that context to program an entry + * into the TSP to allow it to do any remaining book keeping + ******************************************************************************/ +static void tspd_cpu_suspend_finish_handler(uint64_t suspend_level) +{ + int32_t rc = 0; + uint64_t mpidr = read_mpidr(); + uint32_t linear_id = platform_get_core_pos(mpidr); + tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id]; + + assert(tsp_vectors); + assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_SUSPEND); + + /* Program the entry point, suspend_level and enter the SP */ + write_ctx_reg(get_gpregs_ctx(&tsp_ctx->cpu_ctx), + CTX_GPREG_X0, + suspend_level); + cm_set_elr_el3(SECURE, (uint64_t) &tsp_vectors->cpu_resume_entry); + rc = tspd_synchronous_sp_entry(tsp_ctx); + + /* + * Read the response from the TSP. A non-zero return means that + * something went wrong while communicating with the TSP. + */ + if (rc != 0) + panic(); + + /* Update its context to reflect the state the SP is in */ + set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_ON); +} + +/******************************************************************************* + * Return the type of TSP the TSPD is dealing with. Report the current resident + * cpu (mpidr format) if it is a UP/UP migratable TSP. + ******************************************************************************/ +static int32_t tspd_cpu_migrate_info(uint64_t *resident_cpu) +{ + return TSP_MIGRATE_INFO; +} + +/******************************************************************************* + * Structure populated by the TSP Dispatcher to be given a chance to perform any + * TSP bookkeeping before PSCI executes a power mgmt. operation. + ******************************************************************************/ +const spd_pm_ops_t tspd_pm = { + tspd_cpu_on_handler, + tspd_cpu_off_handler, + tspd_cpu_suspend_handler, + tspd_cpu_on_finish_handler, + tspd_cpu_suspend_finish_handler, + NULL, + tspd_cpu_migrate_info +}; + diff --git a/services/spd/tspd/tspd_private.h b/services/spd/tspd/tspd_private.h new file mode 100644 index 0000000..5d7bf4b --- /dev/null +++ b/services/spd/tspd/tspd_private.h @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __TSPD_PRIVATE_H__ +#define __TSPD_PRIVATE_H__ + +#include <arch.h> +#include <context.h> +#include <interrupt_mgmt.h> +#include <platform_def.h> +#include <psci.h> + +/******************************************************************************* + * Secure Payload PM state information e.g. SP is suspended, uninitialised etc + * and macros to access the state information in the per-cpu 'state' flags + ******************************************************************************/ +#define TSP_PSTATE_OFF 0 +#define TSP_PSTATE_ON 1 +#define TSP_PSTATE_SUSPEND 2 +#define TSP_PSTATE_SHIFT 0 +#define TSP_PSTATE_MASK 0x3 +#define get_tsp_pstate(state) ((state >> TSP_PSTATE_SHIFT) & TSP_PSTATE_MASK) +#define clr_tsp_pstate(state) (state &= ~(TSP_PSTATE_MASK \ + << TSP_PSTATE_SHIFT)) +#define set_tsp_pstate(st, pst) do { \ + clr_tsp_pstate(st); \ + st |= (pst & TSP_PSTATE_MASK) << \ + TSP_PSTATE_SHIFT; \ + } while (0); + + +/* + * This flag is used by the TSPD to determine if the TSP is servicing a standard + * SMC request prior to programming the next entry into the TSP e.g. if TSP + * execution is preempted by a non-secure interrupt and handed control to the + * normal world. If another request which is distinct from what the TSP was + * previously doing arrives, then this flag will be help the TSPD to either + * reject the new request or service it while ensuring that the previous context + * is not corrupted. + */ +#define STD_SMC_ACTIVE_FLAG_SHIFT 2 +#define STD_SMC_ACTIVE_FLAG_MASK 1 +#define get_std_smc_active_flag(state) ((state >> STD_SMC_ACTIVE_FLAG_SHIFT) \ + & STD_SMC_ACTIVE_FLAG_MASK) +#define set_std_smc_active_flag(state) (state |= \ + 1 << STD_SMC_ACTIVE_FLAG_SHIFT) +#define clr_std_smc_active_flag(state) (state &= \ + ~(STD_SMC_ACTIVE_FLAG_MASK \ + << STD_SMC_ACTIVE_FLAG_SHIFT)) + +/******************************************************************************* + * Secure Payload execution state information i.e. aarch32 or aarch64 + ******************************************************************************/ +#define TSP_AARCH32 MODE_RW_32 +#define TSP_AARCH64 MODE_RW_64 + +/******************************************************************************* + * The SPD should know the type of Secure Payload. + ******************************************************************************/ +#define TSP_TYPE_UP PSCI_TOS_NOT_UP_MIG_CAP +#define TSP_TYPE_UPM PSCI_TOS_UP_MIG_CAP +#define TSP_TYPE_MP PSCI_TOS_NOT_PRESENT_MP + +/******************************************************************************* + * Secure Payload migrate type information as known to the SPD. We assume that + * the SPD is dealing with an MP Secure Payload. + ******************************************************************************/ +#define TSP_MIGRATE_INFO TSP_TYPE_MP + +/******************************************************************************* + * Number of cpus that the present on this platform. TODO: Rely on a topology + * tree to determine this in the future to avoid assumptions about mpidr + * allocation + ******************************************************************************/ +#define TSPD_CORE_COUNT PLATFORM_CORE_COUNT + +/******************************************************************************* + * Constants that allow assembler code to preserve callee-saved registers of the + * C runtime context while performing a security state switch. + ******************************************************************************/ +#define TSPD_C_RT_CTX_X19 0x0 +#define TSPD_C_RT_CTX_X20 0x8 +#define TSPD_C_RT_CTX_X21 0x10 +#define TSPD_C_RT_CTX_X22 0x18 +#define TSPD_C_RT_CTX_X23 0x20 +#define TSPD_C_RT_CTX_X24 0x28 +#define TSPD_C_RT_CTX_X25 0x30 +#define TSPD_C_RT_CTX_X26 0x38 +#define TSPD_C_RT_CTX_X27 0x40 +#define TSPD_C_RT_CTX_X28 0x48 +#define TSPD_C_RT_CTX_X29 0x50 +#define TSPD_C_RT_CTX_X30 0x58 +#define TSPD_C_RT_CTX_SIZE 0x60 +#define TSPD_C_RT_CTX_ENTRIES (TSPD_C_RT_CTX_SIZE >> DWORD_SHIFT) + +#ifndef __ASSEMBLY__ + +#include <cassert.h> +#include <stdint.h> + +/* + * The number of arguments to save during a SMC call for TSP. + * Currently only x1 and x2 are used by TSP. + */ +#define TSP_NUM_ARGS 0x2 + +/* AArch64 callee saved general purpose register context structure. */ +DEFINE_REG_STRUCT(c_rt_regs, TSPD_C_RT_CTX_ENTRIES); + +/* + * Compile time assertion to ensure that both the compiler and linker + * have the same double word aligned view of the size of the C runtime + * register context. + */ +CASSERT(TSPD_C_RT_CTX_SIZE == sizeof(c_rt_regs_t), \ + assert_spd_c_rt_regs_size_mismatch); + +/******************************************************************************* + * Structure which helps the SPD to maintain the per-cpu state of the SP. + * 'saved_spsr_el3' - temporary copy to allow FIQ handling when the TSP has been + * preempted. + * 'saved_elr_el3' - temporary copy to allow FIQ handling when the TSP has been + * preempted. + * 'state' - collection of flags to track SP state e.g. on/off + * 'mpidr' - mpidr to associate a context with a cpu + * 'c_rt_ctx' - stack address to restore C runtime context from after + * returning from a synchronous entry into the SP. + * 'cpu_ctx' - space to maintain SP architectural state + * 'saved_tsp_args' - space to store arguments for TSP arithmetic operations + * which will queried using the TSP_GET_ARGS SMC by TSP. + ******************************************************************************/ +typedef struct tsp_context { + uint64_t saved_elr_el3; + uint32_t saved_spsr_el3; + uint32_t state; + uint64_t mpidr; + uint64_t c_rt_ctx; + cpu_context_t cpu_ctx; + uint64_t saved_tsp_args[TSP_NUM_ARGS]; +} tsp_context_t; + +/* Helper macros to store and retrieve tsp args from tsp_context */ +#define store_tsp_args(tsp_ctx, x1, x2) do {\ + tsp_ctx->saved_tsp_args[0] = x1;\ + tsp_ctx->saved_tsp_args[1] = x2;\ + } while (0) + +#define get_tsp_args(tsp_ctx, x1, x2) do {\ + x1 = tsp_ctx->saved_tsp_args[0];\ + x2 = tsp_ctx->saved_tsp_args[1];\ + } while (0) + +/* TSPD power management handlers */ +extern const spd_pm_ops_t tspd_pm; + +/******************************************************************************* + * Forward declarations + ******************************************************************************/ +struct tsp_vectors; + +/******************************************************************************* + * Function & Data prototypes + ******************************************************************************/ +uint64_t tspd_enter_sp(uint64_t *c_rt_ctx); +void __dead2 tspd_exit_sp(uint64_t c_rt_ctx, uint64_t ret); +uint64_t tspd_synchronous_sp_entry(tsp_context_t *tsp_ctx); +void __dead2 tspd_synchronous_sp_exit(tsp_context_t *tsp_ctx, uint64_t ret); +int32_t tspd_init_secure_context(uint64_t entrypoint, + uint32_t rw, + uint64_t mpidr, + tsp_context_t *tsp_ctx); +extern tsp_context_t tspd_sp_context[TSPD_CORE_COUNT]; +extern struct tsp_vectors *tsp_vectors; +#endif /*__ASSEMBLY__*/ + +#endif /* __TSPD_PRIVATE_H__ */ diff --git a/services/std_svc/psci/psci_afflvl_off.c b/services/std_svc/psci/psci_afflvl_off.c new file mode 100644 index 0000000..21a4d1a --- /dev/null +++ b/services/std_svc/psci/psci_afflvl_off.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <string.h> +#include "psci_private.h" + +typedef int (*afflvl_off_handler_t)(unsigned long, aff_map_node_t *); + +/******************************************************************************* + * The next three functions implement a handler for each supported affinity + * level which is called when that affinity level is turned off. + ******************************************************************************/ +static int psci_afflvl0_off(unsigned long mpidr, aff_map_node_t *cpu_node) +{ + unsigned int index, plat_state; + int rc = PSCI_E_SUCCESS; + unsigned long sctlr; + + assert(cpu_node->level == MPIDR_AFFLVL0); + + /* State management: mark this cpu as turned off */ + psci_set_state(cpu_node, PSCI_STATE_OFF); + + /* + * Generic management: Get the index for clearing any lingering re-entry + * information and allow the secure world to switch itself off + */ + + /* + * Call the cpu off handler registered by the Secure Payload Dispatcher + * to let it do any bookeeping. Assume that the SPD always reports an + * E_DENIED error if SP refuse to power down + */ + if (psci_spd_pm && psci_spd_pm->svc_off) { + rc = psci_spd_pm->svc_off(0); + if (rc) + return rc; + } + + index = cpu_node->data; + memset(&psci_ns_entry_info[index], 0, sizeof(psci_ns_entry_info[index])); + + /* + * Arch. management. Perform the necessary steps to flush all + * cpu caches. + * + * TODO: This power down sequence varies across cpus so it needs to be + * abstracted out on the basis of the MIDR like in cpu_reset_handler(). + * Do the bare minimal for the time being. Fix this before porting to + * Cortex models. + */ + sctlr = read_sctlr_el3(); + sctlr &= ~SCTLR_C_BIT; + write_sctlr_el3(sctlr); + isb(); /* ensure MMU disable takes immediate effect */ + + /* + * CAUTION: This flush to the level of unification makes an assumption + * about the cache hierarchy at affinity level 0 (cpu) in the platform. + * Ideally the platform should tell psci which levels to flush to exit + * coherency. + */ + dcsw_op_louis(DCCISW); + + /* + * Plat. management: Perform platform specific actions to turn this + * cpu off e.g. exit cpu coherency, program the power controller etc. + */ + if (psci_plat_pm_ops->affinst_off) { + + /* Get the current physical state of this cpu */ + plat_state = psci_get_phys_state(cpu_node); + rc = psci_plat_pm_ops->affinst_off(mpidr, + cpu_node->level, + plat_state); + } + + return rc; +} + +static int psci_afflvl1_off(unsigned long mpidr, aff_map_node_t *cluster_node) +{ + int rc = PSCI_E_SUCCESS; + unsigned int plat_state; + + /* Sanity check the cluster level */ + assert(cluster_node->level == MPIDR_AFFLVL1); + + /* State management: Decrement the cluster reference count */ + psci_set_state(cluster_node, PSCI_STATE_OFF); + + /* + * Keep the physical state of this cluster handy to decide + * what action needs to be taken + */ + plat_state = psci_get_phys_state(cluster_node); + + /* + * Arch. Management. Flush all levels of caches to PoC if + * the cluster is to be shutdown + */ + if (plat_state == PSCI_STATE_OFF) + dcsw_op_all(DCCISW); + + /* + * Plat. Management. Allow the platform to do its cluster + * specific bookeeping e.g. turn off interconnect coherency, + * program the power controller etc. + */ + if (psci_plat_pm_ops->affinst_off) + rc = psci_plat_pm_ops->affinst_off(mpidr, + cluster_node->level, + plat_state); + + return rc; +} + +static int psci_afflvl2_off(unsigned long mpidr, aff_map_node_t *system_node) +{ + int rc = PSCI_E_SUCCESS; + unsigned int plat_state; + + /* Cannot go beyond this level */ + assert(system_node->level == MPIDR_AFFLVL2); + + /* State management: Decrement the system reference count */ + psci_set_state(system_node, PSCI_STATE_OFF); + + /* + * Keep the physical state of the system handy to decide what + * action needs to be taken + */ + plat_state = psci_get_phys_state(system_node); + + /* No arch. and generic bookeeping to do here currently */ + + /* + * Plat. Management : Allow the platform to do its bookeeping + * at this affinity level + */ + if (psci_plat_pm_ops->affinst_off) + rc = psci_plat_pm_ops->affinst_off(mpidr, + system_node->level, + plat_state); + return rc; +} + +static const afflvl_off_handler_t psci_afflvl_off_handlers[] = { + psci_afflvl0_off, + psci_afflvl1_off, + psci_afflvl2_off, +}; + +/******************************************************************************* + * This function takes an array of pointers to affinity instance nodes in the + * topology tree and calls the off handler for the corresponding affinity + * levels + ******************************************************************************/ +static int psci_call_off_handlers(mpidr_aff_map_nodes_t mpidr_nodes, + int start_afflvl, + int end_afflvl, + unsigned long mpidr) +{ + int rc = PSCI_E_INVALID_PARAMS, level; + aff_map_node_t *node; + + for (level = start_afflvl; level <= end_afflvl; level++) { + node = mpidr_nodes[level]; + if (node == NULL) + continue; + + /* + * TODO: In case of an error should there be a way + * of restoring what we might have torn down at + * lower affinity levels. + */ + rc = psci_afflvl_off_handlers[level](mpidr, node); + if (rc != PSCI_E_SUCCESS) + break; + } + + return rc; +} + +/******************************************************************************* + * Top level handler which is called when a cpu wants to power itself down. + * It's assumed that along with turning the cpu off, higher affinity levels will + * be turned off as far as possible. It traverses through all the affinity + * levels performing generic, architectural, platform setup and state management + * e.g. for a cluster that's to be powered off, it will call the platform + * specific code which will disable coherency at the interconnect level if the + * cpu is the last in the cluster. For a cpu it could mean programming the power + * the power controller etc. + * + * The state of all the relevant affinity levels is changed prior to calling the + * affinity level specific handlers as their actions would depend upon the state + * the affinity level is about to enter. + * + * The affinity level specific handlers are called in ascending order i.e. from + * the lowest to the highest affinity level implemented by the platform because + * to turn off affinity level X it is neccesary to turn off affinity level X - 1 + * first. + * + * CAUTION: This function is called with coherent stacks so that coherency can + * be turned off and caches can be flushed safely. + ******************************************************************************/ +int psci_afflvl_off(unsigned long mpidr, + int start_afflvl, + int end_afflvl) +{ + int rc = PSCI_E_SUCCESS; + mpidr_aff_map_nodes_t mpidr_nodes; + + mpidr &= MPIDR_AFFINITY_MASK;; + + /* + * Collect the pointers to the nodes in the topology tree for + * each affinity instance in the mpidr. If this function does + * not return successfully then either the mpidr or the affinity + * levels are incorrect. In either case, we cannot return back + * to the caller as it would not know what to do. + */ + rc = psci_get_aff_map_nodes(mpidr, + start_afflvl, + end_afflvl, + mpidr_nodes); + assert (rc == PSCI_E_SUCCESS); + + /* + * This function acquires the lock corresponding to each affinity + * level so that by the time all locks are taken, the system topology + * is snapshot and state management can be done safely. + */ + psci_acquire_afflvl_locks(mpidr, + start_afflvl, + end_afflvl, + mpidr_nodes); + + /* Perform generic, architecture and platform specific handling */ + rc = psci_call_off_handlers(mpidr_nodes, + start_afflvl, + end_afflvl, + mpidr); + + /* + * Release the locks corresponding to each affinity level in the + * reverse order to which they were acquired. + */ + psci_release_afflvl_locks(mpidr, + start_afflvl, + end_afflvl, + mpidr_nodes); + + return rc; +} diff --git a/services/std_svc/psci/psci_afflvl_on.c b/services/std_svc/psci/psci_afflvl_on.c new file mode 100644 index 0000000..e3a1831 --- /dev/null +++ b/services/std_svc/psci/psci_afflvl_on.c @@ -0,0 +1,486 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <bl31.h> +#include <context_mgmt.h> +#include <platform.h> +#include <runtime_svc.h> +#include <stddef.h> +#include "psci_private.h" + +typedef int (*afflvl_on_handler_t)(unsigned long, + aff_map_node_t *, + unsigned long, + unsigned long); + +/******************************************************************************* + * This function checks whether a cpu which has been requested to be turned on + * is OFF to begin with. + ******************************************************************************/ +static int cpu_on_validate_state(aff_map_node_t *node) +{ + unsigned int psci_state; + + /* Get the raw psci state */ + psci_state = psci_get_state(node); + + if (psci_state == PSCI_STATE_ON || psci_state == PSCI_STATE_SUSPEND) + return PSCI_E_ALREADY_ON; + + if (psci_state == PSCI_STATE_ON_PENDING) + return PSCI_E_ON_PENDING; + + assert(psci_state == PSCI_STATE_OFF); + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * Handler routine to turn a cpu on. It takes care of any generic, architectural + * or platform specific setup required. + * TODO: Split this code across separate handlers for each type of setup? + ******************************************************************************/ +static int psci_afflvl0_on(unsigned long target_cpu, + aff_map_node_t *cpu_node, + unsigned long ns_entrypoint, + unsigned long context_id) +{ + unsigned int index, plat_state; + unsigned long psci_entrypoint; + int rc; + + /* Sanity check to safeguard against data corruption */ + assert(cpu_node->level == MPIDR_AFFLVL0); + + /* + * Generic management: Ensure that the cpu is off to be + * turned on + */ + rc = cpu_on_validate_state(cpu_node); + if (rc != PSCI_E_SUCCESS) + return rc; + + /* + * Call the cpu on handler registered by the Secure Payload Dispatcher + * to let it do any bookeeping. If the handler encounters an error, it's + * expected to assert within + */ + if (psci_spd_pm && psci_spd_pm->svc_on) + psci_spd_pm->svc_on(target_cpu); + + /* + * Arch. management: Derive the re-entry information for + * the non-secure world from the non-secure state from + * where this call originated. + */ + index = cpu_node->data; + rc = psci_set_ns_entry_info(index, ns_entrypoint, context_id); + if (rc != PSCI_E_SUCCESS) + return rc; + + /* Set the secure world (EL3) re-entry point after BL1 */ + psci_entrypoint = (unsigned long) psci_aff_on_finish_entry; + + /* State management: Set this cpu's state as ON PENDING */ + psci_set_state(cpu_node, PSCI_STATE_ON_PENDING); + + /* + * Plat. management: Give the platform the current state + * of the target cpu to allow it to perform the necessary + * steps to power on. + */ + if (psci_plat_pm_ops->affinst_on) { + + /* Get the current physical state of this cpu */ + plat_state = psci_get_phys_state(cpu_node); + rc = psci_plat_pm_ops->affinst_on(target_cpu, + psci_entrypoint, + ns_entrypoint, + cpu_node->level, + plat_state); + } + + return rc; +} + +/******************************************************************************* + * Handler routine to turn a cluster on. It takes care or any generic, arch. + * or platform specific setup required. + * TODO: Split this code across separate handlers for each type of setup? + ******************************************************************************/ +static int psci_afflvl1_on(unsigned long target_cpu, + aff_map_node_t *cluster_node, + unsigned long ns_entrypoint, + unsigned long context_id) +{ + int rc = PSCI_E_SUCCESS; + unsigned int plat_state; + unsigned long psci_entrypoint; + + assert(cluster_node->level == MPIDR_AFFLVL1); + + /* + * There is no generic and arch. specific cluster + * management required + */ + + /* State management: Is not required while turning a cluster on */ + + /* + * Plat. management: Give the platform the current state + * of the target cpu to allow it to perform the necessary + * steps to power on. + */ + if (psci_plat_pm_ops->affinst_on) { + plat_state = psci_get_phys_state(cluster_node); + psci_entrypoint = (unsigned long) psci_aff_on_finish_entry; + rc = psci_plat_pm_ops->affinst_on(target_cpu, + psci_entrypoint, + ns_entrypoint, + cluster_node->level, + plat_state); + } + + return rc; +} + +/******************************************************************************* + * Handler routine to turn a cluster of clusters on. It takes care or any + * generic, arch. or platform specific setup required. + * TODO: Split this code across separate handlers for each type of setup? + ******************************************************************************/ +static int psci_afflvl2_on(unsigned long target_cpu, + aff_map_node_t *system_node, + unsigned long ns_entrypoint, + unsigned long context_id) +{ + int rc = PSCI_E_SUCCESS; + unsigned int plat_state; + unsigned long psci_entrypoint; + + /* Cannot go beyond affinity level 2 in this psci imp. */ + assert(system_node->level == MPIDR_AFFLVL2); + + /* + * There is no generic and arch. specific system management + * required + */ + + /* State management: Is not required while turning a system on */ + + /* + * Plat. management: Give the platform the current state + * of the target cpu to allow it to perform the necessary + * steps to power on. + */ + if (psci_plat_pm_ops->affinst_on) { + plat_state = psci_get_phys_state(system_node); + psci_entrypoint = (unsigned long) psci_aff_on_finish_entry; + rc = psci_plat_pm_ops->affinst_on(target_cpu, + psci_entrypoint, + ns_entrypoint, + system_node->level, + plat_state); + } + + return rc; +} + +/* Private data structure to make this handlers accessible through indexing */ +static const afflvl_on_handler_t psci_afflvl_on_handlers[] = { + psci_afflvl0_on, + psci_afflvl1_on, + psci_afflvl2_on, +}; + +/******************************************************************************* + * This function takes an array of pointers to affinity instance nodes in the + * topology tree and calls the on handler for the corresponding affinity + * levels + ******************************************************************************/ +static int psci_call_on_handlers(mpidr_aff_map_nodes_t target_cpu_nodes, + int start_afflvl, + int end_afflvl, + unsigned long target_cpu, + unsigned long entrypoint, + unsigned long context_id) +{ + int rc = PSCI_E_INVALID_PARAMS, level; + aff_map_node_t *node; + + for (level = end_afflvl; level >= start_afflvl; level--) { + node = target_cpu_nodes[level]; + if (node == NULL) + continue; + + /* + * TODO: In case of an error should there be a way + * of undoing what we might have setup at higher + * affinity levels. + */ + rc = psci_afflvl_on_handlers[level](target_cpu, + node, + entrypoint, + context_id); + if (rc != PSCI_E_SUCCESS) + break; + } + + return rc; +} + +/******************************************************************************* + * Generic handler which is called to physically power on a cpu identified by + * its mpidr. It traverses through all the affinity levels performing generic, + * architectural, platform setup and state management e.g. for a cpu that is + * to be powered on, it will ensure that enough information is stashed for it + * to resume execution in the non-secure security state. + * + * The state of all the relevant affinity levels is changed after calling the + * affinity level specific handlers as their actions would depend upon the state + * the affinity level is currently in. + * + * The affinity level specific handlers are called in descending order i.e. from + * the highest to the lowest affinity level implemented by the platform because + * to turn on affinity level X it is neccesary to turn on affinity level X + 1 + * first. + ******************************************************************************/ +int psci_afflvl_on(unsigned long target_cpu, + unsigned long entrypoint, + unsigned long context_id, + int start_afflvl, + int end_afflvl) +{ + int rc = PSCI_E_SUCCESS; + mpidr_aff_map_nodes_t target_cpu_nodes; + unsigned long mpidr = read_mpidr() & MPIDR_AFFINITY_MASK; + + /* + * Collect the pointers to the nodes in the topology tree for + * each affinity instance in the mpidr. If this function does + * not return successfully then either the mpidr or the affinity + * levels are incorrect. + */ + rc = psci_get_aff_map_nodes(target_cpu, + start_afflvl, + end_afflvl, + target_cpu_nodes); + if (rc != PSCI_E_SUCCESS) + return rc; + + + /* + * This function acquires the lock corresponding to each affinity + * level so that by the time all locks are taken, the system topology + * is snapshot and state management can be done safely. + */ + psci_acquire_afflvl_locks(mpidr, + start_afflvl, + end_afflvl, + target_cpu_nodes); + + /* Perform generic, architecture and platform specific handling. */ + rc = psci_call_on_handlers(target_cpu_nodes, + start_afflvl, + end_afflvl, + target_cpu, + entrypoint, + context_id); + + /* + * This loop releases the lock corresponding to each affinity level + * in the reverse order to which they were acquired. + */ + psci_release_afflvl_locks(mpidr, + start_afflvl, + end_afflvl, + target_cpu_nodes); + + return rc; +} + +/******************************************************************************* + * The following functions finish an earlier affinity power on request. They + * are called by the common finisher routine in psci_common.c. + ******************************************************************************/ +static unsigned int psci_afflvl0_on_finish(unsigned long mpidr, + aff_map_node_t *cpu_node) +{ + unsigned int index, plat_state, state, rc = PSCI_E_SUCCESS; + + assert(cpu_node->level == MPIDR_AFFLVL0); + + /* Ensure we have been explicitly woken up by another cpu */ + state = psci_get_state(cpu_node); + assert(state == PSCI_STATE_ON_PENDING); + + /* + * Plat. management: Perform the platform specific actions + * for this cpu e.g. enabling the gic or zeroing the mailbox + * register. The actual state of this cpu has already been + * changed. + */ + if (psci_plat_pm_ops->affinst_on_finish) { + + /* Get the physical state of this cpu */ + plat_state = get_phys_state(state); + rc = psci_plat_pm_ops->affinst_on_finish(mpidr, + cpu_node->level, + plat_state); + assert(rc == PSCI_E_SUCCESS); + } + + /* + * Arch. management: Turn on mmu & restore architectural state + */ + bl31_plat_enable_mmu(); + + /* + * All the platform specific actions for turning this cpu + * on have completed. Perform enough arch.initialization + * to run in the non-secure address space. + */ + bl31_arch_setup(); + + /* + * Use the more complex exception vectors to enable SPD + * initialisation. SP_EL3 should point to a 'cpu_context' + * structure. The calling cpu should have set the + * context already + */ + assert(cm_get_context(mpidr, NON_SECURE)); + cm_set_next_eret_context(NON_SECURE); + cm_init_pcpu_ptr_cache(); + write_vbar_el3((uint64_t) runtime_exceptions); + + /* + * Call the cpu on finish handler registered by the Secure Payload + * Dispatcher to let it do any bookeeping. If the handler encounters an + * error, it's expected to assert within + */ + if (psci_spd_pm && psci_spd_pm->svc_on_finish) + psci_spd_pm->svc_on_finish(0); + + /* + * Generic management: Now we just need to retrieve the + * information that we had stashed away during the cpu_on + * call to set this cpu on its way. First get the index + * for restoring the re-entry info + */ + index = cpu_node->data; + psci_get_ns_entry_info(index); + + /* State management: mark this cpu as on */ + psci_set_state(cpu_node, PSCI_STATE_ON); + + /* Clean caches before re-entering normal world */ + dcsw_op_louis(DCCSW); + + return rc; +} + +static unsigned int psci_afflvl1_on_finish(unsigned long mpidr, + aff_map_node_t *cluster_node) +{ + unsigned int plat_state, rc = PSCI_E_SUCCESS; + + assert(cluster_node->level == MPIDR_AFFLVL1); + + /* + * Plat. management: Perform the platform specific actions + * as per the old state of the cluster e.g. enabling + * coherency at the interconnect depends upon the state with + * which this cluster was powered up. If anything goes wrong + * then assert as there is no way to recover from this + * situation. + */ + if (psci_plat_pm_ops->affinst_on_finish) { + + /* Get the physical state of this cluster */ + plat_state = psci_get_phys_state(cluster_node); + rc = psci_plat_pm_ops->affinst_on_finish(mpidr, + cluster_node->level, + plat_state); + assert(rc == PSCI_E_SUCCESS); + } + + /* State management: Increment the cluster reference count */ + psci_set_state(cluster_node, PSCI_STATE_ON); + + return rc; +} + + +static unsigned int psci_afflvl2_on_finish(unsigned long mpidr, + aff_map_node_t *system_node) +{ + unsigned int plat_state, rc = PSCI_E_SUCCESS; + + /* Cannot go beyond this affinity level */ + assert(system_node->level == MPIDR_AFFLVL2); + + /* + * Currently, there are no architectural actions to perform + * at the system level. + */ + + /* + * Plat. management: Perform the platform specific actions + * as per the old state of the cluster e.g. enabling + * coherency at the interconnect depends upon the state with + * which this cluster was powered up. If anything goes wrong + * then assert as there is no way to recover from this + * situation. + */ + if (psci_plat_pm_ops->affinst_on_finish) { + + /* Get the physical state of the system */ + plat_state = psci_get_phys_state(system_node); + rc = psci_plat_pm_ops->affinst_on_finish(mpidr, + system_node->level, + plat_state); + assert(rc == PSCI_E_SUCCESS); + } + + /* State management: Increment the system reference count */ + psci_set_state(system_node, PSCI_STATE_ON); + + return rc; +} + +const afflvl_power_on_finisher_t psci_afflvl_on_finishers[] = { + psci_afflvl0_on_finish, + psci_afflvl1_on_finish, + psci_afflvl2_on_finish, +}; + diff --git a/services/std_svc/psci/psci_afflvl_suspend.c b/services/std_svc/psci/psci_afflvl_suspend.c new file mode 100644 index 0000000..377afdf --- /dev/null +++ b/services/std_svc/psci/psci_afflvl_suspend.c @@ -0,0 +1,608 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <bl_common.h> +#include <arch.h> +#include <arch_helpers.h> +#include <context.h> +#include <context_mgmt.h> +#include <runtime_svc.h> +#include <stddef.h> +#include "psci_private.h" + +typedef int (*afflvl_suspend_handler_t)(unsigned long, + aff_map_node_t *, + unsigned long, + unsigned long, + unsigned int); + +/******************************************************************************* + * This function sets the power state of the current cpu while + * powering down during a cpu_suspend call + ******************************************************************************/ +void psci_set_suspend_power_state(aff_map_node_t *node, unsigned int power_state) +{ + /* + * Check that nobody else is calling this function on our behalf & + * this information is being set only in the cpu node + */ + assert(node->mpidr == (read_mpidr() & MPIDR_AFFINITY_MASK)); + assert(node->level == MPIDR_AFFLVL0); + + /* Save PSCI power state parameter for the core in suspend context */ + psci_suspend_context[node->data].power_state = power_state; + + /* + * Flush the suspend data to PoC since it will be accessed while + * returning back from suspend with the caches turned off + */ + flush_dcache_range( + (unsigned long)&psci_suspend_context[node->data], + sizeof(suspend_context_t)); +} + +/******************************************************************************* + * This function gets the affinity level till which a cpu is powered down + * during a cpu_suspend call. Returns PSCI_INVALID_DATA if the + * power state saved for the node is invalid + ******************************************************************************/ +int psci_get_suspend_afflvl(unsigned long mpidr) +{ + aff_map_node_t *node; + + node = psci_get_aff_map_node(mpidr & MPIDR_AFFINITY_MASK, + MPIDR_AFFLVL0); + assert(node); + + return psci_get_aff_map_node_suspend_afflvl(node); +} + + +/******************************************************************************* + * This function gets the affinity level till which the current cpu was powered + * down during a cpu_suspend call. Returns PSCI_INVALID_DATA if the + * power state saved for the node is invalid + ******************************************************************************/ +int psci_get_aff_map_node_suspend_afflvl(aff_map_node_t *node) +{ + unsigned int power_state; + + assert(node->level == MPIDR_AFFLVL0); + + power_state = psci_suspend_context[node->data].power_state; + return ((power_state == PSCI_INVALID_DATA) ? + power_state : psci_get_pstate_afflvl(power_state)); +} + +/******************************************************************************* + * This function gets the state id of a cpu stored in suspend context + * while powering down during a cpu_suspend call. Returns 0xFFFFFFFF + * if the power state saved for the node is invalid + ******************************************************************************/ +int psci_get_suspend_stateid(unsigned long mpidr) +{ + aff_map_node_t *node; + unsigned int power_state; + + node = psci_get_aff_map_node(mpidr & MPIDR_AFFINITY_MASK, + MPIDR_AFFLVL0); + assert(node); + assert(node->level == MPIDR_AFFLVL0); + + power_state = psci_suspend_context[node->data].power_state; + return ((power_state == PSCI_INVALID_DATA) ? + power_state : psci_get_pstate_id(power_state)); +} + +/******************************************************************************* + * The next three functions implement a handler for each supported affinity + * level which is called when that affinity level is about to be suspended. + ******************************************************************************/ +static int psci_afflvl0_suspend(unsigned long mpidr, + aff_map_node_t *cpu_node, + unsigned long ns_entrypoint, + unsigned long context_id, + unsigned int power_state) +{ + unsigned int index, plat_state; + unsigned long psci_entrypoint, sctlr; + el3_state_t *saved_el3_state; + int rc = PSCI_E_SUCCESS; + + /* Sanity check to safeguard against data corruption */ + assert(cpu_node->level == MPIDR_AFFLVL0); + + /* Save PSCI power state parameter for the core in suspend context */ + psci_set_suspend_power_state(cpu_node, power_state); + + /* + * Generic management: Store the re-entry information for the non-secure + * world and allow the secure world to suspend itself + */ + + /* + * Call the cpu suspend handler registered by the Secure Payload + * Dispatcher to let it do any bookeeping. If the handler encounters an + * error, it's expected to assert within + */ + if (psci_spd_pm && psci_spd_pm->svc_suspend) + psci_spd_pm->svc_suspend(power_state); + + /* State management: mark this cpu as suspended */ + psci_set_state(cpu_node, PSCI_STATE_SUSPEND); + + /* + * Generic management: Store the re-entry information for the + * non-secure world + */ + index = cpu_node->data; + rc = psci_set_ns_entry_info(index, ns_entrypoint, context_id); + if (rc != PSCI_E_SUCCESS) + return rc; + + /* + * Arch. management: Save the EL3 state in the 'cpu_context' + * structure that has been allocated for this cpu, flush the + * L1 caches and exit intra-cluster coherency et al + */ + cm_el3_sysregs_context_save(NON_SECURE); + rc = PSCI_E_SUCCESS; + + /* + * The EL3 state to PoC since it will be accessed after a + * reset with the caches turned off + */ + saved_el3_state = get_el3state_ctx(cm_get_context(mpidr, NON_SECURE)); + flush_dcache_range((uint64_t) saved_el3_state, sizeof(*saved_el3_state)); + + /* Set the secure world (EL3) re-entry point after BL1 */ + psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry; + + /* + * Arch. management. Perform the necessary steps to flush all + * cpu caches. + * + * TODO: This power down sequence varies across cpus so it needs to be + * abstracted out on the basis of the MIDR like in cpu_reset_handler(). + * Do the bare minimal for the time being. Fix this before porting to + * Cortex models. + */ + sctlr = read_sctlr_el3(); + sctlr &= ~SCTLR_C_BIT; + write_sctlr_el3(sctlr); + isb(); /* ensure MMU disable takes immediate effect */ + + /* + * CAUTION: This flush to the level of unification makes an assumption + * about the cache hierarchy at affinity level 0 (cpu) in the platform. + * Ideally the platform should tell psci which levels to flush to exit + * coherency. + */ + dcsw_op_louis(DCCISW); + + /* + * Plat. management: Allow the platform to perform the + * necessary actions to turn off this cpu e.g. set the + * platform defined mailbox with the psci entrypoint, + * program the power controller etc. + */ + if (psci_plat_pm_ops->affinst_suspend) { + plat_state = psci_get_phys_state(cpu_node); + rc = psci_plat_pm_ops->affinst_suspend(mpidr, + psci_entrypoint, + ns_entrypoint, + cpu_node->level, + plat_state); + } + + return rc; +} + +static int psci_afflvl1_suspend(unsigned long mpidr, + aff_map_node_t *cluster_node, + unsigned long ns_entrypoint, + unsigned long context_id, + unsigned int power_state) +{ + int rc = PSCI_E_SUCCESS; + unsigned int plat_state; + unsigned long psci_entrypoint; + + /* Sanity check the cluster level */ + assert(cluster_node->level == MPIDR_AFFLVL1); + + /* State management: Decrement the cluster reference count */ + psci_set_state(cluster_node, PSCI_STATE_SUSPEND); + + /* + * Keep the physical state of this cluster handy to decide + * what action needs to be taken + */ + plat_state = psci_get_phys_state(cluster_node); + + /* + * Arch. management: Flush all levels of caches to PoC if the + * cluster is to be shutdown + */ + if (plat_state == PSCI_STATE_OFF) + dcsw_op_all(DCCISW); + + /* + * Plat. Management. Allow the platform to do its cluster + * specific bookeeping e.g. turn off interconnect coherency, + * program the power controller etc. + */ + if (psci_plat_pm_ops->affinst_suspend) { + + /* + * Sending the psci entrypoint is currently redundant + * beyond affinity level 0 but one never knows what a + * platform might do. Also it allows us to keep the + * platform handler prototype the same. + */ + psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry; + rc = psci_plat_pm_ops->affinst_suspend(mpidr, + psci_entrypoint, + ns_entrypoint, + cluster_node->level, + plat_state); + } + + return rc; +} + + +static int psci_afflvl2_suspend(unsigned long mpidr, + aff_map_node_t *system_node, + unsigned long ns_entrypoint, + unsigned long context_id, + unsigned int power_state) +{ + int rc = PSCI_E_SUCCESS; + unsigned int plat_state; + unsigned long psci_entrypoint; + + /* Cannot go beyond this */ + assert(system_node->level == MPIDR_AFFLVL2); + + /* State management: Decrement the system reference count */ + psci_set_state(system_node, PSCI_STATE_SUSPEND); + + /* + * Keep the physical state of the system handy to decide what + * action needs to be taken + */ + plat_state = psci_get_phys_state(system_node); + + /* + * Plat. Management : Allow the platform to do its bookeeping + * at this affinity level + */ + if (psci_plat_pm_ops->affinst_suspend) { + + /* + * Sending the psci entrypoint is currently redundant + * beyond affinity level 0 but one never knows what a + * platform might do. Also it allows us to keep the + * platform handler prototype the same. + */ + psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry; + rc = psci_plat_pm_ops->affinst_suspend(mpidr, + psci_entrypoint, + ns_entrypoint, + system_node->level, + plat_state); + } + + return rc; +} + +static const afflvl_suspend_handler_t psci_afflvl_suspend_handlers[] = { + psci_afflvl0_suspend, + psci_afflvl1_suspend, + psci_afflvl2_suspend, +}; + +/******************************************************************************* + * This function takes an array of pointers to affinity instance nodes in the + * topology tree and calls the suspend handler for the corresponding affinity + * levels + ******************************************************************************/ +static int psci_call_suspend_handlers(mpidr_aff_map_nodes_t mpidr_nodes, + int start_afflvl, + int end_afflvl, + unsigned long mpidr, + unsigned long entrypoint, + unsigned long context_id, + unsigned int power_state) +{ + int rc = PSCI_E_INVALID_PARAMS, level; + aff_map_node_t *node; + + for (level = start_afflvl; level <= end_afflvl; level++) { + node = mpidr_nodes[level]; + if (node == NULL) + continue; + + /* + * TODO: In case of an error should there be a way + * of restoring what we might have torn down at + * lower affinity levels. + */ + rc = psci_afflvl_suspend_handlers[level](mpidr, + node, + entrypoint, + context_id, + power_state); + if (rc != PSCI_E_SUCCESS) + break; + } + + return rc; +} + +/******************************************************************************* + * Top level handler which is called when a cpu wants to suspend its execution. + * It is assumed that along with turning the cpu off, higher affinity levels + * until the target affinity level will be turned off as well. It traverses + * through all the affinity levels performing generic, architectural, platform + * setup and state management e.g. for a cluster that's to be suspended, it will + * call the platform specific code which will disable coherency at the + * interconnect level if the cpu is the last in the cluster. For a cpu it could + * mean programming the power controller etc. + * + * The state of all the relevant affinity levels is changed prior to calling the + * affinity level specific handlers as their actions would depend upon the state + * the affinity level is about to enter. + * + * The affinity level specific handlers are called in ascending order i.e. from + * the lowest to the highest affinity level implemented by the platform because + * to turn off affinity level X it is neccesary to turn off affinity level X - 1 + * first. + * + * CAUTION: This function is called with coherent stacks so that coherency can + * be turned off and caches can be flushed safely. + ******************************************************************************/ +int psci_afflvl_suspend(unsigned long mpidr, + unsigned long entrypoint, + unsigned long context_id, + unsigned int power_state, + int start_afflvl, + int end_afflvl) +{ + int rc = PSCI_E_SUCCESS; + mpidr_aff_map_nodes_t mpidr_nodes; + + mpidr &= MPIDR_AFFINITY_MASK; + + /* + * Collect the pointers to the nodes in the topology tree for + * each affinity instance in the mpidr. If this function does + * not return successfully then either the mpidr or the affinity + * levels are incorrect. + */ + rc = psci_get_aff_map_nodes(mpidr, + start_afflvl, + end_afflvl, + mpidr_nodes); + if (rc != PSCI_E_SUCCESS) + return rc; + + /* + * This function acquires the lock corresponding to each affinity + * level so that by the time all locks are taken, the system topology + * is snapshot and state management can be done safely. + */ + psci_acquire_afflvl_locks(mpidr, + start_afflvl, + end_afflvl, + mpidr_nodes); + + /* Perform generic, architecture and platform specific handling */ + rc = psci_call_suspend_handlers(mpidr_nodes, + start_afflvl, + end_afflvl, + mpidr, + entrypoint, + context_id, + power_state); + + /* + * Release the locks corresponding to each affinity level in the + * reverse order to which they were acquired. + */ + psci_release_afflvl_locks(mpidr, + start_afflvl, + end_afflvl, + mpidr_nodes); + + return rc; +} + +/******************************************************************************* + * The following functions finish an earlier affinity suspend request. They + * are called by the common finisher routine in psci_common.c. + ******************************************************************************/ +static unsigned int psci_afflvl0_suspend_finish(unsigned long mpidr, + aff_map_node_t *cpu_node) +{ + unsigned int index, plat_state, state, rc = PSCI_E_SUCCESS; + int32_t suspend_level; + + assert(cpu_node->level == MPIDR_AFFLVL0); + + /* Ensure we have been woken up from a suspended state */ + state = psci_get_state(cpu_node); + assert(state == PSCI_STATE_SUSPEND); + + /* + * Plat. management: Perform the platform specific actions + * before we change the state of the cpu e.g. enabling the + * gic or zeroing the mailbox register. If anything goes + * wrong then assert as there is no way to recover from this + * situation. + */ + if (psci_plat_pm_ops->affinst_suspend_finish) { + + /* Get the physical state of this cpu */ + plat_state = get_phys_state(state); + rc = psci_plat_pm_ops->affinst_suspend_finish(mpidr, + cpu_node->level, + plat_state); + assert(rc == PSCI_E_SUCCESS); + } + + /* Get the index for restoring the re-entry information */ + index = cpu_node->data; + + /* + * Arch. management: Restore the stashed EL3 architectural + * context from the 'cpu_context' structure for this cpu. + */ + cm_el3_sysregs_context_restore(NON_SECURE); + rc = PSCI_E_SUCCESS; + + /* + * Use the more complex exception vectors to enable SPD + * initialisation. SP_EL3 should point to a 'cpu_context' + * structure. The non-secure context should have been + * set on this cpu prior to suspension. + */ + assert(cm_get_context(mpidr, NON_SECURE)); + cm_set_next_eret_context(NON_SECURE); + cm_init_pcpu_ptr_cache(); + write_vbar_el3((uint64_t) runtime_exceptions); + + /* + * Call the cpu suspend finish handler registered by the Secure Payload + * Dispatcher to let it do any bookeeping. If the handler encounters an + * error, it's expected to assert within + */ + if (psci_spd_pm && psci_spd_pm->svc_suspend) { + suspend_level = psci_get_aff_map_node_suspend_afflvl(cpu_node); + assert (suspend_level != PSCI_INVALID_DATA); + psci_spd_pm->svc_suspend_finish(suspend_level); + } + + /* Invalidate the suspend context for the node */ + psci_set_suspend_power_state(cpu_node, PSCI_INVALID_DATA); + + /* + * Generic management: Now we just need to retrieve the + * information that we had stashed away during the suspend + * call to set this cpu on its way. + */ + psci_get_ns_entry_info(index); + + /* State management: mark this cpu as on */ + psci_set_state(cpu_node, PSCI_STATE_ON); + + /* Clean caches before re-entering normal world */ + dcsw_op_louis(DCCSW); + + return rc; +} + +static unsigned int psci_afflvl1_suspend_finish(unsigned long mpidr, + aff_map_node_t *cluster_node) +{ + unsigned int plat_state, rc = PSCI_E_SUCCESS; + + assert(cluster_node->level == MPIDR_AFFLVL1); + + /* + * Plat. management: Perform the platform specific actions + * as per the old state of the cluster e.g. enabling + * coherency at the interconnect depends upon the state with + * which this cluster was powered up. If anything goes wrong + * then assert as there is no way to recover from this + * situation. + */ + if (psci_plat_pm_ops->affinst_suspend_finish) { + + /* Get the physical state of this cpu */ + plat_state = psci_get_phys_state(cluster_node); + rc = psci_plat_pm_ops->affinst_suspend_finish(mpidr, + cluster_node->level, + plat_state); + assert(rc == PSCI_E_SUCCESS); + } + + /* State management: Increment the cluster reference count */ + psci_set_state(cluster_node, PSCI_STATE_ON); + + return rc; +} + + +static unsigned int psci_afflvl2_suspend_finish(unsigned long mpidr, + aff_map_node_t *system_node) +{ + unsigned int plat_state, rc = PSCI_E_SUCCESS;; + + /* Cannot go beyond this affinity level */ + assert(system_node->level == MPIDR_AFFLVL2); + + /* + * Currently, there are no architectural actions to perform + * at the system level. + */ + + /* + * Plat. management: Perform the platform specific actions + * as per the old state of the cluster e.g. enabling + * coherency at the interconnect depends upon the state with + * which this cluster was powered up. If anything goes wrong + * then assert as there is no way to recover from this + * situation. + */ + if (psci_plat_pm_ops->affinst_suspend_finish) { + + /* Get the physical state of the system */ + plat_state = psci_get_phys_state(system_node); + rc = psci_plat_pm_ops->affinst_suspend_finish(mpidr, + system_node->level, + plat_state); + assert(rc == PSCI_E_SUCCESS); + } + + /* State management: Increment the system reference count */ + psci_set_state(system_node, PSCI_STATE_ON); + + return rc; +} + +const afflvl_power_on_finisher_t psci_afflvl_suspend_finishers[] = { + psci_afflvl0_suspend_finish, + psci_afflvl1_suspend_finish, + psci_afflvl2_suspend_finish, +}; + diff --git a/services/std_svc/psci/psci_common.c b/services/std_svc/psci/psci_common.c new file mode 100644 index 0000000..b1ee10d --- /dev/null +++ b/services/std_svc/psci/psci_common.c @@ -0,0 +1,550 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <context.h> +#include <context_mgmt.h> +#include <debug.h> +#include <platform.h> +#include "psci_private.h" + +/* + * SPD power management operations, expected to be supplied by the registered + * SPD on successful SP initialization + */ +const spd_pm_ops_t *psci_spd_pm; + +/******************************************************************************* + * Arrays that contains information needs to resume a cpu's execution when woken + * out of suspend or off states. Each cpu is allocated a single entry in each + * array during startup. + ******************************************************************************/ +suspend_context_t psci_suspend_context[PSCI_NUM_AFFS]; +ns_entry_info_t psci_ns_entry_info[PSCI_NUM_AFFS]; + +/******************************************************************************* + * Grand array that holds the platform's topology information for state + * management of affinity instances. Each node (aff_map_node) in the array + * corresponds to an affinity instance e.g. cluster, cpu within an mpidr + ******************************************************************************/ +aff_map_node_t psci_aff_map[PSCI_NUM_AFFS] +__attribute__ ((section("tzfw_coherent_mem"))); + +/******************************************************************************* + * Pointer to functions exported by the platform to complete power mgmt. ops + ******************************************************************************/ +const plat_pm_ops_t *psci_plat_pm_ops; + +/******************************************************************************* + * Routine to return the maximum affinity level to traverse to after a cpu has + * been physically powered up. It is expected to be called immediately after + * reset from assembler code. It has to find its 'aff_map_node' instead of + * getting it as an argument. + * TODO: Calling psci_get_aff_map_node() with the MMU disabled is slow. Add + * support to allow faster access to the target affinity level. + ******************************************************************************/ +int get_power_on_target_afflvl(unsigned long mpidr) +{ + aff_map_node_t *node; + unsigned int state; + int afflvl; + + /* Retrieve our node from the topology tree */ + node = psci_get_aff_map_node(mpidr & MPIDR_AFFINITY_MASK, + MPIDR_AFFLVL0); + assert(node); + + /* + * Return the maximum supported affinity level if this cpu was off. + * Call the handler in the suspend code if this cpu had been suspended. + * Any other state is invalid. + */ + state = psci_get_state(node); + if (state == PSCI_STATE_ON_PENDING) + return get_max_afflvl(); + + if (state == PSCI_STATE_SUSPEND) { + afflvl = psci_get_aff_map_node_suspend_afflvl(node); + assert(afflvl != PSCI_INVALID_DATA); + return afflvl; + } + return PSCI_E_INVALID_PARAMS; +} + +/******************************************************************************* + * Simple routine to retrieve the maximum affinity level supported by the + * platform and check that it makes sense. + ******************************************************************************/ +int get_max_afflvl() +{ + int aff_lvl; + + aff_lvl = plat_get_max_afflvl(); + assert(aff_lvl <= MPIDR_MAX_AFFLVL && aff_lvl >= MPIDR_AFFLVL0); + + return aff_lvl; +} + +/******************************************************************************* + * Simple routine to set the id of an affinity instance at a given level in the + * mpidr. + ******************************************************************************/ +unsigned long mpidr_set_aff_inst(unsigned long mpidr, + unsigned char aff_inst, + int aff_lvl) +{ + unsigned long aff_shift; + + assert(aff_lvl <= MPIDR_AFFLVL3); + + /* + * Decide the number of bits to shift by depending upon + * the affinity level + */ + aff_shift = get_afflvl_shift(aff_lvl); + + /* Clear the existing affinity instance & set the new one*/ + mpidr &= ~(MPIDR_AFFLVL_MASK << aff_shift); + mpidr |= aff_inst << aff_shift; + + return mpidr; +} + +/******************************************************************************* + * This function sanity checks a range of affinity levels. + ******************************************************************************/ +int psci_check_afflvl_range(int start_afflvl, int end_afflvl) +{ + /* Sanity check the parameters passed */ + if (end_afflvl > MPIDR_MAX_AFFLVL) + return PSCI_E_INVALID_PARAMS; + + if (start_afflvl < MPIDR_AFFLVL0) + return PSCI_E_INVALID_PARAMS; + + if (end_afflvl < start_afflvl) + return PSCI_E_INVALID_PARAMS; + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * This function is passed an array of pointers to affinity level nodes in the + * topology tree for an mpidr. It picks up locks for each affinity level bottom + * up in the range specified. + ******************************************************************************/ +void psci_acquire_afflvl_locks(unsigned long mpidr, + int start_afflvl, + int end_afflvl, + mpidr_aff_map_nodes_t mpidr_nodes) +{ + int level; + + for (level = start_afflvl; level <= end_afflvl; level++) { + if (mpidr_nodes[level] == NULL) + continue; + bakery_lock_get(mpidr, &mpidr_nodes[level]->lock); + } +} + +/******************************************************************************* + * This function is passed an array of pointers to affinity level nodes in the + * topology tree for an mpidr. It releases the lock for each affinity level top + * down in the range specified. + ******************************************************************************/ +void psci_release_afflvl_locks(unsigned long mpidr, + int start_afflvl, + int end_afflvl, + mpidr_aff_map_nodes_t mpidr_nodes) +{ + int level; + + for (level = end_afflvl; level >= start_afflvl; level--) { + if (mpidr_nodes[level] == NULL) + continue; + bakery_lock_release(mpidr, &mpidr_nodes[level]->lock); + } +} + +/******************************************************************************* + * Simple routine to determine whether an affinity instance at a given level + * in an mpidr exists or not. + ******************************************************************************/ +int psci_validate_mpidr(unsigned long mpidr, int level) +{ + aff_map_node_t *node; + + node = psci_get_aff_map_node(mpidr, level); + if (node && (node->state & PSCI_AFF_PRESENT)) + return PSCI_E_SUCCESS; + else + return PSCI_E_INVALID_PARAMS; +} + +/******************************************************************************* + * This function retrieves all the stashed information needed to correctly + * resume a cpu's execution in the non-secure state after it has been physically + * powered on i.e. turned ON or resumed from SUSPEND + ******************************************************************************/ +void psci_get_ns_entry_info(unsigned int index) +{ + unsigned long sctlr = 0, scr, el_status, id_aa64pfr0; + uint64_t mpidr = read_mpidr(); + cpu_context_t *ns_entry_context; + gp_regs_t *ns_entry_gpregs; + + scr = read_scr(); + + /* Find out which EL we are going to */ + id_aa64pfr0 = read_id_aa64pfr0_el1(); + el_status = (id_aa64pfr0 >> ID_AA64PFR0_EL2_SHIFT) & + ID_AA64PFR0_ELX_MASK; + + /* Restore endianess */ + if (psci_ns_entry_info[index].sctlr & SCTLR_EE_BIT) + sctlr |= SCTLR_EE_BIT; + else + sctlr &= ~SCTLR_EE_BIT; + + /* Turn off MMU and Caching */ + sctlr &= ~(SCTLR_M_BIT | SCTLR_C_BIT | SCTLR_M_BIT); + + /* Set the register width */ + if (psci_ns_entry_info[index].scr & SCR_RW_BIT) + scr |= SCR_RW_BIT; + else + scr &= ~SCR_RW_BIT; + + scr |= SCR_NS_BIT; + + if (el_status) + write_sctlr_el2(sctlr); + else + write_sctlr_el1(sctlr); + + /* Fulfill the cpu_on entry reqs. as per the psci spec */ + ns_entry_context = (cpu_context_t *) cm_get_context(mpidr, NON_SECURE); + assert(ns_entry_context); + + /* + * Setup general purpose registers to return the context id and + * prevent leakage of secure information into the normal world. + */ + ns_entry_gpregs = get_gpregs_ctx(ns_entry_context); + write_ctx_reg(ns_entry_gpregs, + CTX_GPREG_X0, + psci_ns_entry_info[index].context_id); + + /* + * Tell the context management library to setup EL3 system registers to + * be able to ERET into the ns state, and SP_EL3 points to the right + * context to exit from EL3 correctly. + */ + cm_set_el3_eret_context(NON_SECURE, + psci_ns_entry_info[index].eret_info.entrypoint, + psci_ns_entry_info[index].eret_info.spsr, + scr); + + cm_set_next_eret_context(NON_SECURE); +} + +/******************************************************************************* + * This function retrieves and stashes all the information needed to correctly + * resume a cpu's execution in the non-secure state after it has been physically + * powered on i.e. turned ON or resumed from SUSPEND. This is done prior to + * turning it on or before suspending it. + ******************************************************************************/ +int psci_set_ns_entry_info(unsigned int index, + unsigned long entrypoint, + unsigned long context_id) +{ + int rc = PSCI_E_SUCCESS; + unsigned int rw, mode, ee, spsr = 0; + unsigned long id_aa64pfr0 = read_id_aa64pfr0_el1(), scr = read_scr(); + unsigned long el_status; + unsigned long daif; + + /* Figure out what mode do we enter the non-secure world in */ + el_status = (id_aa64pfr0 >> ID_AA64PFR0_EL2_SHIFT) & + ID_AA64PFR0_ELX_MASK; + + /* + * Figure out whether the cpu enters the non-secure address space + * in aarch32 or aarch64 + */ + rw = scr & SCR_RW_BIT; + if (rw) { + + /* + * Check whether a Thumb entry point has been provided for an + * aarch64 EL + */ + if (entrypoint & 0x1) + return PSCI_E_INVALID_PARAMS; + + if (el_status && (scr & SCR_HCE_BIT)) { + mode = MODE_EL2; + ee = read_sctlr_el2() & SCTLR_EE_BIT; + } else { + mode = MODE_EL1; + ee = read_sctlr_el1() & SCTLR_EE_BIT; + } + + spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + + psci_ns_entry_info[index].sctlr |= ee; + psci_ns_entry_info[index].scr |= SCR_RW_BIT; + } else { + + + if (el_status && (scr & SCR_HCE_BIT)) { + mode = MODE32_hyp; + ee = read_sctlr_el2() & SCTLR_EE_BIT; + } else { + mode = MODE32_svc; + ee = read_sctlr_el1() & SCTLR_EE_BIT; + } + + /* + * TODO: Choose async. exception bits if HYP mode is not + * implemented according to the values of SCR.{AW, FW} bits + */ + daif = DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT; + + spsr = SPSR_MODE32(mode, entrypoint & 0x1, ee, daif); + + /* Ensure that the CSPR.E and SCTLR.EE bits match */ + psci_ns_entry_info[index].sctlr |= ee; + psci_ns_entry_info[index].scr &= ~SCR_RW_BIT; + } + + psci_ns_entry_info[index].eret_info.entrypoint = entrypoint; + psci_ns_entry_info[index].eret_info.spsr = spsr; + psci_ns_entry_info[index].context_id = context_id; + + return rc; +} + +/******************************************************************************* + * This function takes a pointer to an affinity node in the topology tree and + * returns its state. State of a non-leaf node needs to be calculated. + ******************************************************************************/ +unsigned short psci_get_state(aff_map_node_t *node) +{ + assert(node->level >= MPIDR_AFFLVL0 && node->level <= MPIDR_MAX_AFFLVL); + + /* A cpu node just contains the state which can be directly returned */ + if (node->level == MPIDR_AFFLVL0) + return (node->state >> PSCI_STATE_SHIFT) & PSCI_STATE_MASK; + + /* + * For an affinity level higher than a cpu, the state has to be + * calculated. It depends upon the value of the reference count + * which is managed by each node at the next lower affinity level + * e.g. for a cluster, each cpu increments/decrements the reference + * count. If the reference count is 0 then the affinity level is + * OFF else ON. + */ + if (node->ref_count) + return PSCI_STATE_ON; + else + return PSCI_STATE_OFF; +} + +/******************************************************************************* + * This function takes a pointer to an affinity node in the topology tree and + * a target state. State of a non-leaf node needs to be converted to a reference + * count. State of a leaf node can be set directly. + ******************************************************************************/ +void psci_set_state(aff_map_node_t *node, unsigned short state) +{ + assert(node->level >= MPIDR_AFFLVL0 && node->level <= MPIDR_MAX_AFFLVL); + + /* + * For an affinity level higher than a cpu, the state is used + * to decide whether the reference count is incremented or + * decremented. Entry into the ON_PENDING state does not have + * effect. + */ + if (node->level > MPIDR_AFFLVL0) { + switch (state) { + case PSCI_STATE_ON: + node->ref_count++; + break; + case PSCI_STATE_OFF: + case PSCI_STATE_SUSPEND: + node->ref_count--; + break; + case PSCI_STATE_ON_PENDING: + /* + * An affinity level higher than a cpu will not undergo + * a state change when it is about to be turned on + */ + return; + default: + assert(0); + } + } else { + node->state &= ~(PSCI_STATE_MASK << PSCI_STATE_SHIFT); + node->state |= (state & PSCI_STATE_MASK) << PSCI_STATE_SHIFT; + } +} + +/******************************************************************************* + * An affinity level could be on, on_pending, suspended or off. These are the + * logical states it can be in. Physically either it is off or on. When it is in + * the state on_pending then it is about to be turned on. It is not possible to + * tell whether that's actually happenned or not. So we err on the side of + * caution & treat the affinity level as being turned off. + ******************************************************************************/ +unsigned short psci_get_phys_state(aff_map_node_t *node) +{ + unsigned int state; + + state = psci_get_state(node); + return get_phys_state(state); +} + +/******************************************************************************* + * This function takes an array of pointers to affinity instance nodes in the + * topology tree and calls the physical power on handler for the corresponding + * affinity levels + ******************************************************************************/ +static int psci_call_power_on_handlers(mpidr_aff_map_nodes_t mpidr_nodes, + int start_afflvl, + int end_afflvl, + afflvl_power_on_finisher_t *pon_handlers, + unsigned long mpidr) +{ + int rc = PSCI_E_INVALID_PARAMS, level; + aff_map_node_t *node; + + for (level = end_afflvl; level >= start_afflvl; level--) { + node = mpidr_nodes[level]; + if (node == NULL) + continue; + + /* + * If we run into any trouble while powering up an + * affinity instance, then there is no recovery path + * so simply return an error and let the caller take + * care of the situation. + */ + rc = pon_handlers[level](mpidr, node); + if (rc != PSCI_E_SUCCESS) + break; + } + + return rc; +} + +/******************************************************************************* + * Generic handler which is called when a cpu is physically powered on. It + * traverses through all the affinity levels performing generic, architectural, + * platform setup and state management e.g. for a cluster that's been powered + * on, it will call the platform specific code which will enable coherency at + * the interconnect level. For a cpu it could mean turning on the MMU etc. + * + * The state of all the relevant affinity levels is changed after calling the + * affinity level specific handlers as their actions would depend upon the state + * the affinity level is exiting from. + * + * The affinity level specific handlers are called in descending order i.e. from + * the highest to the lowest affinity level implemented by the platform because + * to turn on affinity level X it is neccesary to turn on affinity level X + 1 + * first. + * + * CAUTION: This function is called with coherent stacks so that coherency and + * the mmu can be turned on safely. + ******************************************************************************/ +void psci_afflvl_power_on_finish(unsigned long mpidr, + int start_afflvl, + int end_afflvl, + afflvl_power_on_finisher_t *pon_handlers) +{ + mpidr_aff_map_nodes_t mpidr_nodes; + int rc; + + mpidr &= MPIDR_AFFINITY_MASK; + + /* + * Collect the pointers to the nodes in the topology tree for + * each affinity instance in the mpidr. If this function does + * not return successfully then either the mpidr or the affinity + * levels are incorrect. Either case is an irrecoverable error. + */ + rc = psci_get_aff_map_nodes(mpidr, + start_afflvl, + end_afflvl, + mpidr_nodes); + if (rc != PSCI_E_SUCCESS) + panic(); + + /* + * This function acquires the lock corresponding to each affinity + * level so that by the time all locks are taken, the system topology + * is snapshot and state management can be done safely. + */ + psci_acquire_afflvl_locks(mpidr, + start_afflvl, + end_afflvl, + mpidr_nodes); + + /* Perform generic, architecture and platform specific handling */ + rc = psci_call_power_on_handlers(mpidr_nodes, + start_afflvl, + end_afflvl, + pon_handlers, + mpidr); + if (rc != PSCI_E_SUCCESS) + panic(); + + /* + * This loop releases the lock corresponding to each affinity level + * in the reverse order to which they were acquired. + */ + psci_release_afflvl_locks(mpidr, + start_afflvl, + end_afflvl, + mpidr_nodes); +} + +/******************************************************************************* + * This function initializes the set of hooks that PSCI invokes as part of power + * management operation. The power management hooks are expected to be provided + * by the SPD, after it finishes all its initialization + ******************************************************************************/ +void psci_register_spd_pm_hook(const spd_pm_ops_t *pm) +{ + psci_spd_pm = pm; +} diff --git a/services/std_svc/psci/psci_entry.S b/services/std_svc/psci/psci_entry.S new file mode 100644 index 0000000..3954ab1 --- /dev/null +++ b/services/std_svc/psci/psci_entry.S @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <asm_macros.S> +#include <psci.h> + + .globl psci_aff_on_finish_entry + .globl psci_aff_suspend_finish_entry + .globl __psci_cpu_off + .globl __psci_cpu_suspend + .globl psci_power_down_wfi + + /* ----------------------------------------------------- + * This cpu has been physically powered up. Depending + * upon whether it was resumed from suspend or simply + * turned on, call the common power on finisher with + * the handlers (chosen depending upon original state). + * For ease, the finisher is called with coherent + * stacks. This allows the cluster/cpu finishers to + * enter coherency and enable the mmu without running + * into issues. We switch back to normal stacks once + * all this is done. + * ----------------------------------------------------- + */ +func psci_aff_on_finish_entry + adr x23, psci_afflvl_on_finishers + b psci_aff_common_finish_entry + +psci_aff_suspend_finish_entry: + adr x23, psci_afflvl_suspend_finishers + +psci_aff_common_finish_entry: + adr x22, psci_afflvl_power_on_finish + + /* --------------------------------------------- + * Exceptions should not occur at this point. + * Set VBAR in order to handle and report any + * that do occur + * --------------------------------------------- + */ + adr x0, early_exceptions + msr vbar_el3, x0 + isb + + /* --------------------------------------------- + * Enable Debug and SError interrupts + * --------------------------------------------- + */ + msr daifclr, #(DAIF_ABT_BIT | DAIF_DBG_BIT) + + /* --------------------------------------------- + * Use SP_EL0 for the C runtime stack. + * --------------------------------------------- + */ + msr spsel, #0 + + mrs x0, mpidr_el1 + bl platform_set_coherent_stack + + /* --------------------------------------------- + * Call the finishers starting from affinity + * level 0. + * --------------------------------------------- + */ + mrs x0, mpidr_el1 + bl get_power_on_target_afflvl + cmp x0, xzr + b.lt _panic + mov x3, x23 + mov x2, x0 + mov x1, #MPIDR_AFFLVL0 + mrs x0, mpidr_el1 + blr x22 + + /* -------------------------------------------- + * Give ourselves a stack allocated in Normal + * -IS-WBWA memory + * -------------------------------------------- + */ + mrs x0, mpidr_el1 + bl platform_set_stack + + b el3_exit +_panic: + b _panic + + /* ----------------------------------------------------- + * The following two stubs give the calling cpu a + * coherent stack to allow flushing of caches without + * suffering from stack coherency issues + * ----------------------------------------------------- + */ +func __psci_cpu_off + func_prologue + sub sp, sp, #0x10 + stp x19, x20, [sp, #0] + mov x19, sp + mrs x0, mpidr_el1 + bl platform_set_coherent_stack + bl psci_cpu_off + mov sp, x19 + ldp x19, x20, [sp,#0] + add sp, sp, #0x10 + func_epilogue + ret + +func __psci_cpu_suspend + func_prologue + sub sp, sp, #0x20 + stp x19, x20, [sp, #0] + stp x21, x22, [sp, #0x10] + mov x19, sp + mov x20, x0 + mov x21, x1 + mov x22, x2 + mrs x0, mpidr_el1 + bl platform_set_coherent_stack + mov x0, x20 + mov x1, x21 + mov x2, x22 + bl psci_cpu_suspend + mov sp, x19 + ldp x21, x22, [sp,#0x10] + ldp x19, x20, [sp,#0] + add sp, sp, #0x20 + func_epilogue + ret + + /* -------------------------------------------- + * This function is called to indicate to the + * power controller that it is safe to power + * down this cpu. It should not exit the wfi + * and will be released from reset upon power + * up. 'wfi_spill' is used to catch erroneous + * exits from wfi. + * -------------------------------------------- + */ +func psci_power_down_wfi + dsb sy // ensure write buffer empty + wfi +wfi_spill: + b wfi_spill + diff --git a/services/std_svc/psci/psci_main.c b/services/std_svc/psci/psci_main.c new file mode 100644 index 0000000..c0866fb --- /dev/null +++ b/services/std_svc/psci/psci_main.c @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <runtime_svc.h> +#include <debug.h> +#include "psci_private.h" + +/******************************************************************************* + * PSCI frontend api for servicing SMCs. Described in the PSCI spec. + ******************************************************************************/ +int psci_cpu_on(unsigned long target_cpu, + unsigned long entrypoint, + unsigned long context_id) + +{ + int rc; + unsigned int start_afflvl, end_afflvl; + + /* Determine if the cpu exists of not */ + rc = psci_validate_mpidr(target_cpu, MPIDR_AFFLVL0); + if (rc != PSCI_E_SUCCESS) { + goto exit; + } + + /* + * To turn this cpu on, specify which affinity + * levels need to be turned on + */ + start_afflvl = MPIDR_AFFLVL0; + end_afflvl = get_max_afflvl(); + rc = psci_afflvl_on(target_cpu, + entrypoint, + context_id, + start_afflvl, + end_afflvl); + +exit: + return rc; +} + +unsigned int psci_version(void) +{ + return PSCI_MAJOR_VER | PSCI_MINOR_VER; +} + +int psci_cpu_suspend(unsigned int power_state, + unsigned long entrypoint, + unsigned long context_id) +{ + int rc; + unsigned long mpidr; + unsigned int target_afflvl, pstate_type; + + /* Check SBZ bits in power state are zero */ + if (psci_validate_power_state(power_state)) + return PSCI_E_INVALID_PARAMS; + + /* Sanity check the requested state */ + target_afflvl = psci_get_pstate_afflvl(power_state); + if (target_afflvl > MPIDR_MAX_AFFLVL) + return PSCI_E_INVALID_PARAMS; + + /* Determine the 'state type' in the 'power_state' parameter */ + pstate_type = psci_get_pstate_type(power_state); + + /* + * Ensure that we have a platform specific handler for entering + * a standby state. + */ + if (pstate_type == PSTATE_TYPE_STANDBY) { + if (!psci_plat_pm_ops->affinst_standby) + return PSCI_E_INVALID_PARAMS; + + rc = psci_plat_pm_ops->affinst_standby(power_state); + assert(rc == PSCI_E_INVALID_PARAMS || rc == PSCI_E_SUCCESS); + return rc; + } + + /* + * Do what is needed to enter the power down state. Upon success, + * enter the final wfi which will power down this cpu else return + * an error. + */ + mpidr = read_mpidr(); + rc = psci_afflvl_suspend(mpidr, + entrypoint, + context_id, + power_state, + MPIDR_AFFLVL0, + target_afflvl); + if (rc == PSCI_E_SUCCESS) + psci_power_down_wfi(); + assert(rc == PSCI_E_INVALID_PARAMS); + return rc; +} + +int psci_cpu_off(void) +{ + int rc; + unsigned long mpidr; + int target_afflvl = get_max_afflvl(); + + mpidr = read_mpidr(); + + /* + * Traverse from the highest to the lowest affinity level. When the + * lowest affinity level is hit, all the locks are acquired. State + * management is done immediately followed by cpu, cluster ... + * ..target_afflvl specific actions as this function unwinds back. + */ + rc = psci_afflvl_off(mpidr, MPIDR_AFFLVL0, target_afflvl); + + /* + * Check if all actions needed to safely power down this cpu have + * successfully completed. Enter a wfi loop which will allow the + * power controller to physically power down this cpu. + */ + if (rc == PSCI_E_SUCCESS) + psci_power_down_wfi(); + + /* + * The only error cpu_off can return is E_DENIED. So check if that's + * indeed the case. + */ + assert (rc == PSCI_E_DENIED); + + return rc; +} + +int psci_affinity_info(unsigned long target_affinity, + unsigned int lowest_affinity_level) +{ + int rc = PSCI_E_INVALID_PARAMS; + unsigned int aff_state; + aff_map_node_t *node; + + if (lowest_affinity_level > get_max_afflvl()) + return rc; + + node = psci_get_aff_map_node(target_affinity, lowest_affinity_level); + if (node && (node->state & PSCI_AFF_PRESENT)) { + + /* + * TODO: For affinity levels higher than 0 i.e. cpu, the + * state will always be either ON or OFF. Need to investigate + * how critical is it to support ON_PENDING here. + */ + aff_state = psci_get_state(node); + + /* A suspended cpu is available & on for the OS */ + if (aff_state == PSCI_STATE_SUSPEND) { + aff_state = PSCI_STATE_ON; + } + + rc = aff_state; + } + + return rc; +} + +/* Unimplemented */ +int psci_migrate(unsigned int target_cpu) +{ + return PSCI_E_NOT_SUPPORTED; +} + +/* Unimplemented */ +unsigned int psci_migrate_info_type(void) +{ + return PSCI_TOS_NOT_PRESENT_MP; +} + +unsigned long psci_migrate_info_up_cpu(void) +{ + /* + * Return value of this currently unsupported call depends upon + * what psci_migrate_info_type() returns. + */ + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * PSCI top level handler for servicing SMCs. + ******************************************************************************/ +uint64_t psci_smc_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *cookie, + void *handle, + uint64_t flags) +{ + uint64_t rc; + + switch (smc_fid) { + case PSCI_VERSION: + rc = psci_version(); + break; + + case PSCI_CPU_OFF: + rc = __psci_cpu_off(); + break; + + case PSCI_CPU_SUSPEND_AARCH64: + case PSCI_CPU_SUSPEND_AARCH32: + rc = __psci_cpu_suspend(x1, x2, x3); + break; + + case PSCI_CPU_ON_AARCH64: + case PSCI_CPU_ON_AARCH32: + rc = psci_cpu_on(x1, x2, x3); + break; + + case PSCI_AFFINITY_INFO_AARCH32: + case PSCI_AFFINITY_INFO_AARCH64: + rc = psci_affinity_info(x1, x2); + break; + + case PSCI_MIG_AARCH32: + case PSCI_MIG_AARCH64: + rc = psci_migrate(x1); + break; + + case PSCI_MIG_INFO_TYPE: + rc = psci_migrate_info_type(); + break; + + case PSCI_MIG_INFO_UP_CPU_AARCH32: + case PSCI_MIG_INFO_UP_CPU_AARCH64: + rc = psci_migrate_info_up_cpu(); + break; + + default: + rc = SMC_UNK; + WARN("Unimplemented PSCI Call: 0x%x \n", smc_fid); + } + + SMC_RET1(handle, rc); +} diff --git a/services/std_svc/psci/psci_private.h b/services/std_svc/psci/psci_private.h new file mode 100644 index 0000000..747a2d4 --- /dev/null +++ b/services/std_svc/psci/psci_private.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __PSCI_PRIVATE_H__ +#define __PSCI_PRIVATE_H__ + +#include <arch.h> +#include <bakery_lock.h> +#include <psci.h> + +/******************************************************************************* + * The following two data structures hold the generic information to bringup + * a suspended/hotplugged out cpu + ******************************************************************************/ +typedef struct eret_params { + unsigned long entrypoint; + unsigned long spsr; +} eret_params_t; + +typedef struct ns_entry_info { + eret_params_t eret_info; + unsigned long context_id; + unsigned int scr; + unsigned int sctlr; +} ns_entry_info_t; + +/******************************************************************************* + * The following two data structures hold the topology tree which in turn tracks + * the state of the all the affinity instances supported by the platform. + ******************************************************************************/ +typedef struct aff_map_node { + unsigned long mpidr; + unsigned short ref_count; + unsigned char state; + unsigned char level; + unsigned int data; + bakery_lock_t lock; +} aff_map_node_t; + +typedef struct aff_limits_node { + int min; + int max; +} aff_limits_node_t; + +/******************************************************************************* + * This data structure holds secure world context that needs to be preserved + * across cpu_suspend calls which enter the power down state. + ******************************************************************************/ +typedef struct suspend_context { + unsigned int power_state; +} __aligned(CACHE_WRITEBACK_GRANULE) suspend_context_t; + +typedef aff_map_node_t (*mpidr_aff_map_nodes_t[MPIDR_MAX_AFFLVL]); +typedef unsigned int (*afflvl_power_on_finisher_t)(unsigned long, + aff_map_node_t *); + +/******************************************************************************* + * Data prototypes + ******************************************************************************/ +extern suspend_context_t psci_suspend_context[PSCI_NUM_AFFS]; +extern ns_entry_info_t psci_ns_entry_info[PSCI_NUM_AFFS]; +extern const plat_pm_ops_t *psci_plat_pm_ops; +extern aff_map_node_t psci_aff_map[PSCI_NUM_AFFS]; + +/******************************************************************************* + * SPD's power management hooks registered with PSCI + ******************************************************************************/ +extern const spd_pm_ops_t *psci_spd_pm; + +/******************************************************************************* + * Function prototypes + ******************************************************************************/ +/* Private exported functions from psci_common.c */ +int get_max_afflvl(void); +unsigned short psci_get_state(aff_map_node_t *node); +unsigned short psci_get_phys_state(aff_map_node_t *node); +void psci_set_state(aff_map_node_t *node, unsigned short state); +void psci_get_ns_entry_info(unsigned int index); +unsigned long mpidr_set_aff_inst(unsigned long, unsigned char, int); +int psci_validate_mpidr(unsigned long, int); +int get_power_on_target_afflvl(unsigned long mpidr); +void psci_afflvl_power_on_finish(unsigned long, + int, + int, + afflvl_power_on_finisher_t *); +int psci_set_ns_entry_info(unsigned int index, + unsigned long entrypoint, + unsigned long context_id); +int psci_check_afflvl_range(int start_afflvl, int end_afflvl); +void psci_acquire_afflvl_locks(unsigned long mpidr, + int start_afflvl, + int end_afflvl, + mpidr_aff_map_nodes_t mpidr_nodes); +void psci_release_afflvl_locks(unsigned long mpidr, + int start_afflvl, + int end_afflvl, + mpidr_aff_map_nodes_t mpidr_nodes); + +/* Private exported functions from psci_setup.c */ +int psci_get_aff_map_nodes(unsigned long mpidr, + int start_afflvl, + int end_afflvl, + mpidr_aff_map_nodes_t mpidr_nodes); +aff_map_node_t *psci_get_aff_map_node(unsigned long, int); + +/* Private exported functions from psci_affinity_on.c */ +int psci_afflvl_on(unsigned long, + unsigned long, + unsigned long, + int, + int); + +/* Private exported functions from psci_affinity_off.c */ +int psci_afflvl_off(unsigned long, int, int); + +/* Private exported functions from psci_affinity_suspend.c */ +void psci_set_suspend_power_state(aff_map_node_t *node, + unsigned int power_state); +int psci_get_aff_map_node_suspend_afflvl(aff_map_node_t *node); +int psci_afflvl_suspend(unsigned long, + unsigned long, + unsigned long, + unsigned int, + int, + int); +unsigned int psci_afflvl_suspend_finish(unsigned long, int, int); + + +#endif /* __PSCI_PRIVATE_H__ */ diff --git a/services/std_svc/psci/psci_setup.c b/services/std_svc/psci/psci_setup.c new file mode 100644 index 0000000..a1587b7 --- /dev/null +++ b/services/std_svc/psci/psci_setup.c @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <bl_common.h> +#include <context.h> +#include <context_mgmt.h> +#include <platform.h> +#include <stddef.h> +#include "psci_private.h" + +/******************************************************************************* + * Per cpu non-secure contexts used to program the architectural state prior + * return to the normal world. + * TODO: Use the memory allocator to set aside memory for the contexts instead + * of relying on platform defined constants. Using PSCI_NUM_AFFS will be an + * overkill. + ******************************************************************************/ +static cpu_context_t psci_ns_context[PLATFORM_CORE_COUNT]; + +/******************************************************************************* + * In a system, a certain number of affinity instances are present at an + * affinity level. The cumulative number of instances across all levels are + * stored in 'psci_aff_map'. The topology tree has been flattenned into this + * array. To retrieve nodes, information about the extents of each affinity + * level i.e. start index and end index needs to be present. 'psci_aff_limits' + * stores this information. + ******************************************************************************/ +static aff_limits_node_t psci_aff_limits[MPIDR_MAX_AFFLVL + 1]; + +/******************************************************************************* + * 'psci_ns_einfo_idx' keeps track of the next free index in the + * 'psci_ns_entry_info' & 'psci_suspend_context' arrays. + ******************************************************************************/ +static unsigned int psci_ns_einfo_idx; + +/******************************************************************************* + * Routines for retrieving the node corresponding to an affinity level instance + * in the mpidr. The first one uses binary search to find the node corresponding + * to the mpidr (key) at a particular affinity level. The second routine decides + * extents of the binary search at each affinity level. + ******************************************************************************/ +static int psci_aff_map_get_idx(unsigned long key, + int min_idx, + int max_idx) +{ + int mid; + + /* + * Terminating condition: If the max and min indices have crossed paths + * during the binary search then the key has not been found. + */ + if (max_idx < min_idx) + return PSCI_E_INVALID_PARAMS; + + /* + * Bisect the array around 'mid' and then recurse into the array chunk + * where the key is likely to be found. The mpidrs in each node in the + * 'psci_aff_map' for a given affinity level are stored in an ascending + * order which makes the binary search possible. + */ + mid = min_idx + ((max_idx - min_idx) >> 1); /* Divide by 2 */ + if (psci_aff_map[mid].mpidr > key) + return psci_aff_map_get_idx(key, min_idx, mid - 1); + else if (psci_aff_map[mid].mpidr < key) + return psci_aff_map_get_idx(key, mid + 1, max_idx); + else + return mid; +} + +aff_map_node_t *psci_get_aff_map_node(unsigned long mpidr, int aff_lvl) +{ + int rc; + + /* Right shift the mpidr to the required affinity level */ + mpidr = mpidr_mask_lower_afflvls(mpidr, aff_lvl); + + rc = psci_aff_map_get_idx(mpidr, + psci_aff_limits[aff_lvl].min, + psci_aff_limits[aff_lvl].max); + if (rc >= 0) + return &psci_aff_map[rc]; + else + return NULL; +} + +/******************************************************************************* + * This function populates an array with nodes corresponding to a given range of + * affinity levels in an mpidr. It returns successfully only when the affinity + * levels are correct, the mpidr is valid i.e. no affinity level is absent from + * the topology tree & the affinity instance at level 0 is not absent. + ******************************************************************************/ +int psci_get_aff_map_nodes(unsigned long mpidr, + int start_afflvl, + int end_afflvl, + mpidr_aff_map_nodes_t mpidr_nodes) +{ + int rc = PSCI_E_INVALID_PARAMS, level; + aff_map_node_t *node; + + rc = psci_check_afflvl_range(start_afflvl, end_afflvl); + if (rc != PSCI_E_SUCCESS) + return rc; + + for (level = start_afflvl; level <= end_afflvl; level++) { + + /* + * Grab the node for each affinity level. No affinity level + * can be missing as that would mean that the topology tree + * is corrupted. + */ + node = psci_get_aff_map_node(mpidr, level); + if (node == NULL) { + rc = PSCI_E_INVALID_PARAMS; + break; + } + + /* + * Skip absent affinity levels unless it's afffinity level 0. + * An absent cpu means that the mpidr is invalid. Save the + * pointer to the node for the present affinity level + */ + if (!(node->state & PSCI_AFF_PRESENT)) { + if (level == MPIDR_AFFLVL0) { + rc = PSCI_E_INVALID_PARAMS; + break; + } + + mpidr_nodes[level] = NULL; + } else + mpidr_nodes[level] = node; + } + + return rc; +} + +/******************************************************************************* + * Function which initializes the 'aff_map_node' corresponding to an affinity + * level instance. Each node has a unique mpidr, level and bakery lock. The data + * field is opaque and holds affinity level specific data e.g. for affinity + * level 0 it contains the index into arrays that hold the secure/non-secure + * state for a cpu that's been turned on/off + ******************************************************************************/ +static void psci_init_aff_map_node(unsigned long mpidr, + int level, + unsigned int idx) +{ + unsigned char state; + uint32_t linear_id; + psci_aff_map[idx].mpidr = mpidr; + psci_aff_map[idx].level = level; + bakery_lock_init(&psci_aff_map[idx].lock); + + /* + * If an affinity instance is present then mark it as OFF to begin with. + */ + state = plat_get_aff_state(level, mpidr); + psci_aff_map[idx].state = state; + + if (level == MPIDR_AFFLVL0) { + + /* + * Mark the cpu as OFF. Higher affinity level reference counts + * have already been memset to 0 + */ + if (state & PSCI_AFF_PRESENT) + psci_set_state(&psci_aff_map[idx], PSCI_STATE_OFF); + + /* Ensure that we have not overflowed the psci_ns_einfo array */ + assert(psci_ns_einfo_idx < PSCI_NUM_AFFS); + + psci_aff_map[idx].data = psci_ns_einfo_idx; + /* Invalidate the suspend context for the node */ + psci_suspend_context[psci_ns_einfo_idx].power_state = PSCI_INVALID_DATA; + psci_ns_einfo_idx++; + + /* + * Associate a non-secure context with this affinity + * instance through the context management library. + */ + linear_id = platform_get_core_pos(mpidr); + assert(linear_id < PLATFORM_CORE_COUNT); + + cm_set_context(mpidr, + (void *) &psci_ns_context[linear_id], + NON_SECURE); + + } + + return; +} + +/******************************************************************************* + * Core routine used by the Breadth-First-Search algorithm to populate the + * affinity tree. Each level in the tree corresponds to an affinity level. This + * routine's aim is to traverse to the target affinity level and populate nodes + * in the 'psci_aff_map' for all the siblings at that level. It uses the current + * affinity level to keep track of how many levels from the root of the tree + * have been traversed. If the current affinity level != target affinity level, + * then the platform is asked to return the number of children that each + * affinity instance has at the current affinity level. Traversal is then done + * for each child at the next lower level i.e. current affinity level - 1. + * + * CAUTION: This routine assumes that affinity instance ids are allocated in a + * monotonically increasing manner at each affinity level in a mpidr starting + * from 0. If the platform breaks this assumption then this code will have to + * be reworked accordingly. + ******************************************************************************/ +static unsigned int psci_init_aff_map(unsigned long mpidr, + unsigned int affmap_idx, + int cur_afflvl, + int tgt_afflvl) +{ + unsigned int ctr, aff_count; + + assert(cur_afflvl >= tgt_afflvl); + + /* + * Find the number of siblings at the current affinity level & + * assert if there are none 'cause then we have been invoked with + * an invalid mpidr. + */ + aff_count = plat_get_aff_count(cur_afflvl, mpidr); + assert(aff_count); + + if (tgt_afflvl < cur_afflvl) { + for (ctr = 0; ctr < aff_count; ctr++) { + mpidr = mpidr_set_aff_inst(mpidr, ctr, cur_afflvl); + affmap_idx = psci_init_aff_map(mpidr, + affmap_idx, + cur_afflvl - 1, + tgt_afflvl); + } + } else { + for (ctr = 0; ctr < aff_count; ctr++, affmap_idx++) { + mpidr = mpidr_set_aff_inst(mpidr, ctr, cur_afflvl); + psci_init_aff_map_node(mpidr, cur_afflvl, affmap_idx); + } + + /* affmap_idx is 1 greater than the max index of cur_afflvl */ + psci_aff_limits[cur_afflvl].max = affmap_idx - 1; + } + + return affmap_idx; +} + +/******************************************************************************* + * This function initializes the topology tree by querying the platform. To do + * so, it's helper routines implement a Breadth-First-Search. At each affinity + * level the platform conveys the number of affinity instances that exist i.e. + * the affinity count. The algorithm populates the psci_aff_map recursively + * using this information. On a platform that implements two clusters of 4 cpus + * each, the populated aff_map_array would look like this: + * + * <- cpus cluster0 -><- cpus cluster1 -> + * --------------------------------------------------- + * | 0 | 1 | 0 | 1 | 2 | 3 | 0 | 1 | 2 | 3 | + * --------------------------------------------------- + * ^ ^ + * cluster __| cpu __| + * limit limit + * + * The first 2 entries are of the cluster nodes. The next 4 entries are of cpus + * within cluster 0. The last 4 entries are of cpus within cluster 1. + * The 'psci_aff_limits' array contains the max & min index of each affinity + * level within the 'psci_aff_map' array. This allows restricting search of a + * node at an affinity level between the indices in the limits array. + ******************************************************************************/ +int32_t psci_setup(void) +{ + unsigned long mpidr = read_mpidr(); + int afflvl, affmap_idx, max_afflvl; + aff_map_node_t *node; + + psci_ns_einfo_idx = 0; + psci_plat_pm_ops = NULL; + + /* Find out the maximum affinity level that the platform implements */ + max_afflvl = get_max_afflvl(); + assert(max_afflvl <= MPIDR_MAX_AFFLVL); + + /* + * This call traverses the topology tree with help from the platform and + * populates the affinity map using a breadth-first-search recursively. + * We assume that the platform allocates affinity instance ids from 0 + * onwards at each affinity level in the mpidr. FIRST_MPIDR = 0.0.0.0 + */ + affmap_idx = 0; + for (afflvl = max_afflvl; afflvl >= MPIDR_AFFLVL0; afflvl--) { + affmap_idx = psci_init_aff_map(FIRST_MPIDR, + affmap_idx, + max_afflvl, + afflvl); + } + + /* + * Set the bounds for the affinity counts of each level in the map. Also + * flush out the entire array so that it's visible to subsequent power + * management operations. The 'psci_aff_map' array is allocated in + * coherent memory so does not need flushing. The 'psci_aff_limits' + * array is allocated in normal memory. It will be accessed when the mmu + * is off e.g. after reset. Hence it needs to be flushed. + */ + for (afflvl = MPIDR_AFFLVL0; afflvl < max_afflvl; afflvl++) { + psci_aff_limits[afflvl].min = + psci_aff_limits[afflvl + 1].max + 1; + } + + flush_dcache_range((unsigned long) psci_aff_limits, + sizeof(psci_aff_limits)); + + /* + * Mark the affinity instances in our mpidr as ON. No need to lock as + * this is the primary cpu. + */ + mpidr &= MPIDR_AFFINITY_MASK; + for (afflvl = MPIDR_AFFLVL0; afflvl <= max_afflvl; afflvl++) { + + node = psci_get_aff_map_node(mpidr, afflvl); + assert(node); + + /* Mark each present node as ON. */ + if (node->state & PSCI_AFF_PRESENT) + psci_set_state(node, PSCI_STATE_ON); + } + + platform_setup_pm(&psci_plat_pm_ops); + assert(psci_plat_pm_ops); + + return 0; +} diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c new file mode 100644 index 0000000..6cb0319 --- /dev/null +++ b/services/std_svc/std_svc_setup.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <debug.h> +#include <psci.h> +#include <runtime_svc.h> +#include <std_svc.h> +#include <stdint.h> +#include <uuid.h> + +/* Standard Service UUID */ +DEFINE_SVC_UUID(arm_svc_uid, + 0x108d905b, 0xf863, 0x47e8, 0xae, 0x2d, + 0xc0, 0xfb, 0x56, 0x41, 0xf6, 0xe2); + +/* Setup Standard Services */ +static int32_t std_svc_setup(void) +{ + /* + * PSCI is the only specification implemented as a Standard Service. + * Invoke PSCI setup from here + */ + return psci_setup(); +} + +/* + * Top-level Standard Service SMC handler. This handler will in turn dispatch + * calls to PSCI SMC handler + */ +uint64_t std_svc_smc_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *cookie, + void *handle, + uint64_t flags) +{ + /* + * Dispatch PSCI calls to PSCI SMC handler and return its return + * value + */ + if (is_psci_fid(smc_fid)) { + return psci_smc_handler(smc_fid, x1, x2, x3, x4, cookie, + handle, flags); + } + + switch (smc_fid) { + case ARM_STD_SVC_CALL_COUNT: + /* + * Return the number of Standard Service Calls. PSCI is the only + * standard service implemented; so return number of PSCI calls + */ + SMC_RET1(handle, PSCI_NUM_CALLS); + + case ARM_STD_SVC_UID: + /* Return UID to the caller */ + SMC_UUID_RET(handle, arm_svc_uid); + + case ARM_STD_SVC_VERSION: + /* Return the version of current implementation */ + SMC_RET2(handle, STD_SVC_VERSION_MAJOR, STD_SVC_VERSION_MINOR); + + default: + WARN("Unimplemented Standard Service Call: 0x%x \n", smc_fid); + SMC_RET1(handle, SMC_UNK); + } +} + +/* Register Standard Service Calls as runtime service */ +DECLARE_RT_SVC( + std_svc, + + OEN_STD_START, + OEN_STD_END, + SMC_TYPE_FAST, + std_svc_setup, + std_svc_smc_handler +); diff --git a/tools/fip_create/Makefile b/tools/fip_create/Makefile new file mode 100644 index 0000000..69569a1 --- /dev/null +++ b/tools/fip_create/Makefile @@ -0,0 +1,62 @@ +# +# Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 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. +# +# Neither the name of ARM nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific +# prior written permission. +# +# 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. +# + +PROJECT = fip_create +OBJECTS = fip_create.o + +CFLAGS = -Wall -Werror -pedantic -std=c99 +ifeq (${DEBUG},1) + CFLAGS += -g -O0 -DDEBUG +else + CFLAGS += -O2 +endif + +# Make soft links and include from local directory otherwise wrong headers +# could get pulled in from firmware tree. +INCLUDE_PATHS = -I. + +CC := gcc +RM := rm -rf + +.PHONY: all clean + +all: ${PROJECT} + +${PROJECT}: ${OBJECTS} Makefile + @echo " LD $@" + ${Q}${CC} ${OBJECTS} -o $@ + +%.o: %.c %.h Makefile + @echo " CC $<" + ${Q}${CC} -c ${CFLAGS} ${INCLUDE_PATHS} $< -o $@ + +clean: + ${Q}${RM} ${PROJECT} + ${Q}${RM} ${OBJECTS} diff --git a/tools/fip_create/fip_create.c b/tools/fip_create/fip_create.c new file mode 100644 index 0000000..d1802b7 --- /dev/null +++ b/tools/fip_create/fip_create.c @@ -0,0 +1,671 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 <errno.h> +#include <getopt.h> /* getopt_long() is a GNU extention */ +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include "fip_create.h" +#include "firmware_image_package.h" + +/* Values returned by getopt() as part of the command line parsing */ +#define OPT_TOC_ENTRY 0 +#define OPT_DUMP 1 +#define OPT_HELP 2 + +file_info_t files[MAX_FILES]; +unsigned file_info_count = 0; +uuid_t uuid_null = {0}; + +/* + * TODO: Add ability to specify and flag different file types. + * Add flags to the toc_entry? + * const char* format_type_str[] = { "RAW", "ELF", "PIC" }; + */ + +/* The images used depends on the platform. */ +static entry_lookup_list_t toc_entry_lookup_list[] = { + { "Trusted Boot Firmware BL2", UUID_TRUSTED_BOOT_FIRMWARE_BL2, + "bl2", NULL, FLAG_FILENAME }, + { "SCP Firmware BL3-0", UUID_SCP_FIRMWARE_BL30, + "bl30", NULL, FLAG_FILENAME}, + { "EL3 Runtime Firmware BL3-1", UUID_EL3_RUNTIME_FIRMWARE_BL31, + "bl31", NULL, FLAG_FILENAME}, + { "Secure Payload BL3-2 (Trusted OS)", UUID_SECURE_PAYLOAD_BL32, + "bl32", NULL, FLAG_FILENAME}, + { "Non-Trusted Firmware BL3-3", UUID_NON_TRUSTED_FIRMWARE_BL33, + "bl33", NULL, FLAG_FILENAME}, + { NULL, {0}, 0 } +}; + + +/* Return 0 for equal uuids */ +static inline int compare_uuids(const uuid_t *uuid1, const uuid_t *uuid2) +{ + return memcmp(uuid1, uuid2, sizeof(uuid_t)); +} + + +static inline void copy_uuid(uuid_t *to_uuid, const uuid_t *from_uuid) +{ + memcpy(to_uuid, from_uuid, sizeof(uuid_t)); +} + + +static void print_usage(void) +{ + entry_lookup_list_t *entry = toc_entry_lookup_list; + + printf("Usage: fip_create [options] FIP_FILENAME\n\n"); + printf("\tThis tool is used to create a Firmware Image Package.\n\n"); + printf("Options:\n"); + printf("\t--help: Print this help message and exit\n"); + printf("\t--dump: Print contents of FIP\n\n"); + printf("\tComponents that can be added/updated:\n"); + for (; entry->command_line_name != NULL; entry++) { + printf("\t--%s%s\t\t%s", + entry->command_line_name, + (entry->flags & FLAG_FILENAME) ? " FILENAME" : "", + entry->name); + printf("\n"); + } +} + + +static entry_lookup_list_t *get_entry_lookup_from_uuid(const uuid_t *uuid) +{ + unsigned int lookup_index = 0; + + while (toc_entry_lookup_list[lookup_index].command_line_name != NULL) { + if (compare_uuids(&toc_entry_lookup_list[lookup_index].name_uuid, + uuid) == 0) { + return &toc_entry_lookup_list[lookup_index]; + } + lookup_index++; + } + return NULL; +} + + +static file_info_t *find_file_info_from_uuid(const uuid_t *uuid) +{ + int index; + + for (index = 0; index < file_info_count; index++) { + if (compare_uuids(&files[index].name_uuid, uuid) == 0) { + return &files[index]; + } + } + return NULL; +} + + +static int add_file_info_entry(entry_lookup_list_t *lookup_entry, char *filename) +{ + file_info_t *file_info_entry; + int error; + struct stat file_status; + bool is_new_entry = false; + + /* Check if the file already exists in the array */ + file_info_entry = find_file_info_from_uuid(&lookup_entry->name_uuid); + if (file_info_entry == NULL) { + /* The file does not exist in the current list; take the next + * one available in the file_info list. 'file_info_count' is + * incremented in case of successful update at the end of the + * function. + */ + file_info_entry = &files[file_info_count]; + is_new_entry = true; + + /* Copy the uuid for the new entry */ + copy_uuid(&file_info_entry->name_uuid, + &lookup_entry->name_uuid); + } + + /* Get the file information for entry */ + error = stat(filename, &file_status); + if (error != 0) { + printf("Error: Cannot get information for file \"%s\": %s\n", + filename, strerror(errno)); + return errno; + } + file_info_entry->filename = filename; + file_info_entry->size = (unsigned int)file_status.st_size; + file_info_entry->entry = lookup_entry; + + /* Increment the file_info counter on success if it is new file entry */ + if (is_new_entry) { + file_info_count++; + + /* Ensure we do not overflow */ + if (file_info_count > MAX_FILES) { + printf("ERROR: Too many files in Package\n"); + return 1; + } + } + + return 0; +} + + +static int write_memory_to_file(const uint8_t *start, const char *filename, + unsigned int size) +{ + FILE *stream; + unsigned int bytes_written; + + /* Write the packed file out to the filesystem */ + stream = fopen(filename, "r+"); + if (stream == NULL) { + stream = fopen(filename, "w"); + if (stream == NULL) { + printf("Error: Cannot create output file \"%s\": %s\n", + filename, strerror(errno)); + return errno; + } else { + printf("Creating \"%s\"\n", filename); + } + } else { + printf("Updating \"%s\"\n", filename); + } + + bytes_written = fwrite(start, sizeof(uint8_t), size, stream); + fclose(stream); + + if (bytes_written != size) { + printf("Error: Incorrect write for file \"%s\": Size=%u," + "Written=%u bytes.\n", filename, size, bytes_written); + return EIO; + } + + return 0; +} + + +static int read_file_to_memory(void *memory, const file_info_t *info) +{ + FILE *stream; + unsigned int bytes_read; + + /* If the file_info is defined by its filename we need to load it */ + if (info->filename) { + /* Read image from filesystem */ + stream = fopen(info->filename, "r"); + if (stream == NULL) { + printf("Error: Cannot open file \"%s\": %s\n", + info->filename, strerror(errno)); + return errno; + } + + bytes_read = (unsigned int)fread(memory, sizeof(uint8_t), + info->size, stream); + fclose(stream); + if (bytes_read != info->size) { + printf("Error: Incomplete read for file \"%s\":" + "Size=%u, Read=%u bytes.\n", info->filename, + info->size, bytes_read); + return EIO; + } + } else { + if (info->image_buffer == NULL) { + printf("ERROR: info->image_buffer = NULL\n"); + return EIO; + } + /* Copy the file_info buffer (extracted from the existing + * image package) into the new buffer. + */ + memcpy(memory, info->image_buffer, info->size); + } + + return 0; +} + + +/* Create the image package file */ +static int pack_images(const char *fip_filename) +{ + int status; + uint8_t *fip_base_address; + void *entry_address; + fip_toc_header_t *toc_header; + fip_toc_entry_t *toc_entry; + unsigned int entry_index; + unsigned int toc_size; + unsigned int fip_size; + unsigned int entry_offset_address; + unsigned int payload_size = 0; + + /* Validate filename */ + if ((fip_filename == NULL) || (strcmp(fip_filename, "") == 0)) { + return EINVAL; + } + + /* Payload size calculation */ + for (entry_index = 0; entry_index < file_info_count; entry_index++) { + payload_size += files[entry_index].size; + } + + /* Allocate memory for entire package, including the final null entry */ + toc_size = (sizeof(fip_toc_header_t) + + (sizeof(fip_toc_entry_t) * (file_info_count + 1))); + fip_size = toc_size + payload_size; + fip_base_address = malloc(fip_size); + if (fip_base_address == NULL) { + printf("Error: Can't allocate enough memory to create package." + "Process aborted.\n"); + return ENOMEM; + } + memset(fip_base_address, 0, fip_size); + + /* Create ToC Header */ + toc_header = (fip_toc_header_t *)fip_base_address; + toc_header->name = TOC_HEADER_NAME; + toc_header->serial_number = TOC_HEADER_SERIAL_NUMBER; + toc_header->flags = 0; + + toc_entry = (fip_toc_entry_t *)(fip_base_address + + sizeof(fip_toc_header_t)); + + /* Calculate the starting address of the first image, right after the + * toc header. + */ + entry_offset_address = toc_size; + entry_index = 0; + + /* Create the package in memory. */ + for (entry_index = 0; entry_index < file_info_count; entry_index++) { + entry_address = (fip_base_address + entry_offset_address); + status = read_file_to_memory(entry_address, + &files[entry_index]); + if (status != 0) { + printf("Error: While reading \"%s\" from filesystem.\n", + files[entry_index].filename); + return status; + } + + copy_uuid(&toc_entry->uuid, &files[entry_index].name_uuid); + toc_entry->offset_address = entry_offset_address; + toc_entry->size = files[entry_index].size; + toc_entry->flags = 0; + entry_offset_address += toc_entry->size; + toc_entry++; + } + + /* Add a null uuid entry to mark the end of toc entries */ + copy_uuid(&toc_entry->uuid, &uuid_null); + toc_entry->offset_address = entry_offset_address; + toc_entry->size = 0; + toc_entry->flags = 0; + + /* Save the package to file */ + status = write_memory_to_file(fip_base_address, fip_filename, fip_size); + if (status != 0) { + printf("Error: Failed while writing package to file \"%s\" " + "with status=%d.\n", fip_filename, status); + return status; + } + return 0; +} + + +static void dump_toc(void) +{ + unsigned int index = 0; + unsigned int image_offset; + unsigned int image_size = 0; + + image_offset = sizeof(fip_toc_header_t) + + (sizeof(fip_toc_entry_t) * (file_info_count + 1)); + + printf("Firmware Image Package ToC:\n"); + printf("---------------------------\n"); + for (index = 0; index < file_info_count; index++) { + if (files[index].entry) { + printf("- %s: ", files[index].entry->name); + } else { + printf("- Unknown entry: "); + } + image_size = files[index].size; + + printf("offset=0x%X, size=0x%X\n", image_offset, image_size); + image_offset += image_size; + + if (files[index].filename) { + printf(" file: '%s'\n", files[index].filename); + } + } + printf("---------------------------\n"); +} + + +/* Read and load existing package into memory. */ +static int parse_fip(const char *fip_filename) +{ + FILE *fip; + char *fip_buffer; + char *fip_buffer_end; + int fip_size, read_fip_size; + fip_toc_header_t *toc_header; + fip_toc_entry_t *toc_entry; + bool found_last_toc_entry = false; + file_info_t *file_info_entry; + int status = -1; + struct stat st; + + fip = fopen(fip_filename, "r"); + if (fip == NULL) { + /* If the fip does not exist just return, it should not be + * considered as an error. The package will be created later + */ + status = 0; + goto parse_fip_return; + } + + if (stat(fip_filename, &st) != 0) { + status = errno; + goto parse_fip_fclose; + } else { + fip_size = (int)st.st_size; + } + + /* Allocate a buffer to read the package */ + fip_buffer = (char *)malloc(fip_size); + if (fip_buffer == NULL) { + printf("ERROR: Cannot allocate %d bytes.\n", fip_size); + status = errno; + goto parse_fip_fclose; + } + fip_buffer_end = fip_buffer + fip_size; + + /* Read the file */ + read_fip_size = fread(fip_buffer, sizeof(char), fip_size, fip); + if (read_fip_size != fip_size) { + printf("ERROR: Cannot read the FIP.\n"); + status = EIO; + goto parse_fip_free; + } + fclose(fip); + fip = NULL; + + /* The package must at least contain the ToC Header */ + if (fip_size < sizeof(fip_toc_header_t)) { + printf("ERROR: Given FIP is smaller than the ToC header.\n"); + status = EINVAL; + goto parse_fip_free; + } + /* Set the ToC Header at the base of the buffer */ + toc_header = (fip_toc_header_t *)fip_buffer; + /* The first toc entry should be just after the ToC header */ + toc_entry = (fip_toc_entry_t *)(toc_header + 1); + + /* While the ToC entry is contained into the buffer */ + int cnt = 0; + while (((char *)toc_entry + sizeof(fip_toc_entry_t)) < fip_buffer_end) { + cnt++; + /* Check if the ToC Entry is the last one */ + if (compare_uuids(&toc_entry->uuid, &uuid_null) == 0) { + found_last_toc_entry = true; + status = 0; + break; + } + + /* Add the entry into file_info */ + + /* Get the new entry in the array and clear it */ + file_info_entry = &files[file_info_count++]; + memset(file_info_entry, 0, sizeof(file_info_t)); + + /* Copy the info from the ToC entry */ + copy_uuid(&file_info_entry->name_uuid, &toc_entry->uuid); + file_info_entry->image_buffer = fip_buffer + + toc_entry->offset_address; + file_info_entry->size = toc_entry->size; + + /* Check if there is a corresponding entry in lookup table */ + file_info_entry->entry = + get_entry_lookup_from_uuid(&toc_entry->uuid); + + /* Go to the next ToC entry */ + toc_entry++; + } + + if (!found_last_toc_entry) { + printf("ERROR: Given FIP does not have an end ToC entry.\n"); + status = EINVAL; + goto parse_fip_free; + } else { + /* All is well, we should not free any of the loaded images */ + goto parse_fip_fclose; + } + + parse_fip_free: + if (fip_buffer != NULL) { + free(fip_buffer); + fip_buffer = NULL; + } + + parse_fip_fclose: + if (fip != NULL) { + fclose(fip); + } + + parse_fip_return: + return status; +} + + +/* Parse all command-line options and return the FIP name if present. */ +static char *get_filename(int argc, char **argv, struct option *options) +{ + int c; + char *filename = NULL; + + /* Reset option pointer so we parse all args. starts at 1. + * The filename is the only argument that does not have an option flag. + */ + optind = 1; + while (1) { + c = getopt_long(argc, argv, "", options, NULL); + if (c == -1) + break; + + if (c == '?') { + /* Failed to parse an option. Fail. */ + return NULL; + } + } + + /* Only one argument left then it is the filename. + * We dont expect any other options + */ + if (optind + 1 == argc) + filename = argv[optind]; + + return filename; +} + + +/* Work through command-line options */ +static int parse_cmdline(int argc, char **argv, struct option *options, + int *do_pack) +{ + int c; + int status = 0; + int option_index = 0; + entry_lookup_list_t *lookup_entry; + int do_dump = 0; + + /* restart parse to process all options. starts at 1. */ + optind = 1; + while (1) { + c = getopt_long(argc, argv, "", options, &option_index); + if (c == -1) + break; + + switch (c) { + case OPT_TOC_ENTRY: + if (optarg) { + /* Does the option expect a filename. */ + lookup_entry = &toc_entry_lookup_list[option_index]; + if (lookup_entry->flags & FLAG_FILENAME) { + status = add_file_info_entry(lookup_entry, optarg); + if (status != 0) { + printf("Failed to process %s\n", + options[option_index].name); + break; + } else { + /* Update package */ + *do_pack = 1; + } + } + } + break; + + case OPT_DUMP: + do_dump = 1; + continue; + + case OPT_HELP: + print_usage(); + exit(0); + + default: + /* Unrecognised options are caught in get_filename() */ + break; + } + } + + + /* Do not dump toc if we have an error as it could hide the error */ + if ((status == 0) && (do_dump)) { + dump_toc(); + } + + return status; + +} + +int main(int argc, char **argv) +{ + int i; + int status; + char *fip_filename; + int do_pack = 0; + + /* Clear file list table. */ + memset(files, 0, sizeof(files)); + + /* Initialise for getopt_long(). + * Use image table as defined at top of file to get options. + * Add 'dump' option, 'help' option and end marker. + */ + static struct option long_options[(sizeof(toc_entry_lookup_list)/ + sizeof(entry_lookup_list_t)) + 2]; + + for (i = 0; + /* -1 because we dont want to process end marker in toc table */ + i < sizeof(toc_entry_lookup_list)/sizeof(entry_lookup_list_t) - 1; + i++) { + long_options[i].name = toc_entry_lookup_list[i].command_line_name; + /* The only flag defined at the moment is for a FILENAME */ + long_options[i].has_arg = toc_entry_lookup_list[i].flags ? 1 : 0; + long_options[i].flag = 0; + long_options[i].val = OPT_TOC_ENTRY; + } + + /* Add '--dump' option */ + long_options[i].name = "dump"; + long_options[i].has_arg = 0; + long_options[i].flag = 0; + long_options[i].val = OPT_DUMP; + + /* Add '--help' option */ + long_options[++i].name = "help"; + long_options[i].has_arg = 0; + long_options[i].flag = 0; + long_options[i].val = OPT_HELP; + + /* Zero the last entry (required) */ + long_options[++i].name = 0; + long_options[i].has_arg = 0; + long_options[i].flag = 0; + long_options[i].val = 0; + +#ifdef DEBUG + /* Print all supported options */ + for (i = 0; i < sizeof(long_options)/sizeof(struct option); i++) { + printf("long opt (%d) : name = %s\n", i, long_options[i].name); + } +#endif /* DEBUG */ + + /* As the package may already exist and is to be updated we need to get + * the filename from the arguments and load from it. + * NOTE: As this is the first function to look at the program arguments + * it causes a failure if bad options were provided. + */ + fip_filename = get_filename(argc, argv, long_options); + + /* Try to open the file and load it into memory */ + if (fip_filename != NULL) { + status = parse_fip(fip_filename); + if (status != 0) { + return status; + } + } + + /* Work through provided program arguments and perform actions */ + status = parse_cmdline(argc, argv, long_options, &do_pack); + if (status != 0) { + return status; + }; + + if (fip_filename == NULL) { + printf("ERROR: Missing FIP filename\n"); + print_usage(); + return 0; + } + + /* Processed all command line options. Create/update the package if + * required. + */ + if (do_pack) { + status = pack_images(fip_filename); + if (status != 0) { + printf("Failed to create package (status = %d).\n", + status); + } + } + + return status; +} diff --git a/tools/fip_create/fip_create.h b/tools/fip_create/fip_create.h new file mode 100644 index 0000000..ef321cd --- /dev/null +++ b/tools/fip_create/fip_create.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __FIP_CREATE_H__ +#define __FIP_CREATE_H__ + +#include <stdint.h> +#include <uuid.h> + +#define MAX_FILES 10 + +/* TODO: Update this number as required */ +#define TOC_HEADER_SERIAL_NUMBER 0x12345678 + +#define FLAG_FILENAME (1 << 0) + +typedef struct entry_lookup_list { + const char *name; + uuid_t name_uuid; + const char *command_line_name; + struct file_info *info; + unsigned int flags; +} entry_lookup_list_t; + +typedef struct file_info { + uuid_t name_uuid; + const char *filename; + unsigned int size; + void *image_buffer; + entry_lookup_list_t *entry; +} file_info_t; + +#endif /* __FIP_CREATE_H__ */ diff --git a/tools/fip_create/firmware_image_package.h b/tools/fip_create/firmware_image_package.h new file mode 100644 index 0000000..f4554ec --- /dev/null +++ b/tools/fip_create/firmware_image_package.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * 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 __FIRMWARE_IMAGE_PACKAGE_H__ +#define __FIRMWARE_IMAGE_PACKAGE_H__ + +#include <stdint.h> +#include <uuid.h> + +/* This is used as a signature to validate the blob header */ +#define TOC_HEADER_NAME 0xAA640001 + + +/* ToC Entry UUIDs */ +#define UUID_TRUSTED_BOOT_FIRMWARE_BL2 \ + {0x0becf95f, 0x224d, 0x4d3e, 0xa5, 0x44, {0xc3, 0x9d, 0x81, 0xc7, 0x3f, 0x0a} } +#define UUID_SCP_FIRMWARE_BL30 \ + {0x3dfd6697, 0xbe89, 0x49e8, 0xae, 0x5d, {0x78, 0xa1, 0x40, 0x60, 0x82, 0x13} } +#define UUID_EL3_RUNTIME_FIRMWARE_BL31 \ + {0x6d08d447, 0xfe4c, 0x4698, 0x9b, 0x95, {0x29, 0x50, 0xcb, 0xbd, 0x5a, 0x00} } +#define UUID_SECURE_PAYLOAD_BL32 \ + {0x89e1d005, 0xdc53, 0x4713, 0x8d, 0x2b, {0x50, 0x0a, 0x4b, 0x7a, 0x3e, 0x38} } +#define UUID_NON_TRUSTED_FIRMWARE_BL33 \ + {0xa7eed0d6, 0xeafc, 0x4bd5, 0x97, 0x82, {0x99, 0x34, 0xf2, 0x34, 0xb6, 0xe4} } + +typedef struct fip_toc_header { + uint32_t name; + uint32_t serial_number; + uint64_t flags; +} fip_toc_header_t; + +typedef struct fip_toc_entry { + uuid_t uuid; + uint64_t offset_address; + uint64_t size; + uint64_t flags; +} fip_toc_entry_t; + +#endif /* __FIRMWARE_IMAGE_PACKAGE_H__ */ diff --git a/tools/fip_create/uuid.h b/tools/fip_create/uuid.h new file mode 100644 index 0000000..5c4767b --- /dev/null +++ b/tools/fip_create/uuid.h @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2002 Marcel Moolenaar + * 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 AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD$ + */ + +/* + * Portions copyright (c) 2014, ARM Limited and Contributors. + * All rights reserved. + */ + +#ifndef _SYS_UUID_H_ +#define _SYS_UUID_H_ + +#include <sys/cdefs.h> + +/* Length of a node address (an IEEE 802 address). */ +#define _UUID_NODE_LEN 6 + +/* + * See also: + * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt + * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm + * + * A DCE 1.1 compatible source representation of UUIDs. + */ +struct uuid { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint8_t clock_seq_hi_and_reserved; + uint8_t clock_seq_low; + uint8_t node[_UUID_NODE_LEN]; +}; + +/* XXX namespace pollution? */ +typedef struct uuid uuid_t; + +#endif /* _SYS_UUID_H_ */ |