0001
0002 #include <linux/console.h>
0003 #include <linux/kernel.h>
0004 #include <linux/init.h>
0005 #include <linux/string.h>
0006 #include <linux/screen_info.h>
0007 #include <linux/usb/ch9.h>
0008 #include <linux/pci_regs.h>
0009 #include <linux/pci_ids.h>
0010 #include <linux/errno.h>
0011 #include <linux/pgtable.h>
0012 #include <asm/io.h>
0013 #include <asm/processor.h>
0014 #include <asm/fcntl.h>
0015 #include <asm/setup.h>
0016 #include <xen/hvc-console.h>
0017 #include <asm/pci-direct.h>
0018 #include <asm/fixmap.h>
0019 #include <linux/usb/ehci_def.h>
0020 #include <linux/usb/xhci-dbgp.h>
0021 #include <asm/pci_x86.h>
0022
0023
0024 #define VGABASE (__ISA_IO_base + 0xb8000)
0025
0026 static int max_ypos = 25, max_xpos = 80;
0027 static int current_ypos = 25, current_xpos;
0028
0029 static void early_vga_write(struct console *con, const char *str, unsigned n)
0030 {
0031 char c;
0032 int i, k, j;
0033
0034 while ((c = *str++) != '\0' && n-- > 0) {
0035 if (current_ypos >= max_ypos) {
0036
0037 for (k = 1, j = 0; k < max_ypos; k++, j++) {
0038 for (i = 0; i < max_xpos; i++) {
0039 writew(readw(VGABASE+2*(max_xpos*k+i)),
0040 VGABASE + 2*(max_xpos*j + i));
0041 }
0042 }
0043 for (i = 0; i < max_xpos; i++)
0044 writew(0x720, VGABASE + 2*(max_xpos*j + i));
0045 current_ypos = max_ypos-1;
0046 }
0047 #ifdef CONFIG_KGDB_KDB
0048 if (c == '\b') {
0049 if (current_xpos > 0)
0050 current_xpos--;
0051 } else if (c == '\r') {
0052 current_xpos = 0;
0053 } else
0054 #endif
0055 if (c == '\n') {
0056 current_xpos = 0;
0057 current_ypos++;
0058 } else if (c != '\r') {
0059 writew(((0x7 << 8) | (unsigned short) c),
0060 VGABASE + 2*(max_xpos*current_ypos +
0061 current_xpos++));
0062 if (current_xpos >= max_xpos) {
0063 current_xpos = 0;
0064 current_ypos++;
0065 }
0066 }
0067 }
0068 }
0069
0070 static struct console early_vga_console = {
0071 .name = "earlyvga",
0072 .write = early_vga_write,
0073 .flags = CON_PRINTBUFFER,
0074 .index = -1,
0075 };
0076
0077
0078
0079 static unsigned long early_serial_base = 0x3f8;
0080
0081 #define XMTRDY 0x20
0082
0083 #define DLAB 0x80
0084
0085 #define TXR 0
0086 #define RXR 0
0087 #define IER 1
0088 #define IIR 2
0089 #define FCR 2
0090 #define LCR 3
0091 #define MCR 4
0092 #define LSR 5
0093 #define MSR 6
0094 #define DLL 0
0095 #define DLH 1
0096
0097 static unsigned int io_serial_in(unsigned long addr, int offset)
0098 {
0099 return inb(addr + offset);
0100 }
0101
0102 static void io_serial_out(unsigned long addr, int offset, int value)
0103 {
0104 outb(value, addr + offset);
0105 }
0106
0107 static unsigned int (*serial_in)(unsigned long addr, int offset) = io_serial_in;
0108 static void (*serial_out)(unsigned long addr, int offset, int value) = io_serial_out;
0109
0110 static int early_serial_putc(unsigned char ch)
0111 {
0112 unsigned timeout = 0xffff;
0113
0114 while ((serial_in(early_serial_base, LSR) & XMTRDY) == 0 && --timeout)
0115 cpu_relax();
0116 serial_out(early_serial_base, TXR, ch);
0117 return timeout ? 0 : -1;
0118 }
0119
0120 static void early_serial_write(struct console *con, const char *s, unsigned n)
0121 {
0122 while (*s && n-- > 0) {
0123 if (*s == '\n')
0124 early_serial_putc('\r');
0125 early_serial_putc(*s);
0126 s++;
0127 }
0128 }
0129
0130 static __init void early_serial_hw_init(unsigned divisor)
0131 {
0132 unsigned char c;
0133
0134 serial_out(early_serial_base, LCR, 0x3);
0135 serial_out(early_serial_base, IER, 0);
0136 serial_out(early_serial_base, FCR, 0);
0137 serial_out(early_serial_base, MCR, 0x3);
0138
0139 c = serial_in(early_serial_base, LCR);
0140 serial_out(early_serial_base, LCR, c | DLAB);
0141 serial_out(early_serial_base, DLL, divisor & 0xff);
0142 serial_out(early_serial_base, DLH, (divisor >> 8) & 0xff);
0143 serial_out(early_serial_base, LCR, c & ~DLAB);
0144 }
0145
0146 #define DEFAULT_BAUD 9600
0147
0148 static __init void early_serial_init(char *s)
0149 {
0150 unsigned divisor;
0151 unsigned long baud = DEFAULT_BAUD;
0152 char *e;
0153
0154 if (*s == ',')
0155 ++s;
0156
0157 if (*s) {
0158 unsigned port;
0159 if (!strncmp(s, "0x", 2)) {
0160 early_serial_base = simple_strtoul(s, &e, 16);
0161 } else {
0162 static const int __initconst bases[] = { 0x3f8, 0x2f8 };
0163
0164 if (!strncmp(s, "ttyS", 4))
0165 s += 4;
0166 port = simple_strtoul(s, &e, 10);
0167 if (port > 1 || s == e)
0168 port = 0;
0169 early_serial_base = bases[port];
0170 }
0171 s += strcspn(s, ",");
0172 if (*s == ',')
0173 s++;
0174 }
0175
0176 if (*s) {
0177 baud = simple_strtoull(s, &e, 0);
0178
0179 if (baud == 0 || s == e)
0180 baud = DEFAULT_BAUD;
0181 }
0182
0183
0184 divisor = 115200 / baud;
0185
0186
0187 serial_in = io_serial_in;
0188 serial_out = io_serial_out;
0189
0190
0191 early_serial_hw_init(divisor);
0192 }
0193
0194 #ifdef CONFIG_PCI
0195 static void mem32_serial_out(unsigned long addr, int offset, int value)
0196 {
0197 u32 __iomem *vaddr = (u32 __iomem *)addr;
0198
0199 writel(value, vaddr + offset);
0200 }
0201
0202 static unsigned int mem32_serial_in(unsigned long addr, int offset)
0203 {
0204 u32 __iomem *vaddr = (u32 __iomem *)addr;
0205
0206 return readl(vaddr + offset);
0207 }
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 static __init void early_pci_serial_init(char *s)
0218 {
0219 unsigned divisor;
0220 unsigned long baud = DEFAULT_BAUD;
0221 u8 bus, slot, func;
0222 u32 classcode, bar0;
0223 u16 cmdreg;
0224 char *e;
0225 int force = 0;
0226
0227 if (*s == ',')
0228 ++s;
0229
0230 if (*s == 0)
0231 return;
0232
0233
0234 if (!strncmp(s, "force,", 6)) {
0235 force = 1;
0236 s += 6;
0237 }
0238
0239
0240
0241
0242 bus = (u8)simple_strtoul(s, &e, 16);
0243 s = e;
0244 if (*s != ':')
0245 return;
0246 ++s;
0247 slot = (u8)simple_strtoul(s, &e, 16);
0248 s = e;
0249 if (*s != '.')
0250 return;
0251 ++s;
0252 func = (u8)simple_strtoul(s, &e, 16);
0253 s = e;
0254
0255
0256 if (*s == ',')
0257 s++;
0258
0259
0260
0261
0262 cmdreg = read_pci_config(bus, slot, func, PCI_COMMAND);
0263 classcode = read_pci_config(bus, slot, func, PCI_CLASS_REVISION);
0264 bar0 = read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0);
0265
0266
0267
0268
0269 if (((classcode >> 16 != PCI_CLASS_COMMUNICATION_MODEM) &&
0270 (classcode >> 16 != PCI_CLASS_COMMUNICATION_SERIAL)) ||
0271 (((classcode >> 8) & 0xff) != 0x02)) {
0272 if (!force)
0273 return;
0274 }
0275
0276
0277
0278
0279 if (bar0 & 0x01) {
0280
0281 serial_in = io_serial_in;
0282 serial_out = io_serial_out;
0283 early_serial_base = bar0&0xfffffffc;
0284 write_pci_config(bus, slot, func, PCI_COMMAND,
0285 cmdreg|PCI_COMMAND_IO);
0286 } else {
0287
0288 serial_in = mem32_serial_in;
0289 serial_out = mem32_serial_out;
0290
0291 early_serial_base =
0292 (unsigned long)early_ioremap(bar0 & 0xfffffff0, 0x10);
0293 write_pci_config(bus, slot, func, PCI_COMMAND,
0294 cmdreg|PCI_COMMAND_MEMORY);
0295 }
0296
0297
0298
0299
0300 if (*s) {
0301 if (strcmp(s, "nocfg") == 0)
0302
0303
0304
0305
0306
0307 return;
0308 if (kstrtoul(s, 0, &baud) < 0 || baud == 0)
0309 baud = DEFAULT_BAUD;
0310 }
0311
0312
0313 divisor = 115200 / baud;
0314
0315
0316 early_serial_hw_init(divisor);
0317 }
0318 #endif
0319
0320 static struct console early_serial_console = {
0321 .name = "earlyser",
0322 .write = early_serial_write,
0323 .flags = CON_PRINTBUFFER,
0324 .index = -1,
0325 };
0326
0327 static void early_console_register(struct console *con, int keep_early)
0328 {
0329 if (con->index != -1) {
0330 printk(KERN_CRIT "ERROR: earlyprintk= %s already used\n",
0331 con->name);
0332 return;
0333 }
0334 early_console = con;
0335 if (keep_early)
0336 early_console->flags &= ~CON_BOOT;
0337 else
0338 early_console->flags |= CON_BOOT;
0339 register_console(early_console);
0340 }
0341
0342 static int __init setup_early_printk(char *buf)
0343 {
0344 int keep;
0345
0346 if (!buf)
0347 return 0;
0348
0349 if (early_console)
0350 return 0;
0351
0352 keep = (strstr(buf, "keep") != NULL);
0353
0354 while (*buf != '\0') {
0355 if (!strncmp(buf, "serial", 6)) {
0356 buf += 6;
0357 early_serial_init(buf);
0358 early_console_register(&early_serial_console, keep);
0359 if (!strncmp(buf, ",ttyS", 5))
0360 buf += 5;
0361 }
0362 if (!strncmp(buf, "ttyS", 4)) {
0363 early_serial_init(buf + 4);
0364 early_console_register(&early_serial_console, keep);
0365 }
0366 #ifdef CONFIG_PCI
0367 if (!strncmp(buf, "pciserial", 9)) {
0368 early_pci_serial_init(buf + 9);
0369 early_console_register(&early_serial_console, keep);
0370 buf += 9;
0371 }
0372 #endif
0373 if (!strncmp(buf, "vga", 3) &&
0374 boot_params.screen_info.orig_video_isVGA == 1) {
0375 max_xpos = boot_params.screen_info.orig_video_cols;
0376 max_ypos = boot_params.screen_info.orig_video_lines;
0377 current_ypos = boot_params.screen_info.orig_y;
0378 early_console_register(&early_vga_console, keep);
0379 }
0380 #ifdef CONFIG_EARLY_PRINTK_DBGP
0381 if (!strncmp(buf, "dbgp", 4) && !early_dbgp_init(buf + 4))
0382 early_console_register(&early_dbgp_console, keep);
0383 #endif
0384 #ifdef CONFIG_HVC_XEN
0385 if (!strncmp(buf, "xen", 3))
0386 early_console_register(&xenboot_console, keep);
0387 #endif
0388 #ifdef CONFIG_EARLY_PRINTK_USB_XDBC
0389 if (!strncmp(buf, "xdbc", 4))
0390 early_xdbc_parse_parameter(buf + 4, keep);
0391 #endif
0392
0393 buf++;
0394 }
0395 return 0;
0396 }
0397
0398 early_param("earlyprintk", setup_early_printk);