diff options
25 files changed, 926 insertions, 163 deletions
diff --git a/.checkpatch.conf b/.checkpatch.conf index c8a6084b..0c84fcd0 100644 --- a/.checkpatch.conf +++ b/.checkpatch.conf @@ -36,9 +36,6 @@ # This is not Linux so don't expect a Linux tree! --no-tree -# 'Signed-off-by' lines in commit messages are not mandated for TF. ---no-signoff - # This clarifes the lines indications in the report. # # E.g.: diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 743e65c4..9a05e6c3 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -39,6 +39,9 @@ MEMORY { RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_LIMIT - BL31_BASE } +#ifdef PLAT_EXTRA_LD_SCRIPT +#include <plat.ld.S> +#endif SECTIONS { diff --git a/plat/rockchip/common/aarch64/plat_helpers.S b/plat/rockchip/common/aarch64/plat_helpers.S index d06d4cba..a93b526f 100644 --- a/plat/rockchip/common/aarch64/plat_helpers.S +++ b/plat/rockchip/common/aarch64/plat_helpers.S @@ -67,7 +67,7 @@ handler_a72: * Set the L2 Data RAM latency for Cortex-A72. * Set the L2 Tag RAM latency to for Cortex-A72. */ - mov x0, #((2 << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ + mov x0, #((5 << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ (0x1 << 5)) msr L2CTLR_EL1, x0 isb diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c index 40cd29e3..ff470163 100644 --- a/plat/rockchip/common/aarch64/platform_common.c +++ b/plat/rockchip/common/aarch64/platform_common.c @@ -68,6 +68,7 @@ static const int cci_map[] = { coh_limit - coh_start, \ MT_DEVICE | MT_RW | MT_SECURE); \ mmap_add(plat_rk_mmap); \ + rockchip_plat_sram_mmu_el##_el(); \ init_xlat_tables(); \ \ enable_mmu_el ## _el(0); \ diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c index 47a245a6..b073bde2 100644 --- a/plat/rockchip/common/bl31_plat_setup.c +++ b/plat/rockchip/common/bl31_plat_setup.c @@ -115,10 +115,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, bl32_ep_info = *from_bl2->bl32_ep_info; bl33_ep_info = *from_bl2->bl33_ep_info; - /* - * The code for resuming cpu from suspend must be excuted in pmusram. - * Copy the code into pmusram. - */ plat_rockchip_pmusram_prepare(); /* there may have some board sepcific message need to initialize */ diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h index ad012666..a093e792 100644 --- a/plat/rockchip/common/include/plat_private.h +++ b/plat/rockchip/common/include/plat_private.h @@ -37,6 +37,14 @@ #include <xlat_tables.h> #include <psci.h> +#define __sramdata __attribute__((section(".sram.data"))) +#define __sramconst __attribute__((section(".sram.rodata"))) +#define __sramfunc __attribute__((section(".sram.text"))) \ + __attribute__((noinline)) + +extern uint32_t __bl31_sram_text_start, __bl31_sram_text_end; +extern uint32_t __bl31_sram_data_start, __bl31_sram_data_end; + /****************************************************************************** * For rockchip socs pm ops ******************************************************************************/ @@ -135,6 +143,10 @@ extern uint64_t cpuson_entry_point[PLATFORM_CORE_COUNT]; extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT]; extern const mmap_region_t plat_rk_mmap[]; + +void rockchip_plat_sram_mmu_el3(void); +void plat_rockchip_mem_prepare(void); + #endif /* __ASSEMBLY__ */ /****************************************************************************** diff --git a/plat/rockchip/common/plat_pm.c b/plat/rockchip/common/plat_pm.c index d28100d9..e926345b 100644 --- a/plat/rockchip/common/plat_pm.c +++ b/plat/rockchip/common/plat_pm.c @@ -317,18 +317,6 @@ static void __dead2 rockchip_system_poweroff(void) rockchip_ops->system_off(); } -static void -__dead2 rockchip_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) -{ - if ((RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) && - (rockchip_ops)) { - if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE && - rockchip_ops->sys_pwr_down_wfi) - rockchip_ops->sys_pwr_down_wfi(target_state); - } - psci_power_down_wfi(); -} - /******************************************************************************* * Export the platform handlers via plat_rockchip_psci_pm_ops. The rockchip * standard @@ -341,7 +329,6 @@ const plat_psci_ops_t plat_rockchip_psci_pm_ops = { .pwr_domain_suspend = rockchip_pwr_domain_suspend, .pwr_domain_on_finish = rockchip_pwr_domain_on_finish, .pwr_domain_suspend_finish = rockchip_pwr_domain_suspend_finish, - .pwr_domain_pwr_down_wfi = rockchip_pwr_domain_pwr_down_wfi, .system_reset = rockchip_system_reset, .system_off = rockchip_system_poweroff, .validate_power_state = rockchip_validate_power_state, diff --git a/plat/rockchip/common/pmusram/pmu_sram.c b/plat/rockchip/common/pmusram/pmu_sram.c index bea48754..5c6a6e65 100644 --- a/plat/rockchip/common/pmusram/pmu_sram.c +++ b/plat/rockchip/common/pmusram/pmu_sram.c @@ -24,7 +24,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include <console.h> +#include <debug.h> #include <platform.h> +#include <plat_private.h> /***************************************************************************** * sram only surpport 32-bits access @@ -36,3 +39,33 @@ void u32_align_cpy(uint32_t *dst, const uint32_t *src, size_t bytes) for (i = 0; i < bytes; i++) dst[i] = src[i]; } + +void rockchip_plat_sram_mmu_el3(void) +{ +#ifdef PLAT_EXTRA_LD_SCRIPT + size_t sram_size; + + /* sram.text size */ + sram_size = (char *)&__bl31_sram_text_end - + (char *)&__bl31_sram_text_start; + mmap_add_region((unsigned long)&__bl31_sram_text_start, + (unsigned long)&__bl31_sram_text_start, + sram_size, MT_MEMORY | MT_RO | MT_SECURE); + + /* sram.data size */ + sram_size = (char *)&__bl31_sram_data_end - + (char *)&__bl31_sram_data_start; + mmap_add_region((unsigned long)&__bl31_sram_data_start, + (unsigned long)&__bl31_sram_data_start, + sram_size, MT_MEMORY | MT_RW | MT_SECURE); +#else + /* TODO: Support other SoCs, Just support RK3399 now */ + return; +#endif +} + +void plat_rockchip_mem_prepare(void) +{ + /* The code for resuming cpu from suspend must be excuted in pmusram */ + plat_rockchip_pmusram_prepare(); +} diff --git a/plat/rockchip/common/pmusram/pmu_sram.h b/plat/rockchip/common/pmusram/pmu_sram.h index f2904612..ec2d3416 100644 --- a/plat/rockchip/common/pmusram/pmu_sram.h +++ b/plat/rockchip/common/pmusram/pmu_sram.h @@ -45,16 +45,6 @@ #ifndef __ASSEMBLY__ -/* - * The struct is used in pmu_cpus_on.S which - * gets the data of the struct by the following index - * #define PSRAM_DT_SP 0x0 - * #define PSRAM_DT_DDR_FUNC 0x8 - * #define PSRAM_DT_DDR_DATA 0x10 - * #define PSRAM_DT_DDRFLAG 0x18 - * #define PSRAM_DT_SYS_MODE 0x1c - * #define PSRAM_DT_MPIDR 0x20 - */ struct psram_data_t { uint64_t sp; uint64_t ddr_func; @@ -76,6 +66,7 @@ CASSERT(__builtin_offsetof(struct psram_data_t, ddr_flag) == PSRAM_DT_DDRFLAG, CASSERT(__builtin_offsetof(struct psram_data_t, boot_mpidr) == PSRAM_DT_MPIDR, assert_psram_dt_mpidr_offset_mistmatch); void u32_align_cpy(uint32_t *dst, const uint32_t *src, size_t bytes); + #endif /* __ASSEMBLY__ */ #endif diff --git a/plat/rockchip/rk3399/drivers/m0/Makefile b/plat/rockchip/rk3399/drivers/m0/Makefile new file mode 100644 index 00000000..8adc47e1 --- /dev/null +++ b/plat/rockchip/rk3399/drivers/m0/Makefile @@ -0,0 +1,156 @@ +# +# Copyright (c) 2016, 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. +# + +# Cross Compile +M0_CROSS_COMPILE ?= arm-none-eabi- + +# Build architecture +ARCH := cortex-m0 + +# Build platform +PLAT_M0 ?= rk3399m0 + +ifeq (${V},0) + Q=@ + CHECKCODE_ARGS += --no-summary --terse +else + Q= +endif +export Q + +# All PHONY definition +.PHONY: all clean distclean ${ARCH} +all: ${ARCH} + +.SUFFIXES: + +INCLUDES += -Iinclude/ + +# NOTE: Add C source files here +C_SOURCES := src/startup.c \ + src/main.c + +# Flags definition +CFLAGS := -g +ASFLAGS := -g -Wa,--gdwarf-2 + +ASFLAGS += -mcpu=$(ARCH) -mthumb -Wall -ffunction-sections -O3 +CFLAGS += -mcpu=$(ARCH) -mthumb -Wall -ffunction-sections -O3 + +LDFLAGS := -mcpu=$(ARCH) -mthumb -g -nostartfiles -O3 +LDFLAGS += -Wl,--gc-sections -Wl,--build-id=none + +# Cross tool +CC := ${M0_CROSS_COMPILE}gcc +CPP := ${M0_CROSS_COMPILE}cpp +AS := ${M0_CROSS_COMPILE}gcc +AR := ${M0_CROSS_COMPILE}ar +LD := ${M0_CROSS_COMPILE}ld +OC := ${M0_CROSS_COMPILE}objcopy +OD := ${M0_CROSS_COMPILE}objdump +NM := ${M0_CROSS_COMPILE}nm +PP := ${M0_CROSS_COMPILE}gcc -E ${CFLAGS} + +# 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 + +BUILD_DIR := ${BUILD_PLAT}/obj +BIN_DIR := ${BUILD_PLAT}/bin +SOURCES := $(C_SOURCES) +OBJS := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))) +LINKERFILE := src/rk3399m0.ld +MAPFILE := $(BIN_DIR)/$(PLAT_M0).map +ELF := $(BIN_DIR)/$(PLAT_M0).elf +BIN := $(BIN_DIR)/$(PLAT_M0).bin + +# Function definition related compilation +define MAKE_C +$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2)))) + +$(OBJ) : $(2) + @echo " CC $$<" + $$(Q)$$(CC) $$(CFLAGS) $$(INCLUDES) -c $$< -o $$@ +endef + +define MAKE_S +$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2)))) + +$(OBJ) : $(2) + @echo " AS $$<" + $$(Q)$$(AS) $$(ASFLAGS) -c $$< -o $$@ +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),$(3)))) + + $(eval S_OBJS := $(filter %.S,$(REMAIN))) + $(eval REMAIN := $(filter-out %.S,$(REMAIN))) + $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S,$(1),$(obj),$(3)))) + + $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN))) +endef + +$(BIN_DIR) : + $(Q)mkdir -p "$@" + +$(BUILD_DIR) : $(BIN_DIR) + $(Q)mkdir -p "$@" + +$(ELF) : $(OBJS) $(LINKERFILE) + @echo " LD $@" + $(Q)$(CC) -o $@ $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) \ + $(OBJS) + +$(BIN) : $(ELF) + @echo " BIN $@" + $(Q)$(OC) -O binary $< $@ + +.PHONY : ${ARCH} +${ARCH} : $(BUILD_DIR) $(BIN) + +$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1))) + +# Other common compilation entries +clean: + @echo " CLEAN" + ${Q}rm -rf ${BUILD_BASE}/${PLAT_M0} + ${Q}rm -rf ${VER_BIN_DIR}/$(PLAT_M0)* + +distclean: + @echo " DISTCLEAN" + ${Q}rm -rf ${BUILD_BASE}/${PLAT_M0} + ${Q}rm -rf ${VER_BIN_DIR}/$(PLAT_M0)* diff --git a/plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h b/plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h new file mode 100644 index 00000000..7ea40fac --- /dev/null +++ b/plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, 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 __RK3399_MCU_H__ +#define __RK3399_MCU_H__ + +#define readl(c) ({unsigned int __v = \ + (*(volatile unsigned int *)(c)); __v; }) +#define writel(v, c) ((*(volatile unsigned int *) (c)) = (v)) + +#define MCU_BASE 0x40000000 +#define PMU_BASE (MCU_BASE + 0x07310000) + +#endif /* __RK3399_MCU_H__ */ diff --git a/plat/rockchip/rk3399/drivers/m0/src/main.c b/plat/rockchip/rk3399/drivers/m0/src/main.c new file mode 100644 index 00000000..2e583c70 --- /dev/null +++ b/plat/rockchip/rk3399/drivers/m0/src/main.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016, 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 "rk3399_mcu.h" + +#define PMU_PWRMODE_CON 0x20 +#define PMU_POWER_ST 0x78 + +#define M0_SCR 0xe000ed10 /* System Control Register (SCR) */ + +#define SCR_SLEEPDEEP_SHIFT (1 << 2) + +static void system_wakeup(void) +{ + unsigned int status_value; + unsigned int mode_con; + + while (1) { + status_value = readl(PMU_BASE + PMU_POWER_ST); + if (status_value) { + mode_con = readl(PMU_BASE + PMU_PWRMODE_CON); + writel(mode_con & (~0x01), + PMU_BASE + PMU_PWRMODE_CON); + return; + } + } +} + +int main(void) +{ + unsigned int reg_src; + + system_wakeup(); + + reg_src = readl(M0_SCR); + + /* m0 enter deep sleep mode */ + writel(reg_src | SCR_SLEEPDEEP_SHIFT, M0_SCR); + + for (;;) + __asm volatile("wfi"); + + return 0; +} diff --git a/plat/rockchip/rk3399/drivers/m0/src/rk3399m0.ld b/plat/rockchip/rk3399/drivers/m0/src/rk3399m0.ld new file mode 100644 index 00000000..0b7b124d --- /dev/null +++ b/plat/rockchip/rk3399/drivers/m0/src/rk3399m0.ld @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016, 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. + */ + +OUTPUT_FORMAT("elf32-littlearm") + +SECTIONS { + .m0_bin 0 : { + KEEP(*(.isr_vector)) + ASSERT(. == 0xc0, "ISR vector has the wrong size."); + *(.text*) + *(.rodata*) + *(.data*) + *(.bss*) + . = ALIGN(8); + *(.co_stack*) + } + + /DISCARD/ : { *(.comment) *(.note*) } +} diff --git a/plat/rockchip/rk3399/drivers/m0/src/startup.c b/plat/rockchip/rk3399/drivers/m0/src/startup.c new file mode 100644 index 00000000..47561fdd --- /dev/null +++ b/plat/rockchip/rk3399/drivers/m0/src/startup.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2016, 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 "rk3399_mcu.h" + +/* Stack configuration */ +#define STACK_SIZE 0x00000100 +__attribute__ ((section(".co_stack"))) +unsigned long pstack[STACK_SIZE]; + +/* Macro definition */ +#define WEAK __attribute__ ((weak)) + +/* System exception vector handler */ +__attribute__ ((used)) +void WEAK reset_handler(void); +void WEAK nmi_handler(void); +void WEAK hardware_fault_handler(void); +void WEAK svc_handler(void); +void WEAK pend_sv_handler(void); +void WEAK systick_handler(void); + +extern int main(void); + +/* Function prototypes */ +static void default_reset_handler(void); +static void default_handler(void); + +/* + * The minimal vector table for a Cortex M3. Note that the proper constructs + * must be placed on this to ensure that it ends up at physical address + * 0x00000000. + */ +__attribute__ ((used, section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = { + /* core Exceptions */ + (void *)&pstack[STACK_SIZE], /* the initial stack pointer */ + reset_handler, + nmi_handler, + hardware_fault_handler, + 0, 0, 0, 0, 0, 0, 0, + svc_handler, + 0, 0, + pend_sv_handler, + systick_handler, + + /* external exceptions */ + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; + +/** + * This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + */ +static void default_reset_handler(void) +{ + /* call the application's entry point */ + main(); +} + +/** + * Provide weak aliases for each Exception handler to the Default_Handler. + * As they are weak aliases, any function with the same name will override + * this definition. + */ +#pragma weak reset_handler = default_reset_handler +#pragma weak nmi_handler = default_handler +#pragma weak hardware_fault_handler = default_handler +#pragma weak svc_handler = default_handler +#pragma weak pend_sv_handler = default_handler +#pragma weak systick_handler = default_handler + +/** + * This is the code that gets called when the processor receives + * an unexpected interrupt. This simply enters an infinite loop, + * preserving the system state for examination by a debugger. + */ +static void default_handler(void) +{ + /* go into an infinite loop. */ + while (1) + ; +} diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index 07a5b1e7..8d3f482f 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -48,6 +48,7 @@ #include <pwm.h> #include <soc.h> #include <bl31.h> +#include <rk3399m0.h> DEFINE_BAKERY_LOCK(rockchip_pd_lock); @@ -436,7 +437,7 @@ static void pmu_scu_b_pwrup(void) void plat_rockchip_pmusram_prepare(void) { uint32_t *sram_dst, *sram_src; - size_t sram_size = 2; + size_t sram_size; /* * pmu sram code and data prepare @@ -840,8 +841,6 @@ static void sys_slp_config(void) BIT(PMU_SCU_PD_EN) | BIT(PMU_CCI_PD_EN) | BIT(PMU_CLK_CORE_SRC_GATE_EN) | - BIT(PMU_PERILP_PD_EN) | - BIT(PMU_CLK_PERILP_SRC_GATE_EN) | BIT(PMU_ALIVE_USE_LF) | BIT(PMU_SREF0_ENTER_EN) | BIT(PMU_SREF1_ENTER_EN) | @@ -1058,6 +1057,38 @@ static void resume_gpio(void) } } +static void m0_clock_init(void) +{ + /* enable clocks for M0 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_CLKGATE_CON2, + BITS_WITH_WMASK(0x0, 0x2f, 0)); + + /* switch the parent to xin24M and div == 1 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_CLKSEL_CON0, + BIT_WITH_WMSK(15) | BITS_WITH_WMASK(0x0, 0x1f, 8)); + + /* start M0 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_SOFTRST_CON0, + BITS_WITH_WMASK(0x0, 0x24, 0)); + + /* gating disable for M0 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_GATEDIS_CON0, BIT_WITH_WMSK(1)); +} + +static void m0_reset(void) +{ + /* stop M0 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_SOFTRST_CON0, + BITS_WITH_WMASK(0x24, 0x24, 0)); + + /* recover gating bit for M0 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_GATEDIS_CON0, WMSK_BIT(1)); + + /* disable clocks for M0 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_CLKGATE_CON2, + BITS_WITH_WMASK(0x2f, 0x2f, 0)); +} + static int sys_pwr_domain_suspend(void) { uint32_t wait_cnt = 0; @@ -1071,12 +1102,12 @@ static int sys_pwr_domain_suspend(void) BIT(PMU_CLR_CCIM0) | BIT(PMU_CLR_CCIM1) | BIT(PMU_CLR_CENTER) | - BIT(PMU_CLR_PERILP) | - BIT(PMU_CLR_PMU) | - BIT(PMU_CLR_PERILPM0) | BIT(PMU_CLR_GIC)); sys_slp_config(); + + m0_clock_init(); + pmu_sgrf_rst_hld(); mmio_write_32(SGRF_BASE + SGRF_SOC_CON0_1(1), @@ -1111,6 +1142,7 @@ static int sys_pwr_domain_suspend(void) disable_dvfs_plls(); disable_pwms(); disable_nodvfs_plls(); + suspend_apio(); suspend_gpio(); @@ -1186,12 +1218,12 @@ static int sys_pwr_domain_resume(void) BIT(PMU_CLR_CCIM0) | BIT(PMU_CLR_CCIM1) | BIT(PMU_CLR_CENTER) | - BIT(PMU_CLR_PERILP) | - BIT(PMU_CLR_PMU) | BIT(PMU_CLR_GIC)); plat_rockchip_gic_cpuif_enable(); + m0_reset(); + return 0; } @@ -1236,42 +1268,6 @@ void __dead2 soc_system_off(void) while (1) ; } -static void __dead2 sys_pwr_down_wfi(const psci_power_state_t *target_state) -{ - uint32_t wakeup_status; - - /* - * Check wakeup status and abort suspend early if we see a wakeup - * event. - * - * NOTE: technically I we're supposed to just execute a wfi here and - * we'll either execute a normal suspend/resume or the wfi will be - * treated as a no-op if a wake event was present and caused an abort - * of the suspend/resume. For some reason that's not happening and if - * we execute the wfi while a wake event is pending then the whole - * system wedges. - * - * Until the above is solved this extra check prevents system wedges in - * most cases but there is still a small race condition between checking - * PMU_WAKEUP_STATUS and executing wfi. If a wake event happens in - * there then we will die. - */ - wakeup_status = mmio_read_32(PMU_BASE + PMU_WAKEUP_STATUS); - if (wakeup_status) { - WARN("early wake, will not enter power mode.\n"); - - mmio_write_32(PMU_BASE + PMU_PWRMODE_CON, 0); - - disable_mmu_icache_el3(); - bl31_warm_entrypoint(); - - while (1) - ; - } else { - /* Enter WFI */ - psci_power_down_wfi(); - } -} static struct rockchip_pm_ops_cb pm_ops = { .cores_pwr_dm_on = cores_pwr_domain_on, @@ -1287,7 +1283,6 @@ static struct rockchip_pm_ops_cb pm_ops = { .sys_pwr_dm_resume = sys_pwr_domain_resume, .sys_gbl_soft_reset = soc_soft_reset, .system_off = soc_system_off, - .sys_pwr_down_wfi = sys_pwr_down_wfi, }; void plat_rockchip_pmu_init(void) diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c new file mode 100644 index 00000000..01f08e6d --- /dev/null +++ b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, 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. + */ + +/* convoluted way to make sure that the define is pasted just the right way */ +#define _INCBIN(file, sym) \ + __asm__( \ + ".section .sram.incbin\n" \ + ".global " #sym "\n" \ + ".type " #sym ", %object\n" \ + ".align 4\n" \ + #sym ":\n" \ + ".incbin \"" #file "\"\n" \ + ".size " #sym ", .-" #sym "\n" \ + ".global " #sym "_end\n" \ + #sym "_end:\n" \ + ) + +#define INCBIN(file, sym) _INCBIN(file, sym) + +INCBIN(RK3399M0FW, rk3399m0_bin); diff --git a/plat/rockchip/rk3399/drivers/pmu/rk3399m0.h b/plat/rockchip/rk3399/drivers/pmu/rk3399m0.h new file mode 100644 index 00000000..78b350a2 --- /dev/null +++ b/plat/rockchip/rk3399/drivers/pmu/rk3399m0.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, 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 __RK3399M0_H__ +#define __RK3399M0_H__ + +/* pmu_fw.c */ +extern char rk3399m0_bin[]; +extern char rk3399m0_bin_end[]; + +#define M0_BINCODE_BASE ((uintptr_t)rk3399m0_bin) + +#endif /* __RK3399M0_H__ */ diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c index 6af7a2e2..e99db19c 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.c +++ b/plat/rockchip/rk3399/drivers/soc/soc.c @@ -35,6 +35,7 @@ #include <platform_def.h> #include <plat_private.h> #include <rk3399_def.h> +#include <rk3399m0.h> #include <soc.h> /* Table of regions to map using the MMU. */ @@ -387,6 +388,20 @@ void __dead2 soc_global_soft_reset(void) ; } +static void soc_m0_init(void) +{ + /* secure config for pmu M0 */ + mmio_write_32(SGRF_BASE + SGRF_PMU_CON(0), WMSK_BIT(7)); + + /* set the execute address for M0 */ + mmio_write_32(SGRF_BASE + SGRF_PMU_CON(3), + BITS_WITH_WMASK((M0_BINCODE_BASE >> 12) & 0xffff, + 0xffff, 0)); + mmio_write_32(SGRF_BASE + SGRF_PMU_CON(7), + BITS_WITH_WMASK((M0_BINCODE_BASE >> 28) & 0xf, + 0xf, 0)); +} + void plat_rockchip_soc_init(void) { secure_timer_init(); @@ -394,4 +409,5 @@ void plat_rockchip_soc_init(void) sgrf_init(); soc_global_soft_reset_init(); plat_rockchip_gpio_init(); + soc_m0_init(); } diff --git a/plat/rockchip/rk3399/drivers/soc/soc.h b/plat/rockchip/rk3399/drivers/soc/soc.h index d4c2b695..9693f57c 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.h +++ b/plat/rockchip/rk3399/drivers/soc/soc.h @@ -293,6 +293,18 @@ struct deepsleep_data_s { #define GRF_DDRC1_CON0 0xe388 #define GRF_DDRC1_CON1 0xe38c +#define PMUCRU_CLKSEL_CON0 0x0080 +#define PMUCRU_CLKGATE_CON2 0x0108 +#define PMUCRU_SOFTRST_CON0 0x0110 +#define PMUCRU_GATEDIS_CON0 0x0130 + +#define SGRF_SOC_CON6 0x0e018 +#define SGRF_PERILP_CON0 0x08100 +#define SGRF_PERILP_CON(n) (SGRF_PERILP_CON0 + (n) * 4) +#define SGRF_PMU_CON0 0x0c100 +#define SGRF_PMU_CON(n) (SGRF_PMU_CON0 + (n) * 4) +#define PMUCRU_SOFTRST_CON(n) (PMUCRU_SOFTRST_CON0 + (n) * 4) + /* * When system reset in running state, we want the cpus to be reboot * from maskrom (system reboot), diff --git a/plat/rockchip/rk3399/include/plat.ld.S b/plat/rockchip/rk3399/include/plat.ld.S new file mode 100644 index 00000000..1614fbac --- /dev/null +++ b/plat/rockchip/rk3399/include/plat.ld.S @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016, 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 __ROCKCHIP_PLAT_LD_S__ +#define __ROCKCHIP_PLAT_LD_S__ + +MEMORY { + SRAM (rwx): ORIGIN = SRAM_BASE, LENGTH = SRAM_SIZE +} + +SECTIONS +{ + . = SRAM_BASE; + ASSERT(. == ALIGN(4096), + "SRAM_BASE address is not aligned on a page boundary.") + + /* + * The SRAM space allocation for RK3399 + * ---------------- + * | m0 code bin + * ---------------- + * | sram text + * ---------------- + * | sram data + * ---------------- + */ + .incbin_sram : ALIGN(4096) { + __sram_incbin_start = .; + *(.sram.incbin) + . = ALIGN(4096); + __sram_incbin_end = .; + } >SRAM + + .text_sram : ALIGN(4096) { + __bl31_sram_text_start = .; + *(.sram.text) + *(.sram.rodata) + . = ALIGN(4096); + __bl31_sram_text_end = .; + } >SRAM + + .data_sram : ALIGN(4096) { + __bl31_sram_data_start = .; + *(.sram.data) + . = ALIGN(4096); + __bl31_sram_data_end = .; + } >SRAM +} + +#endif /* __ROCKCHIP_PLAT_LD_S__ */ diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk index 36278573..604de9c8 100644 --- a/plat/rockchip/rk3399/platform.mk +++ b/plat/rockchip/rk3399/platform.mk @@ -76,9 +76,28 @@ BL31_SOURCES += ${RK_GIC_SOURCES} ${RK_PLAT_SOC}/plat_sip_calls.c \ ${RK_PLAT_SOC}/drivers/gpio/rk3399_gpio.c \ ${RK_PLAT_SOC}/drivers/pmu/pmu.c \ + ${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c \ ${RK_PLAT_SOC}/drivers/pwm/pwm.c \ ${RK_PLAT_SOC}/drivers/soc/soc.c \ ${RK_PLAT_SOC}/drivers/dram/dram.c \ ${RK_PLAT_SOC}/drivers/dram/dram_spec_timing.c ENABLE_PLAT_COMPAT := 0 + +$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) + +# M0 source build +PLAT_M0 := ${PLAT}m0 + +RK3399M0FW=${BUILD_PLAT}/m0/bin/${PLAT_M0}.bin +$(eval $(call add_define,RK3399M0FW)) + +# CCACHE_EXTRAFILES is needed because ccache doesn't handle .incbin +export CCACHE_EXTRAFILES +${BUILD_PLAT}/bl31/pmu_fw.o: CCACHE_EXTRAFILES=$(RK3399M0FW) +${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c: $(RK3399M0FW) + +.PHONY: $(RK3399M0FW) +$(RK3399M0FW): + $(MAKE) -C ${RK_PLAT_SOC}/drivers/m0 \ + BUILD_PLAT=$(abspath ${BUILD_PLAT}/m0) diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c index b3f02f6c..0084edf7 100644 --- a/tools/fiptool/fiptool.c +++ b/tools/fiptool/fiptool.c @@ -187,7 +187,7 @@ static void free_images(void) } } -static toc_entry_t *get_entry_lookup_from_uuid(const uuid_t *uuid) +static toc_entry_t *lookup_entry_from_uuid(uuid_t *uuid) { toc_entry_t *toc_entry = toc_entries; @@ -197,6 +197,19 @@ static toc_entry_t *get_entry_lookup_from_uuid(const uuid_t *uuid) return NULL; } +static image_t *lookup_image_from_uuid(uuid_t *uuid) +{ + image_t *image; + int i; + + for (i = 0; i < nr_images; i++) { + image = images[i]; + if (memcmp(&image->uuid, uuid, sizeof(uuid_t)) == 0) + return image; + } + return NULL; +} + static int parse_fip(char *filename, fip_toc_header_t *toc_header_out) { struct stat st; @@ -268,16 +281,6 @@ static int parse_fip(char *filename, fip_toc_header_t *toc_header_out) toc_entry->size); image->size = toc_entry->size; - image->toc_entry = get_entry_lookup_from_uuid(&toc_entry->uuid); - if (image->toc_entry == NULL) { - add_image(image); - toc_entry++; - continue; - } - - assert(image->toc_entry->image == NULL); - /* Link backpointer from lookup entry. */ - image->toc_entry->image = image; add_image(image); toc_entry++; @@ -290,12 +293,14 @@ static int parse_fip(char *filename, fip_toc_header_t *toc_header_out) return 0; } -static image_t *read_image_from_file(toc_entry_t *toc_entry, char *filename) +static image_t *read_image_from_file(uuid_t *uuid, char *filename) { struct stat st; image_t *image; FILE *fp; + assert(uuid != NULL); + fp = fopen(filename, "r"); if (fp == NULL) log_err("fopen %s", filename); @@ -307,7 +312,7 @@ static image_t *read_image_from_file(toc_entry_t *toc_entry, char *filename) if (image == NULL) log_err("malloc"); - memcpy(&image->uuid, &toc_entry->uuid, sizeof(uuid_t)); + memcpy(&image->uuid, uuid, sizeof(uuid_t)); image->buffer = malloc(st.st_size); if (image->buffer == NULL) @@ -315,7 +320,6 @@ static image_t *read_image_from_file(toc_entry_t *toc_entry, char *filename) if (fread(image->buffer, 1, st.st_size, fp) != st.st_size) log_errx("Failed to read %s", filename); image->size = st.st_size; - image->toc_entry = toc_entry; fclose(fp); return image; @@ -391,18 +395,21 @@ static int info_cmd(int argc, char *argv[]) (sizeof(fip_toc_entry_t) * (nr_images + 1)); for (i = 0; i < nr_images; i++) { + toc_entry_t *toc_entry; + image = images[i]; - if (image->toc_entry != NULL) - printf("%s: ", image->toc_entry->name); + toc_entry = lookup_entry_from_uuid(&image->uuid); + if (toc_entry != NULL) + printf("%s: ", toc_entry->name); else printf("Unknown entry: "); image_size = image->size; printf("offset=0x%llX, size=0x%llX", (unsigned long long)image_offset, (unsigned long long)image_size); - if (image->toc_entry != NULL) + if (toc_entry != NULL) printf(", cmdline=\"--%s\"", - image->toc_entry->cmdline_name); + toc_entry->cmdline_name); if (verbose) { unsigned char md[SHA256_DIGEST_LENGTH]; @@ -505,7 +512,7 @@ static int pack_images(char *filename, uint64_t toc_flags) static void update_fip(void) { toc_entry_t *toc_entry; - image_t *image; + image_t *new_image, *old_image; /* Add or replace images in the FIP file. */ for (toc_entry = toc_entries; @@ -514,21 +521,21 @@ static void update_fip(void) if (toc_entry->action != DO_PACK) continue; - image = read_image_from_file(toc_entry, toc_entry->action_arg); - if (toc_entry->image != NULL) { + new_image = read_image_from_file(&toc_entry->uuid, + toc_entry->action_arg); + old_image = lookup_image_from_uuid(&toc_entry->uuid); + if (old_image != NULL) { if (verbose) log_dbgx("Replacing image %s.bin with %s", toc_entry->cmdline_name, toc_entry->action_arg); - replace_image(toc_entry->image, image); + replace_image(old_image, new_image); } else { if (verbose) log_dbgx("Adding image %s", toc_entry->action_arg); - add_image(image); + add_image(new_image); } - /* Link backpointer from lookup entry. */ - toc_entry->image = image; free(toc_entry->action_arg); toc_entry->action_arg = NULL; @@ -758,23 +765,13 @@ static int unpack_cmd(int argc, char *argv[]) if (chdir(outdir) == -1) log_err("chdir %s", outdir); - /* Mark all images to be unpacked. */ - if (unpack_all) { - for (toc_entry = toc_entries; - toc_entry->cmdline_name != NULL; - toc_entry++) { - if (toc_entry->image != NULL) { - toc_entry->action = DO_UNPACK; - toc_entry->action_arg = NULL; - } - } - } - /* Unpack all specified images. */ for (toc_entry = toc_entries; toc_entry->cmdline_name != NULL; toc_entry++) { - if (toc_entry->action != DO_UNPACK) + image_t *image; + + if (!unpack_all && toc_entry->action != DO_UNPACK) continue; /* Build filename. */ @@ -785,9 +782,11 @@ static int unpack_cmd(int argc, char *argv[]) snprintf(file, sizeof(file), "%s", toc_entry->action_arg); - if (toc_entry->image == NULL) { - log_warnx("Requested image %s is not in %s", - file, argv[0]); + image = lookup_image_from_uuid(&toc_entry->uuid); + if (image == NULL) { + if (!unpack_all) + log_warnx("Requested image %s is not in %s", + file, argv[0]); free(toc_entry->action_arg); toc_entry->action_arg = NULL; continue; @@ -796,7 +795,7 @@ static int unpack_cmd(int argc, char *argv[]) if (access(file, F_OK) != 0 || fflag) { if (verbose) log_dbgx("Unpacking %s", file); - write_image_to_file(toc_entry->image, file); + write_image_to_file(image, file); } else { log_warnx("File %s already exists, use --force to overwrite it", file); @@ -885,13 +884,16 @@ static int remove_cmd(int argc, char *argv[]) for (toc_entry = toc_entries; toc_entry->cmdline_name != NULL; toc_entry++) { + image_t *image; + if (toc_entry->action != DO_REMOVE) continue; - if (toc_entry->image != NULL) { + image = lookup_image_from_uuid(&toc_entry->uuid); + if (image != NULL) { if (verbose) log_dbgx("Removing %s.bin", toc_entry->cmdline_name); - remove_image(toc_entry->image); + remove_image(image); } else { log_warnx("Requested image %s.bin is not in %s", toc_entry->cmdline_name, argv[0]); @@ -983,6 +985,8 @@ int main(int argc, char *argv[]) strcmp(argv[0], "--verbose") == 0) { verbose = 1; argc--, argv++; + if (argc < 1) + usage(); } for (i = 0; i < NELEM(cmds); i++) { diff --git a/tools/fiptool/fiptool.h b/tools/fiptool/fiptool.h index 0fe64c0c..77051076 100644 --- a/tools/fiptool/fiptool.h +++ b/tools/fiptool/fiptool.h @@ -57,7 +57,6 @@ typedef struct image { uuid_t uuid; size_t size; void *buffer; - struct toc_entry *toc_entry; } image_t; typedef struct cmd { diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c index e8fbbbaa..b92e8daf 100644 --- a/tools/fiptool/tbbr_config.c +++ b/tools/fiptool/tbbr_config.c @@ -35,49 +35,155 @@ /* The images used depends on the platform. */ toc_entry_t toc_entries[] = { - { "SCP Firmware Updater Configuration FWU SCP_BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U, - "scp-fwu-cfg", NULL, 0, NULL }, - { "AP Firmware Updater Configuration BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_BL2U, - "ap-fwu-cfg", NULL, 0, NULL }, - { "Firmware Updater NS_BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U, - "fwu", NULL, 0, NULL }, - { "Non-Trusted Firmware Updater certificate", UUID_TRUSTED_FWU_CERT, - "fwu-cert", NULL, 0, NULL }, - { "Trusted Boot Firmware BL2", UUID_TRUSTED_BOOT_FIRMWARE_BL2, - "tb-fw", NULL, 0, NULL }, - { "SCP Firmware SCP_BL2", UUID_SCP_FIRMWARE_SCP_BL2, - "scp-fw", NULL, 0, NULL }, - { "EL3 Runtime Firmware BL31", UUID_EL3_RUNTIME_FIRMWARE_BL31, - "soc-fw", NULL, 0, NULL }, - { "Secure Payload BL32 (Trusted OS)", UUID_SECURE_PAYLOAD_BL32, - "tos-fw", NULL, 0, NULL }, - { "Non-Trusted Firmware BL33", UUID_NON_TRUSTED_FIRMWARE_BL33, - "nt-fw", NULL, 0, NULL }, + { + .name = "SCP Firmware Updater Configuration FWU SCP_BL2U", + .uuid = UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U, + .cmdline_name = "scp-fwu-cfg", + .action = 0, + .action_arg = NULL + }, + { + .name = "AP Firmware Updater Configuration BL2U", + .uuid = UUID_TRUSTED_UPDATE_FIRMWARE_BL2U, + .cmdline_name = "ap-fwu-cfg", + .action = 0, + .action_arg = NULL + }, + { + .name = "Firmware Updater NS_BL2U", + .uuid = UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U, + .cmdline_name = "fwu", + .action = 0, + .action_arg = NULL + }, + { + .name = "Non-Trusted Firmware Updater certificate", + .uuid = UUID_TRUSTED_FWU_CERT, + .cmdline_name = "fwu-cert", + .action = 0, + .action_arg = NULL + }, + { + .name = "Trusted Boot Firmware BL2", + .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, + .cmdline_name = "tb-fw", + .action = 0, + .action_arg = NULL + }, + { + .name = "SCP Firmware SCP_BL2", + .uuid = UUID_SCP_FIRMWARE_SCP_BL2, + .cmdline_name = "scp-fw", + .action = 0, + .action_arg = NULL + }, + { + .name = "EL3 Runtime Firmware BL31", + .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, + .cmdline_name = "soc-fw", + .action = 0, + .action_arg = NULL + }, + { + .name = "Secure Payload BL32 (Trusted OS)", + .uuid = UUID_SECURE_PAYLOAD_BL32, + .cmdline_name = "tos-fw", + .action = 0, + .action_arg = NULL + }, + { + .name = "Non-Trusted Firmware BL33", + .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, + .cmdline_name = "nt-fw", + .action = 0, + .action_arg = NULL + }, /* Key Certificates */ - { "Root Of Trust key certificate", UUID_ROT_KEY_CERT, - "rot-cert", NULL, 0, NULL }, - { "Trusted key certificate", UUID_TRUSTED_KEY_CERT, - "trusted-key-cert", NULL, 0, NULL }, - { "SCP Firmware key certificate", UUID_SCP_FW_KEY_CERT, - "scp-fw-key-cert", NULL, 0, NULL }, - { "SoC Firmware key certificate", UUID_SOC_FW_KEY_CERT, - "soc-fw-key-cert", NULL, 0, NULL }, - { "Trusted OS Firmware key certificate", UUID_TRUSTED_OS_FW_KEY_CERT, - "tos-fw-key-cert", NULL, 0, NULL }, - { "Non-Trusted Firmware key certificate", UUID_NON_TRUSTED_FW_KEY_CERT, - "nt-fw-key-cert", NULL, 0, NULL }, + { + .name = "Root Of Trust key certificate", + .uuid = UUID_ROT_KEY_CERT, + .cmdline_name = "rot-cert", + .action = 0, + .action_arg = NULL + }, + { + .name = "Trusted key certificate", + .uuid = UUID_TRUSTED_KEY_CERT, + .cmdline_name = "trusted-key-cert", + .action = 0, + .action_arg = NULL + }, + { + .name = "SCP Firmware key certificate", + .uuid = UUID_SCP_FW_KEY_CERT, + .cmdline_name = "scp-fw-key-cert", + .action = 0, + .action_arg = NULL + }, + { + .name = "SoC Firmware key certificate", + .uuid = UUID_SOC_FW_KEY_CERT, + .cmdline_name = "soc-fw-key-cert", + .action = 0, + .action_arg = NULL + }, + { + .name = "Trusted OS Firmware key certificate", + .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, + .cmdline_name = "tos-fw-key-cert", + .action = 0, + .action_arg = NULL + }, + { + .name = "Non-Trusted Firmware key certificate", + .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, + .cmdline_name = "nt-fw-key-cert", + .action = 0, + .action_arg = NULL + }, /* Content certificates */ - { "Trusted Boot Firmware BL2 certificate", UUID_TRUSTED_BOOT_FW_CERT, - "tb-fw-cert", NULL, 0, NULL }, - { "SCP Firmware content certificate", UUID_SCP_FW_CONTENT_CERT, - "scp-fw-cert", NULL, 0, NULL }, - { "SoC Firmware content certificate", UUID_SOC_FW_CONTENT_CERT, - "soc-fw-cert", NULL, 0, NULL }, - { "Trusted OS Firmware content certificate", UUID_TRUSTED_OS_FW_CONTENT_CERT, - "tos-fw-cert", NULL, 0, NULL }, - { "Non-Trusted Firmware content certificate", UUID_NON_TRUSTED_FW_CONTENT_CERT, - "nt-fw-cert", NULL, 0, NULL }, - { NULL, { 0 }, NULL, NULL, 0, NULL } + { + .name = "Trusted Boot Firmware BL2 certificate", + .uuid = UUID_TRUSTED_BOOT_FW_CERT, + .cmdline_name = "tb-fw-cert", + .action = 0, + .action_arg = NULL + }, + { + .name = "SCP Firmware content certificate", + .uuid = UUID_SCP_FW_CONTENT_CERT, + .cmdline_name = "scp-fw-cert", + .action = 0, + .action_arg = NULL + }, + { + .name = "SoC Firmware content certificate", + .uuid = UUID_SOC_FW_CONTENT_CERT, + .cmdline_name = "soc-fw-cert", + .action = 0, + .action_arg = NULL + }, + { + .name = "Trusted OS Firmware content certificate", + .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, + .cmdline_name = "tos-fw-cert", + .action = 0, + .action_arg = NULL + }, + { + .name = "Non-Trusted Firmware content certificate", + .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, + .cmdline_name = "nt-fw-cert", + .action = 0, + .action_arg = NULL + }, + { + .name = NULL, + .uuid = { 0 }, + .cmdline_name = NULL, + .action = 0, + .action_arg = NULL + } }; size_t toc_entries_len = sizeof(toc_entries) / sizeof(toc_entries[0]); diff --git a/tools/fiptool/tbbr_config.h b/tools/fiptool/tbbr_config.h index d771a9bb..c4593359 100644 --- a/tools/fiptool/tbbr_config.h +++ b/tools/fiptool/tbbr_config.h @@ -42,7 +42,6 @@ typedef struct toc_entry { const char *name; uuid_t uuid; const char *cmdline_name; - struct image *image; int action; char *action_arg; } toc_entry_t; |