Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/blackfin/kernel/shadow_console.c
10817 views
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 (0x500)
19
#define SHADOW_CONSOLE_END (0x1000)
20
#define SHADOW_CONSOLE_MAGIC_LOC (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
52
__init int shadow_console_enabled(void)
53
{
54
return early_shadow_console.flags & CON_ENABLED;
55
}
56
57
__init void mark_shadow_error(void)
58
{
59
int *loc = (int *)SHADOW_CONSOLE_MAGIC_LOC;
60
loc[0] = SHADOW_CONSOLE_MAGIC;
61
loc[1] = SHADOW_CONSOLE_START;
62
}
63
64
__init void enable_shadow_console(void)
65
{
66
if (!shadow_console_enabled()) {
67
register_console(&early_shadow_console);
68
/* for now, assume things are going to fail */
69
mark_shadow_error();
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
}
112
113