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

4.104.114.84.95
Last change on this file since dac4208 was dac4208, checked in by Ralf Corsepius <ralf.corsepius@…>, on 03/31/04 at 03:47:07

2004-03-31 Ralf Corsepius <ralf_corsepius@…>

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