diff --git a/docs/marvell/build.txt b/docs/marvell/build.txt index b354ab6..8a669c1 100644 --- a/docs/marvell/build.txt +++ b/docs/marvell/build.txt @@ -63,8 +63,7 @@ - BLE_PATH: Points to BLE (Binary ROM extension) sources folder. Only required for A8K builds. - The parameter is optional, its default value is "ble". - For the BLE source location, check the section "Tools and external components installation" + The parameter is optional, its default value is "plat/marvell/a8k/common/ble". - MV_DDR_PATH: For A7/8K, use this parameter to point to mv_ddr driver sources to allow BLE build. For A37x0, @@ -138,7 +137,7 @@ -------------------- - PLAT_RECOVERY_IMAGE_ENABLE: When set this option to enable secondary recovery function when build atf. In order to build UART recovery image this operation should be disabled for a70x0 and a80x0 - because of hardware limitation (boot from secondary image can interrupt UART recovery process). + because of hardware limitation (boot from secondary image can interrupt UART recovery process). This MACRO definition is set in plat/marvell/a8k/common/include/platform_def.h file (for more information about build options, please refer to section 'Summary of build options' in TF-A user-guide: @@ -184,14 +183,10 @@ (3) Armada3700 tools available at the following repository (use the latest release branch):: https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell.git -Armada70x0 and Armada80x0 Builds require installation of 2 components ---------------------------------------------------------------------- +Armada70x0 and Armada80x0 Builds require installation of an additional component +-------------------------------------------------------------------------------- (1) DDR initialization library sources (mv_ddr) available at the following repository (use the "mv_ddr-armada-atf-mainline" branch):: https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git -(2) BLE sources available at the following repository (use the "atf-mainline" branch):: - https://github.com/MarvellEmbeddedProcessors/ble-marvell.git - - diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/a8k/common/a8k_common.mk index 364935c..49745ce 100644 --- a/plat/marvell/a8k/common/a8k_common.mk +++ b/plat/marvell/a8k/common/a8k_common.mk @@ -106,7 +106,7 @@ include $(PLAT_COMMON_BASE)/mss/mss_a8k.mk # BLE (ROM context execution code, AKA binary extension) -BLE_PATH ?= ble +BLE_PATH ?= $(PLAT_COMMON_BASE)/ble include ${BLE_PATH}/ble.mk $(eval $(call MAKE_BL,e)) diff --git a/plat/marvell/a8k/common/ble/ble.ld.S b/plat/marvell/a8k/common/ble/ble.ld.S new file mode 100644 index 0000000..d7a0592 --- /dev/null +++ b/plat/marvell/a8k/common/ble/ble.ld.S @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) +OUTPUT_ARCH(PLATFORM_LINKER_ARCH) +ENTRY(ble_main) + +MEMORY { + RAM (rwx): ORIGIN = BLE_BASE, LENGTH = BLE_LIMIT - BLE_BASE +} + +SECTIONS +{ + . = BLE_BASE; + + ro . : { + __RO_START__ = .; + *ble_main.o(.entry*) + *(.text*) + *(.rodata*) + __RO_END_UNALIGNED__ = .; + __RO_END__ = .; + } >RAM + + /* + * Define a linker symbol to mark start of the RW memory area for this + * image. + */ + __RW_START__ = . ; + + .data . : { + __DATA_START__ = .; + *(.data*) + __DATA_END__ = .; + } >RAM + + stacks . (NOLOAD) : { + __STACKS_START__ = .; + *(tzfw_normal_stacks) + __STACKS_END__ = .; + } >RAM + + .bss : { + __BSS_START__ = .; + *(.bss*) + __BSS_END__ = .; + } >RAM + + /* + * Extend the BLE binary to the maximum size allocated for it in platform + * definition files and prevent overlapping between BLE BSS section and + * additional extensions that can follow the BLE in flash image preamble. + * This situation happens for instance when secure extension is added to + * the image preamble. + */ + .fill LOADADDR(.bss) + SIZEOF(.bss) : { + FILL(0xDEADC0DE); + . = ORIGIN(RAM) + LENGTH(RAM) - 1; + BYTE(0x00) + } >RAM + + /* + * Define a linker symbol to mark end of the RW memory area for this + * image. + */ + __RW_END__ = .; + __BLE_END__ = .; + + __BSS_SIZE__ = SIZEOF(.bss); +} diff --git a/plat/marvell/a8k/common/ble/ble.mk b/plat/marvell/a8k/common/ble/ble.mk new file mode 100644 index 0000000..a76083e --- /dev/null +++ b/plat/marvell/a8k/common/ble/ble.mk @@ -0,0 +1,31 @@ +# Copyright (C) 2018 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses + +MV_DDR_PATH ?= drivers/marvell/mv_ddr + +MV_DDR_LIB = $(CURDIR)/$(BUILD_PLAT)/ble/mv_ddr_lib.a +LIBC_LIB = $(CURDIR)/$(BUILD_PLAT)/lib/libc.a +BLE_LIBS = $(MV_DDR_LIB) $(LIBC_LIB) +PLAT_MARVELL = plat/marvell + +BLE_SOURCES += $(BLE_PATH)/ble_main.c \ + $(BLE_PATH)/ble_mem.S \ + drivers/delay_timer/delay_timer.c \ + $(PLAT_MARVELL)/common/plat_delay_timer.c + +PLAT_INCLUDES += -I$(MV_DDR_PATH) \ + -I$(CURDIR)/include/ \ + -I$(CURDIR)/include/drivers \ + -I$(CURDIR)/include/lib \ + -I$(CURDIR)/include/lib/libc \ + -I$(CURDIR)/include/lib/libc/aarch64 \ + -I$(CURDIR)/drivers/marvell + +BLE_LINKERFILE := $(BLE_PATH)/ble.ld.S + +FORCE: + +$(MV_DDR_LIB): FORCE + @+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(PLAT_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(CURDIR)/$(BUILD_PLAT)/ble diff --git a/plat/marvell/a8k/common/ble/ble_main.c b/plat/marvell/a8k/common/ble/ble_main.c new file mode 100644 index 0000000..e52c738 --- /dev/null +++ b/plat/marvell/a8k/common/ble/ble_main.c @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BR_FLAG_SILENT 0x1 +#define SKIP_IMAGE_CODE 0xDEADB002 + +void mailbox_clean(void) +{ + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + memset(mailbox, 0, PLAT_MARVELL_MAILBOX_SIZE); +} + +int exec_ble_main(int bootrom_flags) +{ + int skip = 0; + uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; + + /* + * In some situations, like boot from UART, bootrom will + * request to avoid printing to console. in that case don't + * initialize the console and prints will be ignored + */ + if ((bootrom_flags & BR_FLAG_SILENT) == 0) + console_init(PLAT_MARVELL_BOOT_UART_BASE, + PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, + MARVELL_CONSOLE_BAUDRATE); + + NOTICE("Starting binary extension\n"); + + /* initiliaze time (for delay functionality) */ + plat_delay_timer_init(); + + ble_plat_setup(&skip); + + /* if there's skip image request, bootrom will load from the image + * saved on the next address of the flash + */ + if (skip) + return SKIP_IMAGE_CODE; + + /* + * Check if the mailbox magic number is stored at index MBOX_IDX_MAGIC + * and the suspend to RAM magic number at index MBOX_IDX_SUSPEND_MAGIC. + * If the above is true, this is the recovery from suspend to RAM state. + * In such case the mailbox should remain intact, since it stores the + * warm boot jump address to be used by the TF-A in BL31. + * Othervise the mailbox should be cleaned from a garbage data. + */ + if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || + mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) { + NOTICE("Cold boot\n"); + mailbox_clean(); + } else { + void (*bootrom_exit)(void) = + (void (*)(void))mailbox[MBOX_IDX_ROM_EXIT_ADDR]; + + INFO("Recovery...\n"); + /* + * If this is recovery from suspend, two things has to be done: + * 1. Define the DRAM region as executable memory for preparing + * jump to TF-A + * 2. Instead of returning control to the BootROM, invalidate + * and flush caches, and continue execution at address stored + * in the mailbox. + * This should be done until the BootROM have a native support + * for the system restore flow. + */ + marvell_ble_prepare_exit(); + bootrom_exit(); + } + + return 0; +} + +/* NOTE: don't notify this function, all code must be added to exec_ble_main + * in order to keep the end of ble_main as a fixed address. + */ +int __attribute__ ((section(".entry"))) ble_main(int bootrom_flags) +{ + volatile int ret; + + ret = exec_ble_main(bootrom_flags); + return ret; +} diff --git a/plat/marvell/a8k/common/ble/ble_mem.S b/plat/marvell/a8k/common/ble/ble_mem.S new file mode 100644 index 0000000..a48d546 --- /dev/null +++ b/plat/marvell/a8k/common/ble/ble_mem.S @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include +#include + +#define PTE_NON_EXEC_OFF 54 /* XN - eXecute Never bit offset - see VMSAv8-64 */ + + .globl marvell_ble_prepare_exit + +func marvell_ble_prepare_exit + /* + * Read the page table base and set the first page to be executable. + * This is required for jumping to DRAM for further execution. + */ + mrs x0, ttbr0_el3 + ldr x1, [x0] + mov x2, #1 + bic x1, x1, x2, lsl #PTE_NON_EXEC_OFF + str x1, [x0] + tlbi alle3 + dsb sy + isb + ret +endfunc marvell_ble_prepare_exit diff --git a/tools/doimage/Makefile b/tools/doimage/Makefile index bc74369..9cec681 100644 --- a/tools/doimage/Makefile +++ b/tools/doimage/Makefile @@ -39,7 +39,7 @@ @echo "Built $@ successfully" @echo -%.o: %.c %.h Makefile +%.o: %.c Makefile @echo " CC $<" ${Q}${CC} -c ${CFLAGS} ${INCLUDE_PATHS} $< -o $@ diff --git a/tools/stm32image/Makefile b/tools/stm32image/Makefile index 80dfbec..a593d31 100644 --- a/tools/stm32image/Makefile +++ b/tools/stm32image/Makefile @@ -12,8 +12,7 @@ OBJECTS := stm32image.o V := 0 -override CPPFLAGS += -D_GNU_SOURCE -CFLAGS := -Wall -Werror -pedantic -std=c99 +CFLAGS := -Wall -Werror -pedantic -std=c99 -D_GNU_SOURCE ifeq (${DEBUG},1) CFLAGS += -g -O0 -DDEBUG else @@ -39,7 +38,7 @@ @echo "Built $@ successfully" @${ECHO_BLANK_LINE} -%.o: %.c %.h Makefile +%.o: %.c Makefile @echo " CC $<" ${Q}${CC} -c ${CFLAGS} $< -o $@