
Hi Vladimir,
On Mon, 18 Nov 2019 at 17:59, Vladimir Olovyannikov vladimir.olovyannikov@broadcom.com wrote:
From: Sheetal Tigadoli sheetal.tigadoli@broadcom.com
Allow ELOG to use DDR for logging.
Signed-off-by: Sheetal Tigadoli sheetal.tigadoli@broadcom.com Signed-off-by: Vladimir Olovyannikov vladimir.olovyannikov@broadcom.com
common/Kconfig | 8 ++++++++ common/Makefile | 1 + common/bcm_elog.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++ common/console.c | 22 +++++++++++++++++++++ include/bcm_elog.h | 37 ++++++++++++++++++++++++++++++++++ 5 files changed, 117 insertions(+) create mode 100644 common/bcm_elog.c create mode 100644 include/bcm_elog.h
diff --git a/common/Kconfig b/common/Kconfig index d9ecf79e0a..f78296ec63 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -632,6 +632,14 @@ config SYS_STDIO_DEREGISTER removed (for example a USB keyboard) then this option can be enabled to ensure this is handled correctly.
+config BCM_ELOG
bool "Broadcom error logging support"
default n
help
Enables broadcom error logging support to be used with brcm
platforms, say Y to this option to enable the logging support.
If unsure, say N.
endmenu
menu "Logging" diff --git a/common/Makefile b/common/Makefile index 302d8beaf3..5f1338f281 100644 --- a/common/Makefile +++ b/common/Makefile @@ -95,6 +95,7 @@ else obj-$(CONFIG_SPL_SERIAL_SUPPORT) += console.o endif else +obj-$(CONFIG_BCM_ELOG) += bcm_elog.o obj-y += console.o endif # CONFIG_SPL_BUILD
diff --git a/common/bcm_elog.c b/common/bcm_elog.c new file mode 100644 index 0000000000..9f51636b24 --- /dev/null +++ b/common/bcm_elog.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2019 Broadcom
- */
+#include <bcm_elog.h>
+/* Log one character */ +int log2ddr(const char ch) +{
u32 offset, len;
uintptr_t base = BCM_ELOG_UBOOT_BASE;
offset = readl(base + BCM_ELOG_OFF_OFFSET);
len = readl(base + BCM_ELOG_LEN_OFFSET);
writeb(ch, base + offset);
offset++;
/* log buffer is now full and need to wrap around */
if (offset >= BCM_ELOG_UBOOT_SIZE)
offset = BCM_ELOG_HEADER_LEN;
/* only increment length when log buffer is not full */
if (len < BCM_ELOG_UBOOT_SIZE - BCM_ELOG_HEADER_LEN)
len++;
writel(offset, base + BCM_ELOG_OFF_OFFSET);
writel(len, base + BCM_ELOG_LEN_OFFSET);
return 0;
+}
+/* Routine to initialize error logging */ +void bcm_elog_init(uintptr_t base, u32 size) +{
u32 val;
/*
* If a valid signature is found, it means logging is already
* initialize. In this case, we should not re-initialize the entry
* header in the designated memory
*/
val = readl(base + BCM_ELOG_SIG_OFFSET);
if (val != BCM_ELOG_SIG_VAL) {
writel(base + BCM_ELOG_SIG_OFFSET, BCM_ELOG_SIG_VAL);
writel(base + BCM_ELOG_OFF_OFFSET, BCM_ELOG_HEADER_LEN);
writel(base + BCM_ELOG_LEN_OFFSET, 0);
}
+} diff --git a/common/console.c b/common/console.c index 168ba60d0d..25ebd6e431 100644 --- a/common/console.c +++ b/common/console.c @@ -20,6 +20,10 @@ #include <env_internal.h> #include <watchdog.h>
+#ifdef CONFIG_BCM_ELOG +#include <bcm_elog.h> +#endif
DECLARE_GLOBAL_DATA_PTR;
static int on_console(const char *name, const char *value, enum env_op op, @@ -536,6 +540,9 @@ void putc(const char c) if (!gd->have_console) return pre_console_putc(c);
+#ifdef CONFIG_BCM_ELOG
log2ddr(c);
+#endif if (gd->flags & GD_FLG_DEVINIT) { /* Send to the standard output */ fputc(stdout, c); @@ -587,6 +594,17 @@ void puts(const char *s) if (!gd->have_console) return pre_console_puts(s);
+#ifdef CONFIG_BCM_ELOG
{
const char *tmp = s;
while (*tmp) {
int c = *tmp++;
log2ddr(c);
}
}
+#endif
Firstly this change to a common file should be in a separate patch.
Secondly, we really can't do this sort of hack.
You could use the existing log() subsystem with a driver for your log system. See log_console.c for an example. Then, when enabled, log data can go to your driver.
if (gd->flags & GD_FLG_DEVINIT) { /* Send to the standard output */ fputs(stdout, s);
@@ -776,6 +794,10 @@ int console_init_f(void)
print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT1_SERIAL);
+#ifdef CONFIG_BCM_ELOG
bcm_elog_init(BCM_ELOG_UBOOT_BASE, BCM_ELOG_UBOOT_SIZE);
+#endif
return 0;
}
diff --git a/include/bcm_elog.h b/include/bcm_elog.h new file mode 100644 index 0000000000..62352bf5a3 --- /dev/null +++ b/include/bcm_elog.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- (C) Copyright 2019 Broadcom
- */
+#ifndef __BCM_ELOG_H__ +#define __BCM_ELOG_H__
+#include <asm/io.h> +#include <linux/types.h>
+/* Default AP error logging base address */ +#ifndef ELOG_AP_UART_LOG_BASE +#define ELOG_AP_UART_LOG_BASE 0x8f110000 +#endif
+/* Reserve 16K to store error logs */ +#define BCM_ELOG_UBOOT_BASE ELOG_AP_UART_LOG_BASE +#define BCM_ELOG_UBOOT_SIZE 0x4000
+/* error logging signature */ +#define BCM_ELOG_SIG_OFFSET 0x0000 +#define BCM_ELOG_SIG_VAL 0x75767971
+/* current logging offset that points to where new logs should be added */ +#define BCM_ELOG_OFF_OFFSET 0x0004
+/* current logging length (excluding header) */ +#define BCM_ELOG_LEN_OFFSET 0x0008
+#define BCM_ELOG_HEADER_LEN 12
+int log2ddr(const char ch); +void bcm_elog_init(uintptr_t base, uint32_t size);
+#endif /* __BCM_ELOG_H__ */
2.17.1
Regards, Simon