Diff markup
001 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 018
019 #include <sos/errno.h> 019 #include <sos/errno.h>
020 #include <hwcore/ioports.h> 020 #include <hwcore/ioports.h>
021 #include <sos/klibc.h> 021 #include <sos/klibc.h>
022 #include <hwcore/irq.h> 022 #include <hwcore/irq.h>
023 #include <drivers/devices.h> 023 #include <drivers/devices.h>
024 024
025 #include "tty.h" 025 #include "tty.h"
026 026
027 #define SERIAL_BAUDRATE_MAX 115200 027 #define SERIAL_BAUDRATE_MAX 115200
028 028
029 029
030 #ifndef DEBUG_SERIAL_PORT 030 #ifndef DEBUG_SERIAL_PORT
031 # define DEBUG_SERIAL_PORT 0 031 # define DEBUG_SERIAL_PORT 0
032 #endif 032 #endif
033 #ifndef DEBUG_SERIAL_SPEED 033 #ifndef DEBUG_SERIAL_SPEED
034 # define DEBUG_SERIAL_SPEED 9600 034 # define DEBUG_SERIAL_SPEED 9600
035 #endif 035 #endif
036 036
037 037
038 #define UART_TX 0 038 #define UART_TX 0
039 #define UART_RX 0 039 #define UART_RX 0
040 #define UART_DLL 0 040 #define UART_DLL 0
041 #define UART_IER 1 041 #define UART_IER 1
042 #define UART_DLH 1 042 #define UART_DLH 1
043 #define UART_IIR 2 043 #define UART_IIR 2
044 #define UART_FCR 2 044 #define UART_FCR 2
045 #define UART_LCR 3 045 #define UART_LCR 3
046 #define UART_MCR 4 046 #define UART_MCR 4
047 #define UART_LSR 5 047 #define UART_LSR 5
048 #define UART_MSR 6 048 #define UART_MSR 6
049 #define UART_SR 7 049 #define UART_SR 7
050 050
051 051
052 #define UART_DATA_READY 0x01 052 #define UART_DATA_READY 0x01
053 #define UART_EMPTY_TRANSMITTER 0x20 053 #define UART_EMPTY_TRANSMITTER 0x20
054 054
055 055
056 #define UART_NO_PARITY 0x00 056 #define UART_NO_PARITY 0x00
057 #define UART_ODD_PARITY 0x08 057 #define UART_ODD_PARITY 0x08
058 #define UART_EVEN_PARITY 0x18 058 #define UART_EVEN_PARITY 0x18
059 059
060 060
061 #define UART_5BITS_WORD 0x00 061 #define UART_5BITS_WORD 0x00
062 #define UART_6BITS_WORD 0x01 062 #define UART_6BITS_WORD 0x01
063 #define UART_7BITS_WORD 0x02 063 #define UART_7BITS_WORD 0x02
064 #define UART_8BITS_WORD 0x03 064 #define UART_8BITS_WORD 0x03
065 065
066 066
067 #define UART_1_STOP_BIT 0x00 067 #define UART_1_STOP_BIT 0x00
068 #define UART_2_STOP_BITS 0x04 068 #define UART_2_STOP_BITS 0x04
069 069
070 070
071 #define UART_DLAB 0x80 071 #define UART_DLAB 0x80
072 072
073 073
074 #define UART_ENABLE_FIFO 0xC7 074 #define UART_ENABLE_FIFO 0xC7
075 075
076 076
077 #define UART_ENABLE_MODEM 0x0B 077 #define UART_ENABLE_MODEM 0x0B
078 078
079 079
080 static struct 080 static struct
081 { 081 {
082 unsigned short iobase; 082 unsigned short iobase;
083 unsigned short is_enabled; 083 unsigned short is_enabled;
084 struct tty_device *tty; 084 struct tty_device *tty;
085 } _serial_config [] = { { 0x3f8, FALSE }, 085 } _serial_config [] = { { 0x3f8, FALSE },
086 { 0x2f8, FALSE }, 086 { 0x2f8, FALSE },
087 { 0x3e8, FALSE }, 087 { 0x3e8, FALSE },
088 { 0x2e8, FALSE } }; 088 { 0x2e8, FALSE } };
089 089
090 #define SERIAL_PORT_MAX 4 090 #define SERIAL_PORT_MAX 4
091 091
092 #define serial_inb inb 092 #define serial_inb inb
093 #define serial_outb(port,val) outb(val,port) 093 #define serial_outb(port,val) outb(val,port)
094 094
095 inline static int 095 inline static int
096 serial_isready (unsigned short port) 096 serial_isready (unsigned short port)
097 { 097 {
098 unsigned char status; 098 unsigned char status;
099 099
100 status = serial_inb (port + UART_LSR); 100 status = serial_inb (port + UART_LSR);
101 return (status & UART_DATA_READY) ? : -1; 101 return (status & UART_DATA_READY) ? : -1;
102 } 102 }
103 103
104 104
105 static char 105 static char
106 serial_getchar (unsigned short unit) 106 serial_getchar (unsigned short unit)
107 { 107 {
108 if(unit >= SERIAL_PORT_MAX 108 if(unit >= SERIAL_PORT_MAX
109 || _serial_config[unit].is_enabled == FAL 109 || _serial_config[unit].is_enabled == FALSE)
110 return -1; 110 return -1;
111 111
112 112
113 while ((serial_inb (_serial_config[unit].iob 113 while ((serial_inb (_serial_config[unit].iobase + UART_LSR)
114 & UART_DATA_READY) == 0) 114 & UART_DATA_READY) == 0)
115 ; 115 ;
116 116
117 117
118 return serial_inb (_serial_config[unit].ioba 118 return serial_inb (_serial_config[unit].iobase + UART_RX);
119 } 119 }
120 120
121 121
122 122
123 static int 123 static int
124 serial_putchar (unsigned short port, char c) 124 serial_putchar (unsigned short port, char c)
125 { 125 {
126 126
127 int timeout = 10000; 127 int timeout = 10000;
128 128
129 129
130 while ((serial_inb (port + UART_LSR) & UART_ 130 while ((serial_inb (port + UART_LSR) & UART_EMPTY_TRANSMITTER) == 0)
131 if (--timeout == 0) 131 if (--timeout == 0)
132 132
133 return -1; 133 return -1;
134 134
135 serial_outb (port + UART_TX, c); 135 serial_outb (port + UART_TX, c);
136 return 0; 136 return 0;
137 } 137 }
138 138
139 static char serial_printk_buf[1024]; 139 static char serial_printk_buf[1024];
140 140
141 inline static int serial_prints(unsigned short 141 inline static int serial_prints(unsigned short unit, const char *str)
142 { 142 {
143 const char *c; 143 const char *c;
144 unsigned short port; 144 unsigned short port;
145 145
146 if(unit >= SERIAL_PORT_MAX 146 if(unit >= SERIAL_PORT_MAX
147 || _serial_config[unit].is_enabled == FAL 147 || _serial_config[unit].is_enabled == FALSE)
148 return -1; 148 return -1;
149 149
150 port = _serial_config[unit].iobase; 150 port = _serial_config[unit].iobase;
151 151
152 for (c = str; *c != '\0'; c++) 152 for (c = str; *c != '\0'; c++)
153 serial_putchar(port, *c); 153 serial_putchar(port, *c);
154 154
155 155
156 return (int) (c-str); 156 return (int) (c-str);
157 } 157 }
158 158
159 int sos_serial_printf(unsigned short unit, con 159 int sos_serial_printf(unsigned short unit, const char *format, ...)
160 { 160 {
161 va_list args; 161 va_list args;
162 int len; 162 int len;
163 163
164 va_start(args, format); 164 va_start(args, format);
165 len=vsnprintf(serial_printk_buf,sizeof(seria 165 len=vsnprintf(serial_printk_buf,sizeof(serial_printk_buf),format,args);
166 166
167 return serial_prints(unit, serial_printk_buf 167 return serial_prints(unit, serial_printk_buf);
168 } 168 }
169 169
170 170
171 static void serial_irq_handler (int irq_level) 171 static void serial_irq_handler (int irq_level)
172 { 172 {
173 unsigned char chr; 173 unsigned char chr;
174 174
175 if (irq_level == SOS_IRQ_COM1) 175 if (irq_level == SOS_IRQ_COM1)
176 { 176 {
177 char c[2]; 177 char c[2];
178 chr = serial_inb (_serial_config[0].ioba 178 chr = serial_inb (_serial_config[0].iobase + UART_RX);
179 179
180 180
181 181
182 if (chr == '\r') 182 if (chr == '\r')
183 chr = '\n'; 183 chr = '\n';
184 else if (chr == 127) 184 else if (chr == 127)
185 chr = '\b'; 185 chr = '\b';
186 186
187 187
188 c[0] = chr; 188 c[0] = chr;
189 c[1] = '\0'; 189 c[1] = '\0';
190 190
191 tty_add_chars (_serial_config[0].tty, c) 191 tty_add_chars (_serial_config[0].tty, c);
192 } 192 }
193 } 193 }
194 194
195 static sos_ret_t sos_serial_putchar (char c) 195 static sos_ret_t sos_serial_putchar (char c)
196 { 196 {
197 sos_ret_t ret; 197 sos_ret_t ret;
198 int i; !! 198 unsigned int i;
199 199
200 200
201 201
202 202
203 203
204 if (c == '\b') 204 if (c == '\b')
205 { 205 {
206 const char *str = "\e[D \e[D"; 206 const char *str = "\e[D \e[D";
207 207
208 for (i = 0; i < strlen(str); i++) 208 for (i = 0; i < strlen(str); i++)
209 { 209 {
210 ret = serial_putchar (_serial_config 210 ret = serial_putchar (_serial_config[0].iobase, str[i]);
211 if (ret != SOS_OK) 211 if (ret != SOS_OK)
212 return ret; 212 return ret;
213 } 213 }
214 214
215 return SOS_OK; 215 return SOS_OK;
216 } 216 }
217 217
218 return serial_putchar (_serial_config[0].iob 218 return serial_putchar (_serial_config[0].iobase, c);
219 } 219 }
220 220
221 221
222 222
223 sos_ret_t sos_serial_subsystem_setup (sos_bool 223 sos_ret_t sos_serial_subsystem_setup (sos_bool_t enable)
224 { 224 {
225 unsigned short div = 0; 225 unsigned short div = 0;
226 unsigned char status = 0; 226 unsigned char status = 0;
227 unsigned short serial_port; 227 unsigned short serial_port;
228 228
229 unsigned short unit = 0; 229 unsigned short unit = 0;
230 unsigned int speed = 115200; 230 unsigned int speed = 115200;
231 int word_len = UART_8BITS_WORD; 231 int word_len = UART_8BITS_WORD;
232 int parity = UART_NO_PARITY; 232 int parity = UART_NO_PARITY;
233 int stop_bit_len = UART_1_STOP_BIT; 233 int stop_bit_len = UART_1_STOP_BIT;
234 234
235 if (unit >= SERIAL_PORT_MAX) 235 if (unit >= SERIAL_PORT_MAX)
236 return -1; 236 return -1;
237 237
238 serial_port = _serial_config[unit].iobase; 238 serial_port = _serial_config[unit].iobase;
239 239
240 240
241 serial_outb (serial_port + UART_IER, 0); 241 serial_outb (serial_port + UART_IER, 0);
242 242
243 243
244 serial_outb (serial_port + UART_LCR, UART_DL 244 serial_outb (serial_port + UART_LCR, UART_DLAB);
245 245
246 246
247 if (speed > SERIAL_BAUDRATE_MAX) 247 if (speed > SERIAL_BAUDRATE_MAX)
248 return -1; 248 return -1;
249 249
250 div = SERIAL_BAUDRATE_MAX / speed; 250 div = SERIAL_BAUDRATE_MAX / speed;
251 251
252 serial_outb (serial_port + UART_DLL, div & 0 252 serial_outb (serial_port + UART_DLL, div & 0xFF);
253 serial_outb (serial_port + UART_DLH, div >> 253 serial_outb (serial_port + UART_DLH, div >> 8);
254 254
255 255
256 status |= parity | word_len | stop_bit_len; 256 status |= parity | word_len | stop_bit_len;
257 serial_outb (serial_port + UART_LCR, status) 257 serial_outb (serial_port + UART_LCR, status);
258 258
259 259
260 serial_outb (serial_port + UART_FCR, UART_EN 260 serial_outb (serial_port + UART_FCR, UART_ENABLE_FIFO);
261 261
262 262
263 serial_outb (serial_port + UART_MCR, UART_EN 263 serial_outb (serial_port + UART_MCR, UART_ENABLE_MODEM);
264 264
265 265
266 while (serial_isready (serial_port) != -1) 266 while (serial_isready (serial_port) != -1)
267 (void) serial_getchar (unit); 267 (void) serial_getchar (unit);
268 268
269 _serial_config[unit].is_enabled = TRUE; 269 _serial_config[unit].is_enabled = TRUE;
270 270
271 return SOS_OK; 271 return SOS_OK;
272 } 272 }
273 273
274 274
275 275
276 276
277 sos_ret_t sos_ttyS0_subsystem_setup (void) 277 sos_ret_t sos_ttyS0_subsystem_setup (void)
278 { 278 {
279 sos_ret_t ret; 279 sos_ret_t ret;
280 280
281 <<
282 ret = tty_create (SOS_CHARDEV_SERIAL_MINOR, 281 ret = tty_create (SOS_CHARDEV_SERIAL_MINOR, sos_serial_putchar,
283 & _serial_config[0].tty); 282 & _serial_config[0].tty);
284 if (SOS_OK != ret) 283 if (SOS_OK != ret)
285 return ret; 284 return ret;
286 285
287 sos_irq_set_routine (SOS_IRQ_COM1, serial_ir 286 sos_irq_set_routine (SOS_IRQ_COM1, serial_irq_handler);
288 287
289 288
290 serial_outb (_serial_config[0].iobase + UART 289 serial_outb (_serial_config[0].iobase + UART_IER, 1);
291 290
292 return SOS_OK; 291 return SOS_OK;
293 } 292 }