xref: /haiku/src/system/kernel/arch/generic/debug_uart_8250.cpp (revision 372a66634410cf0450e426716c14ad42d40c0da4)
1 /*
2  * Copyright (c) 2008 Travis Geiselbrecht
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 
25 #include <debug.h>
26 #include <arch/generic/debug_uart_8250.h>
27 
28 
29 DebugUART8250::DebugUART8250(addr_t base, int64 clock)
30 	: DebugUART(base, clock)
31 {
32 }
33 
34 
35 DebugUART8250::~DebugUART8250()
36 {
37 }
38 
39 #define UART_RHR    0
40 #define UART_THR    0
41 #define UART_DLL    0
42 #define UART_IER    1
43 #define UART_DLH    1
44 #define UART_IIR    2
45 #define UART_FCR    2
46 #define UART_EFR    2
47 #define UART_LCR    3
48 #define UART_MCR    4
49 #define UART_LSR    5
50 #define UART_MSR    6
51 #define UART_TCR    6
52 #define UART_SPR    7
53 #define UART_TLR    7
54 
55 #define LCR_8N1		0x03
56 
57 #define FCR_FIFO_EN	0x01	/* Fifo enable */
58 #define FCR_RXSR	0x02	/* Receiver soft reset */
59 #define FCR_TXSR	0x04	/* Transmitter soft reset */
60 
61 #define MCR_DTR		0x01
62 #define MCR_RTS		0x02
63 #define MCR_DMA_EN	0x04
64 #define MCR_TX_DFR	0x08
65 
66 #define LCR_WLS_MSK	0x03	/* character length select mask */
67 #define LCR_WLS_5	0x00	/* 5 bit character length */
68 #define LCR_WLS_6	0x01	/* 6 bit character length */
69 #define LCR_WLS_7	0x02	/* 7 bit character length */
70 #define LCR_WLS_8	0x03	/* 8 bit character length */
71 #define LCR_STB		0x04	/* Number of stop Bits, off = 1, on = 1.5 or 2) */
72 #define LCR_PEN		0x08	/* Parity eneble */
73 #define LCR_EPS		0x10	/* Even Parity Select */
74 #define LCR_STKP	0x20	/* Stick Parity */
75 #define LCR_SBRK	0x40	/* Set Break */
76 #define LCR_BKSE	0x80	/* Bank select enable */
77 
78 #define LSR_DR		0x01	/* Data ready */
79 #define LSR_OE		0x02	/* Overrun */
80 #define LSR_PE		0x04	/* Parity error */
81 #define LSR_FE		0x08	/* Framing error */
82 #define LSR_BI		0x10	/* Break */
83 #define LSR_THRE	0x20	/* Xmit holding register empty */
84 #define LSR_TEMT	0x40	/* Xmitter empty */
85 #define LSR_ERR		0x80	/* Error */
86 
87 
88 void
89 DebugUART8250::InitPort(uint32 baud)
90 {
91 	Disable();
92 
93 	uint16 baudDivisor = Clock() / (16 * baud);
94 
95 	// Write standard uart settings
96 	Out8(UART_LCR, LCR_8N1);
97 	// 8N1
98 	Out8(UART_IER, 0);
99 	// Disable interrupt
100 	Out8(UART_FCR, 0);
101 	// Disable FIFO
102 	Out8(UART_MCR, MCR_DTR | MCR_RTS);
103 	// DTR / RTS
104 
105 	// Gain access to, and program baud divisor
106 	unsigned char buffer = In8(UART_LCR);
107 	Out8(UART_LCR, buffer | LCR_BKSE);
108 	Out8(UART_DLL, baudDivisor & 0xff);
109 	Out8(UART_DLH, (baudDivisor >> 8) & 0xff);
110 	Out8(UART_LCR, buffer & ~LCR_BKSE);
111 
112 //	Out8(UART_MDR1, 0); // UART 16x mode
113 //	Out8(UART_LCR, 0xBF); // config mode B
114 //	Out8(UART_EFR, (1<<7)|(1<<6)); // hw flow control
115 //	Out8(UART_LCR, LCR_8N1); // operational mode
116 
117 	Enable();
118 }
119 
120 
121 void
122 DebugUART8250::InitEarly()
123 {
124 }
125 
126 
127 void
128 DebugUART8250::Init()
129 {
130 }
131 
132 
133 int
134 DebugUART8250::PutChar(char c)
135 {
136 	while (!(In8(UART_LSR) & (1<<6)));
137 		// wait for the last char to get out
138 	Out8(UART_THR, c);
139 	return 0;
140 }
141 
142 
143 /* returns -1 if no data available */
144 int
145 DebugUART8250::GetChar(bool wait)
146 {
147 	if (wait) {
148 		while (!(In8(UART_LSR) & (1<<0)));
149 			// wait for data to show up in the rx fifo
150 	} else {
151 		if (!(In8(UART_LSR) & (1<<0)))
152 			return -1;
153 	}
154 	return In8(UART_RHR);
155 }
156 
157 
158 void
159 DebugUART8250::FlushTx()
160 {
161 	while (!(In8(UART_LSR) & (1<<6)));
162 		// wait for the last char to get out
163 }
164 
165 
166 void
167 DebugUART8250::FlushRx()
168 {
169 	// empty the rx fifo
170 	while (In8(UART_LSR) & (1<<0)) {
171 		volatile char c = In8(UART_RHR);
172 		(void)c;
173 	}
174 }
175