1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <arch/io.h>
22#include <uart8250.h>
23#include <pc80/mc146818rtc.h>
24#if CONFIG_USE_OPTION_TABLE
25#include "option_table.h"
26#endif
27#if !defined(__SMM__) && !defined(__PRE_RAM__)
28#include <device/device.h>
29#endif
30
31
32
33static inline int uart8250_mem_can_tx_byte(unsigned base_port)
34{
35 return read8(base_port + UART_LSR) & UART_MSR_DSR;
36}
37
38static inline void uart8250_mem_wait_to_tx_byte(unsigned base_port)
39{
40 while(!uart8250_mem_can_tx_byte(base_port))
41 ;
42}
43
44static inline void uart8250_mem_wait_until_sent(unsigned base_port)
45{
46 while(!(read8(base_port + UART_LSR) & UART_LSR_TEMT))
47 ;
48}
49
50void uart8250_mem_tx_byte(unsigned base_port, unsigned char data)
51{
52 uart8250_mem_wait_to_tx_byte(base_port);
53 write8(base_port + UART_TBR, data);
54
55 uart8250_mem_wait_until_sent(base_port);
56}
57
58int uart8250_mem_can_rx_byte(unsigned base_port)
59{
60 return read8(base_port + UART_LSR) & UART_LSR_DR;
61}
62
63unsigned char uart8250_mem_rx_byte(unsigned base_port)
64{
65 while(!uart8250_mem_can_rx_byte(base_port))
66 ;
67 return read8(base_port + UART_RBR);
68}
69
70void uart8250_mem_init(unsigned base_port, unsigned divisor)
71{
72
73 write8(base_port + UART_IER, 0x0);
74
75 write8(base_port + UART_FCR, UART_FCR_FIFO_EN);
76
77
78 write8(base_port + UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
79
80
81 write8(base_port + UART_LCR, UART_LCR_DLAB | CONFIG_TTYS0_LCS);
82
83
84 write8(base_port + UART_DLL, divisor & 0xFF);
85 write8(base_port + UART_DLM, (divisor >> 8) & 0xFF);
86
87
88 write8(base_port + UART_LCR, CONFIG_TTYS0_LCS);
89}
90
91u32 uart_mem_init(void)
92{
93 unsigned uart_baud = CONFIG_TTYS0_BAUD;
94 u32 uart_bar = 0;
95 unsigned div;
96
97
98#if !defined(__SMM__) && CONFIG_USE_OPTION_TABLE
99 static const unsigned baud[8] = { 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200 };
100 unsigned b_index = 0;
101#if defined(__PRE_RAM__)
102 b_index = read_option(CMOS_VSTART_baud_rate, CMOS_VLEN_baud_rate, 0);
103 b_index &= 7;
104 uart_baud = baud[b_index];
105#else
106 if (get_option(&b_index, "baud_rate") == 0) {
107 uart_baud = baud[b_index];
108 }
109#endif
110#endif
111
112
113#if CONFIG_DRIVERS_OXFORD_OXPCIE
114
115#if defined(MORE_TESTING) && !defined(__SMM__) && !defined(__PRE_RAM__)
116 device_t dev = dev_find_device(0x1415, 0xc158, NULL);
117
118 if (dev) {
119 struct resource *res = find_resource(dev, 0x10);
120
121 if (res) {
122 uart_bar = res->base + 0x1000;
123
124 }
125 }
126
127 if (!uart_bar)
128#endif
129 uart_bar = CONFIG_OXFORD_OXPCIE_BASE_ADDRESS + 0x1000;
130
131
132 div = 4000000 / uart_baud;
133#endif
134
135 if (uart_bar)
136 uart8250_mem_init(uart_bar, div);
137
138 return uart_bar;
139}
140