From 0ae53640b54f2c30e52044f7102ba08915b988a7 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Tue, 9 Oct 2007 17:24:49 +0800 Subject: Blackfin arch: Initial patch to add earlyprintk support This allows debugging of problems which happen eary in the kernel boot process (after bootargs are parsed, but before serial subsystem is fully initialized) Signed-off-by: Robin Getz Signed-off-by: Bryan Wu --- arch/blackfin/Kconfig | 14 ++++ arch/blackfin/kernel/Makefile | 1 + arch/blackfin/kernel/early_printk.c | 161 ++++++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 arch/blackfin/kernel/early_printk.c (limited to 'arch/blackfin') diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 26ebb0e8c431..cc789b988f3a 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -1164,6 +1164,20 @@ config DEBUG_BFIN_NO_KERN_HWTRACE Say Y here to disable hardware tracing in some known "jumpy" pieces of code so that the trace buffer will extend further back. +config EARLY_PRINTK + bool "Early printk" + default n + help + This option enables special console drivers which allow the kernel + to print messages very early in the bootup process. + + This is useful for kernel debugging when your machine crashes very + early before the console code is initialized. After enabling this + feature, you must add "earlyprintk=serial,uart0,57600" to the + command line (bootargs). It is safe to say Y here in all cases, as + all of this lives in the init section and is thrown away after the + kernel boots completely. + config DUAL_CORE_TEST_MODULE tristate "Dual Core Test Module" depends on (BF561) diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 243883ec6de1..8aeb6066b19b 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o obj-$(CONFIG_KGDB) += kgdb.o +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c new file mode 100644 index 000000000000..9bf61706694f --- /dev/null +++ b/arch/blackfin/kernel/early_printk.c @@ -0,0 +1,161 @@ +/* + * File: arch/blackfin/kernel/early_printk.c + * Based on: arch/x86_64/kernel/early_printk.c + * Author: Robin Getz +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_BFIN +extern struct console *bfin_earlyserial_init(unsigned int port, + unsigned int cflag); +#endif + +static struct console *early_console; + +/* Default console + * Port n == ttyBFn + * cflags == UART output modes + */ +#define DEFAULT_PORT 0 +#define DEFAULT_CFLAG CS8|B57600 + +#ifdef CONFIG_SERIAL_CORE +/* What should get here is "0,57600" */ +static struct console * __init earlyserial_init(char *buf) +{ + int baud, bit; + char parity; + unsigned int serial_port = DEFAULT_PORT; + unsigned int cflag = DEFAULT_CFLAG; + + serial_port = simple_strtoul(buf, &buf, 10); + buf++; + + cflag = 0; + baud = simple_strtoul(buf, &buf, 10); + switch (baud) { + case 1200: + cflag |= B1200; + break; + case 2400: + cflag |= B2400; + break; + case 4800: + cflag |= B4800; + break; + case 9600: + cflag |= B9600; + break; + case 19200: + cflag |= B19200; + break; + case 38400: + cflag |= B38400; + break; + case 115200: + cflag |= B115200; + break; + default: + cflag |= B57600; + } + + parity = buf[0]; + buf++; + switch (parity) { + case 'e': + cflag |= PARENB; + break; + case 'o': + cflag |= PARODD; + break; + } + + bit = simple_strtoul(buf, &buf, 10); + switch (bit) { + case 5: + cflag |= CS5; + break; + case 6: + cflag |= CS5; + break; + case 7: + cflag |= CS5; + break; + default: + cflag |= CS8; + } + +#ifdef CONFIG_SERIAL_BFIN + return bfin_earlyserial_init(serial_port, cflag); +#else + return NULL; +#endif + +} +#endif + +int __init setup_early_printk(char *buf) +{ + + /* Crashing in here would be really bad, so check both the var + and the pointer before we start using it + */ + if (!buf) + return 0; + + if (!*buf) + return 0; + + if (early_console != NULL) + return 0; + +#ifdef CONFIG_SERIAL_BFIN + /* Check for Blackfin Serial */ + if (!strncmp(buf, "serial,uart", 11)) { + buf += 11; + early_console = earlyserial_init(buf); + } +#endif +#ifdef CONFIG_FB + /* TODO: add framebuffer console support */ +#endif + + if (likely(early_console)) { + early_console->flags |= CON_BOOT; + + register_console(early_console); + printk(KERN_INFO "early printk enabled on %s%d\n", + early_console->name, + early_console->index); + } + + return 0; +} + +early_param("earlyprintk", setup_early_printk); -- cgit v1.2.2