From: Sheetal Tigadoli <[email protected]>

Allow ELOG to use DDR for logging.

Signed-off-by: Sheetal Tigadoli <[email protected]>
Signed-off-by: Vladimir Olovyannikov <[email protected]>
---
 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
        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

_______________________________________________
U-Boot mailing list
[email protected]
https://lists.denx.de/listinfo/u-boot

Reply via email to