ia64/xen-unstable
changeset 4924:630959a20980
bitkeeper revision 1.1159.282.1 (42886ca0o3TWunjlIeQALC1vadfg9g)
early_printk.c:
Add support for CONFIG_EARLY_PRINTK over Xen's serial console.
new file
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
early_printk.c:
Add support for CONFIG_EARLY_PRINTK over Xen's serial console.
new file
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author | cl349@firebug.cl.cam.ac.uk |
---|---|
date | Mon May 16 09:49:20 2005 +0000 (2005-05-16) |
parents | b3e15fadc1c1 |
children | d0a4a77aa98f |
files | .rootkeys linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/early_printk.c |
line diff
1.1 --- a/.rootkeys Sat May 14 10:14:54 2005 +0000 1.2 +++ b/.rootkeys Mon May 16 09:49:20 2005 +0000 1.3 @@ -249,6 +249,7 @@ 4110f478aeQWllIN7J4kouAHiAqrPw linux-2.6 1.4 40f562392LBhwmOxVPsYdkYXMxI_ZQ linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c 1.5 414c113396tK1HTVeUalm3u-1DF16g linux-2.6.11-xen-sparse/arch/xen/kernel/skbuff.c 1.6 3f68905c5eiA-lBMQSvXLMWS1ikDEA linux-2.6.11-xen-sparse/arch/xen/kernel/xen_proc.c 1.7 +428868bbQust_FkSdkerMqYBWfrVKg linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/early_printk.c 1.8 41261688yS8eAyy-7kzG4KBs0xbYCA linux-2.6.11-xen-sparse/drivers/Makefile 1.9 4108f5c1WfTIrs0HZFeV39sttekCTw linux-2.6.11-xen-sparse/drivers/char/mem.c 1.10 4111308bZAIzwf_Kzu6x1TZYZ3E0_Q linux-2.6.11-xen-sparse/drivers/char/tty_io.c
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/early_printk.c Mon May 16 09:49:20 2005 +0000 2.3 @@ -0,0 +1,242 @@ 2.4 +#include <linux/config.h> 2.5 +#include <linux/console.h> 2.6 +#include <linux/kernel.h> 2.7 +#include <linux/init.h> 2.8 +#include <linux/string.h> 2.9 +#include <asm/io.h> 2.10 +#include <asm/processor.h> 2.11 + 2.12 +/* Simple VGA output */ 2.13 + 2.14 +#ifdef __i386__ 2.15 +#define VGABASE (__ISA_IO_base + 0xb8000) 2.16 +#else 2.17 +#define VGABASE ((void __iomem *)0xffffffff800b8000UL) 2.18 +#endif 2.19 + 2.20 +#define MAX_YPOS 25 2.21 +#define MAX_XPOS 80 2.22 + 2.23 +static int current_ypos = 1, current_xpos = 0; 2.24 + 2.25 +static void early_vga_write(struct console *con, const char *str, unsigned n) 2.26 +{ 2.27 + char c; 2.28 + int i, k, j; 2.29 + 2.30 + while ((c = *str++) != '\0' && n-- > 0) { 2.31 + if (current_ypos >= MAX_YPOS) { 2.32 + /* scroll 1 line up */ 2.33 + for (k = 1, j = 0; k < MAX_YPOS; k++, j++) { 2.34 + for (i = 0; i < MAX_XPOS; i++) { 2.35 + writew(readw(VGABASE + 2*(MAX_XPOS*k + i)), 2.36 + VGABASE + 2*(MAX_XPOS*j + i)); 2.37 + } 2.38 + } 2.39 + for (i = 0; i < MAX_XPOS; i++) 2.40 + writew(0x720, VGABASE + 2*(MAX_XPOS*j + i)); 2.41 + current_ypos = MAX_YPOS-1; 2.42 + } 2.43 + if (c == '\n') { 2.44 + current_xpos = 0; 2.45 + current_ypos++; 2.46 + } else if (c != '\r') { 2.47 + writew(((0x7 << 8) | (unsigned short) c), 2.48 + VGABASE + 2*(MAX_XPOS*current_ypos + 2.49 + current_xpos++)); 2.50 + if (current_xpos >= MAX_XPOS) { 2.51 + current_xpos = 0; 2.52 + current_ypos++; 2.53 + } 2.54 + } 2.55 + } 2.56 +} 2.57 + 2.58 +static struct console early_vga_console = { 2.59 + .name = "earlyvga", 2.60 + .write = early_vga_write, 2.61 + .flags = CON_PRINTBUFFER, 2.62 + .index = -1, 2.63 +}; 2.64 + 2.65 +#ifndef CONFIG_XEN 2.66 +/* Serial functions loosely based on a similar package from Klaus P. Gerlicher */ 2.67 + 2.68 +int early_serial_base = 0x3f8; /* ttyS0 */ 2.69 + 2.70 +#define XMTRDY 0x20 2.71 + 2.72 +#define DLAB 0x80 2.73 + 2.74 +#define TXR 0 /* Transmit register (WRITE) */ 2.75 +#define RXR 0 /* Receive register (READ) */ 2.76 +#define IER 1 /* Interrupt Enable */ 2.77 +#define IIR 2 /* Interrupt ID */ 2.78 +#define FCR 2 /* FIFO control */ 2.79 +#define LCR 3 /* Line control */ 2.80 +#define MCR 4 /* Modem control */ 2.81 +#define LSR 5 /* Line Status */ 2.82 +#define MSR 6 /* Modem Status */ 2.83 +#define DLL 0 /* Divisor Latch Low */ 2.84 +#define DLH 1 /* Divisor latch High */ 2.85 + 2.86 +static int early_serial_putc(unsigned char ch) 2.87 +{ 2.88 + unsigned timeout = 0xffff; 2.89 + while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout) 2.90 + cpu_relax(); 2.91 + outb(ch, early_serial_base + TXR); 2.92 + return timeout ? 0 : -1; 2.93 +} 2.94 + 2.95 +static void early_serial_write(struct console *con, const char *s, unsigned n) 2.96 +{ 2.97 + while (*s && n-- > 0) { 2.98 + early_serial_putc(*s); 2.99 + if (*s == '\n') 2.100 + early_serial_putc('\r'); 2.101 + s++; 2.102 + } 2.103 +} 2.104 + 2.105 +#define DEFAULT_BAUD 9600 2.106 + 2.107 +static __init void early_serial_init(char *s) 2.108 +{ 2.109 + unsigned char c; 2.110 + unsigned divisor; 2.111 + unsigned baud = DEFAULT_BAUD; 2.112 + char *e; 2.113 + 2.114 + if (*s == ',') 2.115 + ++s; 2.116 + 2.117 + if (*s) { 2.118 + unsigned port; 2.119 + if (!strncmp(s,"0x",2)) { 2.120 + early_serial_base = simple_strtoul(s, &e, 16); 2.121 + } else { 2.122 + static int bases[] = { 0x3f8, 0x2f8 }; 2.123 + 2.124 + if (!strncmp(s,"ttyS",4)) 2.125 + s += 4; 2.126 + port = simple_strtoul(s, &e, 10); 2.127 + if (port > 1 || s == e) 2.128 + port = 0; 2.129 + early_serial_base = bases[port]; 2.130 + } 2.131 + s += strcspn(s, ","); 2.132 + if (*s == ',') 2.133 + s++; 2.134 + } 2.135 + 2.136 + outb(0x3, early_serial_base + LCR); /* 8n1 */ 2.137 + outb(0, early_serial_base + IER); /* no interrupt */ 2.138 + outb(0, early_serial_base + FCR); /* no fifo */ 2.139 + outb(0x3, early_serial_base + MCR); /* DTR + RTS */ 2.140 + 2.141 + if (*s) { 2.142 + baud = simple_strtoul(s, &e, 0); 2.143 + if (baud == 0 || s == e) 2.144 + baud = DEFAULT_BAUD; 2.145 + } 2.146 + 2.147 + divisor = 115200 / baud; 2.148 + c = inb(early_serial_base + LCR); 2.149 + outb(c | DLAB, early_serial_base + LCR); 2.150 + outb(divisor & 0xff, early_serial_base + DLL); 2.151 + outb((divisor >> 8) & 0xff, early_serial_base + DLH); 2.152 + outb(c & ~DLAB, early_serial_base + LCR); 2.153 +} 2.154 +#else 2.155 + 2.156 +static void 2.157 +early_serial_write(struct console *con, const char *s, unsigned count) 2.158 +{ 2.159 + int n; 2.160 + 2.161 + while (count > 0) { 2.162 + n = HYPERVISOR_console_io(CONSOLEIO_write, count, (char *)s); 2.163 + if (n <= 0) 2.164 + break; 2.165 + count -= n; 2.166 + s += n; 2.167 + } 2.168 +} 2.169 + 2.170 +static __init void early_serial_init(char *s) 2.171 +{ 2.172 +} 2.173 +#endif 2.174 + 2.175 +static struct console early_serial_console = { 2.176 + .name = "earlyser", 2.177 + .write = early_serial_write, 2.178 + .flags = CON_PRINTBUFFER, 2.179 + .index = -1, 2.180 +}; 2.181 + 2.182 +/* Direct interface for emergencies */ 2.183 +struct console *early_console = &early_vga_console; 2.184 +static int early_console_initialized = 0; 2.185 + 2.186 +void early_printk(const char *fmt, ...) 2.187 +{ 2.188 + char buf[512]; 2.189 + int n; 2.190 + va_list ap; 2.191 + 2.192 + va_start(ap,fmt); 2.193 + n = vscnprintf(buf,512,fmt,ap); 2.194 + early_console->write(early_console,buf,n); 2.195 + va_end(ap); 2.196 +} 2.197 + 2.198 +static int keep_early; 2.199 + 2.200 +int __init setup_early_printk(char *opt) 2.201 +{ 2.202 + char *space; 2.203 + char buf[256]; 2.204 + 2.205 + if (early_console_initialized) 2.206 + return -1; 2.207 + 2.208 + opt = strchr(opt, '=') + 1; 2.209 + 2.210 + strlcpy(buf,opt,sizeof(buf)); 2.211 + space = strchr(buf, ' '); 2.212 + if (space) 2.213 + *space = 0; 2.214 + 2.215 + if (strstr(buf,"keep")) 2.216 + keep_early = 1; 2.217 + 2.218 + if (!strncmp(buf, "serial", 6)) { 2.219 + early_serial_init(buf + 6); 2.220 + early_console = &early_serial_console; 2.221 + } else if (!strncmp(buf, "ttyS", 4)) { 2.222 + early_serial_init(buf); 2.223 + early_console = &early_serial_console; 2.224 + } else if (!strncmp(buf, "vga", 3)) { 2.225 + early_console = &early_vga_console; 2.226 + } 2.227 + early_console_initialized = 1; 2.228 + register_console(early_console); 2.229 + return 0; 2.230 +} 2.231 + 2.232 +void __init disable_early_printk(void) 2.233 +{ 2.234 + if (!early_console_initialized || !early_console) 2.235 + return; 2.236 + if (!keep_early) { 2.237 + printk("disabling early console\n"); 2.238 + unregister_console(early_console); 2.239 + early_console_initialized = 0; 2.240 + } else { 2.241 + printk("keeping early console\n"); 2.242 + } 2.243 +} 2.244 + 2.245 +__setup("earlyprintk=", setup_early_printk);