File indexing completed on 2025-05-11 08:24:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <bsp.h>
0038 #include <bsp/fatal.h>
0039 #include <rtems/libio.h>
0040 #include <rtems/console.h>
0041 #include <stdlib.h>
0042 #include <string.h>
0043 #include <assert.h>
0044 #include <termios.h>
0045
0046 #include <rtems/termiostypes.h>
0047 #include <libchip/serial.h>
0048 #include "legacy-console.h"
0049
0050 unsigned long Console_Port_Count = 0;
0051 console_tbl **Console_Port_Tbl = NULL;
0052 console_data *Console_Port_Data = NULL;
0053 rtems_device_minor_number Console_Port_Minor = 0;
0054 static bool console_initialized = false;
0055
0056
0057
0058
0059
0060
0061
0062 console_tbl* console_find_console_entry(
0063 const char *match,
0064 size_t length,
0065 rtems_device_minor_number *match_minor
0066 )
0067 {
0068 rtems_device_minor_number minor;
0069
0070
0071
0072
0073 if (match == NULL) {
0074 if (*match_minor < Console_Port_Count)
0075 return Console_Port_Tbl[*match_minor];
0076 return NULL;
0077 }
0078
0079 for (minor=0; minor < Console_Port_Count ; minor++) {
0080 console_tbl *cptr = Console_Port_Tbl[minor];
0081
0082
0083
0084
0085
0086 if ( !strncmp( cptr->sDeviceName, match, length ) ) {
0087 *match_minor = minor;
0088 return cptr;
0089 }
0090 }
0091
0092 return NULL;
0093 }
0094
0095
0096
0097
0098
0099
0100
0101 void console_initialize_data(void)
0102 {
0103 int i;
0104
0105 if ( Console_Port_Tbl )
0106 return;
0107
0108
0109
0110
0111 Console_Port_Count = Console_Configuration_Count;
0112 Console_Port_Tbl = malloc( Console_Port_Count * sizeof( console_tbl * ) );
0113 if (Console_Port_Tbl == NULL)
0114 bsp_fatal( BSP_FATAL_CONSOLE_NO_MEMORY_0 );
0115
0116
0117
0118
0119 Console_Port_Data = calloc( Console_Port_Count, sizeof( console_data ) );
0120 if ( Console_Port_Data == NULL ) {
0121 bsp_fatal( BSP_FATAL_CONSOLE_NO_MEMORY_3 );
0122 }
0123
0124
0125
0126
0127 for (i=0 ; i < Console_Port_Count ; i++) {
0128 Console_Port_Tbl[i] = &Console_Configuration_Ports[i];
0129 }
0130 }
0131
0132
0133
0134
0135
0136
0137
0138 void console_register_devices(
0139 console_tbl *new_ports,
0140 size_t number_of_ports
0141 )
0142 {
0143 int old_number_of_ports;
0144 int i;
0145
0146
0147
0148
0149 console_initialize_data();
0150
0151
0152
0153
0154
0155 if ( console_initialized ) {
0156 bsp_fatal( BSP_FATAL_CONSOLE_MULTI_INIT );
0157 }
0158
0159
0160
0161
0162 old_number_of_ports = Console_Port_Count;
0163 Console_Port_Count += number_of_ports;
0164 Console_Port_Tbl = realloc(
0165 Console_Port_Tbl,
0166 Console_Port_Count * sizeof(console_tbl *)
0167 );
0168 if ( Console_Port_Tbl == NULL ) {
0169 bsp_fatal( BSP_FATAL_CONSOLE_NO_MEMORY_1 );
0170 }
0171
0172
0173
0174
0175
0176
0177 Console_Port_Data = realloc(
0178 Console_Port_Data,
0179 Console_Port_Count * sizeof(console_data)
0180 );
0181 if ( Console_Port_Data == NULL ) {
0182 bsp_fatal( BSP_FATAL_CONSOLE_NO_MEMORY_2 );
0183 }
0184 memset(Console_Port_Data, '\0', Console_Port_Count * sizeof(console_data));
0185
0186
0187
0188
0189 for (i=0 ; i < number_of_ports ; i++) {
0190 Console_Port_Tbl[old_number_of_ports + i] = &new_ports[i];
0191 }
0192 }
0193
0194
0195
0196
0197
0198
0199 rtems_device_driver console_open(
0200 rtems_device_major_number major,
0201 rtems_device_minor_number minor,
0202 void * arg
0203 )
0204 {
0205 rtems_status_code status;
0206 rtems_libio_open_close_args_t *args = arg;
0207 rtems_libio_ioctl_args_t IoctlArgs;
0208 struct termios Termios;
0209 rtems_termios_callbacks Callbacks;
0210 console_tbl *cptr;
0211 struct rtems_termios_tty *current_tty;
0212
0213
0214
0215
0216 if ( minor > Console_Port_Count ) {
0217 return RTEMS_INVALID_NUMBER;
0218 }
0219
0220
0221
0222
0223
0224 cptr = Console_Port_Tbl[minor];
0225 Callbacks.firstOpen = cptr->pDeviceFns->deviceFirstOpen;
0226 Callbacks.lastClose = cptr->pDeviceFns->deviceLastClose;
0227 Callbacks.pollRead = cptr->pDeviceFns->deviceRead;
0228 Callbacks.write = cptr->pDeviceFns->deviceWrite;
0229 Callbacks.setAttributes = cptr->pDeviceFns->deviceSetAttributes;
0230 if (cptr->pDeviceFlow != NULL) {
0231 Callbacks.stopRemoteTx = cptr->pDeviceFlow->deviceStopRemoteTx;
0232 Callbacks.startRemoteTx = cptr->pDeviceFlow->deviceStartRemoteTx;
0233 } else {
0234 Callbacks.stopRemoteTx = NULL;
0235 Callbacks.startRemoteTx = NULL;
0236 }
0237 if (cptr->pDeviceFns->deviceOutputUsesInterrupts) {
0238 Callbacks.outputUsesInterrupts = TERMIOS_IRQ_DRIVEN;
0239 } else {
0240 Callbacks.outputUsesInterrupts = TERMIOS_POLLED;
0241 }
0242
0243
0244
0245
0246
0247
0248 status = rtems_termios_open( major, minor, arg, &Callbacks );
0249 Console_Port_Data[minor].termios_data = args->iop->data1;
0250
0251
0252 current_tty = Console_Port_Data[minor].termios_data;
0253
0254 if ( (current_tty->refcount == 1) ) {
0255
0256
0257
0258
0259 #if defined(BSP_DEFAULT_BAUD_RATE)
0260 rtems_termios_set_initial_baud( current_tty, BSP_DEFAULT_BAUD_RATE );
0261 #endif
0262
0263
0264
0265
0266 if ( minor != Console_Port_Minor ) {
0267
0268
0269
0270 IoctlArgs.iop = args->iop;
0271 IoctlArgs.command = TIOCGETA;
0272 IoctlArgs.buffer = &Termios;
0273 rtems_termios_ioctl( &IoctlArgs );
0274
0275 Termios.c_lflag = ICANON;
0276 IoctlArgs.command = TIOCSETA;
0277 rtems_termios_ioctl( &IoctlArgs );
0278 }
0279 }
0280
0281 if (rtems_libio_iop_is_readable(args->iop) &&
0282 cptr->pDeviceFlow &&
0283 cptr->pDeviceFlow->deviceStartRemoteTx) {
0284 cptr->pDeviceFlow->deviceStartRemoteTx(minor);
0285 }
0286
0287 return status;
0288 }
0289
0290
0291
0292
0293
0294
0295 rtems_device_driver console_close(
0296 rtems_device_major_number major,
0297 rtems_device_minor_number minor,
0298 void * arg
0299 )
0300 {
0301 rtems_libio_open_close_args_t *args = arg;
0302 struct rtems_termios_tty *current_tty;
0303 console_tbl *cptr;
0304
0305 cptr = Console_Port_Tbl[minor];
0306
0307
0308 current_tty = Console_Port_Data[minor].termios_data;
0309
0310
0311
0312
0313 if ( (current_tty->refcount == 1) ) {
0314 if (rtems_libio_iop_is_readable(args->iop) &&
0315 cptr->pDeviceFlow &&
0316 cptr->pDeviceFlow->deviceStopRemoteTx) {
0317 cptr->pDeviceFlow->deviceStopRemoteTx(minor);
0318 }
0319 }
0320
0321 return rtems_termios_close (arg);
0322 }
0323
0324
0325
0326
0327
0328
0329 rtems_device_driver console_initialize(
0330 rtems_device_major_number major,
0331 rtems_device_minor_number minor_arg,
0332 void *arg
0333 )
0334 {
0335 rtems_status_code status;
0336 rtems_device_minor_number minor;
0337 console_tbl *port;
0338
0339
0340
0341
0342
0343
0344 console_initialize_data();
0345
0346
0347
0348
0349
0350 console_initialized = true;
0351
0352
0353
0354
0355
0356
0357 rtems_termios_initialize();
0358 bsp_console_select();
0359
0360
0361
0362
0363
0364 for (minor=0 ; minor < Console_Port_Count ; minor++) {
0365
0366
0367
0368
0369 port = Console_Port_Tbl[minor];
0370
0371 if ( (!port->deviceProbe || port->deviceProbe(minor)) &&
0372 port->pDeviceFns->deviceProbe(minor)) {
0373
0374 if (port->sDeviceName != NULL) {
0375 status = rtems_io_register_name( port->sDeviceName, major, minor );
0376 if (status != RTEMS_SUCCESSFUL) {
0377 bsp_fatal( BSP_FATAL_CONSOLE_REGISTER_DEV_0 );
0378 }
0379 }
0380
0381 if (minor == Console_Port_Minor) {
0382 status = rtems_io_register_name( CONSOLE_DEVICE_NAME, major, minor );
0383 if (status != RTEMS_SUCCESSFUL) {
0384 bsp_fatal( BSP_FATAL_CONSOLE_REGISTER_DEV_1 );
0385 }
0386 }
0387
0388
0389
0390
0391 port->pDeviceFns->deviceInitialize(minor);
0392
0393 }
0394 }
0395
0396 return RTEMS_SUCCESSFUL;
0397 }
0398
0399
0400
0401
0402
0403
0404 rtems_device_driver console_read(
0405 rtems_device_major_number major,
0406 rtems_device_minor_number minor,
0407 void * arg
0408 )
0409 {
0410 return rtems_termios_read (arg);
0411 }
0412
0413
0414
0415
0416
0417
0418 rtems_device_driver console_write(
0419 rtems_device_major_number major,
0420 rtems_device_minor_number minor,
0421 void * arg
0422 )
0423 {
0424 return rtems_termios_write (arg);
0425 }