1// Copyright 2016 The Fuchsia Authors 2// Copyright (c) 2009 Corey Tabaka 3// 4// Use of this source code is governed by a MIT-style 5// license that can be found in the LICENSE file or at 6// https://opensource.org/licenses/MIT 7 8#include <arch/x86.h> 9#include <arch/x86/apic.h> 10#include <bits.h> 11#include <dev/interrupt.h> 12#include <kernel/cmdline.h> 13#include <kernel/spinlock.h> 14#include <kernel/thread.h> 15#include <kernel/timer.h> 16#include <lib/cbuf.h> 17#include <lib/debuglog.h> 18#include <lk/init.h> 19#include <platform.h> 20#include <platform/console.h> 21#include <platform/debug.h> 22#include <platform/pc.h> 23#include <platform/pc/bootloader.h> 24#include <reg.h> 25#include <stdarg.h> 26#include <stdio.h> 27#include <stdlib.h> 28#include <string.h> 29#include <trace.h> 30#include <vm/physmap.h> 31#include <zircon/time.h> 32#include <zircon/types.h> 33 34#include "platform_p.h" 35 36static const int uart_baud_rate = 115200; 37static int uart_io_port = 0x3f8; 38static uint64_t uart_mem_addr = 0; 39static uint32_t uart_irq = ISA_IRQ_SERIAL1; 40 41cbuf_t console_input_buf; 42static bool output_enabled = false; 43uint32_t uart_fifo_depth; 44 45// tx driven irq 46static bool uart_tx_irq_enabled = false; 47static event_t uart_dputc_event = EVENT_INITIAL_VALUE(uart_dputc_event, true, 48 EVENT_FLAG_AUTOUNSIGNAL); 49static spin_lock_t uart_spinlock = SPIN_LOCK_INITIAL_VALUE; 50 51static uint8_t uart_read(uint8_t reg) { 52 if (uart_mem_addr) { 53 return (uint8_t)readl(uart_mem_addr + 4 * reg); 54 } else { 55 return (uint8_t)inp((uint16_t)(uart_io_port + reg)); 56 } 57} 58 59static void uart_write(uint8_t reg, uint8_t val) { 60 if (uart_mem_addr) { 61 writel(val, uart_mem_addr + 4 * reg); 62 } else { 63 outp((uint16_t)(uart_io_port + reg), val); 64 } 65} 66 67static void uart_irq_handler(void *arg) { 68 spin_lock(&uart_spinlock); 69 70 // see why we have gotten an irq 71 for (;;) { 72 uint8_t iir = uart_read(2); 73 if (BIT(iir, 0)) 74 break; // no valid interrupt 75 76 // 3 bit identification field 77 uint ident = BITS(iir, 3, 0); 78 switch (ident) { 79 case 0b0100: 80 case 0b1100: { 81 // rx fifo is non empty, drain it 82 unsigned char c = uart_read(0); 83 cbuf_write_char(&console_input_buf, c); 84 break; 85 } 86 case 0b0010: 87 // transmitter is empty, signal any waiting senders 88 event_signal(&uart_dputc_event, true); 89 // disable the tx irq 90 uart_write(1, (1<<0)); // just rx interrupt enable 91 break; 92 case 0b0110: // receiver line status 93 uart_read(5); // read the LSR 94 break; 95 default: 96 spin_unlock(&uart_spinlock); 97 panic("UART: unhandled ident %#x\n", ident); 98 } 99 } 100 101 spin_unlock(&uart_spinlock); 102} 103 104static void platform_drain_debug_uart_rx(void) { 105 while (uart_read(5) & (1<<0)) { 106 unsigned char c = uart_read(0); 107 cbuf_write_char(&console_input_buf, c); 108 } 109} 110 111// for devices where the uart rx interrupt doesn't seem to work 112static void uart_rx_poll(timer_t* t, zx_time_t now, void* arg) { 113 zx_time_t deadline = zx_time_add_duration(now, ZX_MSEC(10)); 114 timer_set(t, deadline, TIMER_SLACK_CENTER, ZX_MSEC(1), uart_rx_poll, NULL); 115 platform_drain_debug_uart_rx(); 116} 117 118void platform_debug_start_uart_timer(); 119 120void platform_debug_start_uart_timer(void) { 121 static timer_t uart_rx_poll_timer; 122 static bool started = false; 123 124 if (!started) { 125 started = true; 126 timer_init(&uart_rx_poll_timer); 127 timer_set(&uart_rx_poll_timer, zx_time_add_duration(current_time(), ZX_MSEC(10)), 128 TIMER_SLACK_CENTER, ZX_MSEC(1), uart_rx_poll, NULL); 129 } 130} 131 132static void init_uart() { 133 /* configure the uart */ 134 int divisor = 115200 / uart_baud_rate; 135 136 /* get basic config done so that tx functions */ 137 uart_write(1, 0); // mask all irqs 138 uart_write(3, 0x80); // set up to load divisor latch 139 uart_write(0, static_cast<uint8_t>(divisor)); // lsb 140 uart_write(1, static_cast<uint8_t>(divisor >> 8)); // msb 141 uart_write(3, 3); // 8N1 142 // enable FIFO, rx FIFO reset, tx FIFO reset, 16750 64 byte fifo enable, 143 // Rx FIFO irq trigger level at 14-bytes 144 uart_write(2, 0xe7); 145 // Drive flow control bits high since we don't actively manage them 146 uart_write(4, 0x3); 147 148 /* figure out the fifo depth */ 149 uint8_t fcr = uart_read(2); 150 if (BITS_SHIFT(fcr, 7, 6) == 3 && BIT(fcr, 5)) { 151 // this is a 16750 152 uart_fifo_depth = 64; 153 } else if (BITS_SHIFT(fcr, 7, 6) == 3) { 154 // this is a 16550A 155 uart_fifo_depth = 16; 156 } else { 157 uart_fifo_depth = 1; 158 } 159} 160 161bool platform_serial_enabled() { 162 return bootloader.uart.type != ZBI_UART_NONE; 163} 164 165// This just initializes the default serial console to be disabled. 166// It's in a function rather than just a compile-time assignment to the 167// bootloader structure because our C++ compiler doesn't support non-trivial 168// designated initializers. 169void pc_init_debug_default_early() { 170 bootloader.uart.type = ZBI_UART_NONE; 171} 172 173static void handle_serial_cmdline() { 174 const char* serial_mode = cmdline_get("kernel.serial"); 175 if (serial_mode == NULL) { 176 return; 177 } 178 if (!strcmp(serial_mode, "none")) { 179 bootloader.uart.type = ZBI_UART_NONE; 180 return; 181 } 182 if (!strcmp(serial_mode, "legacy")) { 183 bootloader.uart.type = ZBI_UART_PC_PORT; 184 bootloader.uart.base = 0x3f8; 185 bootloader.uart.irq = ISA_IRQ_SERIAL1; 186 return; 187 } 188 189 // type can be "ioport" or "mmio" 190 constexpr size_t kMaxTypeLen = 6 + 1; 191 char type_buf[kMaxTypeLen]; 192 // Addr can be up to 32 characters (numeric in any base strtoul will take), 193 // and + 1 for \0 194 constexpr size_t kMaxAddrLen = 32 + 1; 195 char addr_buf[kMaxAddrLen]; 196 197 char* endptr; 198 const char* addr_start; 199 const char* irq_start; 200 size_t addr_len, type_len; 201 unsigned long irq_val; 202 203 addr_start = strchr(serial_mode, ','); 204 if (addr_start == nullptr) { 205 goto bail; 206 } 207 addr_start++; 208 irq_start = strchr(addr_start, ','); 209 if (irq_start == nullptr) { 210 goto bail; 211 } 212 irq_start++; 213 214 // Parse out the type part 215 type_len = addr_start - serial_mode - 1; 216 if (type_len + 1 > kMaxTypeLen) { 217 goto bail; 218 } 219 memcpy(type_buf, serial_mode, type_len); 220 type_buf[type_len] = 0; 221 if (!strcmp(type_buf, "ioport")) { 222 bootloader.uart.type = ZBI_UART_PC_PORT; 223 } else if (!strcmp(type_buf, "mmio")) { 224 bootloader.uart.type = ZBI_UART_PC_MMIO; 225 } else { 226 goto bail; 227 } 228 229 // Parse out the address part 230 addr_len = irq_start - addr_start - 1; 231 if (addr_len + 1 > kMaxAddrLen) { 232 goto bail; 233 } 234 memcpy(addr_buf, addr_start, addr_len); 235 addr_buf[addr_len] = 0; 236 bootloader.uart.base = strtoul(addr_buf, &endptr, 0); 237 if (endptr != addr_buf + addr_len) { 238 goto bail; 239 } 240 241 // Parse out the IRQ part 242 irq_val = strtoul(irq_start, &endptr, 0); 243 if (*endptr != '\0' || irq_val > UINT32_MAX) { 244 goto bail; 245 } 246 // For now, we don't support non-ISA IRQs 247 if (irq_val >= NUM_ISA_IRQS) { 248 goto bail; 249 } 250 bootloader.uart.irq = static_cast<uint32_t>(irq_val); 251 return; 252 253bail: 254 bootloader.uart.type = ZBI_UART_NONE; 255 return; 256} 257 258void pc_init_debug_early() { 259 handle_serial_cmdline(); 260 261 switch (bootloader.uart.type) { 262 case ZBI_UART_PC_PORT: 263 uart_io_port = static_cast<uint32_t>(bootloader.uart.base); 264 uart_irq = bootloader.uart.irq; 265 break; 266 case ZBI_UART_PC_MMIO: 267 uart_mem_addr = (uint64_t)paddr_to_physmap(bootloader.uart.base); 268 uart_irq = bootloader.uart.irq; 269 break; 270 case ZBI_UART_NONE: // fallthrough 271 default: 272 bootloader.uart.type = ZBI_UART_NONE; 273 return; 274 } 275 276 init_uart(); 277 278 output_enabled = true; 279 280 dprintf(INFO, "UART: FIFO depth %u\n", uart_fifo_depth); 281} 282 283void pc_init_debug(void) { 284 bool tx_irq_driven = false; 285 /* finish uart init to get rx going */ 286 cbuf_initialize(&console_input_buf, 1024); 287 288 if (!platform_serial_enabled()) { 289 // Need to bail after initializing the input_buf to prevent unintialized 290 // access to it. 291 return; 292 } 293 294 if ((uart_irq == 0) || cmdline_get_bool("kernel.debug_uart_poll", false) || 295 dlog_bypass()) { 296 printf("debug-uart: polling enabled\n"); 297 platform_debug_start_uart_timer(); 298 } else { 299 uart_irq = apic_io_isa_to_global(static_cast<uint8_t>(uart_irq)); 300 zx_status_t status = register_int_handler(uart_irq, uart_irq_handler, NULL); 301 DEBUG_ASSERT(status == ZX_OK); 302 unmask_interrupt(uart_irq); 303 304 uart_write(1, (1<<0)); // enable receive data available interrupt 305 306 // modem control register: Axiliary Output 2 is another IRQ enable bit 307 const uint8_t mcr = uart_read(4); 308 uart_write(4, mcr | 0x8); 309 printf("UART: started IRQ driven RX\n"); 310 tx_irq_driven = true; 311 } 312 if (tx_irq_driven) { 313 // start up tx driven output 314 printf("UART: started IRQ driven TX\n"); 315 uart_tx_irq_enabled = true; 316 } 317} 318 319void pc_suspend_debug(void) { 320 output_enabled = false; 321} 322 323void pc_resume_debug(void) { 324 if (platform_serial_enabled()) { 325 init_uart(); 326 output_enabled = true; 327 } 328} 329 330/* 331 * This is called when the FIFO is detected to be empty. So we can write an 332 * entire FIFO's worth of bytes. Much more efficient than writing 1 byte 333 * at a time (and then checking for FIFO to drain). 334 */ 335static char *debug_platform_tx_FIFO_bytes(const char *str, size_t *len, 336 bool *copied_CR, 337 size_t *wrote_bytes, 338 bool map_NL) 339{ 340 size_t i, copy_bytes;; 341 char *s = (char *)str; 342 343 copy_bytes = MIN(uart_fifo_depth, *len); 344 for (i = 0 ; i < copy_bytes ; i++) { 345 if (*s == '\n' && map_NL && !*copied_CR) { 346 uart_write(0, '\r'); 347 *copied_CR = true; 348 if (++i == copy_bytes) 349 break; 350 uart_write(0, '\n'); 351 } else { 352 uart_write(0, *s); 353 *copied_CR = false; 354 } 355 s++; 356 (*len)--; 357 } 358 if (wrote_bytes != NULL) 359 *wrote_bytes = i; 360 return s; 361} 362 363/* 364 * dputs() Tx is either polling driven (if the caller is non-preemptible 365 * or earlyboot or panic) or blocking (and irq driven). 366 * TODO - buffered Tx support may be a win, (lopri but worth investigating) 367 * When we do that dputs() can be completely asynchronous, and return when 368 * the write has been (atomically) deposited into the buffer, except when 369 * we run out of room in the Tx buffer (rare) - we'd either need to spin 370 * (if non-blocking) or block waiting for space in the Tx buffer (adding 371 * support to optionally block in cbuf_write_char() would be easiest way 372 * to achieve that). 373 * 374 * block : Blocking vs Non-Blocking 375 * map_NL : If true, map a '\n' to '\r'+'\n' 376 */ 377static void platform_dputs(const char* str, size_t len, 378 bool block, bool map_NL) { 379 spin_lock_saved_state_t state; 380 bool copied_CR = false; 381 size_t wrote; 382 383 // drop strings if we haven't initialized the uart yet 384 if (unlikely(!output_enabled)) 385 return; 386 if (!uart_tx_irq_enabled) 387 block = false; 388 spin_lock_irqsave(&uart_spinlock, state); 389 while (len > 0) { 390 // Is FIFO empty ? 391 while (!(uart_read(5) & (1<<5))) { 392 if (block) { 393 /* 394 * We want to Tx more and FIFO is empty, re-enable 395 * Tx interrupts before blocking. 396 */ 397 uart_write(1, (1<<0)|(1<<1)); // rx and tx interrupt enable 398 spin_unlock_irqrestore(&uart_spinlock, state); 399 event_wait(&uart_dputc_event); 400 } else { 401 spin_unlock_irqrestore(&uart_spinlock, state); 402 arch_spinloop_pause(); 403 } 404 spin_lock_irqsave(&uart_spinlock, state); 405 } 406 // Fifo is completely empty now, we can shove an entire 407 // fifo's worth of Tx... 408 str = debug_platform_tx_FIFO_bytes(str, &len, &copied_CR, 409 &wrote, map_NL); 410 if (block && wrote > 0) { 411 // If blocking/irq driven wakeps, enable rx/tx intrs 412 uart_write(1, (1<<0)|(1<<1)); // rx and tx interrupt enable 413 } 414 } 415 spin_unlock_irqrestore(&uart_spinlock, state); 416} 417 418void platform_dputs_thread(const char* str, size_t len) { 419 if (platform_serial_enabled()) { 420 platform_dputs(str, len, true, true); 421 } 422} 423 424void platform_dputs_irq(const char* str, size_t len) { 425 if (platform_serial_enabled()) { 426 platform_dputs(str, len, false, true); 427 } 428} 429 430// polling versions of debug uart read/write 431static int debug_uart_getc_poll(char *c) { 432 // if there is a character available, read it 433 if (uart_read(5) & (1<<0)) { 434 *c = uart_read(0); 435 return 0; 436 } 437 438 return -1; 439} 440 441static void debug_uart_putc_poll(char c) { 442 // while the fifo is non empty, spin 443 while (!(uart_read(5) & (1<<6))) { 444 arch_spinloop_pause(); 445 } 446 uart_write(0, c); 447} 448 449 450int platform_dgetc(char* c, bool wait) { 451 if (platform_serial_enabled()) { 452 return static_cast<int>(cbuf_read_char(&console_input_buf, c, wait)); 453 } 454 return ZX_ERR_NOT_SUPPORTED; 455} 456 457// panic time polling IO for the panic shell 458void platform_pputc(char c) { 459 if (platform_serial_enabled()) { 460 if (c == '\n') 461 debug_uart_putc_poll('\r'); 462 debug_uart_putc_poll(c); 463 } 464} 465 466int platform_pgetc(char *c, bool wait) { 467 if (platform_serial_enabled()) { 468 return debug_uart_getc_poll(c); 469 } 470 return ZX_ERR_NOT_SUPPORTED; 471} 472 473/* 474 * Called on start of a panic. 475 * When we do Tx buffering, drain the Tx buffer here in polling mode. 476 * Turn off Tx interrupts, so force Tx be polling from this point 477 */ 478void platform_debug_panic_start(void) { 479 uart_tx_irq_enabled = false; 480} 481