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

4.104.114.84.9
Last change on this file since 50f93fb was 50f93fb, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 17, 2007 at 2:09:43 PM

2007-09-17 Joel Sherrill <joel.sherrill@…>

  • PCI_bus/universe.c, console/console.c, include/bsp.h, irq/FPGA.c, startup/bspstart.c, startup/genpvec.c, startup/spurious.c: Eliminate DEBUG_puts.
  • Property mode set to 100644
File size: 9.5 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#include <rtems/bspIo.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 *  console_inbyte_nonblocking
66 *
67 *  Console Termios polling input entry point.
68 */
69
70int console_inbyte_nonblocking(
71  int minor
72)
73{
74  int                       port = minor;
75
76  /*
77   * verify port Number
78   */
79  assert ( port < NUM_Z85C30_PORTS );
80
81  /*
82   * return a character from the 85c30 port.
83   */
84  return inbyte_nonblocking_85c30( &Ports_85C30[ port ] );
85}
86
87rtems_device_driver console_close(
88  rtems_device_major_number major,
89  rtems_device_minor_number minor,
90  void                    * arg
91)
92{
93  return rtems_termios_close (arg);
94}
95
96rtems_device_driver console_read(
97  rtems_device_major_number major,
98  rtems_device_minor_number minor,
99  void                    * arg
100)
101{
102  return rtems_termios_read (arg);
103}
104
105rtems_device_driver console_write(
106  rtems_device_major_number major,
107  rtems_device_minor_number minor,
108  void                    * arg
109)
110{
111  return rtems_termios_write (arg);
112}
113
114rtems_device_driver console_control(
115  rtems_device_major_number major,
116  rtems_device_minor_number minor,
117  void                    * arg
118)
119{
120  return rtems_termios_ioctl (arg);
121}
122
123/*
124 *  Interrupt driven console IO
125 */
126
127#if CONSOLE_USE_INTERRUPTS
128
129rtems_isr console_isr(
130  rtems_vector_number vector
131)
132{
133  int  i;
134
135  for (i=0; i < NUM_Z85C30_PORTS; i++){
136      ISR_85c30_Async( &Ports_85C30[i] );
137
138#if (0) /* XXX - TO TEST LOOP BACKS comment this out. */
139    if ( Ports_85C30[i].Chip->vector == vector ) {
140      ISR_85c30_Async( &Ports_85C30[i] );
141    }
142#endif
143  }
144}
145
146void console_exit()
147{
148  int i;
149  volatile Ring_buffer_t *buffer;
150  uint32_t         ch;
151
152  for ( i=0 ; i < NUM_Z85C30_PORTS ; i++ ) {
153
154    buffer = &( Ports_85C30[i].Protocol->TX_Buffer);
155
156    while ( !Ring_buffer_Is_empty( buffer ) ) {
157      Ring_buffer_Remove_character( buffer, ch );
158      outbyte_polled_85c30( Ports_85C30[i].ctrl, ch );
159    }
160  }
161}
162
163void console_initialize_interrupts( void )
164{
165  volatile Ring_buffer_t     *buffer;
166  Console_Protocol  *protocol;
167  int               i;
168
169  for ( i=0 ; i < NUM_Z85C30_PORTS ; i++ ) {
170    protocol = Ports_85C30[i].Protocol;
171
172    /*
173     * Initialize the ring buffer and set to not transmitting.
174     */
175    buffer = &protocol->TX_Buffer;
176    Ring_buffer_Initialize( buffer );
177    protocol->Is_TX_active = FALSE;
178  }
179
180  /*
181   * Connect each vector to the interupt service routine.
182   */
183  for (i=0; i < NUM_Z85C30_CHIPS; i++)
184    set_vector( console_isr, Chips_85C30[i].vector, 1 );
185
186  atexit( console_exit );
187
188}
189void console_outbyte_interrupts(
190  const Port_85C30_info *Port,
191  char ch
192);
193
194/* XXXXXX */
195#endif
196
197/* PAGE
198 *
199 *  console_initialize
200 *
201 *  Routine called to initialize the console device driver.
202 */
203rtems_device_driver console_initialize(
204  rtems_device_major_number  major,
205  rtems_device_minor_number  minor,
206  void                      *arg
207)
208{
209  rtems_status_code          status;
210  rtems_device_minor_number  console;
211  int                        port, chip, p0,p1;
212
213  /*
214   * initialize the termio interface.
215   */
216  rtems_termios_initialize();
217
218  /*
219   *  Register Device Names
220   */
221  console = USE_FOR_CONSOLE;
222  status = rtems_io_register_name( "/dev/console", major, console );
223  if (status != RTEMS_SUCCESSFUL)
224    rtems_fatal_error_occurred(status);
225
226  /*
227   *  Initialize Hardware
228   */
229
230/*
231 * INITIALIZE_COM_PORTS is defined in the linker script.  If it is
232 * true all serial chips on the board are to be reset at startup
233 * otherwise the reset is assumed to occur elsewhere (ie. in the
234 * debugger...)
235 */
236#if ( INITIALIZE_COM_PORTS )
237
238  /*
239   * Force to perform a hardware reset w/o
240   * Master interrupt enable via register 9
241   */
242
243  for (port=0; port<NUM_Z85C30_PORTS; port++){
244    p0 = port;
245    port++;
246    p1 = port;
247    Reset_85c30_chip( Ports_85C30[p0].ctrl, Ports_85C30[p1].ctrl );
248  }
249#else
250  /* TEMP - To see if this makes a diff with the new ports.
251   *        Never reset chip 1 when using the chip as a monitor
252   */
253  for (port=2; port<NUM_Z85C30_PORTS; port++){
254    p0 = port;
255    port++;
256    p1 = port;
257    Reset_85c30_chip( Ports_85C30[p0].ctrl, Ports_85C30[p1].ctrl );
258  }
259#endif
260
261  /*
262   * Initialize each port.
263   * Note:  the ports are numbered such that 0,1 are on the first chip
264   *        2,3 are on the second ....
265   */
266
267  for (port=0; port<NUM_Z85C30_PORTS; port++) {
268    chip = port >> 1;
269    initialize_85c30_port( &Ports_85C30[port] );
270  }
271
272#if CONSOLE_USE_INTERRUPTS
273  console_initialize_interrupts();
274#endif
275
276  return RTEMS_SUCCESSFUL;
277}
278
279/* PAGE
280 *
281 *  console_write_support
282 *
283 *  Console Termios output entry point.
284 *
285 */
286int console_write_support(
287  int   minor,
288  const char *buf,
289  int   len)
290{
291  int nwrite = 0;
292  volatile uint8_t         *csr;
293  int                       port = minor;
294
295  /*
296   * verify port Number
297   */
298  assert ( port < NUM_Z85C30_PORTS );
299
300  /*
301   * Set the csr based upon the port number.
302   */
303  csr = Ports_85C30[ port ].ctrl;
304
305  /*
306   * poll each byte in the string out of the port.
307   */
308  while (nwrite < len) {
309#if (CONSOLE_USE_INTERRUPTS)
310    console_outbyte_interrupts( &Ports_85C30[ port ], *buf++ );
311#else
312    outbyte_polled_85c30( csr, *buf++ );
313#endif
314   nwrite++;
315  }
316
317  /*
318   * return the number of bytes written.
319   */
320  return nwrite;
321}
322
323/* PAGE
324 *
325 *  console_open
326 *
327 *  open a port as a termios console.
328 *
329 */
330rtems_device_driver console_open(
331  rtems_device_major_number major,
332  rtems_device_minor_number minor,
333  void                    * arg
334)
335{
336  rtems_status_code sc;
337  int               port = minor;
338#if (CONSOLE_USE_INTERRUPTS)
339  rtems_libio_open_close_args_t *args = arg;
340  static const rtems_termios_callbacks intrCallbacks = {
341    NULL,                       /* firstOpen */
342    NULL,                       /* lastClose */
343    NULL,                       /* pollRead */
344    console_write_support,      /* write */
345    NULL,                       /* setAttributes */
346    NULL,                       /* stopRemoteTx */
347    NULL,                       /* startRemoteTx */
348    1                           /* outputUsesInterrupts */
349  };
350#else
351  static const rtems_termios_callbacks pollCallbacks = {
352    NULL,                       /* firstOpen */
353    NULL,                       /* lastClose */
354    console_inbyte_nonblocking, /* pollRead */
355    console_write_support,      /* write */
356    NULL,                       /* setAttributes */
357    NULL,                       /* stopRemoteTx */
358    NULL,                       /* startRemoteTx */
359    0                           /* outputUsesInterrupts */
360  };
361#endif
362
363  /*
364   * Verify the minor number is valid.
365   */
366  if (minor < 0)
367    return RTEMS_INVALID_NUMBER;
368
369  if ( port > NUM_Z85C30_PORTS )
370     return RTEMS_INVALID_NUMBER;
371
372  /*
373   *  open the port as a termios console driver.
374   */
375
376#if (CONSOLE_USE_INTERRUPTS)
377   sc = rtems_termios_open( major, minor, arg, &intrCallbacks );
378
379   Ports_85C30[ minor ].Protocol->console_termios_data = args->iop->data1;
380#else
381   sc = rtems_termios_open( major, minor, arg, &pollCallbacks );
382#endif
383
384  return sc;
385}
386
387#if (CONSOLE_USE_INTERRUPTS)
388
389/*
390 *  console_outbyte_interrupts
391 *
392 *  This routine transmits a character out.
393 *
394 *  Input parameters:
395 *    port - port to transmit character to
396 *    ch  - character to be transmitted
397 *
398 *  Output parameters:  NONE
399 *
400 *  Return values:      NONE
401 */
402void console_outbyte_interrupts(
403  const Port_85C30_info *Port,
404  char ch
405)
406{
407  Console_Protocol   *protocol;
408  uint32_t            isrlevel;
409
410  protocol = Port->Protocol;
411
412  /*
413   *  If this is the first character then we need to prime the pump
414   */
415
416  if ( protocol->Is_TX_active == FALSE ) {
417
418    rtems_interrupt_disable( isrlevel );
419    protocol->Is_TX_active = TRUE;
420    outbyte_polled_85c30( Port->ctrl, ch );
421    rtems_interrupt_enable( isrlevel );
422
423    return;
424  }
425
426  while ( Ring_buffer_Is_full( &protocol->TX_Buffer ) );
427
428  Ring_buffer_Add_character( &protocol->TX_Buffer, ch );
429}
430
431#endif
432
433/* const char arg to be compatible with BSP_output_char decl. */
434void
435debug_putc_onlcr(const char c)
436{
437  int                      console;
438  volatile uint8_t         *csr;
439  uint32_t                 isrlevel;
440
441  console = USE_FOR_CONSOLE;
442  csr = Ports_85C30[ console ].ctrl;
443
444  rtems_interrupt_disable( isrlevel );
445  outbyte_polled_85c30( csr, c );
446  rtems_interrupt_enable( isrlevel );
447}
448
449BSP_output_char_function_type   BSP_output_char = debug_putc_onlcr;
450/* const char arg to be compatible with BSP_output_char decl. */
451
Note: See TracBrowser for help on using the repository browser.