File indexing completed on 2025-05-11 08:24:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <stdlib.h>
0019 #include <assert.h>
0020
0021 #include <rtems/console.h>
0022 #include <rtems/libio.h>
0023 #include <bsp.h>
0024
0025
0026
0027
0028
0029 #if (CONSOLE_USE_INTERRUPTS)
0030
0031
0032
0033
0034
0035 #include <rtems/ringbuf.h>
0036
0037 Ring_buffer_t TX_Buffer[ 2 ];
0038 bool Is_TX_active[ 2 ];
0039
0040 void *console_termios_data[ 2 ];
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 rtems_isr console_isr_a(
0056 rtems_vector_number vector
0057 )
0058 {
0059 char ch;
0060 int UStat;
0061
0062 if ( (UStat = LEON_REG.UART_Status_1) & LEON_REG_UART_STATUS_DR ) {
0063 if (UStat & LEON_REG_UART_STATUS_ERR) {
0064 LEON_REG.UART_Status_1 = LEON_REG_UART_STATUS_CLR;
0065 }
0066 ch = LEON_REG.UART_Channel_1;
0067
0068 rtems_termios_enqueue_raw_characters( console_termios_data[ 0 ], &ch, 1 );
0069 }
0070
0071 if ( LEON_REG.UART_Status_1 & LEON_REG_UART_STATUS_THE ) {
0072 if ( !Ring_buffer_Is_empty( &TX_Buffer[ 0 ] ) ) {
0073 Ring_buffer_Remove_character( &TX_Buffer[ 0 ], ch );
0074 LEON_REG.UART_Channel_1 = (uint32_t) ch;
0075 } else
0076 Is_TX_active[ 0 ] = false;
0077 }
0078
0079 LEON_Clear_interrupt( LEON_INTERRUPT_UART_1_RX_TX );
0080 }
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 rtems_isr console_isr_b(
0096 rtems_vector_number vector
0097 )
0098 {
0099 char ch;
0100 int UStat;
0101
0102 if ( (UStat = LEON_REG.UART_Status_2) & LEON_REG_UART_STATUS_DR ) {
0103 if (UStat & LEON_REG_UART_STATUS_ERR) {
0104 LEON_REG.UART_Status_2 = LEON_REG_UART_STATUS_CLR;
0105 }
0106 ch = LEON_REG.UART_Channel_2;
0107 rtems_termios_enqueue_raw_characters( console_termios_data[ 1 ], &ch, 1 );
0108
0109 }
0110
0111 if ( LEON_REG.UART_Status_2 & LEON_REG_UART_STATUS_THE ) {
0112 if ( !Ring_buffer_Is_empty( &TX_Buffer[ 1 ] ) ) {
0113 Ring_buffer_Remove_character( &TX_Buffer[ 1 ], ch );
0114 LEON_REG.UART_Channel_2 = (uint32_t) ch;
0115 } else
0116 Is_TX_active[ 1 ] = false;
0117 }
0118
0119 LEON_Clear_interrupt( LEON_INTERRUPT_UART_2_RX_TX );
0120 }
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 void console_exit()
0136 {
0137 uint32_t port;
0138 uint32_t ch;
0139
0140
0141
0142
0143
0144
0145 LEON_Mask_interrupt( LEON_INTERRUPT_UART_1_RX_TX );
0146 LEON_Mask_interrupt( LEON_INTERRUPT_UART_2_RX_TX );
0147
0148 for ( port=0 ; port <= 1 ; port++ ) {
0149 while ( !Ring_buffer_Is_empty( &TX_Buffer[ port ] ) ) {
0150 Ring_buffer_Remove_character( &TX_Buffer[ port ], ch );
0151 console_outbyte_polled( port, ch );
0152 }
0153 }
0154
0155
0156
0157
0158
0159
0160 while ( (LEON_REG.UART_Status_1 & LEON_REG_UART_STATUS_THE) !=
0161 LEON_REG_UART_STATUS_THE );
0162
0163 while ( (LEON_REG.UART_Status_2 & LEON_REG_UART_STATUS_THE) !=
0164 LEON_REG_UART_STATUS_THE );
0165
0166 LEON_REG.UART_Control_1 = 0;
0167 LEON_REG.UART_Control_2 = 0;
0168 LEON_REG.UART_Status_1 = 0;
0169 LEON_REG.UART_Status_2 = 0;
0170
0171
0172 }
0173
0174 #define CONSOLE_UART_1_TRAP LEON_TRAP_TYPE( LEON_INTERRUPT_UART_1_RX_TX )
0175 #define CONSOLE_UART_2_TRAP LEON_TRAP_TYPE( LEON_INTERRUPT_UART_2_RX_TX )
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190 #ifdef RDB_BREAK_IN
0191 extern uint32_t trap_table[];
0192 #endif
0193
0194 void console_initialize_interrupts( void )
0195 {
0196 Ring_buffer_Initialize( &TX_Buffer[ 0 ] );
0197 Ring_buffer_Initialize( &TX_Buffer[ 1 ] );
0198
0199 Is_TX_active[ 0 ] = false;
0200 Is_TX_active[ 1 ] = false;
0201
0202 atexit( console_exit );
0203
0204 LEON_REG.UART_Control_1 |= LEON_REG_UART_CTRL_RI | LEON_REG_UART_CTRL_TI;
0205 LEON_REG.UART_Control_2 |= LEON_REG_UART_CTRL_RI | LEON_REG_UART_CTRL_TI;
0206
0207 set_vector( console_isr_a, CONSOLE_UART_1_TRAP, 1 );
0208 #ifdef RDB_BREAK_IN
0209 if (trap_table[0x150/4] == 0x91d02000)
0210 #endif
0211 set_vector( console_isr_b, CONSOLE_UART_2_TRAP, 1 );
0212 }
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228 void console_outbyte_interrupt(
0229 int port,
0230 char ch
0231 )
0232 {
0233
0234
0235
0236
0237 if ( Is_TX_active[ port ] == false ) {
0238 Is_TX_active[ port ] = true;
0239 console_outbyte_polled( port, ch );
0240 return;
0241 }
0242
0243 while ( Ring_buffer_Is_full( &TX_Buffer[ port ] ) );
0244
0245 Ring_buffer_Add_character( &TX_Buffer[ port ], ch );
0246 }
0247
0248 #endif
0249
0250
0251
0252
0253
0254
0255 static ssize_t console_write_support (int minor, const char *buf, size_t len)
0256 {
0257 int nwrite = 0;
0258
0259 while (nwrite < len) {
0260 #if (CONSOLE_USE_INTERRUPTS)
0261 console_outbyte_interrupt( minor, *buf++ );
0262 #else
0263 console_outbyte_polled( minor, *buf++ );
0264 #endif
0265 nwrite++;
0266 }
0267 return nwrite;
0268 }
0269
0270
0271
0272
0273
0274
0275 rtems_device_driver console_initialize(
0276 rtems_device_major_number major,
0277 rtems_device_minor_number minor,
0278 void *arg
0279 )
0280 {
0281 rtems_status_code status;
0282
0283 rtems_termios_initialize();
0284
0285
0286
0287
0288
0289 status = rtems_io_register_name( "/dev/console", major, 0 );
0290 if (status != RTEMS_SUCCESSFUL)
0291 rtems_fatal_error_occurred(status);
0292
0293 status = rtems_io_register_name( "/dev/console_b", major, 1 );
0294 if (status != RTEMS_SUCCESSFUL)
0295 rtems_fatal_error_occurred(status);
0296
0297
0298
0299
0300
0301 LEON_REG.UART_Control_1 |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE;
0302 LEON_REG.UART_Control_2 |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE |
0303 LEON_REG_UART_CTRL_RI;
0304 LEON_REG.UART_Status_1 = 0;
0305 LEON_REG.UART_Status_2 = 0;
0306 #if (CONSOLE_USE_INTERRUPTS)
0307 console_initialize_interrupts();
0308 #endif
0309
0310 return RTEMS_SUCCESSFUL;
0311 }
0312
0313 rtems_device_driver console_open(
0314 rtems_device_major_number major,
0315 rtems_device_minor_number minor,
0316 void * arg
0317 )
0318 {
0319 rtems_status_code sc;
0320 #if (CONSOLE_USE_INTERRUPTS)
0321 rtems_libio_open_close_args_t *args = arg;
0322 static const rtems_termios_callbacks intrCallbacks = {
0323 NULL,
0324 NULL,
0325 NULL,
0326 console_write_support,
0327 NULL,
0328 NULL,
0329 NULL,
0330 TERMIOS_POLLED
0331 };
0332 #else
0333 static const rtems_termios_callbacks pollCallbacks = {
0334 NULL,
0335 NULL,
0336 console_inbyte_nonblocking,
0337 console_write_support,
0338 NULL,
0339 NULL,
0340 NULL,
0341 TERMIOS_POLLED
0342 };
0343 #endif
0344
0345 assert( minor <= 1 );
0346 if ( minor > 2 )
0347 return RTEMS_INVALID_NUMBER;
0348
0349 #if (CONSOLE_USE_INTERRUPTS)
0350 sc = rtems_termios_open (major, minor, arg, &intrCallbacks);
0351
0352 console_termios_data[ minor ] = args->iop->data1;
0353 #else
0354 sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
0355 #endif
0356 (void) sc;
0357
0358 return RTEMS_SUCCESSFUL;
0359 }
0360
0361 rtems_device_driver console_close(
0362 rtems_device_major_number major,
0363 rtems_device_minor_number minor,
0364 void * arg
0365 )
0366 {
0367 return rtems_termios_close (arg);
0368 }
0369
0370 rtems_device_driver console_read(
0371 rtems_device_major_number major,
0372 rtems_device_minor_number minor,
0373 void * arg
0374 )
0375 {
0376 return rtems_termios_read (arg);
0377 }
0378
0379 rtems_device_driver console_write(
0380 rtems_device_major_number major,
0381 rtems_device_minor_number minor,
0382 void * arg
0383 )
0384 {
0385 return rtems_termios_write (arg);
0386 }
0387
0388 rtems_device_driver console_control(
0389 rtems_device_major_number major,
0390 rtems_device_minor_number minor,
0391 void * arg
0392 )
0393 {
0394 return rtems_termios_ioctl (arg);
0395 }