File indexing completed on 2025-05-11 08:23:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <assert.h>
0019
0020 #include <rtems.h>
0021 #include <rtems/libio.h>
0022 #include <bsp/irq.h>
0023
0024 #include <bsp.h>
0025 #include <libchip/serial.h>
0026 #include <libchip/sersupp.h>
0027
0028 #include RTEMS_XPARAMETERS_H
0029
0030
0031 #define PARITY_ERROR 0x80
0032 #define FRAME_ERROR 0x40
0033 #define OVERRUN_ERROR 0x20
0034 #define STATUS_REG_ERROR_MASK ( PARITY_ERROR | FRAME_ERROR | OVERRUN_ERROR )
0035
0036 #define INTR_ENABLED 0x10
0037 #define TX_FIFO_FULL 0x08
0038 #define TX_FIFO_EMPTY 0x04
0039 #define RX_FIFO_FULL 0x02
0040 #define RX_FIFO_VALID_DATA 0x01
0041
0042 #define ENABLE_INTR 0x10
0043 #define RST_RX_FIFO 0x02
0044 #define RST_TX_FIFO 0x01
0045
0046
0047 #define TX_FIFO_SIZE 16
0048 #define RX_FIFO_SIZE 16
0049
0050
0051
0052
0053 #define RECV_REG 0
0054 #define TRAN_REG 4
0055 #define STAT_REG 8
0056 #define CTRL_REG 12
0057
0058
0059
0060 static inline uint32_t xlite_uart_control(uint32_t base)
0061 {
0062 uint32_t c = *((volatile uint32_t*)(base+CTRL_REG));
0063 return c;
0064 }
0065
0066
0067 static inline uint32_t xlite_uart_status(uint32_t base)
0068 {
0069 uint32_t c = *((volatile uint32_t*)(base+STAT_REG));
0070 return c;
0071 }
0072
0073
0074 static inline uint32_t xlite_uart_read(uint32_t base)
0075 {
0076 uint32_t c = *((volatile uint32_t*)(base+RECV_REG));
0077 return c;
0078 }
0079
0080
0081 static inline void xlite_uart_write(uint32_t base, char ch)
0082 {
0083 *(volatile uint32_t*)(base+TRAN_REG) = (uint32_t)ch;
0084 return;
0085 }
0086
0087
0088
0089 static int xlite_write_char(uint32_t base, char ch)
0090 {
0091 uint32_t retrycount= 0, idler, status;
0092
0093 while( ((status = xlite_uart_status(base)) & TX_FIFO_FULL) != 0 )
0094 {
0095 ++retrycount;
0096
0097
0098 if( retrycount == 0x4000 )
0099 {
0100
0101 return -1;
0102 }
0103
0104
0105
0106 for( idler= 0; idler < 0x2000; idler++);
0107 }
0108
0109 xlite_uart_write(base, ch);
0110
0111 return 1;
0112 }
0113
0114 static void xlite_init(int minor )
0115 {
0116
0117 }
0118
0119 #if VIRTEX_CONSOLE_USE_INTERRUPTS
0120 static void xlite_interrupt_handler(void *arg)
0121 {
0122 int minor = (int) arg;
0123 const console_tbl *ct = Console_Port_Tbl[minor];
0124 console_data *cd = &Console_Port_Data[minor];
0125 uint32_t base = ct->ulCtrlPort1;
0126 uint32_t status = xlite_uart_status(base);
0127
0128 while ((status & RX_FIFO_VALID_DATA) != 0) {
0129 char c = (char) xlite_uart_read(base);
0130
0131 rtems_termios_enqueue_raw_characters(cd->termios_data, &c, 1);
0132
0133 status = xlite_uart_status(base);
0134 }
0135
0136 if (cd->bActive) {
0137 rtems_termios_dequeue_characters(cd->termios_data, 1);
0138 }
0139 }
0140 #endif
0141
0142 static int xlite_open(
0143 int major,
0144 int minor,
0145 void *arg
0146 )
0147 {
0148 const console_tbl *ct = Console_Port_Tbl[minor];
0149 uint32_t base = ct->ulCtrlPort1;
0150 #if VIRTEX_CONSOLE_USE_INTERRUPTS
0151 rtems_status_code sc;
0152 #endif
0153
0154
0155 *((volatile uint32_t*)(base+STAT_REG)) = 0;
0156
0157
0158 *((volatile uint32_t*)(base+CTRL_REG)) = RST_RX_FIFO | RST_TX_FIFO;
0159
0160 #if VIRTEX_CONSOLE_USE_INTERRUPTS
0161 *((volatile uint32_t*)(base+CTRL_REG)) = ENABLE_INTR;
0162
0163 sc = rtems_interrupt_handler_install(
0164 ct->ulIntVector,
0165 "xlite",
0166 RTEMS_INTERRUPT_UNIQUE,
0167 xlite_interrupt_handler,
0168 (void *) minor
0169 );
0170 assert(sc == RTEMS_SUCCESSFUL);
0171 #endif
0172
0173 return 0;
0174 }
0175
0176 static int xlite_close(
0177 int major,
0178 int minor,
0179 void *arg
0180 )
0181 {
0182 const console_tbl *ct = Console_Port_Tbl[minor];
0183 uint32_t base = ct->ulCtrlPort1;
0184 #if VIRTEX_CONSOLE_USE_INTERRUPTS
0185 rtems_status_code sc;
0186 #endif
0187
0188 *((volatile uint32_t*)(base+CTRL_REG)) = 0;
0189
0190 #if VIRTEX_CONSOLE_USE_INTERRUPTS
0191 sc = rtems_interrupt_handler_remove(
0192 ct->ulIntVector,
0193 xlite_interrupt_handler,
0194 (void *) minor
0195 );
0196 assert(sc == RTEMS_SUCCESSFUL);
0197 #endif
0198
0199 return 0;
0200 }
0201
0202
0203
0204 static int xlite_read_polled (int minor )
0205 {
0206 uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1;
0207
0208 unsigned int status = xlite_uart_status(base);
0209
0210 if(status & RX_FIFO_VALID_DATA)
0211 return (int)xlite_uart_read(base);
0212 else
0213 return -1;
0214 }
0215
0216 #if VIRTEX_CONSOLE_USE_INTERRUPTS
0217
0218 static ssize_t xlite_write_interrupt_driven(
0219 int minor,
0220 const char *buf,
0221 size_t len
0222 )
0223 {
0224 console_data *cd = &Console_Port_Data[minor];
0225
0226 if (len > 0) {
0227 const console_tbl *ct = Console_Port_Tbl[minor];
0228 uint32_t base = ct->ulCtrlPort1;
0229
0230 xlite_uart_write(base, buf[0]);
0231
0232 cd->bActive = true;
0233 } else {
0234 cd->bActive = false;
0235 }
0236
0237 return 0;
0238 }
0239
0240 #else
0241
0242 static ssize_t xlite_write_buffer_polled(
0243 int minor,
0244 const char *buf,
0245 size_t len
0246 )
0247 {
0248 uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1;
0249 int nwrite = 0;
0250
0251
0252
0253
0254 while (nwrite < len)
0255 {
0256 if( xlite_write_char(base, *buf++) < 0 ) break;
0257 nwrite++;
0258 }
0259
0260
0261
0262
0263 return nwrite;
0264 }
0265
0266 #endif
0267
0268 static void xlite_write_char_polled(
0269 int minor,
0270 char c
0271 )
0272 {
0273 uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1;
0274 xlite_write_char(base, c);
0275 return;
0276 }
0277
0278 static int xlite_set_attributes(int minor, const struct termios *t)
0279 {
0280 return RTEMS_SUCCESSFUL;
0281 }
0282
0283
0284
0285
0286
0287
0288
0289 static const console_fns xlite_fns_polled =
0290 {
0291 .deviceProbe = libchip_serial_default_probe,
0292 .deviceFirstOpen = xlite_open,
0293 .deviceLastClose = xlite_close,
0294 .deviceRead = xlite_read_polled,
0295 .deviceInitialize = xlite_init,
0296 .deviceWritePolled = xlite_write_char_polled,
0297 .deviceSetAttributes = xlite_set_attributes,
0298 #if VIRTEX_CONSOLE_USE_INTERRUPTS
0299 .deviceWrite = xlite_write_interrupt_driven,
0300 .deviceOutputUsesInterrupts = true
0301 #else
0302 .deviceWrite = xlite_write_buffer_polled,
0303 .deviceOutputUsesInterrupts = false
0304 #endif
0305 };
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317 console_tbl Console_Configuration_Ports[] = {
0318 {
0319 "/dev/ttyS0",
0320 SERIAL_CUSTOM,
0321 &xlite_fns_polled,
0322 NULL,
0323 NULL,
0324 16,
0325 8,
0326 (void *) NULL,
0327 STDIN_BASEADDRESS,
0328 0,
0329 0,
0330 NULL,
0331 NULL,
0332 NULL,
0333 NULL,
0334 0,
0335 #ifdef XPAR_XPS_INTC_0_RS232_UART_INTERRUPT_INTR
0336 .ulIntVector = XPAR_XPS_INTC_0_RS232_UART_INTERRUPT_INTR
0337 #else
0338 .ulIntVector = 0
0339 #endif
0340 },
0341 #ifdef XPAR_UARTLITE_1_BASEADDR
0342 {
0343 "/dev/ttyS1",
0344 SERIAL_CUSTOM,
0345 &xlite_fns_polled,
0346 NULL,
0347 NULL,
0348 16,
0349 8,
0350 (void *) NULL,
0351 XPAR_UARTLITE_1_BASEADDR,
0352 0,
0353 0,
0354 NULL,
0355 NULL,
0356 NULL,
0357 NULL,
0358 0,
0359 0
0360 },
0361 #endif
0362 #ifdef XPAR_UARTLITE_2_BASEADDR
0363 {
0364 "/dev/ttyS2",
0365 SERIAL_CUSTOM,
0366 &xlite_fns_polled,
0367 NULL,
0368 NULL,
0369 16,
0370 8,
0371 (void *) NULL,
0372 XPAR_UARTLITE_2_BASEADDR,
0373 0,
0374 0,
0375 NULL,
0376 NULL,
0377 NULL,
0378 NULL,
0379 0,
0380 0
0381 },
0382 #endif
0383 #ifdef XPAR_UARTLITE_2_BASEADDR
0384 {
0385 "/dev/ttyS3",
0386 SERIAL_CUSTOM,
0387 &xlite_fns_polled,
0388 NULL,
0389 NULL,
0390 16,
0391 8,
0392 (void *) NULL,
0393 XPAR_UARTLITE_3_BASEADDR,
0394 0,
0395 0,
0396 NULL,
0397 NULL,
0398 NULL,
0399 NULL,
0400 0,
0401 0
0402 }
0403 #endif
0404 };
0405
0406 unsigned long Console_Configuration_Count =
0407 RTEMS_ARRAY_SIZE(Console_Configuration_Ports);
0408
0409
0410 #include <rtems/bspIo.h>
0411
0412 static void outputChar(char ch)
0413 {
0414 xlite_write_char_polled( 0, ch );
0415 }
0416
0417 static int inputChar(void)
0418 {
0419 return xlite_read_polled(0);
0420 }
0421
0422 BSP_output_char_function_type BSP_output_char = outputChar;
0423 BSP_polling_getchar_function_type BSP_poll_char = inputChar;
0424
0425