From 88a0523e914cb28fded2ce398a184e0c0e8843c8 Mon Sep 17 00:00:00 2001
From: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Date: Tue, 19 Jun 2018 09:29:36 +0100
Subject: [PATCH] plat/arm: Migrate AArch64 port to the multi console driver

The old API is deprecated and will eventually be removed.

Arm platforms now use the multi console driver for boot and runtime
consoles. However, the crash console uses the direct console API because
it doesn't need any memory access to work. This makes it more robust
during crashes.

The AArch32 port of the Trusted Firmware doesn't support this new API
yet, so it is only enabled in AArch64 builds. Because of this, the
common code must maintain compatibility with both systems. SP_MIN
doesn't have to be updated because it's only used in AArch32 builds.
The TSP is only used in AArch64, so it only needs to support the new
API without keeping support for the old one.

Special care must be taken because of PSCI_SYSTEM_SUSPEND. In Juno, this
causes the UARTs to reset (except for the one used by the TSP). This
means that they must be unregistered when suspending and re-registered
when resuming. This wasn't a problem with the old driver because it just
restarted the UART, and there were no problems associated with
registering and unregistering consoles.

The size reserved for BL2 has been increased.

Change-Id: Icefd117dd1eb9c498921181a21318c2d2435c441
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
---
 include/drivers/console.h                     |  6 +-
 include/plat/arm/board/common/board_arm_def.h |  2 +-
 include/plat/arm/common/plat_arm.h            |  6 ++
 plat/arm/common/aarch64/arm_helpers.S         | 12 +--
 plat/arm/common/arm_bl1_setup.c               |  4 +-
 plat/arm/common/arm_bl2_el3_setup.c           |  6 +-
 plat/arm/common/arm_bl2_setup.c               |  4 +-
 plat/arm/common/arm_bl2u_setup.c              |  5 +-
 plat/arm/common/arm_bl31_setup.c              | 13 ++-
 plat/arm/common/arm_common.mk                 |  8 +-
 plat/arm/common/arm_console.c                 | 85 +++++++++++++++++++
 plat/arm/common/arm_pm.c                      | 13 ++-
 plat/arm/common/tsp/arm_tsp_setup.c           | 20 ++++-
 13 files changed, 151 insertions(+), 33 deletions(-)
 create mode 100644 plat/arm/common/arm_console.c

diff --git a/include/drivers/console.h b/include/drivers/console.h
index a4d89fe91..6e7ebbf9c 100644
--- a/include/drivers/console.h
+++ b/include/drivers/console.h
@@ -16,9 +16,9 @@
 #define CONSOLE_T_FLUSH			(U(4) * REGSZ)
 #define CONSOLE_T_DRVDATA		(U(5) * REGSZ)
 
-#define CONSOLE_FLAG_BOOT		BIT(0)
-#define CONSOLE_FLAG_RUNTIME		BIT(1)
-#define CONSOLE_FLAG_CRASH		BIT(2)
+#define CONSOLE_FLAG_BOOT		(U(1) << 0)
+#define CONSOLE_FLAG_RUNTIME		(U(1) << 1)
+#define CONSOLE_FLAG_CRASH		(U(1) << 2)
 /* Bits 3 to 7 reserved for additional scopes in future expansion. */
 #define CONSOLE_FLAG_SCOPE_MASK		((U(1) << 8) - 1)
 /* Bits 8 to 31 reserved for non-scope use in future expansion. */
diff --git a/include/plat/arm/board/common/board_arm_def.h b/include/plat/arm/board/common/board_arm_def.h
index 2d8e4c139..030e06737 100644
--- a/include/plat/arm/board/common/board_arm_def.h
+++ b/include/plat/arm/board/common/board_arm_def.h
@@ -89,7 +89,7 @@
 #if TRUSTED_BOARD_BOOT
 # define PLAT_ARM_MAX_BL2_SIZE		0x1E000
 #else
-# define PLAT_ARM_MAX_BL2_SIZE		0x10000
+# define PLAT_ARM_MAX_BL2_SIZE		0x11000
 #endif
 
 /*
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index fc3f4ec3a..33f2c7dbe 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -155,6 +155,12 @@ struct tzc_dmc500_driver_data;
 void arm_tzc_dmc500_setup(struct tzc_dmc500_driver_data *plat_driver_data,
 			const arm_tzc_regions_info_t *tzc_regions);
 
+/* Console utility functions */
+void arm_console_boot_init(void);
+void arm_console_boot_end(void);
+void arm_console_runtime_init(void);
+void arm_console_runtime_end(void);
+
 /* Systimer utility function */
 void arm_configure_sys_timer(void);
 
