1#include <linux/console.h> 2#include <linux/kernel.h> 3#include <linux/init.h> 4#include <linux/string.h> 5#include <linux/screen_info.h> 6#include <linux/usb/ch9.h> 7#include <linux/pci_regs.h> 8#include <linux/pci_ids.h> 9#include <linux/errno.h> 10#include <asm/io.h> 11#include <asm/processor.h> 12#include <asm/fcntl.h> 13#include <asm/setup.h> 14#include <xen/hvc-console.h> 15#include <asm/pci-direct.h> 16#include <asm/fixmap.h> 17#include <asm/intel-mid.h> 18#include <asm/pgtable.h> 19#include <linux/usb/ehci_def.h> 20#include <linux/efi.h> 21#include <asm/efi.h> 22#include <asm/pci_x86.h> 23 24/* Simple VGA output */ 25#define VGABASE (__ISA_IO_base + 0xb8000) 26 27static int max_ypos = 25, max_xpos = 80; 28static int current_ypos = 25, current_xpos; 29 30static void early_vga_write(struct console *con, const char *str, unsigned n) 31{ 32 char c; 33 int i, k, j; 34 35 while ((c = *str++) != '\0' && n-- > 0) { 36 if (current_ypos >= max_ypos) { 37 /* scroll 1 line up */ 38 for (k = 1, j = 0; k < max_ypos; k++, j++) { 39 for (i = 0; i < max_xpos; i++) { 40 writew(readw(VGABASE+2*(max_xpos*k+i)), 41 VGABASE + 2*(max_xpos*j + i)); 42 } 43 } 44 for (i = 0; i < max_xpos; i++) 45 writew(0x720, VGABASE + 2*(max_xpos*j + i)); 46 current_ypos = max_ypos-1; 47 } 48#ifdef CONFIG_KGDB_KDB 49 if (c == '\b') { 50 if (current_xpos > 0) 51 current_xpos--; 52 } else if (c == '\r') { 53 current_xpos = 0; 54 } else 55#endif 56 if (c == '\n') { 57 current_xpos = 0; 58 current_ypos++; 59 } else if (c != '\r') { 60 writew(((0x7 << 8) | (unsigned short) c), 61 VGABASE + 2*(max_xpos*current_ypos + 62 current_xpos++)); 63 if (current_xpos >= max_xpos) { 64 current_xpos = 0; 65 current_ypos++; 66 } 67 } 68 } 69} 70 71static struct console early_vga_console = { 72 .name = "earlyvga", 73 .write = early_vga_write, 74 .flags = CON_PRINTBUFFER, 75 .index = -1, 76}; 77 78/* Serial functions loosely based on a similar package from Klaus P. Gerlicher */ 79 80static unsigned long early_serial_base = 0x3f8; /* ttyS0 */ 81 82#define XMTRDY 0x20 83 84#define DLAB 0x80 85 86#define TXR 0 /* Transmit register (WRITE) */ 87#define RXR 0 /* Receive register (READ) */ 88#define IER 1 /* Interrupt Enable */ 89#define IIR 2 /* Interrupt ID */ 90#define FCR 2 /* FIFO control */ 91#define LCR 3 /* Line control */ 92#define MCR 4 /* Modem control */ 93#define LSR 5 /* Line Status */ 94#define MSR 6 /* Modem Status */ 95#define DLL 0 /* Divisor Latch Low */ 96#define DLH 1 /* Divisor latch High */ 97 98static unsigned int io_serial_in(unsigned long addr, int offset) 99{ 100 return inb(addr + offset); 101} 102 103static void io_serial_out(unsigned long addr, int offset, int value) 104{ 105 outb(value, addr + offset); 106} 107 108static unsigned int (*serial_in)(unsigned long addr, int offset) = io_serial_in; 109static void (*serial_out)(unsigned long addr, int offset, int value) = io_serial_out; 110 111static int early_serial_putc(unsigned char ch) 112{ 113 unsigned timeout = 0xffff; 114 115 while ((serial_in(early_serial_base, LSR) & XMTRDY) == 0 && --timeout) 116 cpu_relax(); 117 serial_out(early_serial_base, TXR, ch); 118 return timeout ? 0 : -1; 119} 120 121static void early_serial_write(struct console *con, const char *s, unsigned n) 122{ 123 while (*s && n-- > 0) { 124 if (*s == '\n') 125 early_serial_putc('\r'); 126 early_serial_putc(*s); 127 s++; 128 } 129} 130 131static __init void early_serial_hw_init(unsigned divisor) 132{ 133 unsigned char c; 134 135 serial_out(early_serial_base, LCR, 0x3); /* 8n1 */ 136 serial_out(early_serial_base, IER, 0); /* no interrupt */ 137 serial_out(early_serial_base, FCR, 0); /* no fifo */ 138 serial_out(early_serial_base, MCR, 0x3); /* DTR + RTS */ 139 140 c = serial_in(early_serial_base, LCR); 141 serial_out(early_serial_base, LCR, c | DLAB); 142 serial_out(early_serial_base, DLL, divisor & 0xff); 143 serial_out(early_serial_base, DLH, (divisor >> 8) & 0xff); 144 serial_out(early_serial_base, LCR, c & ~DLAB); 145} 146 147#define DEFAULT_BAUD 9600 148 149static __init void early_serial_init(char *s) 150{ 151 unsigned divisor; 152 unsigned long baud = DEFAULT_BAUD; 153 char *e; 154 155 if (*s == ',') 156 ++s; 157 158 if (*s) { 159 unsigned port; 160 if (!strncmp(s, "0x", 2)) { 161 early_serial_base = simple_strtoul(s, &e, 16); 162 } else { 163 static const int __initconst bases[] = { 0x3f8, 0x2f8 }; 164 165 if (!strncmp(s, "ttyS", 4)) 166 s += 4; 167 port = simple_strtoul(s, &e, 10); 168 if (port > 1 || s == e) 169 port = 0; 170 early_serial_base = bases[port]; 171 } 172 s += strcspn(s, ","); 173 if (*s == ',') 174 s++; 175 } 176 177 if (*s) { 178 baud = simple_strtoull(s, &e, 0); 179 180 if (baud == 0 || s == e) 181 baud = DEFAULT_BAUD; 182 } 183 184 /* Convert from baud to divisor value */ 185 divisor = 115200 / baud; 186 187 /* These will always be IO based ports */ 188 serial_in = io_serial_in; 189 serial_out = io_serial_out; 190 191 /* Set up the HW */ 192 early_serial_hw_init(divisor); 193} 194 195#ifdef CONFIG_PCI 196static void mem32_serial_out(unsigned long addr, int offset, int value) 197{ 198 u32 __iomem *vaddr = (u32 __iomem *)addr; 199 /* shift implied by pointer type */ 200 writel(value, vaddr + offset); 201} 202 203static unsigned int mem32_serial_in(unsigned long addr, int offset) 204{ 205 u32 __iomem *vaddr = (u32 __iomem *)addr; 206 /* shift implied by pointer type */ 207 return readl(vaddr + offset); 208} 209 210/* 211 * early_pci_serial_init() 212 * 213 * This function is invoked when the early_printk param starts with "pciserial" 214 * The rest of the param should be ",B:D.F,baud" where B, D & F describe the 215 * location of a PCI device that must be a UART device. 216 */ 217static __init void early_pci_serial_init(char *s) 218{ 219 unsigned divisor; 220 unsigned long baud = DEFAULT_BAUD; 221 u8 bus, slot, func; 222 u32 classcode, bar0; 223 u16 cmdreg; 224 char *e; 225 226 227 /* 228 * First, part the param to get the BDF values 229 */ 230 if (*s == ',') 231 ++s; 232 233 if (*s == 0) 234 return; 235 236 bus = (u8)simple_strtoul(s, &e, 16); 237 s = e; 238 if (*s != ':') 239 return; 240 ++s; 241 slot = (u8)simple_strtoul(s, &e, 16); 242 s = e; 243 if (*s != '.') 244 return; 245 ++s; 246 func = (u8)simple_strtoul(s, &e, 16); 247 s = e; 248 249 /* A baud might be following */ 250 if (*s == ',') 251 s++; 252 253 /* 254 * Second, find the device from the BDF 255 */ 256 cmdreg = read_pci_config(bus, slot, func, PCI_COMMAND); 257 classcode = read_pci_config(bus, slot, func, PCI_CLASS_REVISION); 258 bar0 = read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0); 259 260 /* 261 * Verify it is a UART type device 262 */ 263 if (((classcode >> 16 != PCI_CLASS_COMMUNICATION_MODEM) && 264 (classcode >> 16 != PCI_CLASS_COMMUNICATION_SERIAL)) || 265 (((classcode >> 8) & 0xff) != 0x02)) /* 16550 I/F at BAR0 */ 266 return; 267 268 /* 269 * Determine if it is IO or memory mapped 270 */ 271 if (bar0 & 0x01) { 272 /* it is IO mapped */ 273 serial_in = io_serial_in; 274 serial_out = io_serial_out; 275 early_serial_base = bar0&0xfffffffc; 276 write_pci_config(bus, slot, func, PCI_COMMAND, 277 cmdreg|PCI_COMMAND_IO); 278 } else { 279 /* It is memory mapped - assume 32-bit alignment */ 280 serial_in = mem32_serial_in; 281 serial_out = mem32_serial_out; 282 /* WARNING! assuming the address is always in the first 4G */ 283 early_serial_base = 284 (unsigned long)early_ioremap(bar0 & 0xfffffff0, 0x10); 285 write_pci_config(bus, slot, func, PCI_COMMAND, 286 cmdreg|PCI_COMMAND_MEMORY); 287 } 288 289 /* 290 * Lastly, initalize the hardware 291 */ 292 if (*s) { 293 if (strcmp(s, "nocfg") == 0) 294 /* Sometimes, we want to leave the UART alone 295 * and assume the BIOS has set it up correctly. 296 * "nocfg" tells us this is the case, and we 297 * should do no more setup. 298 */ 299 return; 300 if (kstrtoul(s, 0, &baud) < 0 || baud == 0) 301 baud = DEFAULT_BAUD; 302 } 303 304 /* Convert from baud to divisor value */ 305 divisor = 115200 / baud; 306 307 /* Set up the HW */ 308 early_serial_hw_init(divisor); 309} 310#endif 311 312static struct console early_serial_console = { 313 .name = "earlyser", 314 .write = early_serial_write, 315 .flags = CON_PRINTBUFFER, 316 .index = -1, 317}; 318 319static void early_console_register(struct console *con, int keep_early) 320{ 321 if (con->index != -1) { 322 printk(KERN_CRIT "ERROR: earlyprintk= %s already used\n", 323 con->name); 324 return; 325 } 326 early_console = con; 327 if (keep_early) 328 early_console->flags &= ~CON_BOOT; 329 else 330 early_console->flags |= CON_BOOT; 331 register_console(early_console); 332} 333 334static int __init setup_early_printk(char *buf) 335{ 336 int keep; 337 338 if (!buf) 339 return 0; 340 341 if (early_console) 342 return 0; 343 344 keep = (strstr(buf, "keep") != NULL); 345 346 while (*buf != '\0') { 347 if (!strncmp(buf, "serial", 6)) { 348 buf += 6; 349 early_serial_init(buf); 350 early_console_register(&early_serial_console, keep); 351 if (!strncmp(buf, ",ttyS", 5)) 352 buf += 5; 353 } 354 if (!strncmp(buf, "ttyS", 4)) { 355 early_serial_init(buf + 4); 356 early_console_register(&early_serial_console, keep); 357 } 358#ifdef CONFIG_PCI 359 if (!strncmp(buf, "pciserial", 9)) { 360 early_pci_serial_init(buf + 9); 361 early_console_register(&early_serial_console, keep); 362 buf += 9; /* Keep from match the above "serial" */ 363 } 364#endif 365 if (!strncmp(buf, "vga", 3) && 366 boot_params.screen_info.orig_video_isVGA == 1) { 367 max_xpos = boot_params.screen_info.orig_video_cols; 368 max_ypos = boot_params.screen_info.orig_video_lines; 369 current_ypos = boot_params.screen_info.orig_y; 370 early_console_register(&early_vga_console, keep); 371 } 372#ifdef CONFIG_EARLY_PRINTK_DBGP 373 if (!strncmp(buf, "dbgp", 4) && !early_dbgp_init(buf + 4)) 374 early_console_register(&early_dbgp_console, keep); 375#endif 376#ifdef CONFIG_HVC_XEN 377 if (!strncmp(buf, "xen", 3)) 378 early_console_register(&xenboot_console, keep); 379#endif 380#ifdef CONFIG_EARLY_PRINTK_EFI 381 if (!strncmp(buf, "efi", 3)) 382 early_console_register(&early_efi_console, keep); 383#endif 384 385 buf++; 386 } 387 return 0; 388} 389 390early_param("earlyprintk", setup_early_printk); 391