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

4.104.114.95
Last change on this file since 40e7ae2 was 40e7ae2, checked in by Joel Sherrill <joel.sherrill@…>, on 09/03/08 at 20:36:21

2008-09-03 Joel Sherrill <joel.sherrill@…>

  • Makefile.am, README, configure.ac, console/85c30.c, console/console.c, console/consolebsp.h, include/bsp.h, include/gen2.h, irq/FPGA.c, irq/irq.c, irq/irq.h, irq/irq_init.c, start/start.S, startup/bspstart.c, startup/genpvec.c, startup/linkcmds, timer/timer.c, tod/tod.c: Initiate update and testing. Runs hello but does not run ticker yet.
  • 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 *
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
213printk("console_initialize start\n");
214
215  /*
216   * initialize the termio interface.
217   */
218  rtems_termios_initialize();
219
220  /*
221   *  Register Device Names
222   */
223  console = USE_FOR_CONSOLE;
224  status = rtems_io_register_name( "/dev/console", major, console );
225  if (status != RTEMS_SUCCESSFUL)
226    rtems_fatal_error_occurred(status);
227
228  /*
229   *  Initialize Hardware
230   */
231
232/*
233 * INITIALIZE_COM_PORTS is defined in the linker script.  If it is
234 * true all serial chips on the board are to be reset at startup
235 * otherwise the reset is assumed to occur elsewhere (ie. in the
236 * debugger...)
237 */
238#if ( INITIALIZE_COM_PORTS )
239
240  /*
241   * Force to perform a hardware reset w/o
242   * Master interrupt enable via register 9
243   */
244
245  for (port=0; port<NUM_Z85C30_PORTS; port++){
246    p0 = port;
247    port++;
248    p1 = port;
249    Reset_85c30_chip( Ports_85C30[p0].ctrl, Ports_85C30[p1].ctrl );
250  }
251#else
252  /* TEMP - To see if this makes a diff with the new ports.
253   *        Never reset chip 1 when using the chip as a monitor
254   */
255  for (port=2; port<NUM_Z85C30_PORTS; port++){
256    p0 = port;
257    port++;
258    p1 = port;
259    Reset_85c30_chip( Ports_85C30[p0].ctrl, Ports_85C30[p1].ctrl );
260  }
261#endif
262
263  /*
264   * Initialize each port.
265   * Note:  the ports are numbered such that 0,1 are on the first chip
266   *        2,3 are on the second ....
267   */
268
269  for (port=1; port<NUM_Z85C30_PORTS; port++) {
270   chip = port >> 1;
271printk("console_initialize initialize_85c30_port %d\n", port);
272    initialize_85c30_port( &Ports_85C30[port] );
273  }
274
275#if CONSOLE_USE_INTERRUPTS
276printk("console_initialize console_initialize_interrupts\n");
277  console_initialize_interrupts();
278#endif
279
280printk("console_initialize end\n");
281  return RTEMS_SUCCESSFUL;
282}
283
284/* PAGE
285 *
286 *  console_write_support
287 *
288 *  Console Termios output entry point.
289 *
290 */
291int console_write_support(
292  int   minor,
293  const char *buf,
294  int   len)
295{
296  int nwrite = 0;
297  volatile uint8_t         *csr;
298  int                       port = minor;
299
300  /*
301   * verify port Number
302   */
303  assert ( port < NUM_Z85C30_PORTS );
304
305  /*
306   * Set the csr based upon the port number.
307   */
308  csr = Ports_85C30[ port ].ctrl;
309
310  /*
311   * poll each byte in the string out of the port.
312   */
313  while (nwrite < len) {
314#if (CONSOLE_USE_INTERRUPTS)
315    console_outbyte_interrupts( &Ports_85C30[ port ], *buf++ );
316#else
317    outbyte_polled_85c30( csr, *buf++ );
318#endif
319   nwrite++;
320  }
321
322  /*
323   * return the number of bytes written.
324   */
325  return nwrite;
326}
327
328/* PAGE
329 *
330 *  console_open
331 *
332 *  open a port as a termios console.
333 *
334 */
335rtems_device_driver console_open(
336  rtems_device_major_number major,
337  rtems_device_minor_number minor,
338  void                    * arg
339)
340{
341  rtems_status_code sc;
342  int               port = minor;
343#if (CONSOLE_USE_INTERRUPTS)
344  rtems_libio_open_close_args_t *args = arg;
345  static const rtems_termios_callbacks intrCallbacks = {
346    NULL,                       /* firstOpen */
347    NULL,                       /* lastClose */
348    NULL,                       /* pollRead */
349    console_write_support,      /* write */
350    NULL,                       /* setAttributes */
351    NULL,                       /* stopRemoteTx */
352    NULL,                       /* startRemoteTx */
353    1                           /* outputUsesInterrupts */
354  };
355#else
356  static const rtems_termios_callbacks pollCallbacks = {
357    NULL,                       /* firstOpen */
358    NULL,                       /* lastClose */
359    console_inbyte_nonblocking, /* pollRead */
360    console_write_support,      /* write */
361    NULL,                       /* setAttributes */
362    NULL,                       /* stopRemoteTx */
363    NULL,                       /* startRemoteTx */
364    0                           /* outputUsesInterrupts */
365  };
366#endif
367
368  /*
369   * Verify the minor number is valid.
370   */
371  if (minor < 0)
372    return RTEMS_INVALID_NUMBER;
373
374  if ( port > NUM_Z85C30_PORTS )
375     return RTEMS_INVALID_NUMBER;
376
377  /*
378   *  open the port as a termios console driver.
379   */
380
381#if (CONSOLE_USE_INTERRUPTS)
382   sc = rtems_termios_open( major, minor, arg, &intrCallbacks );
383
384   Ports_85C30[ minor ].Protocol->console_termios_data = args->iop->data1;
385#else
386   sc = rtems_termios_open( major, minor, arg, &pollCallbacks );
387#endif
388
389  return sc;
390}
391
392#if (CONSOLE_USE_INTERRUPTS)
393
394/*
395 *  console_outbyte_interrupts
396 *
397 *  This routine transmits a character out.
398 *
399 *  Input parameters:
400 *    port - port to transmit character to
401 *    ch  - character to be transmitted
402 *
403 *  Output parameters:  NONE
404 *
405 *  Return values:      NONE
406 */
407void console_outbyte_interrupts(
408  const Port_85C30_info *Port,
409  char ch
410)
411{
412  Console_Protocol   *protocol;
413  uint32_t            isrlevel;
414
415  protocol = Port->Protocol;
416
417  /*
418   *  If this is the first character then we need to prime the pump
419   */
420
421  if ( protocol->Is_TX_active == FALSE ) {
422
423    rtems_interrupt_disable( isrlevel );
424    protocol->Is_TX_active = TRUE;
425    outbyte_polled_85c30( Port->ctrl, ch );
426    rtems_interrupt_enable( isrlevel );
427
428    return;
429  }
430
431  while ( Ring_buffer_Is_full( &protocol->TX_Buffer ) );
432
433  Ring_buffer_Add_character( &protocol->TX_Buffer, ch );
434}
435
436#endif
437
438/* const char arg to be compatible with BSP_output_char decl. */
439void
440debug_putc_onlcr(const char c)
441{
442  int                      console;
443  volatile uint8_t         *csr;
444  uint32_t                 isrlevel;
445
446  console = USE_FOR_CONSOLE;
447  csr = Ports_85C30[ console ].ctrl;
448
449  if ('\n'==c){
450    rtems_interrupt_disable( isrlevel );
451    outbyte_polled_85c30( csr, '\r' );
452    rtems_interrupt_enable( isrlevel );
453    asm volatile("isync");
454  }
455
456  rtems_interrupt_disable( isrlevel );
457  outbyte_polled_85c30( csr, c );
458  rtems_interrupt_enable( isrlevel );
459}
460
461BSP_output_char_function_type   BSP_output_char = debug_putc_onlcr;
462/* const char arg to be compatible with BSP_output_char decl. */
463
Note: See TracBrowser for help on using the repository browser.