diff --git a/plat/arm/common/aarch64/arm_helpers.S b/plat/arm/common/aarch64/arm_helpers.S
index 760a53af2..752929db5 100644
--- a/plat/arm/common/aarch64/arm_helpers.S
+++ b/plat/arm/common/aarch64/arm_helpers.S
@@ -8,9 +8,9 @@
 
 	.weak	plat_arm_calc_core_pos
 	.weak	plat_my_core_pos
-	.globl	plat_crash_console_init
-	.globl	plat_crash_console_putc
-	.globl	plat_crash_console_flush
+	.weak	plat_crash_console_init
+	.weak	plat_crash_console_putc
+	.weak	plat_crash_console_flush
 	.globl	platform_mem_init
 
 
@@ -50,7 +50,7 @@ func plat_crash_console_init
 	mov_imm	x0, PLAT_ARM_CRASH_UART_BASE
 	mov_imm	x1, PLAT_ARM_CRASH_UART_CLK_IN_HZ
 	mov_imm	x2, ARM_CONSOLE_BAUDRATE
-	b	console_core_init
+	b	console_pl011_core_init
 endfunc plat_crash_console_init
 
 	/* ---------------------------------------------
@@ -62,7 +62,7 @@ endfunc plat_crash_console_init
 	 */
 func plat_crash_console_putc
 	mov_imm	x1, PLAT_ARM_CRASH_UART_BASE
-	b	console_core_putc
+	b	console_pl011_core_putc
 endfunc plat_crash_console_putc
 
 	/* ---------------------------------------------
@@ -75,7 +75,7 @@ endfunc plat_crash_console_putc
 	 */
 func plat_crash_console_flush
 	mov_imm	x0, PLAT_ARM_CRASH_UART_BASE
-	b	console_core_flush
+	b	console_pl011_core_flush
 endfunc plat_crash_console_flush
 
 	/* ---------------------------------------------------------------------
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 379e87df2..e5e730417 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -9,7 +9,6 @@
 #include <arm_xlat_tables.h>
 #include <bl1.h>
 #include <bl_common.h>
-#include <console.h>
 #include <plat_arm.h>
 #include <platform.h>
 #include <platform_def.h>
@@ -45,8 +44,7 @@ void arm_bl1_early_platform_setup(void)
 #endif
 
 	/* Initialize the console to provide early debug support */
-	console_init(PLAT_ARM_BOOT_UART_BASE, PLAT_ARM_BOOT_UART_CLK_IN_HZ,
-			ARM_CONSOLE_BAUDRATE);
+	arm_console_boot_init();
 
 	/* Allow BL1 to see the whole Trusted RAM */
 	bl1_tzram_layout.total_base = ARM_BL_RAM_BASE;
diff --git a/plat/arm/common/arm_bl2_el3_setup.c b/plat/arm/common/arm_bl2_el3_setup.c
index e70d115ee..e7247c63d 100644
--- a/plat/arm/common/arm_bl2_el3_setup.c
+++ b/plat/arm/common/arm_bl2_el3_setup.c
@@ -1,9 +1,8 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include <console.h>
 #include <generic_delay_timer.h>
 #include <plat_arm.h>
 #include <platform.h>
