1 /* 2 * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 * 5 * Copyright 2012, Alexander von Gluck, kallisti5@unixzen.com 6 * Distributed under the terms of the MIT License. 7 */ 8 9 10 #include "serial.h" 11 12 #include <debug_uart_8250.h> 13 #include <board_config.h> 14 #include <boot/platform.h> 15 #include <arch/cpu.h> 16 #include <boot/stage2.h> 17 #include <new> 18 #include <string.h> 19 20 extern "C" { 21 #include <fdt.h> 22 #include <libfdt.h> 23 #include <libfdt_env.h> 24 }; 25 26 27 extern "C" DebugUART *debug_uart_from_fdt(const void *fdt); 28 29 DebugUART* gUART; 30 31 static int32 sSerialEnabled = 0; 32 static char sBuffer[16384]; 33 static uint32 sBufferPosition; 34 35 36 static void 37 serial_putc(char c) 38 { 39 gUART->PutChar(c); 40 } 41 42 43 extern "C" void 44 serial_puts(const char* string, size_t size) 45 { 46 if (sSerialEnabled <= 0) 47 return; 48 49 if (sBufferPosition + size < sizeof(sBuffer)) { 50 memcpy(sBuffer + sBufferPosition, string, size); 51 sBufferPosition += size; 52 } 53 54 while (size-- != 0) { 55 char c = string[0]; 56 57 if (c == '\n') { 58 serial_putc('\r'); 59 serial_putc('\n'); 60 } else if (c != '\r') 61 serial_putc(c); 62 63 string++; 64 } 65 } 66 67 68 extern "C" void 69 serial_disable(void) 70 { 71 sSerialEnabled = 0; 72 } 73 74 75 extern "C" void 76 serial_enable(void) 77 { 78 /* should already be initialized by U-Boot */ 79 /* 80 gUART->InitEarly(); 81 gUART->InitPort(9600); 82 */ 83 sSerialEnabled++; 84 } 85 86 87 extern "C" void 88 serial_cleanup(void) 89 { 90 if (sSerialEnabled <= 0) 91 return; 92 93 gKernelArgs.debug_output = kernel_args_malloc(sBufferPosition); 94 if (gKernelArgs.debug_output != NULL) { 95 memcpy(gKernelArgs.debug_output, sBuffer, sBufferPosition); 96 gKernelArgs.debug_size = sBufferPosition; 97 } 98 } 99 100 101 extern "C" void 102 serial_init(const void *fdt) 103 { 104 // first try with hints from the FDT 105 gUART = debug_uart_from_fdt(fdt); 106 107 #ifdef BOARD_UART_DEBUG 108 // fallback to hardcoded board UART 109 if (gUART == NULL) 110 gUART = arch_get_uart_8250(BOARD_UART_DEBUG, BOARD_UART_CLOCK); 111 #endif 112 113 if (gUART == NULL) 114 return; 115 116 serial_enable(); 117 } 118