Path: blob/master/arch/blackfin/kernel/shadow_console.c
10817 views
/*1* manage a small early shadow of the log buffer which we can pass between the2* bootloader so early crash messages are communicated properly and easily3*4* Copyright 2009 Analog Devices Inc.5*6* Licensed under the GPL-2 or later.7*/89#include <linux/kernel.h>10#include <linux/init.h>11#include <linux/console.h>12#include <linux/string.h>13#include <asm/blackfin.h>14#include <asm/irq_handler.h>15#include <asm/early_printk.h>1617#define SHADOW_CONSOLE_START (0x500)18#define SHADOW_CONSOLE_END (0x1000)19#define SHADOW_CONSOLE_MAGIC_LOC (0x4F0)20#define SHADOW_CONSOLE_MAGIC (0xDEADBEEF)2122static __initdata char *shadow_console_buffer = (char *)SHADOW_CONSOLE_START;2324__init void early_shadow_write(struct console *con, const char *s,25unsigned int n)26{27unsigned int i;28/*29* save 2 bytes for the double null at the end30* once we fail on a long line, make sure we don't write a short line afterwards31*/32if ((shadow_console_buffer + n) <= (char *)(SHADOW_CONSOLE_END - 2)) {33/* can't use memcpy - it may not be relocated yet */34for (i = 0; i <= n; i++)35shadow_console_buffer[i] = s[i];36shadow_console_buffer += n;37shadow_console_buffer[0] = 0;38shadow_console_buffer[1] = 0;39} else40shadow_console_buffer = (char *)SHADOW_CONSOLE_END;41}4243static __initdata struct console early_shadow_console = {44.name = "early_shadow",45.write = early_shadow_write,46.flags = CON_BOOT | CON_PRINTBUFFER,47.index = -1,48.device = 0,49};5051__init int shadow_console_enabled(void)52{53return early_shadow_console.flags & CON_ENABLED;54}5556__init void mark_shadow_error(void)57{58int *loc = (int *)SHADOW_CONSOLE_MAGIC_LOC;59loc[0] = SHADOW_CONSOLE_MAGIC;60loc[1] = SHADOW_CONSOLE_START;61}6263__init void enable_shadow_console(void)64{65if (!shadow_console_enabled()) {66register_console(&early_shadow_console);67/* for now, assume things are going to fail */68mark_shadow_error();69}70}7172static __init int disable_shadow_console(void)73{74/*75* by the time pure_initcall runs, the standard console is enabled,76* and the early_console is off, so unset the magic numbers77* unregistering the console is taken care of in common code (See78* ./kernel/printk:disable_boot_consoles() )79*/80int *loc = (int *)SHADOW_CONSOLE_MAGIC_LOC;8182loc[0] = 0;8384return 0;85}86pure_initcall(disable_shadow_console);8788/*89* since we can't use printk, dump numbers (as hex), n = # bits90*/91__init void early_shadow_reg(unsigned long reg, unsigned int n)92{93/*94* can't use any "normal" kernel features, since thay95* may not be relocated to their execute address yet96*/97int i;98char ascii[11] = " 0x";99100n = n / 4;101reg = reg << ((8 - n) * 4);102n += 3;103104for (i = 3; i <= n ; i++) {105ascii[i] = hex_asc_lo(reg >> 28);106reg <<= 4;107}108early_shadow_write(NULL, ascii, n);109110}111112113