xref: /haiku/src/system/kernel/arch/generic/debug_uart_8250.cpp (revision 5ac9b506412b11afb993bb52d161efe7666958a5)
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 	:
31 	DebugUART(base, clock)
32 {
33 }
34 
35 
36 DebugUART8250::~DebugUART8250()
37 {
38 }
39 
40 
41 #define UART_RHR    0
42 #define UART_THR    0
43 #define UART_DLL    0
44 #define UART_IER    1
45 #define UART_DLH    1
46 #define UART_IIR    2
47 #define UART_FCR    2
48 #define UART_EFR    2
49 #define UART_LCR    3
50 #define UART_MCR    4
51 #define UART_LSR    5
52 #define UART_MSR    6
53 #define UART_TCR    6
54 #define UART_SPR    7
55 #define UART_TLR    7
56 
57 #define LCR_8N1		0x03
58 
59 #define FCR_FIFO_EN	0x01	/* Fifo enable */
60 #define FCR_RXSR	0x02	/* Receiver soft reset */
61 #define FCR_TXSR	0x04	/* Transmitter soft reset */
62 
63 #define MCR_DTR		0x01
64 #define MCR_RTS		0x02
65 #define MCR_DMA_EN	0x04
66 #define MCR_TX_DFR	0x08
67 
68 #define LCR_WLS_MSK	0x03	/* character length select mask */
69 #define LCR_WLS_5	0x00	/* 5 bit character length */
70 #define LCR_WLS_6	0x01	/* 6 bit character length */
71 #define LCR_WLS_7	0x02	/* 7 bit character length */
72 #define LCR_WLS_8	0x03	/* 8 bit character length */
73 #define LCR_STB		0x04	/* Number of stop Bits, off = 1, on = 1.5 or 2) */
74 #define LCR_PEN		0x08	/* Parity eneble */
75 #define LCR_EPS		0x10	/* Even Parity Select */
76 #define LCR_STKP	0x20	/* Stick Parity */
77 #define LCR_SBRK	0x40	/* Set Break */
78 #define LCR_BKSE	0x80	/* Bank select enable */
79 
80 #define LSR_DR		0x01	/* Data ready */
81 #define LSR_OE		0x02	/* Overrun */
82 #define LSR_PE		0x04	/* Parity error */
83 #define LSR_FE		0x08	/* Framing error */
84 #define LSR_BI		0x10	/* Break */
85 #define LSR_THRE	0x20	/* Xmit holding register empty */
86 #define LSR_TEMT	0x40	/* Xmitter empty */
87 #define LSR_ERR		0x80	/* Error */
88 
89 
90 void
91 DebugUART8250::InitPort(uint32 baud)
92 {
93 	Disable();
94 
95 	uint16 baudDivisor = Clock() / (16 * baud);
96 
97 	// Write standard uart settings
98 	Out8(UART_LCR, LCR_8N1);
99 	// 8N1
100 	Out8(UART_IER, 0);
101 	// Disable interrupt
102 	Out8(UART_FCR, 0);
103 	// Disable FIFO
104 	Out8(UART_MCR, MCR_DTR | MCR_RTS);
105 	// DTR / RTS
106 
107 	// Gain access to, and program baud divisor
108 	unsigned char buffer = In8(UART_LCR);
109 	Out8(UART_LCR, buffer | LCR_BKSE);
110 	Out8(UART_DLL, baudDivisor & 0xff);
111 	Out8(UART_DLH, (baudDivisor >> 8) & 0xff);
112 	Out8(UART_LCR, buffer & ~LCR_BKSE);
113 
114 //	Out8(UART_MDR1, 0); // UART 16x mode
115 //	Out8(UART_LCR, 0xBF); // config mode B
116 //	Out8(UART_EFR, (1<<7)|(1<<6)); // hw flow control
117 //	Out8(UART_LCR, LCR_8N1); // operational mode
118 
119 	Enable();
120 }
121 
122 
123 void
124 DebugUART8250::InitEarly()
125 {
126 }
127 
128 
129 void
130 DebugUART8250::Init()
131 {
132 }
133 
134 
135 int
136 DebugUART8250::PutChar(char c)
137 {
138 	while (!(In8(UART_LSR) & (1<<6)));
139 		// wait for the last char to get out
140 	Out8(UART_THR, c);
141 	return 0;
142 }
143 
144 
145 /* returns -1 if no data available */
146 int
147 DebugUART8250::GetChar(bool wait)
148 {
149 	if (wait) {
150 		while (!(In8(UART_LSR) & (1<<0)));
151 			// wait for data to show up in the rx fifo
152 	} else {
153 		if (!(In8(UART_LSR) & (1<<0)))
154 			return -1;
155 	}
156 	return In8(UART_RHR);
157 }
158 
159 
160 void
161 DebugUART8250::FlushTx()
162 {
163 	while (!(In8(UART_LSR) & (1<<6)));
164 		// wait for the last char to get out
165 }
166 
167 
168 void
169 DebugUART8250::FlushRx()
170 {
171 	// empty the rx fifo
172 	while (In8(UART_LSR) & (1<<0)) {
173 		volatile char c = In8(UART_RHR);
174 		(void)c;
175 	}
176 }
177