Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
shadow_console.c
Go to the documentation of this file.
1 /*
2  * manage a small early shadow of the log buffer which we can pass between the
3  * bootloader so early crash messages are communicated properly and easily
4  *
5  * Copyright 2009 Analog Devices Inc.
6  *
7  * Licensed under the GPL-2 or later.
8  */
9 
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/console.h>
13 #include <linux/string.h>
14 #include <asm/blackfin.h>
15 #include <asm/irq_handler.h>
16 #include <asm/early_printk.h>
17 
18 #define SHADOW_CONSOLE_START (CONFIG_PHY_RAM_BASE_ADDRESS + 0x500)
19 #define SHADOW_CONSOLE_END (CONFIG_PHY_RAM_BASE_ADDRESS + 0x1000)
20 #define SHADOW_CONSOLE_MAGIC_LOC (CONFIG_PHY_RAM_BASE_ADDRESS + 0x4F0)
21 #define SHADOW_CONSOLE_MAGIC (0xDEADBEEF)
22 
23 static __initdata char *shadow_console_buffer = (char *)SHADOW_CONSOLE_START;
24 
25 __init void early_shadow_write(struct console *con, const char *s,
26  unsigned int n)
27 {
28  unsigned int i;
29  /*
30  * save 2 bytes for the double null at the end
31  * once we fail on a long line, make sure we don't write a short line afterwards
32  */
33  if ((shadow_console_buffer + n) <= (char *)(SHADOW_CONSOLE_END - 2)) {
34  /* can't use memcpy - it may not be relocated yet */
35  for (i = 0; i <= n; i++)
36  shadow_console_buffer[i] = s[i];
37  shadow_console_buffer += n;
38  shadow_console_buffer[0] = 0;
39  shadow_console_buffer[1] = 0;
40  } else
41  shadow_console_buffer = (char *)SHADOW_CONSOLE_END;
42 }
43 
44 static __initdata struct console early_shadow_console = {
45  .name = "early_shadow",
46  .write = early_shadow_write,
47  .flags = CON_BOOT | CON_PRINTBUFFER,
48  .index = -1,
49  .device = 0,
50 };
51 
53 {
54  return early_shadow_console.flags & CON_ENABLED;
55 }
56 
58 {
59  int *loc = (int *)SHADOW_CONSOLE_MAGIC_LOC;
60  loc[0] = SHADOW_CONSOLE_MAGIC;
61  loc[1] = SHADOW_CONSOLE_START;
62 }
63 
65 {
66  if (!shadow_console_enabled()) {
67  register_console(&early_shadow_console);
68  /* for now, assume things are going to fail */
70  }
71 }
72 
73 static __init int disable_shadow_console(void)
74 {
75  /*
76  * by the time pure_initcall runs, the standard console is enabled,
77  * and the early_console is off, so unset the magic numbers
78  * unregistering the console is taken care of in common code (See
79  * ./kernel/printk:disable_boot_consoles() )
80  */
81  int *loc = (int *)SHADOW_CONSOLE_MAGIC_LOC;
82 
83  loc[0] = 0;
84 
85  return 0;
86 }
87 pure_initcall(disable_shadow_console);
88 
89 /*
90  * since we can't use printk, dump numbers (as hex), n = # bits
91  */
92 __init void early_shadow_reg(unsigned long reg, unsigned int n)
93 {
94  /*
95  * can't use any "normal" kernel features, since thay
96  * may not be relocated to their execute address yet
97  */
98  int i;
99  char ascii[11] = " 0x";
100 
101  n = n / 4;
102  reg = reg << ((8 - n) * 4);
103  n += 3;
104 
105  for (i = 3; i <= n ; i++) {
106  ascii[i] = hex_asc_lo(reg >> 28);
107  reg <<= 4;
108  }
109  early_shadow_write(NULL, ascii, n);
110 
111 }