xref: /haiku/src/system/boot/platform/u-boot/serial.cpp (revision 2b76973fa2401f7a5edf68e6470f3d3210cbcff3)
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