diff options
author | Frederic Weisbecker <fweisbec@gmail.com> | 2009-10-18 01:09:09 +0200 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2009-10-18 01:12:33 +0200 |
commit | 0f8f86c7bdd1c954fbe153af437a0d91a6c5721a (patch) | |
tree | 94a8d419a470a4f9852ca397bb9bbe48db92ff5c /arch/blackfin/kernel/shadow_console.c | |
parent | Merge branch 'linus' into tracing/hw-breakpoints (diff) | |
parent | perf tools: Move dereference after NULL test (diff) | |
download | linux-dev-0f8f86c7bdd1c954fbe153af437a0d91a6c5721a.tar.xz linux-dev-0f8f86c7bdd1c954fbe153af437a0d91a6c5721a.zip |
Merge commit 'perf/core' into perf/hw-breakpoint
Conflicts:
kernel/Makefile
kernel/trace/Makefile
kernel/trace/trace.h
samples/Makefile
Merge reason: We need to be uptodate with the perf events development
branch because we plan to rewrite the breakpoints API on top of
perf events.
Diffstat (limited to 'arch/blackfin/kernel/shadow_console.c')
-rw-r--r-- | arch/blackfin/kernel/shadow_console.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/arch/blackfin/kernel/shadow_console.c b/arch/blackfin/kernel/shadow_console.c new file mode 100644 index 000000000000..557e9fef406a --- /dev/null +++ b/arch/blackfin/kernel/shadow_console.c @@ -0,0 +1,111 @@ +/* + * manage a small early shadow of the log buffer which we can pass between the + * bootloader so early crash messages are communicated properly and easily + * + * Copyright 2009 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/string.h> +#include <asm/blackfin.h> +#include <asm/irq_handler.h> +#include <asm/early_printk.h> + +#define SHADOW_CONSOLE_START (0x500) +#define SHADOW_CONSOLE_END (0x1000) +#define SHADOW_CONSOLE_MAGIC_LOC (0x4F0) +#define SHADOW_CONSOLE_MAGIC (0xDEADBEEF) + +static __initdata char *shadow_console_buffer = (char *)SHADOW_CONSOLE_START; + +__init void early_shadow_write(struct console *con, const char *s, + unsigned int n) +{ + unsigned int i; + /* + * save 2 bytes for the double null at the end + * once we fail on a long line, make sure we don't write a short line afterwards + */ + if ((shadow_console_buffer + n) <= (char *)(SHADOW_CONSOLE_END - 2)) { + /* can't use memcpy - it may not be relocated yet */ + for (i = 0; i <= n; i++) + shadow_console_buffer[i] = s[i]; + shadow_console_buffer += n; + shadow_console_buffer[0] = 0; + shadow_console_buffer[1] = 0; + } else + shadow_console_buffer = (char *)SHADOW_CONSOLE_END; +} + +static __initdata struct console early_shadow_console = { + .name = "early_shadow", + .write = early_shadow_write, + .flags = CON_BOOT | CON_PRINTBUFFER, + .index = -1, + .device = 0, +}; + +__init int shadow_console_enabled(void) +{ + return early_shadow_console.flags & CON_ENABLED; +} + +__init void mark_shadow_error(void) +{ + int *loc = (int *)SHADOW_CONSOLE_MAGIC_LOC; + loc[0] = SHADOW_CONSOLE_MAGIC; + loc[1] = SHADOW_CONSOLE_START; +} + +__init void enable_shadow_console(void) +{ + if (!shadow_console_enabled()) { + register_console(&early_shadow_console); + /* for now, assume things are going to fail */ + mark_shadow_error(); + } +} + +static __init int disable_shadow_console(void) +{ + /* + * by the time pure_initcall runs, the standard console is enabled, + * and the early_console is off, so unset the magic numbers + * unregistering the console is taken care of in common code (See + * ./kernel/printk:disable_boot_consoles() ) + */ + int *loc = (int *)SHADOW_CONSOLE_MAGIC_LOC; + + loc[0] = 0; + + return 0; +} +pure_initcall(disable_shadow_console); + +/* + * since we can't use printk, dump numbers (as hex), n = # bits + */ +__init void early_shadow_reg(unsigned long reg, unsigned int n) +{ + /* + * can't use any "normal" kernel features, since thay + * may not be relocated to their execute address yet + */ + int i; + char ascii[11] = " 0x"; + + n = n / 4; + reg = reg << ((8 - n) * 4); + n += 3; + + for (i = 3; i <= n ; i++) { + ascii[i] = hex_asc_lo(reg >> 28); + reg <<= 4; + } + early_shadow_write(NULL, ascii, n); + +} |