source: rtems/c/src/lib/libbsp/m68k/efi332/console/console.c @ 486c329

4.104.114.84.95
Last change on this file since 486c329 was 486c329, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 20, 1995 at 3:05:19 PM

Actually adding efi bsp's from John Gwynne after forgetting to
commit them.

  • Property mode set to 100644
File size: 9.3 KB
Line 
1/*
2 *  This file contains the efi332 console IO package.
3 *
4 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
5 *  On-Line Applications Research Corporation (OAR).
6 *  All rights assigned to U.S. Government, 1994.
7 *
8 *  This material may be reproduced by or for the U.S. Government pursuant
9 *  to the copyright license under the clause at DFARS 252.227-7013.  This
10 *  notice must appear in all copies of this file and its derivatives.
11 *
12 *  $Id$
13 */
14
15#include <stdlib.h>
16#include <bsp.h>
17#include <rtems/libio.h>
18
19/* BUFFER_LENGTH must be 2^n for n=1, 2, 3, .... */
20#define BUFFER_LENGTH 256
21#define RTS_STOP_SIZE BUFFER_LENGTH-64
22#define RTS_START_SIZE 16
23
24char xmt_buf[BUFFER_LENGTH];
25char rcv_buf[BUFFER_LENGTH];
26/* in: last entry into the buffer; always on a valid character */
27/* out: points to the next character to be pull from the buffer */
28/*    in+1=out => buffer empty */
29/*    in+2=out => buffer full */
30struct UART_buf {
31  char *offset; 
32  char *in; 
33  char *out;
34};
35static volatile struct UART_buf  xmt = { xmt_buf, (char *)0, (char *)1};
36static volatile struct UART_buf  rcv = { rcv_buf, (char *)0, (char *)1};
37static volatile char _debug_flag = 0;
38
39#define SET_RTS(a) {*PORTF0 = (*PORTF0 & 0x4) | ( (a)? 0 : 0x4); }
40#define GET_CTS (!(*PORTF0 & 0x2))
41
42/* _catchSCIint, _catchCTSint, and _catchSPURIOUSint are the
43   interrupt front-ends */
44extern void _catchSCIint();
45asm("   .text
46        .align 2
47        .globl _catchSCIint
48_catchSCIint:
49        moveml %d0-%d7/%a0-%a6,%sp@-       /* save registers */
50        jbsr    uart_interrupt
51        moveml  %sp@+,%d0-%d7/%a0-%a6                           
52        rte
53    ");
54
55extern void _catchCTSint();
56asm("   .text
57        .align 2
58        .globl _catchCTSint
59_catchCTSint:
60        moveml %d0-%d7/%a0-%a6,%sp@-       /* save registers */
61        jbsr    cts_interrupt
62        moveml  %sp@+,%d0-%d7/%a0-%a6                           
63        rte
64    ");
65
66extern void _catchSPURIOUSint();
67asm("   .text
68        .align 2
69        .globl _catchSPURIOUSint
70_catchSPURIOUSint:
71        moveml %d0-%d7/%a0-%a6,%sp@-       /* save registers */
72        jbsr    spurious_interrupt
73        moveml  %sp@+,%d0-%d7/%a0-%a6                           
74        rte
75    ");
76
77int _spurious_int_counter=0;
78
79/* note: cts uses int1. If it "bounces", a spurious interrupt is generated */
80void spurious_interrupt(void) {
81  _spurious_int_counter++;      /* there should never be alot of these */
82}
83
84/* _fake_trap_1 will continue the UART interrupt (%sr *still*
85   UART_ISR_LEVEL) as a trap #1 to enter the debugger */
86
87/* *****fix me; this is for 68000 w/jsr ram exception table ******* */
88asm("   .text
89        .align 2
90_fake_trap_1:
91        unlk %a6                /* clear interrupt frame */
92        lea %sp@(4),%sp         /* remove jbsr instruction */
93        moveml %sp@+,%d0-%d7/%a0-%a6 /* pop registers */
94        jmp (33*6-12)   /* jump exception 1 */
95        ");
96
97/* dispatch UART interrupt */
98void xmit_interrupt(void);
99void rcvr_interrupt(void);
100void _fake_trap_1(void);
101
102void uart_interrupt(void) {
103  /* receiver status bits are cleared by a SCSR read followed
104     by a SCDR read. transmitter status bits are cleared by
105     a SCSR read followed by a SCDR write. */
106  if ((*SCSR) & (TDRE | TC))
107    xmit_interrupt();
108
109  if ((*SCSR) & (RDRF))
110    rcvr_interrupt();
111
112  if (_debug_flag) {
113    _debug_flag = 0;            /* reset the flag */
114    _fake_trap_1();             /* fake a trap #1 */
115  }
116}
117
118/* transfer received character to the buffer */
119void rcvr_interrupt(void) {
120  register char *a, c;
121  register int length;
122
123  while((*SCSR) & (RDRF)) {
124    if ((c=*SCDR) == 0x1a)      /* use ctl-z to reboot */
125      reboot();
126/*     else if (c == 0x03) { */ /* use ctl-c to enter debugger */
127/*       _debug_flag = 1; */
128/*       continue; */
129/*     } */
130
131    *(char *)((int)rcv.offset +(int)
132              (a=(char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1)))) = c;
133    if ((char *)(((int)rcv.in+2) & ((int)BUFFER_LENGTH-1)) != rcv.out)
134      rcv.in=a;
135  };
136
137  length = (BUFFER_LENGTH -1) & ( 
138    ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out
139    + (int)rcv.in + 1);
140  if (length >= RTS_STOP_SIZE)
141    SET_RTS(0);
142}
143
144/* tranfer buffered characters to the UART */
145void xmit_interrupt(void) {
146  register short int oldsr;
147
148  _CPU_ISR_Disable( oldsr ); /* for when outbyte or flush calls */
149  while ((*SCSR) & (TDRE)) {
150    if ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1)) != xmt.out)
151      /* xmit buffer not empty */
152      if (GET_CTS) {
153        /* send next char */
154        *SCDR=*(char *)((int)xmt.offset+(int)xmt.out);
155        xmt.out= (char *)(((int)xmt.out+1) & ((int)BUFFER_LENGTH-1));
156        *SCCR1 = (*SCCR1 & ~(TIE | TCIE)) | (TIE);
157      } 
158      else {
159        /* configue CTS interrupt and shutdown xmit interrupts */
160        *SCCR1 &= ~(TIE | TCIE);
161        *PFPAR |= 0x2;
162        break;
163      }
164    else {
165      /* xmit buffer empty; shutdown interrupts */
166      *SCCR1 &= ~(TIE | TCIE);
167      break;
168    }
169  }
170  _CPU_ISR_Enable( oldsr );
171}
172
173void cts_interrupt(void) {
174  register short int oldsr;
175
176  _CPU_ISR_Disable( oldsr ); /* for when outbyte calls */
177
178  *PFPAR &= ~0x2;
179  *SCCR1 = (*SCCR1 & ~(TIE | TCIE)) | (TIE);
180
181  _CPU_ISR_Enable( oldsr );
182}
183 
184
185
186/* transfer character from the buffer */
187char inbyte(void) {
188  register char a;
189  register int length;
190
191  while ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out);
192  a=*(char *)((int)rcv.offset+(int)rcv.out);
193  rcv.out= (char *)(((int)rcv.out+1) & ((int)BUFFER_LENGTH-1));
194  length = (BUFFER_LENGTH -1) & ( 
195    ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out
196    + (int)rcv.in + 1);
197  if (length < RTS_START_SIZE)
198    SET_RTS(1);
199  return (a);
200}
201
202/* once room is avaliable in the buffer, transfer
203   the character into the buffer and enable
204   the xmtr interrupt */
205void outbyte(char c) {
206  register char *a;
207 
208  while ((char *)(((int)xmt.in+2) & ((int)BUFFER_LENGTH-1)) == xmt.out);
209  *(char *)((int)xmt.offset+(int)
210            (a=(char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1))))=c;
211  xmt.in=a;
212
213  if (!(*SCCR1 & (TIE | TCIE)) && (!(*PFPAR & 0x2)) )
214                                /* if neither interrupts are running, */
215    xmit_interrupt();           /*    we need to restart the xmiter */
216}
217
218void _UART_flush(void) {
219  /* loop till xmt buffer empty. Works with interrupts disabled */
220  while ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1)) != xmt.out)
221    xmit_interrupt();
222  /* loop till UART buffer empty */
223  while ( (*SCSR & TC) == 0 );
224}
225
226/*  console_initialize
227 *
228 *  This routine initializes the console IO driver.
229 *
230 *  Input parameters: NONE
231 *
232 *  Output parameters:  NONE
233 *
234 *  Return values:
235 */
236 
237rtems_device_driver console_initialize(
238  rtems_device_major_number  major,
239  rtems_device_minor_number  minor,
240  void                      *arg
241)
242{
243  rtems_status_code status;
244 
245  *QSMCR = ( SAM(QSM_IARB,0,IARB) );
246  *QILR = ( SAM(ISRL_QSPI,4,ILQSPI) | SAM(ISRL_SCI,0,ILSCI) );
247  *QIVR = ( SAM(EFI_QIVR,0,INTV) );
248
249  *SCCR0 = ( (int)( SYS_CLOCK/SCI_BAUD/32.0+0.5 ) & 0x1fff );
250  *SCCR1 = ( RIE | TE | RE );
251
252  set_vector(_catchSPURIOUSint, EFI_SPINT, 0);
253  set_vector(_catchSCIint, EFI_QIVR, 0);
254  set_vector(_catchCTSint, EFI_INT1, 0);
255  status = rtems_io_register_name(
256    "/dev/console",
257    major,
258    (rtems_device_minor_number) 0
259  );
260 
261  if (status != RTEMS_SUCCESSFUL)
262    rtems_fatal_error_occurred(status);
263 
264  return RTEMS_SUCCESSFUL;
265}
266
267/*  is_character_ready
268 *
269 *  This routine returns TRUE if a character is available.
270 *
271 *  Input parameters: NONE
272 *
273 *  Output parameters:  NONE
274 *
275 *  Return values:
276 */
277
278rtems_boolean is_character_ready(
279  char *ch
280)
281{
282  if ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out)
283    return(FALSE);
284  else
285    return(TRUE);
286}
287
288/*
289 *  Open entry point
290 */
291 
292rtems_device_driver console_open(
293  rtems_device_major_number major,
294  rtems_device_minor_number minor,
295  void                    * arg
296)
297{
298  return RTEMS_SUCCESSFUL;
299}
300 
301/*
302 *  Close entry point
303 */
304 
305rtems_device_driver console_close(
306  rtems_device_major_number major,
307  rtems_device_minor_number minor,
308  void                    * arg
309)
310{
311  return RTEMS_SUCCESSFUL;
312}
313 
314/*
315 * read bytes from the serial port. We only have stdin.
316 */
317 
318rtems_device_driver console_read(
319  rtems_device_major_number major,
320  rtems_device_minor_number minor,
321  void                    * arg
322)
323{
324  rtems_libio_rw_args_t *rw_args;
325  char *buffer;
326  int maximum;
327  int count = 0;
328 
329  rw_args = (rtems_libio_rw_args_t *) arg;
330 
331  buffer = rw_args->buffer;
332  maximum = rw_args->count;
333 
334  for (count = 0; count < maximum; count++) {
335    buffer[ count ] = inbyte();
336    if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
337      buffer[ count++ ]  = '\n';
338      buffer[ count ]  = 0;
339      break;
340    }
341  }
342 
343  rw_args->bytes_moved = count;
344  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
345}
346 
347/*
348 * write bytes to the serial port. Stdout and stderr are the same.
349 */
350 
351rtems_device_driver console_write(
352  rtems_device_major_number major,
353  rtems_device_minor_number minor,
354  void                    * arg
355)
356{
357  int count;
358  int maximum;
359  rtems_libio_rw_args_t *rw_args;
360  char *buffer;
361 
362  rw_args = (rtems_libio_rw_args_t *) arg;
363 
364  buffer = rw_args->buffer;
365  maximum = rw_args->count;
366 
367  for (count = 0; count < maximum; count++) {
368    if ( buffer[ count ] == '\n') {
369      outbyte('\r');
370    }
371    outbyte( buffer[ count ] );
372  }
373 
374  rw_args->bytes_moved = maximum;
375  return 0;
376}
377 
378/*
379 *  IO Control entry point
380 */
381 
382rtems_device_driver console_control(
383  rtems_device_major_number major,
384  rtems_device_minor_number minor,
385  void                    * arg
386)
387{
388  return RTEMS_SUCCESSFUL;
389}
390
Note: See TracBrowser for help on using the repository browser.