@@ -21,8 +20,7 @@ static meminfo_t bl2_el3_tzram_layout;
 void arm_bl2_el3_early_platform_setup(void)
 {
 	/* Initialize the console to provide early debug support */
-	console_init(PLAT_ARM_BOOT_UART_BASE, PLAT_ARM_BOOT_UART_CLK_IN_HZ,
-			ARM_CONSOLE_BAUDRATE);
+	arm_console_boot_init();
 
 	/*
 	 * Allow BL2 to see the whole Trusted RAM. This is determined
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 4ef3a9b0f..3aa99f805 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -8,7 +8,6 @@
 #include <arm_def.h>
 #include <assert.h>
 #include <bl_common.h>
-#include <console.h>
 #include <debug.h>
 #include <desc_image_load.h>
 #include <generic_delay_timer.h>
@@ -176,8 +175,7 @@ struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
 void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, meminfo_t *mem_layout)
 {
 	/* Initialize the console to provide early debug support */
-	console_init(PLAT_ARM_BOOT_UART_BASE, PLAT_ARM_BOOT_UART_CLK_IN_HZ,
-			ARM_CONSOLE_BAUDRATE);
+	arm_console_boot_init();
 
 	/* Setup the BL2 memory layout */
 	bl2_tzram_layout = *mem_layout;
diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c
index 3b8e4aa46..cd691e5c3 100644
--- a/plat/arm/common/arm_bl2u_setup.c
+++ b/plat/arm/common/arm_bl2u_setup.c
@@ -7,7 +7,6 @@
 #include <arch_helpers.h>
 #include <arm_def.h>
 #include <bl_common.h>
-#include <console.h>
 #include <generic_delay_timer.h>
 #include <plat_arm.h>
 #include <platform_def.h>
@@ -36,8 +35,8 @@ void bl2u_platform_setup(void)
 void arm_bl2u_early_platform_setup(meminfo_t *mem_layout, void *plat_info)
 {
 	/* Initialize the console to provide early debug support */
-	console_init(PLAT_ARM_BOOT_UART_BASE, PLAT_ARM_BOOT_UART_CLK_IN_HZ,
-			ARM_CONSOLE_BAUDRATE);
+	arm_console_boot_init();
+
 	generic_delay_timer_init();
 }
 
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 46f7ae0e5..6346f0fff 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -78,8 +78,7 @@ void arm_bl31_early_platform_setup(bl31_params_t *from_bl2, uintptr_t soc_fw_con
 #endif
 {
 	/* Initialize the console to provide early debug support */
-	console_init(PLAT_ARM_BOOT_UART_BASE, PLAT_ARM_BOOT_UART_CLK_IN_HZ,
-			ARM_CONSOLE_BAUDRATE);
+	arm_console_boot_init();
 
 #if RESET_TO_BL31
 	/* There are no parameters from BL2 if BL31 is a reset vector */
@@ -249,12 +248,18 @@ void arm_bl31_platform_setup(void)
 /*******************************************************************************
  * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM
  * standard platforms
+ * Perform BL31 platform setup
  ******************************************************************************/
 void arm_bl31_plat_runtime_setup(void)
 {
+#if MULTI_CONSOLE_API
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
+#else
+	console_uninit();
+#endif
+
 	/* Initialize the runtime console */
-	console_init(PLAT_ARM_BL31_RUN_UART_BASE, PLAT_ARM_BL31_RUN_UART_CLK_IN_HZ,
-			ARM_CONSOLE_BAUDRATE);
+	arm_console_runtime_init();
 }
 
 void bl31_platform_setup(void)
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 4b23ac675..76a75d3b9 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -125,6 +125,11 @@ SEPARATE_CODE_AND_RODATA	:=	1
 # Enable new version of image loading on ARM platforms
 LOAD_IMAGE_V2			:=	1
 
+# Use the multi console API, which is only available for AArch64 for now
+ifeq (${ARCH}, aarch64)
+  MULTI_CONSOLE_API		:=	1
+endif
+
 # Use generic OID definition (tbbr_oid.h)
 USE_TBBR_DEFS			:=	1
 
@@ -141,7 +146,8 @@ PLAT_INCLUDES		+=	-Iinclude/plat/arm/common/aarch64
 endif
 
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/${ARCH}/arm_helpers.S		\
-				plat/arm/common/arm_common.c
+				plat/arm/common/arm_common.c			\
+				plat/arm/common/arm_console.c
 
 ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
 PLAT_BL_COMMON_SOURCES	+=	lib/xlat_tables/xlat_tables_common.c		\
diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c
new file mode 100644
index 000000000..6c8587fc4
--- /dev/null
+++ b/plat/arm/common/arm_console.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <console.h>
+#include <debug.h>
+#include <pl011.h>
+#include <plat_arm.h>
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Functions that set up the console
+ ******************************************************************************/
+#if MULTI_CONSOLE_API
+static console_pl011_t arm_boot_console;
+static console_pl011_t arm_runtime_console;
+#endif
+
+/* Initialize the console to provide early debug support */
+void arm_console_boot_init(void)
+{
+#if MULTI_CONSOLE_API
+	int rc = console_pl011_register(PLAT_ARM_BOOT_UART_BASE,
+					PLAT_ARM_BOOT_UART_CLK_IN_HZ,
+					ARM_CONSOLE_BAUDRATE,
+					&arm_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(&arm_boot_console.console, CONSOLE_FLAG_BOOT);
+#else
+	(void)console_init(PLAT_ARM_BOOT_UART_BASE,
+			   PLAT_ARM_BOOT_UART_CLK_IN_HZ,
+			   ARM_CONSOLE_BAUDRATE);
+#endif /* MULTI_CONSOLE_API */
+}
+
+void arm_console_boot_end(void)
+{
+	(void)console_flush();
+
+#if MULTI_CONSOLE_API
+	(void)console_unregister(&arm_boot_console.console);
+#else
+	console_uninit();
+#endif /* MULTI_CONSOLE_API */
+}
+
+/* Initialize the runtime console */
+void arm_console_runtime_init(void)
+{
+#if MULTI_CONSOLE_API
+	int rc = console_pl011_register(PLAT_ARM_BL31_RUN_UART_BASE,
+					PLAT_ARM_BL31_RUN_UART_CLK_IN_HZ,
+					ARM_CONSOLE_BAUDRATE,
+					&arm_runtime_console);
+	if (rc == 0)
+		panic();
+
+	console_set_scope(&arm_runtime_console.console, CONSOLE_FLAG_RUNTIME);
+#else
+	(void)console_init(PLAT_ARM_BL31_RUN_UART_BASE,
+			   PLAT_ARM_BL31_RUN_UART_CLK_IN_HZ,
+			   ARM_CONSOLE_BAUDRATE);
+#endif /* MULTI_CONSOLE_API */
+}
+
+void arm_console_runtime_end(void)
+{
+	(void)console_flush();
+
+#if MULTI_CONSOLE_API
+	(void)console_unregister(&arm_runtime_console.console);
+#else
+	console_uninit();
+#endif /* MULTI_CONSOLE_API */
+}
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index 44ac5b5d6..4632099e7 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,7 +8,6 @@
 #include <arm_def.h>
 #include <arm_gic.h>
 #include <assert.h>
-#include <console.h>
 #include <errno.h>
 #include <plat_arm.h>
 #include <platform.h>
@@ -159,6 +158,12 @@ void arm_system_pwr_domain_save(void)
 
 	plat_arm_gic_save();
 
+	/*
+	 * Unregister console now so that it is not registered for a second
+	 * time during resume.
+	 */
+	arm_console_runtime_end();
+
 	/*
 	 * All the other peripheral which are configured by ARM TF are
 	 * re-initialized on resume from system suspend. Hence we
@@ -174,8 +179,8 @@ void arm_system_pwr_domain_save(void)
  *****************************************************************************/
 void arm_system_pwr_domain_resume(void)
 {
-	console_init(PLAT_ARM_BL31_RUN_UART_BASE, PLAT_ARM_BL31_RUN_UART_CLK_IN_HZ,
-						ARM_CONSOLE_BAUDRATE);
+	/* Initialize the console */
+	arm_console_runtime_init();
 
 	/* Assert system power domain is available on the platform */
 	assert(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL2);
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index abeaea0bc..16125ad4f 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,8 @@
 #include <arm_def.h>
 #include <bl_common.h>
 #include <console.h>
+#include <debug.h>
+#include <pl011.h>
 #include <plat_arm.h>
 #include <platform_def.h>
 #include <platform_tsp.h>
@@ -22,14 +24,30 @@
 /*******************************************************************************
  * Initialize the UART
  ******************************************************************************/
+#if MULTI_CONSOLE_API
+static console_pl011_t arm_tsp_runtime_console;
+#endif
+
 void arm_tsp_early_platform_setup(void)
 {
+#if MULTI_CONSOLE_API
 	/*
 	 * Initialize a different console than already in use to display
 	 * messages from TSP
 	 */
+	int rc = console_pl011_register(PLAT_ARM_TSP_UART_BASE,
+					PLAT_ARM_TSP_UART_CLK_IN_HZ,
+					ARM_CONSOLE_BAUDRATE,
+					&arm_tsp_runtime_console);
+	if (rc == 0)
+		panic();
+
+	console_set_scope(&arm_tsp_runtime_console.console,
+			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
+#else
 	console_init(PLAT_ARM_TSP_UART_BASE, PLAT_ARM_TSP_UART_CLK_IN_HZ,
 			ARM_CONSOLE_BAUDRATE);
+#endif /* MULTI_CONSOLE_API */
 }
 
 void tsp_early_platform_setup(void)
-- 
GitLab