SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

Diff markup

Differences between /drivers/serial.c (Article 9) and /drivers/serial.c (Article 9.5)


001 /* Copyright (C) 2000  David Decotigny, The KO    001 /* Copyright (C) 2000  David Decotigny, The KOS Team
002                                                   002 
003    This program is free software; you can redi    003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU Genera    004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundatio    005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any lat    006    of the License, or (at your option) any later version.
007                                                   007    
008    This program is distributed in the hope tha    008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the     009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR    010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details    011    GNU General Public License for more details.
012                                                   012    
013    You should have received a copy of the GNU     013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to t    014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 3    015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA.                                           016    USA. 
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 /* Default parameters */                          029 /* Default parameters */
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 /* The offsets of UART registers.  */             037 /* The offsets of UART registers.  */
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 /* For LSR bits.  */                              051 /* For LSR bits.  */
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 /* The type of parity.  */                        055 /* The type of parity.  */
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 /* The type of word length.  */                   060 /* The type of word length.  */
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 /* The type of the length of stop bit.  */        066 /* The type of the length of stop bit.  */
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 /* the switch of DLAB.  */                        070 /* the switch of DLAB.  */
071 #define UART_DLAB               0x80              071 #define UART_DLAB               0x80
072                                                   072 
073 /* Enable the FIFO.  */                           073 /* Enable the FIFO.  */
074 #define UART_ENABLE_FIFO        0xC7              074 #define UART_ENABLE_FIFO        0xC7
075                                                   075 
076 /* Turn on DTR, RTS, and OUT2.  */                076 /* Turn on DTR, RTS, and OUT2.  */
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   /* Wait until data is ready.  */                112   /* Wait until data is ready.  */
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   /* Read and return the data.  */                117   /* Read and return the data.  */
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 /* 0 on success */                                122 /* 0 on success */
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   /* Perhaps a timeout is necessary.  */          126   /* Perhaps a timeout is necessary.  */
127   int timeout = 10000;                            127   int timeout = 10000;
128                                                   128 
129   /* Wait until the transmitter holding regist    129   /* Wait until the transmitter holding register is empty.  */
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       /* There is something wrong. But what ca    132       /* There is something wrong. But what can I do?  */
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       /* Little hacks to get it to work with Q    180       /* Little hacks to get it to work with Qemu serial port
181          emulation. */                            181          emulation. */
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       /* Build a null-terminated string */        187       /* Build a null-terminated string */
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   /* The serial port doesn't understand '\b',     200   /* The serial port doesn't understand '\b', but requires ANSI
201      commands instead. So we emulate '\b' by o    201      commands instead. So we emulate '\b' by outputing "\e[D \e[D"
202      which basically goes backward one charact    202      which basically goes backward one character, prints a space and
203      goes backward one character again. */        203      goes backward one character again. */
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 /* OK On success */                               222 /* OK On success */
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   /* Turn off the interrupt.  */                  240   /* Turn off the interrupt.  */
241   serial_outb (serial_port + UART_IER, 0);        241   serial_outb (serial_port + UART_IER, 0);
242                                                   242 
243   /* Set DLAB.  */                                243   /* Set DLAB.  */
244   serial_outb (serial_port + UART_LCR, UART_DL    244   serial_outb (serial_port + UART_LCR, UART_DLAB);
245                                                   245 
246   /* Set the baud rate.  */                       246   /* Set the baud rate.  */
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   /* Set the line status.  */                     255   /* Set the line status.  */
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   /* Enable the FIFO.  */                         259   /* Enable the FIFO.  */
260   serial_outb (serial_port + UART_FCR, UART_EN    260   serial_outb (serial_port + UART_FCR, UART_ENABLE_FIFO);
261                                                   261 
262   /* Turn on DTR, RTS, and OUT2.  */              262   /* Turn on DTR, RTS, and OUT2.  */
263   serial_outb (serial_port + UART_MCR, UART_EN    263   serial_outb (serial_port + UART_MCR, UART_ENABLE_MODEM);
264                                                   264 
265   /* Drain the input buffer.  */                  265   /* Drain the input buffer.  */
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 /* Cannot be placed in sos_serial_subsystem_in    275 /* Cannot be placed in sos_serial_subsystem_init() because when it
276    gets called, the IRQ handling subsystem is     276    gets called, the IRQ handling subsystem is not yet initialized */
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   /* FIXME */                                  << 
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   /* Enable interrupts */                         288   /* Enable interrupts */
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 }
                                                      

source navigation ] diff markup ] identifier search ] general search ]