source: rtems/c/src/lib/libbsp/powerpc/score603e/console/console.c @ c42bd452

4.104.114.84.9
Last change on this file since c42bd452 was c42bd452, checked in by Joel Sherrill <joel.sherrill@…>, on Nov 2, 1999 at 4:05:41 PM

Split console_reserve_resources into its own file to reduce dependencies.
Still need to move debug io routines out.

  • Property mode set to 100644
File size: 9.8 KB
Line 
1/*
2 *  This file contains the TTY driver for the serial ports on the SCORE603e.
3 *
4 *  This driver uses the termios pseudo driver.
5 *
6 *  Currently only polled mode is supported.
7 *
8 *  COPYRIGHT (c) 1989-1997.
9 *  On-Line Applications Research Corporation (OAR).
10 *  Copyright assigned to U.S. Government, 1994.
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.OARcorp.com/rtems/license.html.
15 *
16 *  $Id$
17 */
18
19#include <bsp.h>
20#include <rtems/libio.h>
21#include <stdlib.h>
22#include <assert.h>
23
24#include "consolebsp.h"
25
26#if (1)
27/*
28 * The Port Used for the Console interface is based upon which
29 * debugger is being used.  The SDS debugger uses a binary
30 * interface on port 0 as part of the debugger.  Thus port 0 can
31 * not be used as the console port for the SDS debugger.
32 */
33
34#if (SCORE603E_USE_SDS)
35#define USE_FOR_CONSOLE_DEF  1
36
37#elif (SCORE603E_USE_OPEN_FIRMWARE)
38#define USE_FOR_CONSOLE_DEF  0
39
40#elif (SCORE603E_USE_NONE)
41#define USE_FOR_CONSOLE_DEF  0
42
43#elif (SCORE603E_USE_DINK)
44#define USE_FOR_CONSOLE_DEF  0
45
46#else
47#error "SCORE603E CONSOLE.C -- what ROM monitor are you using"
48#endif
49
50#endif
51
52#if (0)
53extern int USE_FOR_CONSOLE;
54#endif
55
56int USE_FOR_CONSOLE = USE_FOR_CONSOLE_DEF;
57
58/*
59 *
60 *  Console Device Driver Entry Points
61 */
62 
63/* PAGE
64 *
65 *  DEBUG_puts
66 *
67 *  This should be safe in the event of an error.  It attempts to insure
68 *  that no TX empty interrupts occur while it is doing polled IO.  Then
69 *  it restores the state of that external interrupt.
70 *
71 *  Input parameters:
72 *    string  - pointer to debug output string
73 *
74 *  Output parameters:  NONE
75 *
76 *  Return values:      NONE
77 */
78
79void DEBUG_puts(
80  char *string
81)
82{
83  char *s;
84  int   console;
85  volatile rtems_unsigned8 *csr;
86
87  console = USE_FOR_CONSOLE;
88
89  csr = Ports_85C30[ console ].ctrl;
90
91  /* should disable interrupts here */
92
93  for ( s = string ; *s ; s++ ) 
94    outbyte_polled_85c30( csr, *s );
95
96  outbyte_polled_85c30( csr, '\r' );
97  outbyte_polled_85c30( csr, '\n' );
98
99  /* should enable interrupts here */
100}
101
102/* PAGE
103 *
104 *  console_inbyte_nonblocking
105 *
106 *  Console Termios polling input entry point.
107 */
108
109int console_inbyte_nonblocking( 
110  int minor
111)
112{
113  int                       port = minor;
114
115  /*
116   * verify port Number
117   */
118  assert ( port < NUM_Z85C30_PORTS );
119 
120  /*
121   * return a character from the 85c30 port.
122   */
123  return inbyte_nonblocking_85c30( &Ports_85C30[ port ] );
124}
125 
126rtems_device_driver console_close(
127  rtems_device_major_number major,
128  rtems_device_minor_number minor,
129  void                    * arg
130)
131{
132  return rtems_termios_close (arg);
133}
134 
135rtems_device_driver console_read(
136  rtems_device_major_number major,
137  rtems_device_minor_number minor,
138  void                    * arg
139)
140{
141  return rtems_termios_read (arg);
142}
143 
144rtems_device_driver console_write(
145  rtems_device_major_number major,
146  rtems_device_minor_number minor,
147  void                    * arg
148)
149{
150  return rtems_termios_write (arg);
151}
152 
153rtems_device_driver console_control(
154  rtems_device_major_number major,
155  rtems_device_minor_number minor,
156  void                    * arg
157)
158{
159  return rtems_termios_ioctl (arg);
160}
161
162
163
164/*
165 *  Interrupt driven console IO
166 */
167
168#if CONSOLE_USE_INTERRUPTS
169
170rtems_isr console_isr(
171  rtems_vector_number vector
172)
173{
174  int  i;
175 
176  for (i=0; i < NUM_Z85C30_PORTS; i++){
177      ISR_85c30_Async( &Ports_85C30[i] );
178
179#if (0) /* XXX - TO TEST LOOP BACKS comment this out. */
180    if ( Ports_85C30[i].Chip->vector == vector ) {
181      ISR_85c30_Async( &Ports_85C30[i] );
182    }
183#endif
184  } 
185}
186
187void console_exit()
188{
189  int i;
190  volatile Ring_buffer_t *buffer;
191  rtems_unsigned32 ch;
192
193  for ( i=0 ; i < NUM_Z85C30_PORTS ; i++ ) {
194   
195    buffer = &( Ports_85C30[i].Protocol->TX_Buffer);
196
197    while ( !Ring_buffer_Is_empty( buffer ) ) {
198      Ring_buffer_Remove_character( buffer, ch );
199      outbyte_polled_85c30( Ports_85C30[i].ctrl, ch ); 
200    }
201  }
202}
203
204void console_initialize_interrupts( void )
205{
206  volatile Ring_buffer_t     *buffer;
207  Console_Protocol  *protocol;
208  int               i;
209 
210  for ( i=0 ; i < NUM_Z85C30_PORTS ; i++ ) {
211    protocol = Ports_85C30[i].Protocol;
212
213    /*
214     * Initialize the ring buffer and set to not transmitting.
215     */
216    buffer = &protocol->TX_Buffer;
217    Ring_buffer_Initialize( buffer );
218    protocol->Is_TX_active = FALSE;
219  }
220
221  /*
222   * Connect each vector to the interupt service routine.
223   */
224  for (i=0; i < NUM_Z85C30_CHIPS; i++)
225    set_vector( console_isr, Chips_85C30[i].vector, 1 );
226 
227
228  atexit( console_exit );
229   
230}
231void console_outbyte_interrupts(
232  const Port_85C30_info *Port,
233  char ch
234);
235
236/* XXXXXX */
237#endif
238
239
240/* PAGE
241 *
242 *  console_initialize
243 *
244 *  Routine called to initialize the console device driver.
245 */
246rtems_device_driver console_initialize(
247  rtems_device_major_number  major,
248  rtems_device_minor_number  minor,
249  void                      *arg
250)
251{
252  rtems_status_code          status;
253  rtems_device_minor_number  console;
254  int                        port, chip, p0,p1;
255
256  /*
257   * initialize the termio interface.
258   */
259  rtems_termios_initialize();
260
261  /*
262   *  Register Device Names
263   */
264  console = USE_FOR_CONSOLE;
265  status = rtems_io_register_name( "/dev/console", major, console );
266  if (status != RTEMS_SUCCESSFUL)
267    rtems_fatal_error_occurred(status);
268
269  /*
270   *  Initialize Hardware
271   */
272
273
274/*
275 * INITIALIZE_COM_PORTS is defined in the linker script.  If it is
276 * true all serial chips on the board are to be reset at startup
277 * otherwise the reset is assumed to occur elsewhere (ie. in the
278 * debugger...)
279 */
280#if ( INITIALIZE_COM_PORTS )
281
282  /*
283   * Force to perform a hardware reset w/o
284   * Master interrupt enable via register 9
285   */
286 
287  for (port=0; port<NUM_Z85C30_PORTS; port++){
288    p0 = port;
289    port++;
290    p1 = port;
291    Reset_85c30_chip( Ports_85C30[p0].ctrl, Ports_85C30[p1].ctrl );
292  }
293#else
294  /* TEMP - To see if this makes a diff with the new ports.
295   *        Never reset chip 1 when using the chip as a monitor
296   */
297  for (port=2; port<NUM_Z85C30_PORTS; port++){
298    p0 = port;
299    port++;
300    p1 = port;
301    Reset_85c30_chip( Ports_85C30[p0].ctrl, Ports_85C30[p1].ctrl );
302  }
303#endif
304
305  /*
306   * Initialize each port.
307   * Note:  the ports are numbered such that 0,1 are on the first chip
308   *        2,3 are on the second ....
309   */
310
311  for (port=0; port<NUM_Z85C30_PORTS; port++) {
312    chip = port >> 1;
313    initialize_85c30_port( &Ports_85C30[port] );
314  }
315
316#if CONSOLE_USE_INTERRUPTS
317  console_initialize_interrupts();
318#endif
319
320  return RTEMS_SUCCESSFUL;
321}
322
323/* PAGE
324 *
325 *  console_write_support
326 *
327 *  Console Termios output entry point.
328 *
329 */
330int console_write_support(
331  int   minor, 
332  const char *buf, 
333  int   len)
334{
335  int nwrite = 0;
336  volatile rtems_unsigned8 *csr;
337  int                       port = minor;
338
339  /*
340   * verify port Number
341   */
342  assert ( port < NUM_Z85C30_PORTS );
343
344  /*
345   * Set the csr based upon the port number.
346   */
347  csr = Ports_85C30[ port ].ctrl;
348
349  /*
350   * poll each byte in the string out of the port.
351   */
352  while (nwrite < len) {
353#if (CONSOLE_USE_INTERRUPTS)
354    console_outbyte_interrupts( &Ports_85C30[ port ], *buf++ );
355#else
356    outbyte_polled_85c30( csr, *buf++ );
357#endif
358   nwrite++;
359  }
360
361  /*
362   * return the number of bytes written.
363   */
364  return nwrite;
365}
366
367/* PAGE
368 *
369 *  console_open
370 *
371 *  open a port as a termios console.
372 *
373 */
374rtems_device_driver console_open(
375  rtems_device_major_number major,
376  rtems_device_minor_number minor,
377  void                    * arg
378)
379{
380  rtems_status_code sc;
381  int               port = minor;
382#if (CONSOLE_USE_INTERRUPTS)
383  rtems_libio_open_close_args_t *args = arg;
384  static const rtems_termios_callbacks intrCallbacks = {
385    NULL,                       /* firstOpen */
386    NULL,                       /* lastClose */
387    NULL,                       /* pollRead */
388    console_write_support,      /* write */
389    NULL,                       /* setAttributes */
390    NULL,                       /* stopRemoteTx */
391    NULL,                       /* startRemoteTx */
392    1                           /* outputUsesInterrupts */
393  };
394#else
395  static const rtems_termios_callbacks pollCallbacks = {
396    NULL,                       /* firstOpen */
397    NULL,                       /* lastClose */
398    console_inbyte_nonblocking, /* pollRead */
399    console_write_support,      /* write */
400    NULL,                       /* setAttributes */
401    NULL,                       /* stopRemoteTx */
402    NULL,                       /* startRemoteTx */
403    0                           /* outputUsesInterrupts */
404  };
405#endif
406
407
408  /*
409   * Verify the minor number is valid.
410   */
411  if (minor < 0)
412    return RTEMS_INVALID_NUMBER;
413
414  if ( port > NUM_Z85C30_PORTS )
415     return RTEMS_INVALID_NUMBER;
416
417  /*
418   *  open the port as a termios console driver.
419   */
420
421#if (CONSOLE_USE_INTERRUPTS)
422   sc = rtems_termios_open( major, minor, arg, &intrCallbacks );
423
424   Ports_85C30[ minor ].Protocol->console_termios_data = args->iop->data1;
425#else
426   sc = rtems_termios_open( major, minor, arg, &pollCallbacks );
427#endif
428
429  return sc;
430}
431
432
433#if (CONSOLE_USE_INTERRUPTS)
434
435/*
436 *  console_outbyte_interrupts
437 *
438 *  This routine transmits a character out.
439 *
440 *  Input parameters:
441 *    port - port to transmit character to
442 *    ch  - character to be transmitted
443 *
444 *  Output parameters:  NONE
445 *
446 *  Return values:      NONE
447 */
448void console_outbyte_interrupts(
449  const Port_85C30_info *Port,
450  char ch
451)
452{
453  Console_Protocol   *protocol;
454  rtems_unsigned32    isrlevel;
455
456  protocol = Port->Protocol;
457 
458  /*
459   *  If this is the first character then we need to prime the pump
460   */
461
462  if ( protocol->Is_TX_active == FALSE ) {
463
464    rtems_interrupt_disable( isrlevel );
465    protocol->Is_TX_active = TRUE;
466    outbyte_polled_85c30( Port->ctrl, ch );
467    rtems_interrupt_enable( isrlevel );
468
469    return;
470  }
471
472  while ( Ring_buffer_Is_full( &protocol->TX_Buffer ) );
473 
474  Ring_buffer_Add_character( &protocol->TX_Buffer, ch );
475}
476
477#endif
478
479
480
481
482
483
484
485
486
487
488
Note: See TracBrowser for help on using the repository browser.