Changeset 92a6454 in rtems
- Timestamp:
- 07/05/98 11:00:00 (25 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- e7ff2b2
- Parents:
- 0e8c2000
- Location:
- c/src/lib/libbsp/powerpc/dmv177/console
- Files:
-
- 5 added
- 1 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/lib/libbsp/powerpc/dmv177/console/Makefile.in
r0e8c2000 r92a6454 12 12 13 13 # C source names, if any, go here -- minus the .c 14 C_PIECES=con sole duart14 C_PIECES=config console debugio mc68681cfg z85c30cfg 15 15 C_FILES=$(C_PIECES:%=%.c) 16 16 C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) -
c/src/lib/libbsp/powerpc/dmv177/console/console.c
r0e8c2000 r92a6454 1 1 /* 2 * console.c2 * This file contains the TTY driver for the PPCn_60x 3 3 * 4 4 * This driver uses the termios pseudo driver. 5 5 * 6 * Currently only polled mode is supported. 7 * 8 * COPYRIGHT (c) 1989-1998. 6 * COPYRIGHT (c) 1998 by Radstone Technology 7 * 8 * 9 * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY 10 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 11 * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK 12 * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU. 13 * 14 * You are hereby granted permission to use, copy, modify, and distribute 15 * this file, provided that this notice, plus the above copyright notice 16 * and disclaimer, appears in all copies. Radstone Technology will provide 17 * no support for this code. 18 * 19 * COPYRIGHT (c) 1989-1997. 9 20 * On-Line Applications Research Corporation (OAR). 10 21 * Copyright assigned to U.S. Government, 1994. … … 14 25 * http://www.OARcorp.com/rtems/license.html. 15 26 * 16 * $Id: console.c 17 */ 18 19 #include <stdlib.h> 20 #include <motorola/mc68681.h> 27 * $Id$ 28 */ 29 21 30 #include <bsp.h> 22 31 #include <rtems/libio.h> 32 #include <stdlib.h> 23 33 #include <assert.h> 24 25 #define COM1 0 26 #define COM2 1 27 #define NUM_PORTS 2 28 #define USE_FOR_CONSOLE COM2 34 #include <termios.h> 35 36 #include <libchip/serial.h> 29 37 30 38 /* 31 * Define RDB_BREAK_IN if you need to be able to break in to the 32 * program with a ctrl-c during remote target debugging. If so, 33 * UART B will not be accessible from rtems during remote debugging 34 * if interrupt driven console is used. Does not affect UART A, polled 35 * mode or when the program runs without remote debugging. 36 */ 37 #define RDB_BREAK_IN 38 39 /* Proto-types for Duart.C */ 40 void console_initialize_interrupts( void ); 41 int console_inbyte_nonblocking( int port ); 42 void console_outbyte_polled(int port, char ch); 43 rtems_isr console_isr (rtems_vector_number vector); 44 volatile void init_mc88681(); 45 46 /* PAGE 39 * Load configuration table 40 */ 41 42 extern console_data Console_Port_Data[]; 43 extern unsigned long Console_Port_Count; 44 extern rtems_device_minor_number Console_Port_Minor; 45 46 /* PAGE 47 * 48 * console_open 49 * 50 * open a port as a termios console. 51 * 52 */ 53 rtems_device_driver console_open( 54 rtems_device_major_number major, 55 rtems_device_minor_number minor, 56 void * arg 57 ) 58 { 59 rtems_status_code status; 60 rtems_libio_open_close_args_t *args = arg; 61 rtems_libio_ioctl_args_t IoctlArgs; 62 struct termios Termios; 63 rtems_termios_callbacks Callbacks; 64 console_tbl *cptr; 65 66 /* 67 * Verify the port number is valid. 68 */ 69 if ( minor > Console_Port_Count ) { 70 return RTEMS_INVALID_NUMBER; 71 } 72 73 /* 74 * Open the port as a termios console driver. 75 */ 76 77 cptr = &Console_Port_Tbl[minor]; 78 Callbacks.firstOpen = cptr->pDeviceFns->deviceFirstOpen; 79 Callbacks.lastClose = cptr->pDeviceFns->deviceLastClose; 80 Callbacks.pollRead = cptr->pDeviceFns->deviceRead; 81 Callbacks.write = cptr->pDeviceFns->deviceWrite; 82 Callbacks.setAttributes = cptr->pDeviceFns->deviceSetAttributes; 83 Callbacks.stopRemoteTx = cptr->pDeviceFlow->deviceStopRemoteTx; 84 Callbacks.startRemoteTx = cptr->pDeviceFlow->deviceStartRemoteTx; 85 Callbacks.outputUsesInterrupts = cptr->pDeviceFns->deviceOutputUsesInterrupts; 86 87 /* XXX what about 88 * Console_Port_Tbl[minor].ulMargin, 89 * Console_Port_Tbl[minor].ulHysteresis); 90 */ 91 92 status = rtems_termios_open ( major, minor, arg, &Callbacks ); 93 Console_Port_Data[minor].termios_data = args->iop->data1; 94 95 if (minor!=Console_Port_Minor) { 96 /* 97 * If this is not the console we do not want ECHO and 98 * so forth 99 */ 100 IoctlArgs.iop=args->iop; 101 IoctlArgs.command=RTEMS_IO_GET_ATTRIBUTES; 102 IoctlArgs.buffer=&Termios; 103 rtems_termios_ioctl(&IoctlArgs); 104 Termios.c_lflag=ICANON; 105 IoctlArgs.command=RTEMS_IO_SET_ATTRIBUTES; 106 rtems_termios_ioctl(&IoctlArgs); 107 } 108 109 if ( (args->iop->flags&LIBIO_FLAGS_READ) && 110 Console_Port_Tbl[minor].pDeviceFlow && 111 Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx) { 112 Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx(minor); 113 } 114 115 return status; 116 } 117 118 void console_reserve_resources( 119 rtems_configuration_table *configuration 120 ) 121 { 122 rtems_termios_reserve_resources( configuration, 4 ); 123 } 124 125 126 rtems_device_driver console_close( 127 rtems_device_major_number major, 128 rtems_device_minor_number minor, 129 void * arg 130 ) 131 { 132 rtems_libio_open_close_args_t *args = arg; 133 134 if ( (args->iop->flags&LIBIO_FLAGS_READ) && 135 Console_Port_Tbl[minor].pDeviceFlow && 136 Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx) { 137 Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx(minor); 138 } 139 140 return rtems_termios_close (arg); 141 } 142 143 rtems_device_driver console_read( 144 rtems_device_major_number major, 145 rtems_device_minor_number minor, 146 void * arg 147 ) 148 { 149 return rtems_termios_read (arg); 150 } 151 152 rtems_device_driver console_write( 153 rtems_device_major_number major, 154 rtems_device_minor_number minor, 155 void * arg 156 ) 157 { 158 return rtems_termios_write (arg); 159 } 160 161 rtems_device_driver console_control( 162 rtems_device_major_number major, 163 rtems_device_minor_number minor, 164 void * arg 165 ) 166 { 167 return rtems_termios_ioctl (arg); 168 } 169 170 /* PAGE 47 171 * 48 172 * console_initialize 49 173 * 50 * This routine initializes the console IO driver. 51 * 52 * Input parameters: 53 * major - console device major number 54 * minor - console device minor number 55 * arg - pointer to optional device driver arguments 56 * 57 * Output parameters: NONE 58 * 59 * Return values: 60 * rtems_device_driver status code 61 */ 62 174 * Routine called to initialize the console device driver. 175 */ 176 63 177 rtems_device_driver console_initialize( 64 178 rtems_device_major_number major, … … 67 181 ) 68 182 { 69 rtems_status_code status; 70 int console; 183 rtems_status_code status; 71 184 72 185 /* 73 186 * initialize the termio interface. 74 187 */ 188 75 189 rtems_termios_initialize(); 76 190 77 /* 78 * Register Device Names 79 */ 80 console = USE_FOR_CONSOLE; 81 status = rtems_io_register_name( "/dev/console", major, console ); 82 if (status != RTEMS_SUCCESSFUL) 191 for (minor=0; minor<Console_Port_Count; minor++) { 192 /* 193 * First perform the configuration dependent probe, then the 194 * device dependent probe 195 */ 196 197 if ((!Console_Port_Tbl[minor].deviceProbe || 198 Console_Port_Tbl[minor].deviceProbe(minor)) && 199 Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor)) { 200 /* 201 * Use this device for the console 202 */ 203 break; 204 } 205 } 206 if ( minor==Console_Port_Count ) { 207 /* 208 * Failed to find a working device 209 */ 210 rtems_fatal_error_occurred(RTEMS_IO_ERROR); 211 } 212 213 Console_Port_Minor=minor; 214 215 /* 216 * Register Device Names 217 */ 218 status = rtems_io_register_name("/dev/console", major, Console_Port_Minor ); 219 if (status != RTEMS_SUCCESSFUL) { 83 220 rtems_fatal_error_occurred(status); 84 85 /* 86 * Initialize Hardware 87 */ 88 89 init_mc88681 (); 90 91 #if CONSOLE_USE_INTERRUPTS 92 console_initialize_interrupts(); 93 #endif 94 221 } 222 Console_Port_Tbl[minor].pDeviceFns->deviceInitialize(Console_Port_Minor); 223 224 for (minor++;minor<Console_Port_Count;minor++) { 225 /* 226 * First perform the configuration dependent probe, then the 227 * device dependent probe 228 */ 229 230 if ( (!Console_Port_Tbl[minor].deviceProbe || 231 Console_Port_Tbl[minor].deviceProbe(minor)) && 232 Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor)) { 233 status = rtems_io_register_name( 234 Console_Port_Tbl[minor].sDeviceName, 235 major, 236 minor ); 237 if (status != RTEMS_SUCCESSFUL) { 238 rtems_fatal_error_occurred(status); 239 } 240 241 /* 242 * Initialize the hardware device. 243 */ 244 245 Console_Port_Tbl[minor].pDeviceFns->deviceInitialize(minor); 246 247 } 248 } 249 95 250 return RTEMS_SUCCESSFUL; 96 251 } 97 252 98 /* PAGE99 *100 * console_write_support101 *102 * This routine is Console Termios output entry point.103 *104 * Input parameters:105 * minor - console device minor number106 * buf - buffer of data to be written107 * len - length of data to be written108 *109 * Output parameters: NONE110 *111 * Return values:112 * int number of bytes written113 */114 115 int console_write_support(116 int minor,117 const char *buf,118 int len)119 {120 int nwrite = 0;121 int port = minor;122 123 /*124 * verify port Number125 */126 assert ( port < NUM_PORTS );127 128 /*129 * poll each byte in the string out of the port.130 */131 while (nwrite < len) {132 #if CONSOLE_USE_INTERRUPTS133 #else134 console_outbyte_polled(port, *buf++);135 #endif136 nwrite++;137 }138 139 /*140 * return the number of bytes written.141 */142 return nwrite;143 }144 145 146 /* PAGE147 *148 * DEBUG_puts149 *150 * This should be safe in the event of an error. It attempts to insure151 * that no TX empty interrupts occur while it is doing polled IO. Then152 * it restores the state of that external interrupt.153 *154 * Input parameters:155 * string - pointer to debug output string156 *157 * Output parameters: NONE158 *159 * Return values: NONE160 */161 162 void DEBUG_puts(163 char *string164 )165 {166 char *s;167 rtems_unsigned32 isrlevel;168 169 rtems_interrupt_disable( isrlevel );170 for ( s = string ; *s ; s++ )171 console_outbyte_polled( 0, *s );172 173 console_outbyte_polled( 0, '\r' );174 console_outbyte_polled( 0, '\n' );175 rtems_interrupt_enable( isrlevel );176 }177 178 179 /* PAGE180 *181 * console_open182 *183 * This routine is the console device driver open entry point.184 *185 * Input parameters:186 * major - console device major number187 * minor - console device minor number188 * arg - pointer to optional device driver arguments189 *190 * Output parameters: NONE191 *192 * Return values:193 * rtems_device_driver status code194 */195 196 rtems_device_driver console_open(197 rtems_device_major_number major,198 rtems_device_minor_number minor,199 void * arg200 )201 {202 rtems_status_code sc;203 int port = minor;204 static const rtems_termios_callbacks pollCallbacks = {205 NULL, /* firstOpen */206 NULL, /* lastClose */207 console_inbyte_nonblocking, /* pollRead */208 console_write_support, /* write */209 NULL, /* setAttributes */210 NULL, /* stopRemoteTx */211 NULL, /* startRemoteTx */212 0 /* outputUsesInterrupts */213 };214 215 /*216 * Verify the minor number is valid.217 */218 if (minor < 0)219 return RTEMS_INVALID_NUMBER;220 221 if ( port > NUM_PORTS )222 return RTEMS_INVALID_NUMBER;223 224 /*225 * open the port as a termios console driver.226 */227 sc = rtems_termios_open (major, minor, arg, &pollCallbacks);228 229 return sc;230 }231 232 233 234 /* PAGE235 *236 * console_reserve_resources237 *238 * This routine reserves resources for each port which may be239 * used as a console.240 *241 * Input parameters:242 * configuration - rtems configuration table.243 *244 * Output parameters: NONE245 *246 * Return values: NONE247 */248 249 void console_reserve_resources(250 rtems_configuration_table *configuration251 )252 {253 rtems_termios_reserve_resources( configuration, NUM_PORTS );254 }255 256 /* PAGE257 *258 * console_close259 *260 * This routine is the console device driver close entry point.261 *262 * Input parameters:263 * major - console device major number264 * minor - console device minor number265 * arg - pointer to optional device driver arguments266 *267 * Output parameters: NONE268 *269 * Return values:270 * rtems_device_driver status code271 */272 273 rtems_device_driver console_close(274 rtems_device_major_number major,275 rtems_device_minor_number minor,276 void * arg277 )278 {279 return rtems_termios_close (arg);280 }281 282 /* PAGE283 *284 * console_read285 *286 * This routine is the console device driver read entry point.287 *288 * Input parameters:289 * major - console device major number290 * minor - console device minor number291 * arg - pointer to optional device driver arguments292 *293 * Output parameters: NONE294 *295 * Return values:296 * rtems_device_driver status code297 *298 */299 rtems_device_driver console_read(300 rtems_device_major_number major,301 rtems_device_minor_number minor,302 void * arg303 )304 {305 return rtems_termios_read (arg);306 }307 308 /* PAGE309 *310 * console_write311 *312 * This routine is the console device driver write entry point.313 *314 * Input parameters:315 * major - console device major number316 * minor - console device minor number317 * arg - pointer to optional device driver arguments318 *319 * Output parameters: NONE320 *321 * Return values:322 * rtems_device_driver status code323 *324 */325 rtems_device_driver console_write(326 rtems_device_major_number major,327 rtems_device_minor_number minor,328 void * arg329 )330 {331 return rtems_termios_write (arg);332 }333 334 /* PAGE335 *336 * console_control337 *338 * This routine is console device driver control entry point339 *340 * Input parameters:341 * major - console device major number342 * minor - console device minor number343 * arg - pointer to optional device driver arguments344 *345 * Output parameters: NONE346 *347 * Return values:348 * rtems_device_driver status code349 *350 */351 rtems_device_driver console_control(352 rtems_device_major_number major,353 rtems_device_minor_number minor,354 void * arg355 )356 {357 return rtems_termios_ioctl (arg);358 }359 360 361 /*362 * Interrupt driven console IO363 */364 365 #if CONSOLE_USE_INTERRUPTS366 367 /*368 * Buffers between task and ISRs369 */370 371 #include <ringbuf.h>372 extern Ring_buffer_t TX_Buffer[2];373 extern Ring_buffer_t RX_Buffer[2];374 375 /*376 * console_inbyte_interrupts377 *378 * This routine reads a character from the UART.379 *380 * Input parameters: NONE381 *382 * Output parameters: NONE383 *384 * Return values:385 * character read from UART386 */387 388 char console_inbyte_interrupts( int port )389 {390 char ch;391 392 while ( Ring_buffer_Is_empty( &RX_Buffer[ port ] ) );393 394 Ring_buffer_Remove_character( &RX_Buffer[ port ], ch );395 return ch;396 }397 398 /*399 * console_outbyte_interrupts400 *401 * This routine transmits a character out.402 *403 * Input parameters:404 * port - port to transmit character to405 * ch - character to be transmitted406 *407 * Output parameters: NONE408 *409 * Return values: NONE410 */411 412 void console_outbyte_interrupts(413 int port,414 char ch415 )416 {417 /*418 * If this is the first character then we need to prime the pump419 */420 421 if ( Is_TX_active[ port ] == FALSE ) {422 Is_TX_active[ port ] = TRUE;423 console_outbyte_polled( port, ch );424 return;425 }426 427 while ( Ring_buffer_Is_full( &TX_Buffer[ port ] ) );428 429 Ring_buffer_Add_character( &TX_Buffer[ port ], ch );430 }431 432 /*433 * console_exit434 *435 * This routine allows the console to exit by masking its associated interrupt436 * vectors.437 *438 * Input parameters: NONE439 *440 * Output parameters: NONE441 *442 * Return values: NONE443 */444 445 void console_exit()446 {447 volatile unsigned char *_addr;448 int port;449 450 /*451 * Although the interrupts for the UART are unmasked, the PIL is set to452 * disable all external interrupts. So we might as well do this first.453 */454 455 /* ??? Mask All UART Interrupts */456 457 for (port = MC68681_PORT_A; port <= MC68681_PORT_B; port++) {458 while (!Ring_buffer_Is_empty (&TX_Buffer[port])) {459 Ring_buffer_Remove_character (&TX_Buffer[port],ch);460 console_outbyte_polled (port,ch);461 }462 }463 464 /*465 * Now wait for all the data to actually get out ... the send register466 * should be empty.467 */468 _addr = (unsigned char *) (DUART_ADDR + MC68681_STATUS_REG_A);469 while (!(*_addr & MC68681_TX_EMPTY));470 471 _addr = (unsigned char *) (DUART_ADDR + MC68681_STATUS_REG_B);472 while (!(*_addr & MC68681_TX_EMPTY));473 }474 #endif /* CONSOLE_USE_INTERRUPTS */
Note: See TracChangeset
for help on using the changeset viewer.