From mboxrd@z Thu Jan 1 00:00:00 1970 From: Simon Glass Date: Mon, 25 May 2020 11:03:49 -0600 Subject: [PATCH v1 1/3] common: ns3: add error logging support In-Reply-To: <20200517083257.22191-2-rayagonda.kokatanur@broadcom.com> References: <20200517083257.22191-1-rayagonda.kokatanur@broadcom.com> <20200517083257.22191-2-rayagonda.kokatanur@broadcom.com> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Rayagonda, On Sun, 17 May 2020 at 02:33, Rayagonda Kokatanur wrote: > > From: Sheetal Tigadoli > > Add error logging support in uboot for ns3 platform. > > We log the bootup msgs from all bootstages(BL2, BL31, BL33, and Linux) > on to DDR. When a watchdog is triggered from any of the bootstages, > CRMU copies these logs to QSPI error logging space. > > Later when doing the post-mortem analysis, we parse the QSPI error > log space. Is there a doc somewhere describing the format? If not you should add something to the top of your source file. > > Signed-off-by: Sheetal Tigadoli > Signed-off-by: Rayagonda Kokatanur > --- > common/Kconfig | 8 +++++++ > common/Makefile | 1 + > common/bcm_elog.c | 49 +++++++++++++++++++++++++++++++++++++++ > common/console.c | 22 ++++++++++++++++++ > configs/bcm_ns3_defconfig | 1 + > include/bcm_elog.h | 37 +++++++++++++++++++++++++++++ > 6 files changed, 118 insertions(+) > create mode 100644 common/bcm_elog.c > create mode 100644 include/bcm_elog.h > > diff --git a/common/Kconfig b/common/Kconfig > index 30cba15948..3980ba31e0 100644 > --- a/common/Kconfig > +++ b/common/Kconfig > @@ -634,6 +634,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 Not needed > + 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 2e7a090588..dced769dcf 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..8e89a500b9 > --- /dev/null > +++ b/common/bcm_elog.c > @@ -0,0 +1,49 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright 2020 Broadcom. > + */ > + > +#include > + > +/* Log one character */ > +int log2ddr(const char ch) > +{ > + u32 offset, len; > + uintptr_t base = BCM_ELOG_UBOOT_BASE; This should really be in a driver. Have you looked at logging? See for example log_syslog.c which is an example of writing log info obtained from the log() function. If that doesn't work then perhaps have a UCLASS_MISC driver that you can write to? > + > + 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, uint32_t 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 e398530a13..a65fdc16c2 100644 > --- a/common/console.c > +++ b/common/console.c > @@ -20,6 +20,10 @@ > #include > #include > > +#ifdef CONFIG_BCM_ELOG > +#include > +#endif Can't add this to common code, sorry. Hopefully U-Boot's logging can help here? > + > 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); > @@ -790,6 +808,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/configs/bcm_ns3_defconfig b/configs/bcm_ns3_defconfig > index 13fe9d439e..a2201bf0c9 100644 > --- a/configs/bcm_ns3_defconfig > +++ b/configs/bcm_ns3_defconfig > @@ -14,6 +14,7 @@ CONFIG_LOGLEVEL=7 > CONFIG_SILENT_CONSOLE=y > CONFIG_SILENT_U_BOOT_ONLY=y > # CONFIG_SILENT_CONSOLE_UPDATE_ON_SET is not set > +CONFIG_BCM_ELOG=y > CONFIG_SUPPORT_RAW_INITRD=y > # CONFIG_DISPLAY_CPUINFO is not set > CONFIG_HUSH_PARSER=y > diff --git a/include/bcm_elog.h b/include/bcm_elog.h > new file mode 100644 > index 0000000000..7ba99f1cf7 > --- /dev/null > +++ b/include/bcm_elog.h > @@ -0,0 +1,37 @@ > +/* SPDX-License-Identifier: GPL-2.0+ */ > +/* > + * Copyright 2020 Broadcom. > + * > + */ > + > +#ifndef __BCM_ELOG_H__ > +#define __BCM_ELOG_H__ > + > +#include > +#include > + > +/* 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 This should go in the devicetree node for your driver. > + > +/* 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