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

4.104.115
Last change on this file since 3c4d2451 was 1004c3c1, checked in by Joel Sherrill <joel.sherrill@…>, on 10/02/08 at 14:26:17

2008-10-02 Joel Sherrill <joel.sherrill@…>

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