diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S index 6575af47f..25c21cfcd 100644 --- a/drivers/marvell/uart/a3700_console.S +++ b/drivers/marvell/uart/a3700_console.S @@ -5,16 +5,27 @@ * https://spdx.org/licenses */ +#include #include #include +#define USE_FINISH_CONSOLE_REG_2 +#include - .globl console_core_init - .globl console_core_putc - .globl console_core_getc - .globl console_core_flush + /* + * "core" functions are low-level implementations that don't require + * writable memory and are thus safe to call in BL1 crash context. + */ + .globl console_a3700_core_putc + .globl console_a3700_core_init + .globl console_a3700_core_getc + .globl console_a3700_core_flush + + .globl console_a3700_putc + .globl console_a3700_getc + .globl console_a3700_flush /* ----------------------------------------------- - * int console_core_init(unsigned long base_addr, + * int console_a3700_core_init(unsigned long base_addr, * unsigned int uart_clk, unsigned int baud_rate) * Function to initialize the console without a * C Runtime to print debug information. This @@ -27,7 +38,7 @@ * Clobber list : x1, x2, x3 * ----------------------------------------------- */ -func console_core_init +func console_a3700_core_init /* Check the input base address */ cbz x0, init_fail /* Check baud rate and uart clock for sanity */ @@ -95,10 +106,43 @@ func console_core_init init_fail: mov w0, #0 ret -endfunc console_core_init +endfunc console_a3700_core_init + + .globl console_a3700_register + + /* ----------------------------------------------- + * int console_a3700_register(console_16550_t *console, + uintptr_t base, uint32_t clk, uint32_t baud) + * Function to initialize and register a new a3700 + * console. Storage passed in for the console struct + * *must* be persistent (i.e. not from the stack). + * In: x0 - UART register base address + * w1 - UART clock in Hz + * w2 - Baud rate + * x3 - pointer to empty console_a3700_t struct + * Out: return 1 on success, 0 on error + * Clobber list : x0, x1, x2, x6, x7, x14 + * ----------------------------------------------- + */ +func console_a3700_register + mov x7, x30 + mov x6, x3 + cbz x6, register_fail + str x0, [x6, #CONSOLE_T_A3700_BASE] + + bl console_a3700_core_init + cbz x0, register_fail + + mov x0, x6 + mov x30, x7 + finish_console_register a3700, putc=1, getc=1, flush=1 + +register_fail: + ret x7 +endfunc console_a3700_register /* -------------------------------------------------------- - * int console_core_putc(int c, unsigned int base_addr) + * int console_a3700_core_putc(int c, unsigned int base_addr) * Function to output a character over the console. It * returns the character printed on success or -1 on error. * In : w0 - character to be printed @@ -107,7 +151,7 @@ endfunc console_core_init * Clobber list : x2 * -------------------------------------------------------- */ -func console_core_putc +func console_a3700_core_putc /* Check the input parameter */ cbz x1, putc_error @@ -132,10 +176,25 @@ func console_core_putc putc_error: mov w0, #-1 ret -endfunc console_core_putc +endfunc console_a3700_core_putc + + /* -------------------------------------------------------- + * int console_a3700_putc(int c, console_a3700_t *console) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - pointer to console_t structure + * Out : return -1 on error else return character. + * Clobber list : x2 + * -------------------------------------------------------- + */ +func console_a3700_putc + ldr x1, [x1, #CONSOLE_T_A3700_BASE] + b console_a3700_core_putc +endfunc console_a3700_putc /* --------------------------------------------- - * int console_core_getc(void) + * int console_a3700_core_getc(void) * Function to get a character from the console. * It returns the character grabbed on success * or -1 on error. @@ -144,16 +203,28 @@ endfunc console_core_putc * Clobber list : x0, x1 * --------------------------------------------- */ -func console_core_getc - /* Check if the receive FIFO is empty */ - ret -getc_error: +func console_a3700_core_getc mov w0, #-1 ret -endfunc console_core_getc +endfunc console_a3700_core_getc /* --------------------------------------------- - * int console_core_flush(uintptr_t base_addr) + * int console_a3700_getc(console_a3700_t *console) + * Function to get a character from the console. + * It returns the character grabbed on success + * or -1 on if no character is available. + * In : x0 - pointer to console_t structure + * Out : w0 - character if available, else -1 + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_a3700_getc + ldr x0, [x0, #CONSOLE_T_A3700_BASE] + b console_a3700_core_getc +endfunc console_a3700_getc + + /* --------------------------------------------- + * int console_a3700_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address @@ -161,8 +232,22 @@ endfunc console_core_getc * Clobber list : x0, x1 * --------------------------------------------- */ -func console_core_flush - /* Placeholder */ +func console_a3700_core_flush mov w0, #0 ret -endfunc console_core_flush +endfunc console_a3700_core_flush + + /* --------------------------------------------- + * int console_a3700_flush(console_a3700_t *console) + * Function to force a write of all buffered + * data that hasn't been output. + * In : x0 - pointer to console_t structure + * Out : return -1 on error else return 0. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_a3700_flush + ldr x0, [x0, #CONSOLE_T_A3700_BASE] + b console_a3700_core_flush +endfunc console_a3700_flush + diff --git a/drivers/marvell/uart/a3700_console.h b/include/drivers/marvell/uart/a3700_console.h similarity index 73% rename from drivers/marvell/uart/a3700_console.h rename to include/drivers/marvell/uart/a3700_console.h index de7c4fc59..01335a2a3 100644 --- a/drivers/marvell/uart/a3700_console.h +++ b/include/drivers/marvell/uart/a3700_console.h @@ -8,6 +8,8 @@ #ifndef A3700_CONSOLE_H #define A3700_CONSOLE_H +#include + /* MVEBU UART Registers */ #define UART_RX_REG 0x00 #define UART_TX_REG 0x04 @@ -52,4 +54,26 @@ #define UART_CTRL_TXFIFO_RESET (1 << 15) #define UARTLSR_TXFIFOEMPTY (1 << 6) -#endif /* A3700_CONSOLE_H */ +#define CONSOLE_T_A3700_BASE CONSOLE_T_DRVDATA + +#ifndef __ASSEMBLY__ + +#include + +typedef struct { + console_t console; + uintptr_t base; +} console_a3700_t; + +/* + * Initialize a new a3700 console instance and register it with the console + * framework. The |console| pointer must point to storage that will be valid + * for the lifetime of the console, such as a global or static local variable. + * Its contents will be reinitialized from scratch. + */ +int console_a3700_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, + console_a3700_t *console); + +#endif /*__ASSEMBLY__*/ + +#endif /* A3700_CONSOLE_H */ diff --git a/include/plat/marvell/a3700/common/plat_marvell.h b/include/plat/marvell/a3700/common/plat_marvell.h index 8c289e987..01e42c545 100644 --- a/include/plat/marvell/a3700/common/plat_marvell.h +++ b/include/plat/marvell/a3700/common/plat_marvell.h @@ -39,6 +39,12 @@ void marvell_setup_page_tables(uintptr_t total_base, #endif ); +/* Console utility functions */ +void marvell_console_boot_init(void); +void marvell_console_boot_end(void); +void marvell_console_runtime_init(void); +void marvell_console_runtime_end(void); + /* IO storage utility functions */ void marvell_io_setup(void); diff --git a/include/plat/marvell/a8k/common/plat_marvell.h b/include/plat/marvell/a8k/common/plat_marvell.h index f062491f9..037548da0 100644 --- a/include/plat/marvell/a8k/common/plat_marvell.h +++ b/include/plat/marvell/a8k/common/plat_marvell.h @@ -48,6 +48,12 @@ void marvell_setup_page_tables(uintptr_t total_base, #endif ); +/* Console utility functions */ +void marvell_console_boot_init(void); +void marvell_console_boot_end(void); +void marvell_console_runtime_init(void); +void marvell_console_runtime_end(void); + /* IO storage utility functions */ void marvell_io_setup(void); diff --git a/plat/marvell/a3700/common/a3700_common.mk b/plat/marvell/a3700/common/a3700_common.mk index ff9639499..3983c707c 100644 --- a/plat/marvell/a3700/common/a3700_common.mk +++ b/plat/marvell/a3700/common/a3700_common.mk @@ -71,7 +71,6 @@ TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CL $(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0 DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D - # GICV3 $(eval $(call add_define,CONFIG_GICV3)) @@ -91,8 +90,8 @@ ATF_INCLUDES := -Iinclude/common/tbbr \ PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \ -I$(PLAT_COMMON_BASE)/include \ -I$(PLAT_INCLUDE_BASE)/common \ - -I$(MARVELL_DRV_BASE)/uart \ -I$(MARVELL_DRV_BASE) \ + -Iinclude/drivers/marvell/uart \ -I$/drivers/arm/gic/common/ \ $(ATF_INCLUDES) @@ -159,12 +158,12 @@ ifeq ($(MARVELL_SECURE_BOOT),1) @truncate -s %16 $(WTMI_MULTI_IMG) @openssl enc -aes-256-cbc -e -in $(WTMI_MULTI_IMG) \ -out $(WTMI_ENC_IMG) \ - -K `cat $(IMAGESPATH)/aes-256.txt` -k 0 -nosalt \ + -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ -iv `cat $(IMAGESPATH)/iv.txt` -p @truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE); @openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \ -out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \ - -K `cat $(IMAGESPATH)/aes-256.txt` -k 0 -nosalt \ + -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \ -iv `cat $(IMAGESPATH)/iv.txt` -p endif $(DOIMAGETOOL) $(DOIMAGE_FLAGS) diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/a8k/common/a8k_common.mk index a589004bd..6136a1f59 100644 --- a/plat/marvell/a8k/common/a8k_common.mk +++ b/plat/marvell/a8k/common/a8k_common.mk @@ -25,7 +25,6 @@ $(eval $(call add_define,BL31_CACHE_DISABLE)) $(eval $(call add_define,PCI_EP_SUPPORT)) $(eval $(call assert_boolean,PCI_EP_SUPPORT)) - AP_NUM := 1 $(eval $(call add_define,AP_NUM)) diff --git a/plat/marvell/a8k/common/ble/ble.mk b/plat/marvell/a8k/common/ble/ble.mk index a76083ebf..5f24ced23 100644 --- a/plat/marvell/a8k/common/ble/ble.mk +++ b/plat/marvell/a8k/common/ble/ble.mk @@ -12,8 +12,9 @@ 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 + drivers/delay_timer/delay_timer.c \ + $(PLAT_MARVELL)/common/plat_delay_timer.c \ + $(PLAT_MARVELL)/common/marvell_console.c PLAT_INCLUDES += -I$(MV_DDR_PATH) \ -I$(CURDIR)/include/ \ diff --git a/plat/marvell/a8k/common/ble/ble_main.c b/plat/marvell/a8k/common/ble/ble_main.c index e52c738d3..b04e8b7a6 100644 --- a/plat/marvell/a8k/common/ble/ble_main.c +++ b/plat/marvell/a8k/common/ble/ble_main.c @@ -35,13 +35,11 @@ int exec_ble_main(int bootrom_flags) * 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); + marvell_console_boot_init(); NOTICE("Starting binary extension\n"); - /* initiliaze time (for delay functionality) */ + /* initialize time (for delay functionality) */ plat_delay_timer_init(); ble_plat_setup(&skip); diff --git a/plat/marvell/a8k/common/plat_pm.c b/plat/marvell/a8k/common/plat_pm.c index 0c74b2fe5..1b68d0767 100644 --- a/plat/marvell/a8k/common/plat_pm.c +++ b/plat/marvell/a8k/common/plat_pm.c @@ -19,7 +19,6 @@ #include #include #include -#include #define MVEBU_PRIVATE_UID_REG 0x30 #define MVEBU_RFU_GLOBL_SW_RST 0x84 @@ -614,6 +613,8 @@ static void a8k_pwr_domain_suspend(const psci_power_state_t *target_state) INFO("Suspending to RAM\n"); + marvell_console_runtime_end(); + /* Prevent interrupts from spuriously waking up this cpu */ gicv2_cpuif_disable(); @@ -687,9 +688,7 @@ static void a8k_pwr_domain_suspend_finish( /* Initialize the console to provide * early debug support */ - console_init(PLAT_MARVELL_BOOT_UART_BASE, - PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, - MARVELL_CONSOLE_BAUDRATE); + marvell_console_runtime_init(); bl31_plat_arch_setup(); marvell_bl31_platform_setup(); diff --git a/plat/marvell/common/aarch64/marvell_helpers.S b/plat/marvell/common/aarch64/marvell_helpers.S index 128c3ab69..fbd19cb61 100644 --- a/plat/marvell/common/aarch64/marvell_helpers.S +++ b/plat/marvell/common/aarch64/marvell_helpers.S @@ -65,7 +65,11 @@ func plat_crash_console_init mov_imm x0, PLAT_MARVELL_CRASH_UART_BASE mov_imm x1, PLAT_MARVELL_CRASH_UART_CLK_IN_HZ mov_imm x2, MARVELL_CONSOLE_BAUDRATE - b console_core_init +#ifdef PLAT_a3700 + b console_a3700_core_init +#else + b console_16550_core_init +#endif endfunc plat_crash_console_init /* --------------------------------------------- @@ -77,7 +81,12 @@ endfunc plat_crash_console_init */ func plat_crash_console_putc mov_imm x1, PLAT_MARVELL_CRASH_UART_BASE - b console_core_putc +#ifdef PLAT_a3700 + + b console_a3700_core_putc +#else + b console_16550_core_putc +#endif endfunc plat_crash_console_putc /* --------------------------------------------- @@ -85,12 +94,16 @@ endfunc plat_crash_console_putc * Function to force a write of all buffered * data that hasn't been output. * Out : return -1 on error else return 0. - * Clobber list : x0, x1 + * Clobber list : r0 * --------------------------------------------- */ func plat_crash_console_flush mov_imm x0, PLAT_MARVELL_CRASH_UART_BASE - b console_core_flush +#ifdef PLAT_a3700 + b console_a3700_core_flush +#else + b console_16550_core_flush +#endif endfunc plat_crash_console_flush /* --------------------------------------------------------------------- diff --git a/plat/marvell/common/marvell_bl1_setup.c b/plat/marvell/common/marvell_bl1_setup.c index 4e1b256b0..c96f00679 100644 --- a/plat/marvell/common/marvell_bl1_setup.c +++ b/plat/marvell/common/marvell_bl1_setup.c @@ -35,9 +35,7 @@ meminfo_t *bl1_plat_sec_mem_layout(void) void marvell_bl1_early_platform_setup(void) { /* Initialize the console to provide early debug support */ - console_init(PLAT_MARVELL_BOOT_UART_BASE, - PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, - MARVELL_CONSOLE_BAUDRATE); + marvell_console_boot_init(); /* Allow BL1 to see the whole Trusted RAM */ bl1_ram_layout.total_base = MARVELL_BL_RAM_BASE; diff --git a/plat/marvell/common/marvell_bl2_setup.c b/plat/marvell/common/marvell_bl2_setup.c index d33aba477..883336f0d 100644 --- a/plat/marvell/common/marvell_bl2_setup.c +++ b/plat/marvell/common/marvell_bl2_setup.c @@ -40,9 +40,7 @@ meminfo_t *bl2_plat_sec_mem_layout(void) void marvell_bl2_early_platform_setup(meminfo_t *mem_layout) { /* Initialize the console to provide early debug support */ - console_init(PLAT_MARVELL_BOOT_UART_BASE, - PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, - MARVELL_CONSOLE_BAUDRATE); + marvell_console_boot_init(); /* Setup the BL2 memory layout */ bl2_tzram_layout = *mem_layout; diff --git a/plat/marvell/common/marvell_bl31_setup.c b/plat/marvell/common/marvell_bl31_setup.c index da91b5607..3b1a6f130 100644 --- a/plat/marvell/common/marvell_bl31_setup.c +++ b/plat/marvell/common/marvell_bl31_setup.c @@ -74,9 +74,7 @@ void marvell_bl31_early_platform_setup(void *from_bl2, void *plat_params_from_bl2) { /* Initialize the console to provide early debug support */ - console_init(PLAT_MARVELL_BOOT_UART_BASE, - PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, - MARVELL_CONSOLE_BAUDRATE); + marvell_console_boot_init(); #if RESET_TO_BL31 /* There are no parameters from BL2 if BL31 is a reset vector */ @@ -190,10 +188,10 @@ void marvell_bl31_platform_setup(void) */ void marvell_bl31_plat_runtime_setup(void) { + console_switch_state(CONSOLE_FLAG_RUNTIME); + /* Initialize the runtime console */ - console_init(PLAT_MARVELL_BL31_RUN_UART_BASE, - PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ, - MARVELL_CONSOLE_BAUDRATE); + marvell_console_runtime_init(); } void bl31_platform_setup(void) diff --git a/plat/marvell/common/marvell_common.mk b/plat/marvell/common/marvell_common.mk index 3a6bb0339..fb6fbb585 100644 --- a/plat/marvell/common/marvell_common.mk +++ b/plat/marvell/common/marvell_common.mk @@ -11,6 +11,8 @@ include $(MARVELL_PLAT_BASE)/marvell.mk VERSION_STRING +=(Marvell-${SUBVERSION}) +MULTI_CONSOLE_API := 1 + SEPARATE_CODE_AND_RODATA := 1 # flag to switch from PLL to ARO @@ -28,7 +30,8 @@ PLAT_INCLUDES += -I. -Iinclude/common -Iinclude/common/tbbr \ PLAT_BL_COMMON_SOURCES += lib/xlat_tables/xlat_tables_common.c \ lib/xlat_tables/aarch64/xlat_tables.c \ $(MARVELL_PLAT_BASE)/common/aarch64/marvell_common.c \ - $(MARVELL_PLAT_BASE)/common/aarch64/marvell_helpers.S + $(MARVELL_PLAT_BASE)/common/aarch64/marvell_helpers.S \ + $(MARVELL_COMMON_BASE)/marvell_console.c BL1_SOURCES += drivers/delay_timer/delay_timer.c \ drivers/io/io_fip.c \ diff --git a/plat/marvell/common/marvell_console.c b/plat/marvell/common/marvell_console.c new file mode 100644 index 000000000..eba106dc1 --- /dev/null +++ b/plat/marvell/common/marvell_console.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include +#include + +#ifdef PLAT_a3700 +#include + +static console_a3700_t marvell_boot_console; +static console_a3700_t marvell_runtime_console; +#else +#include + +static console_16550_t marvell_boot_console; +static console_16550_t marvell_runtime_console; +#endif + +/******************************************************************************* + * Functions that set up the console + ******************************************************************************/ + +/* Initialize the console to provide early debug support */ +void marvell_console_boot_init(void) +{ + int rc = +#ifdef PLAT_a3700 + console_a3700_register( +#else + console_16550_register( +#endif + PLAT_MARVELL_BOOT_UART_BASE, + PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, + MARVELL_CONSOLE_BAUDRATE, + &marvell_boot_console); + if (rc == 0) { + /* + * The crash console doesn't use the multi console API, it uses + * the core console functions directly. It is safe to call panic + * and let it print debug information. + */ + panic(); + } + + console_set_scope(&marvell_boot_console.console, + CONSOLE_FLAG_BOOT); +} + +void marvell_console_boot_end(void) +{ + (void)console_flush(); + + (void)console_unregister(&marvell_boot_console.console); +} + +/* Initialize the runtime console */ +void marvell_console_runtime_init(void) +{ + int rc = +#ifdef PLAT_a3700 + console_a3700_register( +#else + console_16550_register( +#endif + PLAT_MARVELL_BOOT_UART_BASE, + PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, + MARVELL_CONSOLE_BAUDRATE, + &marvell_runtime_console); + if (rc == 0) + panic(); + + console_set_scope(&marvell_runtime_console.console, + CONSOLE_FLAG_RUNTIME); +} + +void marvell_console_runtime_end(void) +{ + (void)console_flush(); + + (void)console_unregister(&marvell_runtime_console.console); +}