Merge pull request #1683 from Yann-lms/stm32mp1_multi_console

Add multi console support for STM32MP1
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
index 792703a..303d6ba 100644
--- a/drivers/st/uart/aarch32/stm32_console.S
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -4,30 +4,27 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <asm_macros.S>
+#include <assert_macros.S>
+#define USE_FINISH_CONSOLE_REG_2
+#include <console_macros.S>
+#include <stm32_console.h>
+#include <stm32_uart_regs.h>
 
 #define USART_TIMEOUT		0x1000
 
-#define USART_CR1		0x00
-#define USART_CR1_UE		0x00000001
-#define USART_CR1_TE		0x00000008
-#define USART_CR1_FIFOEN	0x20000000
-
-#define USART_CR2		0x04
-#define USART_CR2_STOP		0x00003000
-
-#define USART_BRR		0x0C
+	/*
+	 * "core" functions are low-level implementations that don't require
+	 * writeable memory and are thus safe to call in BL1 crash context.
+	 */
+	.globl	console_stm32_core_init
+	.globl	console_stm32_core_putc
+	.globl	console_stm32_core_getc
+	.globl	console_stm32_core_flush
 
-#define USART_ISR		0x1C
-#define USART_ISR_TC		0x00000040
-#define USART_ISR_TXE		0x00000080
-#define USART_ISR_TEACK		0x00200000
+	.globl	console_stm32_putc
+	.globl	console_stm32_flush
 
-#define USART_TDR		0x28
 
-	.globl	console_core_init
-	.globl	console_core_putc
-	.globl	console_core_getc
-	.globl	console_core_flush
 
 	/* -----------------------------------------------------------------
 	 * int console_core_init(uintptr_t base_addr,
@@ -45,7 +42,7 @@
 	 * Clobber list : r1, r2, r3
 	 * -----------------------------------------------------------------
 	 */
-func console_core_init
+func console_stm32_core_init
 	/* Check the input base address */
 	cmp	r0, #0
 	beq	core_init_fail
@@ -88,7 +85,43 @@
 core_init_fail:
 	mov	r0, #0
 	bx	lr
