feat(zynqmp): dedicate console for boot and runtime
Introduce a build-time parameter (CONSOLE_RUNTIME) to select
separate runtime console options. For boot-time console, remove
the runtime flag and add a boot/crash flag. Additionally,
introduce an RT_CONSOLE_IS macro to check different UART types.
Implement a common function, console_runtime_init(), to initialize
the runtime console. Ensure that all platforms have access to
this feature.
The current implementation utilizes a single console for boot,
crash, and runtime. Make sure that the dedicated console integrates
into runtime and crash scenarios.
Change-Id: I32913dede3d87109e54d179e7d99f45c33b9097b
Signed-off-by: Prasad Kummari <prasad.kummari@amd.com>
Signed-off-by: Maheedhar Bollapalli <MaheedharSai.Bollapalli@amd.com>
diff --git a/plat/xilinx/common/include/plat_console.h b/plat/xilinx/common/include/plat_console.h
index 0f8320e..b38f347 100644
--- a/plat/xilinx/common/include/plat_console.h
+++ b/plat/xilinx/common/include/plat_console.h
@@ -15,6 +15,12 @@
#define DT_UART_COMPAT "arm,pl011"
#endif
+/*Default console type is either CADENCE0 or CADENCE1 or PL011_0 or PL011_1
+ * Debug console type is DCC
+ **/
+#define PLAT_XLNX_CONSOLE_TYPE_DEFAULT 0
+#define PLAT_XLNX_CONSOLE_TYPE_DEBUG 1
+
typedef struct dt_uart_info_s {
char compatible[30];
uintptr_t base;
@@ -24,4 +30,8 @@
void setup_console(void);
+#if defined(CONSOLE_RUNTIME)
+void console_runtime_init(void);
+#endif
+
#endif /* PLAT_DT_UART_H */
diff --git a/plat/xilinx/common/plat_console.c b/plat/xilinx/common/plat_console.c
index 610c84f..72fd881 100644
--- a/plat/xilinx/common/plat_console.c
+++ b/plat/xilinx/common/plat_console.c
@@ -25,7 +25,51 @@
static console_t boot_console;
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE)) || \
+ defined(CONSOLE_RUNTIME)
+/**
+ * register_console() - Registers the runtime uart with console list.
+ * @uart_base: UART base address
+ * @clock: UART clock.
+ * @baud_rate: UART buad rate
+ * @console: Pointer to the console information structure.
+ * @flags: console flags.
+ */
+static void register_console(uintptr_t uart_base, uint32_t clock,
+ uint32_t baud_rate, console_t *console,
+ uint32_t flags, uint8_t console_type)
+{
+ int32_t rc = 0;
+
+ if (console_type == PLAT_XLNX_CONSOLE_TYPE_DEFAULT) {
+#if defined(PLAT_zynqmp)
+ rc = console_cdns_register(uart_base,
+ clock,
+ baud_rate,
+ console);
+#elif defined(PLAT_versal) || defined(PLAT_versal_net) || defined(PLAT_versal2)
+ rc = console_pl011_register(uart_base,
+ clock,
+ baud_rate,
+ console);
+#endif
+ } else if (console_type == PLAT_XLNX_CONSOLE_TYPE_DEBUG) {
+ rc = console_dcc_register(console);
+ } else {
+ INFO("Invalid console type\n");
+ }
+
+ if (rc == 0) {
+ panic();
+ }
+
+ console_set_scope(console, flags);
+}
+#endif
+
#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+
+static console_t dt_console;
/**
* get_baudrate() - Get the baudrate form DTB.
* @dtb: Address of the Device Tree Blob (DTB).
@@ -222,38 +266,6 @@
}
/**
- * register_console() - Registers the runtime uart with console list.
- * @uart_base: UART base address
- * @clock: UART clock.
- * @baud_rate: UART buad rate
- * @console: Pointer to the console information structure.
- * @flags: console flags.
- */
-static void register_console(uintptr_t uart_base, uint32_t clock,
- uint32_t baud_rate, console_t *console,
- uint32_t flags)
-{
- int32_t rc;
-
-#if defined(PLAT_zynqmp)
- rc = console_cdns_register(uart_base,
- clock,
- baud_rate,
- console);
-#else
- rc = console_pl011_register(uart_base,
- clock,
- baud_rate,
- console);
-#endif
- if (rc == 0) {
- panic();
- }
-
- console_set_scope(console, flags);
-}
-
-/**
* parse_uart_info() - Parse UART information from Device Tree Blob.
* @uart_info: Pointer to the UART information structure.
*
@@ -281,7 +293,8 @@
{
register_console(uart_info->base, clock, uart_info->baud_rate,
console, CONSOLE_FLAG_BOOT |
- CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
+ CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH,
+ PLAT_XLNX_CONSOLE_TYPE_DEFAULT);
console_end(end_console);
INFO("DTB console setup\n");
}
@@ -314,7 +327,6 @@
uint32_t clock)
{
int32_t rc = 0;
- static console_t dt_console;
/* Parse UART information from Device Tree Blob (DTB) */
rc = parse_uart_info(uart_info);
@@ -327,6 +339,11 @@
goto error;
}
+ rc = check_fdt_uart_info(uart_info);
+ if (rc < 0) {
+ goto error;
+ }
+
if (strncmp(uart_info->compatible, DT_UART_COMPAT,
strlen(DT_UART_COMPAT)) == 0) {
handle_dt_console(uart_info, &dt_console, clock, console);
@@ -342,6 +359,64 @@
}
#endif
+#if defined(CONSOLE_RUNTIME)
+void console_runtime_init(void)
+{
+ uint32_t uart_clk = get_uart_clk();
+ static console_t runtime_console;
+ uintptr_t rt_uart_base = 0;
+ uint32_t buad_rate = 0;
+ static dt_uart_info_t dt_info = {0};
+
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+ console_t *console = &dt_console;
+#else
+ console_t *console = &boot_console;
+#endif
+
+#if (RT_CONSOLE_IS(dtb) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+ (!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+ !IS_TFA_IN_OCM(BL31_BASE)))
+ uint32_t rc = parse_uart_info(&dt_info);
+
+ if (rc < 0) {
+ goto error;
+ } else {
+ rt_uart_base = dt_info.base;
+ buad_rate = dt_info.baud_rate;
+ }
+#elif defined(PLAT_zynqmp)
+ if (RT_CONSOLE_IS(cadence) || (RT_CONSOLE_IS(cadence1))) {
+ rt_uart_base = (uintptr_t)RT_UART_BASE;
+ buad_rate = (uint32_t)UART_BAUDRATE;
+ }
+#else
+ if (RT_CONSOLE_IS(pl011) || (RT_CONSOLE_IS(pl011_1))) {
+ rt_uart_base = (uintptr_t)RT_UART_BASE;
+ buad_rate = (uint32_t)UART_BAUDRATE;
+ }
+#endif
+ /*skip console registration if runtime and boot console are same */
+ if (console->base != rt_uart_base) {
+ /* Remove runtime flag from boot console */
+ console_set_scope(console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH);
+
+ register_console(rt_uart_base, uart_clk, buad_rate, &runtime_console,
+ CONSOLE_FLAG_RUNTIME, PLAT_XLNX_CONSOLE_TYPE_DEFAULT);
+ INFO("Successfully initialized runtime console\n");
+ }
+
+#if (RT_CONSOLE_IS(dtb) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+ (!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+ !IS_TFA_IN_OCM(BL31_BASE)))
+error:
+ if (rc < 0) {
+ ERROR("Failed to parse uart info in runtime console\n");
+ }
+#endif
+}
+#endif
+
void setup_console(void)
{
int32_t rc;
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 50d4240..a6d270c 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -191,6 +191,10 @@
#endif
custom_runtime_setup();
+
+#if defined(CONSOLE_RUNTIME)
+ console_runtime_init();
+#endif
}
/*
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index d715ce2..ef72c2c 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -17,6 +17,15 @@
#define CONSOLE_IS(con) (ZYNQMP_CONSOLE_ID_ ## con == ZYNQMP_CONSOLE)
+/* Runtime console */
+#define RT_CONSOLE_ID_cadence 1
+#define RT_CONSOLE_ID_cadence0 1
+#define RT_CONSOLE_ID_cadence1 2
+#define RT_CONSOLE_ID_dcc 3
+#define RT_CONSOLE_ID_dtb 4
+
+#define RT_CONSOLE_IS(con) (RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
/* Default counter frequency */
#define ZYNQMP_DEFAULT_COUNTER_FREQ 0U
@@ -152,6 +161,17 @@
# error "invalid ZYNQMP_CONSOLE"
#endif
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(cadence) || RT_CONSOLE_IS(dcc) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE ZYNQMP_UART0_BASE
+#elif RT_CONSOLE_IS(cadence1)
+# define RT_UART_BASE ZYNQMP_UART1_BASE
+#else
+# error "invalid CONSOLE_RUNTIME"
+#endif
+#endif
+
/* Must be non zero */
#define UART_BAUDRATE 115200
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 9fdc649..92c9d1f 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -117,6 +117,20 @@
endif
$(eval $(call add_define_val,ZYNQMP_CONSOLE,ZYNQMP_CONSOLE_ID_${ZYNQMP_CONSOLE}))
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= cadence
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},cadence cadence0 cadence1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
# Build PM code as a Library
include plat/xilinx/zynqmp/libpm.mk