-endfunc console_core_init
+endfunc console_stm32_core_init
+
+	.globl console_stm32_register
+
+	/* -------------------------------------------------------
+	 * int console_stm32_register(uintptr_t baseaddr,
+	 *     uint32_t clock, uint32_t baud,
+	 *     struct console_stm32 *console);
+	 * Function to initialize and register a new STM32
+	 * console. Storage passed in for the console struct
+	 * *must* be persistent (i.e. not from the stack).
+	 * In: r0 - UART register base address
+	 *     r1 - UART clock in Hz
+	 *     r2 - Baud rate
+	 *     r3 - pointer to empty console_stm32 struct
+	 * Out: return 1 on success, 0 on error
+	 * Clobber list : r0, r1, r2
+	 * -------------------------------------------------------
+	 */
+func console_stm32_register
+	push	{r4, lr}
+	mov	r4, r3
+	cmp	r4, #0
+	beq	register_fail
+	str	r0, [r4, #CONSOLE_T_STM32_BASE]
+
+	bl console_stm32_core_init
+	cmp	r0, #0
+	beq	register_fail
+
+	mov	r0, r4
+	pop	{r4, lr}
+	finish_console_register stm32 putc=1, getc=0, flush=1
+
+register_fail:
+	pop	{r4, pc}
+endfunc console_stm32_register
 
 	/* ---------------------------------------------------------------
 	 * int console_core_putc(int c, uintptr_t base_addr)
@@ -102,7 +135,7 @@
 	 * Clobber list : r2
 	 * ---------------------------------------------------------------
 	 */
-func console_core_putc
+func console_stm32_core_putc
 	/* Check the input parameter */
 	cmp	r1, #0
 	beq	putc_error
@@ -138,7 +171,26 @@
 putc_error:
 	mov	r0, #-1
 	bx	lr
-endfunc console_core_putc
+endfunc console_stm32_core_putc
+
+	/* ------------------------------------------------------------
+	 * int console_stm32_putc(int c, struct console_stm32 *console)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In: r0 - character to be printed
+	 *     r1 - pointer to console_t structure
+	 * Out : return -1 on error else return character.
+	 * Clobber list: r2
+	 * ------------------------------------------------------------
+	 */
+func console_stm32_putc
+#if ENABLE_ASSERTIONS
+	cmp	r1, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	r1, [r1, #CONSOLE_T_STM32_BASE]
+	b	console_stm32_core_putc
+endfunc console_stm32_putc
 
 	/* -----------------------------------------------------------
 	 * int console_core_getc(uintptr_t base_addr)
@@ -151,11 +203,11 @@
 	 * Clobber list : r0, r1
 	 * -----------------------------------------------------------
 	 */
-func console_core_getc
+func console_stm32_core_getc
 	/* Not supported */
 	mov	r0, #-1
 	bx	lr
-endfunc console_core_getc
+endfunc console_stm32_core_getc
 
 	/* ---------------------------------------------------------------
 	 * int console_core_flush(uintptr_t base_addr)
@@ -168,7 +220,7 @@
 	 * Clobber list : r0, r1
 	 * ---------------------------------------------------------------
 	 */
-func console_core_flush
+func console_stm32_core_flush
 	cmp	r0, #0
 	beq	flush_error
 	/* Check Transmit Data Register Empty */
@@ -181,4 +233,22 @@
 flush_error:
 	mov	r0, #-1
 	bx	lr
-endfunc console_core_flush
+endfunc console_stm32_core_flush
+
+	/* ------------------------------------------------------
+	 * int console_stm32_flush(struct console_stm32 *console)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : r0 - pointer to console_t structure
+	 * Out : return -1 on error else return 0.
+	 * Clobber list: r0, r1
+	 * ------------------------------------------------------
+	 */
+func console_stm32_flush
+#if ENABLE_ASSERTIONS
+	cmp	r0, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	r0, [r0, #CONSOLE_T_STM32_BASE]
+	b	console_stm32_core_flush
+endfunc console_stm32_flush
diff --git a/include/drivers/st/stm32_console.h b/include/drivers/st/stm32_console.h
new file mode 100644
index 0000000..57e6d74
--- /dev/null
+++ b/include/drivers/st/stm32_console.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32_CONSOLE_H
+#define STM32_CONSOLE_H
+
+#include <console.h>
+
+#define CONSOLE_T_STM32_BASE	CONSOLE_T_DRVDATA
+
+#ifndef __ASSEMBLY__
+
+#include <stdint.h>
+
+struct console_stm32 {
+	console_t console;
+	uintptr_t base;
+};
+
+/*
+ * Initialize a new STM32 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_stm32_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
+			   struct console_stm32 *console);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* STM32_CONSOLE_H */
diff --git a/include/drivers/st/stm32_uart_regs.h b/include/drivers/st/stm32_uart_regs.h
new file mode 100644
index 0000000..e78d3d4
--- /dev/null
+++ b/include/drivers/st/stm32_uart_regs.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32_UART_REGS_H
+#define STM32_UART_REGS_H
+
+#include <utils_def.h>
+
+#define USART_CR1		U(0x00)
+#define USART_CR2		U(0x04)
+#define USART_CR3		U(0x08)
+#define USART_BRR		U(0x0C)
+#define USART_GTPR		U(0x10)
+#define USART_RTOR		U(0x14)
+#define USART_RQR		U(0x18)
+#define USART_ISR		U(0x1C)
+#define USART_ICR		U(0x20)
+#define USART_RDR		U(0x24)
+#define USART_TDR		U(0x28)
+#define USART_PRESC		U(0x2C)
+
+/* USART_CR1 register fields */
+#define USART_CR1_UE		BIT(0)
+#define USART_CR1_UESM		BIT(1)
+#define USART_CR1_RE		BIT(2)
+#define USART_CR1_TE		BIT(3)
+#define USART_CR1_IDLEIE	BIT(4)
+#define USART_CR1_RXNEIE	BIT(5)
+#define USART_CR1_TCIE		BIT(6)
+#define USART_CR1_TXEIE		BIT(7)
+#define USART_CR1_PEIE		BIT(8)
+#define USART_CR1_PS		BIT(9)
+#define USART_CR1_PCE		BIT(10)
+#define USART_CR1_WAKE		BIT(11)
+#define USART_CR1_M		(BIT(28) | BIT(12))
+#define USART_CR1_M0		BIT(12)
+#define USART_CR1_MME		BIT(13)
+#define USART_CR1_CMIE		BIT(14)
+#define USART_CR1_OVER8		BIT(15)
+#define USART_CR1_DEDT		GENMASK(20, 16)
+#define USART_CR1_DEDT_0	BIT(16)
+#define USART_CR1_DEDT_1	BIT(17)
+#define USART_CR1_DEDT_2	BIT(18)
+#define USART_CR1_DEDT_3	BIT(19)
+#define USART_CR1_DEDT_4	BIT(20)
+#define USART_CR1_DEAT		GENMASK(25, 21)
+#define USART_CR1_DEAT_0	BIT(21)
+#define USART_CR1_DEAT_1	BIT(22)
+#define USART_CR1_DEAT_2	BIT(23)
+#define USART_CR1_DEAT_3	BIT(24)
+#define USART_CR1_DEAT_4	BIT(25)
+#define USART_CR1_RTOIE		BIT(26)
+#define USART_CR1_EOBIE		BIT(27)
+#define USART_CR1_M1		BIT(28)
+#define USART_CR1_FIFOEN	BIT(29)
+#define USART_CR1_TXFEIE	BIT(30)
+#define USART_CR1_RXFFIE	BIT(31)
+
+/* USART_CR2 register fields */
+#define USART_CR2_SLVEN		BIT(0)
+#define USART_CR2_DIS_NSS	BIT(3)
+#define USART_CR2_ADDM7		BIT(4)
+#define USART_CR2_LBDL		BIT(5)
+#define USART_CR2_LBDIE		BIT(6)
+#define USART_CR2_LBCL		BIT(8)
+#define USART_CR2_CPHA		BIT(9)
+#define USART_CR2_CPOL		BIT(10)
+#define USART_CR2_CLKEN		BIT(11)
+#define USART_CR2_STOP		GENMASK(13, 12)
+#define USART_CR2_STOP_0	BIT(12)
+#define USART_CR2_STOP_1	BIT(13)
+#define USART_CR2_LINEN		BIT(14)
+#define USART_CR2_SWAP		BIT(15)
+#define USART_CR2_RXINV		BIT(16)
+#define USART_CR2_TXINV		BIT(17)
+#define USART_CR2_DATAINV	BIT(18)
+#define USART_CR2_MSBFIRST	BIT(19)
+#define USART_CR2_ABREN		BIT(20)
+#define USART_CR2_ABRMODE	GENMASK(22, 21)
+#define USART_CR2_ABRMODE_0	BIT(21)
+#define USART_CR2_ABRMODE_1	BIT(22)
+#define USART_CR2_RTOEN		BIT(23)
+#define USART_CR2_ADD		GENMASK(31, 24)
+
+/* USART_CR3 register fields */
+#define USART_CR3_EIE		BIT(0)
+#define USART_CR3_IREN		BIT(1)
+#define USART_CR3_IRLP		BIT(2)
+#define USART_CR3_HDSEL		BIT(3)
+#define USART_CR3_NACK		BIT(4)
+#define USART_CR3_SCEN		BIT(5)
+#define USART_CR3_DMAR		BIT(6)
+#define USART_CR3_DMAT		BIT(7)
+#define USART_CR3_RTSE		BIT(8)
+#define USART_CR3_CTSE		BIT(9)
+#define USART_CR3_CTSIE		BIT(10)
+#define USART_CR3_ONEBIT	BIT(11)
+#define USART_CR3_OVRDIS	BIT(12)
+#define USART_CR3_DDRE		BIT(13)
+#define USART_CR3_DEM		BIT(14)
+#define USART_CR3_DEP		BIT(15)
+#define USART_CR3_SCARCNT	GENMASK(19, 17)
+#define USART_CR3_SCARCNT_0	BIT(17)
+#define USART_CR3_SCARCNT_1	BIT(18)
+#define USART_CR3_SCARCNT_2	BIT(19)
+#define USART_CR3_WUS		GENMASK(21, 20)
+#define USART_CR3_WUS_0		BIT(20)
+#define USART_CR3_WUS_1		BIT(21)
+#define USART_CR3_WUFIE		BIT(22)
+#define USART_CR3_TXFTIE	BIT(23)
+#define USART_CR3_TCBGTIE	BIT(24)
+#define USART_CR3_RXFTCFG	GENMASK(27, 25)
+#define USART_CR3_RXFTCFG_0	BIT(25)
+#define USART_CR3_RXFTCFG_1	BIT(26)
+#define USART_CR3_RXFTCFG_2	BIT(27)
+#define USART_CR3_RXFTIE	BIT(28)
+#define USART_CR3_TXFTCFG	GENMASK(31, 29)
+#define USART_CR3_TXFTCFG_0	BIT(29)
+#define USART_CR3_TXFTCFG_1	BIT(30)
+#define USART_CR3_TXFTCFG_2	BIT(31)
+
+/* USART_BRR register fields */
+#define USART_BRR_DIV_FRACTION	GENMASK(3, 0)
+#define USART_BRR_DIV_MANTISSA	GENMASK(15, 4)
+
+/* USART_GTPR register fields */
+#define USART_GTPR_PSC		GENMASK(7, 0)
+#define USART_GTPR_GT		GENMASK(15, 8)
+
+/* USART_RTOR register fields */
+#define USART_RTOR_RTO		GENMASK(23, 0)
+#define USART_RTOR_BLEN		GENMASK(31, 24)
+
+/* USART_RQR register fields */
+#define USART_RQR_ABRRQ		BIT(0)
+#define USART_RQR_SBKRQ		BIT(1)
+#define USART_RQR_MMRQ		BIT(2)
+#define USART_RQR_RXFRQ		BIT(3)
+#define USART_RQR_TXFRQ		BIT(4)
+
+/* USART_ISR register fields */
+#define USART_ISR_PE		BIT(0)
+#define USART_ISR_FE		BIT(1)
+#define USART_ISR_NE		BIT(2)
+#define USART_ISR_ORE		BIT(3)
+#define USART_ISR_IDLE		BIT(4)
+#define USART_ISR_RXNE		BIT(5)
+#define USART_ISR_TC		BIT(6)
+#define USART_ISR_TXE		BIT(7)
+#define USART_ISR_LBDF		BIT(8)
+#define USART_ISR_CTSIF		BIT(9)
+#define USART_ISR_CTS		BIT(10)
+#define USART_ISR_RTOF		BIT(11)
+#define USART_ISR_EOBF		BIT(12)
+#define USART_ISR_UDR		BIT(13)
+#define USART_ISR_ABRE		BIT(14)
+#define USART_ISR_ABRF		BIT(15)
+#define USART_ISR_BUSY		BIT(16)
+#define USART_ISR_CMF		BIT(17)
+#define USART_ISR_SBKF		BIT(18)
+#define USART_ISR_RWU		BIT(19)
+#define USART_ISR_WUF		BIT(20)
+#define USART_ISR_TEACK		BIT(21)
+#define USART_ISR_REACK		BIT(22)
+#define USART_ISR_TXFE		BIT(23)
+#define USART_ISR_RXFF		BIT(24)
+#define USART_ISR_TCBGT		BIT(25)
+#define USART_ISR_RXFT		BIT(26)
+#define USART_ISR_TXFT		BIT(27)
+
+/* USART_ICR register fields */
+#define USART_ICR_PECF		BIT(0)
+#define USART_ICR_FECF		BIT(1)
+#define USART_ICR_NCF		BIT(2)
+#define USART_ICR_ORECF		BIT(3)
+#define USART_ICR_IDLECF	BIT(4)
+#define USART_ICR_TCCF		BIT(6)
+#define USART_ICR_TCBGT		BIT(7)
+#define USART_ICR_LBDCF		BIT(8)
+#define USART_ICR_CTSCF		BIT(9)
+#define USART_ICR_RTOCF		BIT(11)
+#define USART_ICR_EOBCF		BIT(12)
+#define USART_ICR_UDRCF		BIT(13)
+#define USART_ICR_CMCF		BIT(17)
+#define USART_ICR_WUCF		BIT(20)
+
+/* USART_RDR register fields */
+#define USART_RDR_RDR		GENMASK(8, 0)
+
+/* USART_TDR register fields */
+#define USART_TDR_TDR		GENMASK(8, 0)
+
+/* USART_PRESC register fields */
+#define USART_PRESC_PRESCALER	GENMASK(3, 0)
+
+#endif /* STM32_UART_REGS_H */
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 1dd57cb..fa13caa 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -30,11 +30,19 @@
  * position @h. For example
  * GENMASK_64(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
+#if defined(__LINKER__) || defined(__ASSEMBLY__)
+#define GENMASK_32(h, l) \
+	(((0xFFFFFFFF) << (l)) & (0xFFFFFFFF >> (32 - 1 - (h))))
+
+#define GENMASK_64(h, l) \
+	((~0 << (l)) & (~0 >> (64 - 1 - (h))))
+#else
 #define GENMASK_32(h, l) \
 	(((~UINT32_C(0)) << (l)) & (~UINT32_C(0) >> (32 - 1 - (h))))
 
 #define GENMASK_64(h, l) \
 	(((~UINT64_C(0)) << (l)) & (~UINT64_C(0) >> (64 - 1 - (h))))
+#endif
 
 #ifdef AARCH32
 #define GENMASK				GENMASK_32
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 9f2d8bd..d85ae96 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -8,7 +8,6 @@
 #include <assert.h>
 #include <bl_common.h>
 #include <boot_api.h>
-#include <console.h>
 #include <debug.h>
 #include <delay_timer.h>
 #include <desc_image_load.h>
@@ -16,11 +15,12 @@
 #include <mmio.h>
 #include <platform.h>
 #include <platform_def.h>
+#include <stm32_console.h>
 #include <stm32mp1_clk.h>
+#include <stm32mp1_context.h>
 #include <stm32mp1_dt.h>
 #include <stm32mp1_pmic.h>
 #include <stm32mp1_private.h>
-#include <stm32mp1_context.h>
 #include <stm32mp1_pwr.h>
 #include <stm32mp1_ram.h>
 #include <stm32mp1_rcc.h>
@@ -28,6 +28,8 @@
 #include <string.h>
 #include <xlat_tables_v2.h>
 
+static struct console_stm32 console;
+
 void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
 				  u_register_t arg2, u_register_t arg3)
 {
@@ -137,8 +139,8 @@
 
 	clk_rate = stm32mp1_clk_get_rate((unsigned long)dt_dev_info.clock);
 
-	if (console_init(dt_dev_info.base, clk_rate,
-			 STM32MP1_UART_BAUDRATE) == 0) {
+	if (console_stm32_register(dt_dev_info.base, clk_rate,
+				   STM32MP1_UART_BAUDRATE, &console) == 0) {
 		panic();
 	}
 
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 678a852..f4a0ca4 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -8,6 +8,7 @@
 ARM_WITH_NEON		:=	yes
 BL2_AT_EL3		:=	1
 USE_COHERENT_MEM	:=	0
+MULTI_CONSOLE_API	:=	1
 
 STM32_TF_VERSION	?=	0
 
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index 56598c8..bd4f2ec 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -7,7 +7,6 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <bl_common.h>
-#include <console.h>
 #include <context.h>
 #include <context_mgmt.h>
 #include <debug.h>
@@ -17,6 +16,7 @@
 #include <platform.h>
 #include <platform_def.h>
 #include <platform_sp_min.h>
+#include <stm32_console.h>
 #include <stm32mp1_clk.h>
 #include <stm32mp1_dt.h>
 #include <stm32mp1_private.h>
@@ -30,6 +30,8 @@
  ******************************************************************************/
 static entry_point_info_t bl33_image_ep_info;
 
+static struct console_stm32 console;
+
 /*******************************************************************************
  * Interrupt handler for FIQ (secure IRQ)
  ******************************************************************************/
@@ -112,8 +114,9 @@
 	result = dt_get_stdout_uart_info(&dt_dev_info);
 
 	if ((result > 0) && dt_dev_info.status) {
-		if (console_init(dt_dev_info.base, 0, STM32MP1_UART_BAUDRATE)
-		    == 0) {
+		if (console_stm32_register(dt_dev_info.base, 0,
+					   STM32MP1_UART_BAUDRATE, &console) ==
+		    0) {
 			panic();
 		}
 	}
diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S
index b0ea0d8..673706e 100644
--- a/plat/st/stm32mp1/stm32mp1_helper.S
+++ b/plat/st/stm32mp1/stm32mp1_helper.S
@@ -149,7 +149,7 @@
 	ldr	r0, =STM32MP1_DEBUG_USART_BASE
 	ldr	r1, =STM32MP1_HSI_CLK
 	ldr	r2, =STM32MP1_UART_BAUDRATE
-	b	console_core_init
+	b	console_stm32_core_init
 endfunc plat_crash_console_init
 
 	/* ---------------------------------------------
@@ -160,7 +160,7 @@
 	 */
 func plat_crash_console_flush
 	ldr	r1, =STM32MP1_DEBUG_USART_BASE
-	b	console_core_flush
+	b	console_stm32_core_flush
 endfunc plat_crash_console_flush
 
 	/* ---------------------------------------------
@@ -176,5 +176,5 @@
 	 */
 func plat_crash_console_putc
 	ldr	r1, =STM32MP1_DEBUG_USART_BASE
-	b	console_core_putc
+	b	console_stm32_core_putc
 endfunc plat_crash_console_putc