OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [m68k/] [efi68k/] [console/] [console.c] - Blame information for rev 773

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 *  This file contains the efi68k console IO package.
3
 *
4
 *  COPYRIGHT (c) 1989-1999.
5
 *  On-Line Applications Research Corporation (OAR).
6
 *
7
 *  The license and distribution terms for this file may be
8
 *  found in the file LICENSE in this distribution or at
9
 *  http://www.OARcorp.com/rtems/license.html.
10
 *
11
 *  $Id: console.c,v 1.2 2001-09-27 12:00:03 chris Exp $
12
 */
13
 
14
#include <stdlib.h>
15
#include <bsp.h>
16
#include <rtems/libio.h>
17
 
18
 
19
#define BAUD 38400
20
#define CLK_FREQ 8000000.0
21
 
22
/* BUFFER_LENGTH must be 2^n for n=1, 2, 3, .... */
23
#define BUFFER_LENGTH 256
24
#define RTS_STOP_SIZE BUFFER_LENGTH-64
25
#define RTS_START_SIZE 16
26
 
27
char xmt_buf[BUFFER_LENGTH];
28
char rcv_buf[BUFFER_LENGTH];
29
/* in: last entry into the buffer; always on a valid character */
30
/* out: points to the next character to be pull from the buffer */
31
/*    in+1=out => buffer empty */
32
/*    in+2=out => buffer full */
33
struct UART_buf {
34
  char *offset;
35
  char *in;
36
  char *out;
37
};
38
static volatile struct UART_buf  xmt = { xmt_buf, (char *)0, (char *)1};
39
static volatile struct UART_buf  rcv = { rcv_buf, (char *)0, (char *)1};
40
static volatile char _debug_flag = 0;
41
static volatile char _tx_stop = 0;
42
 
43
/* _catchUARTint is the interrupt front-end */
44
extern void _catchUARTint();
45
asm("   .text
46
        .align 2
47
        .globl _catchUARTint
48
_catchUARTint:
49
        lea    %sp@(4),%sp                /* pop return address */
50
        moveml %d0-%d7/%a0-%a6,%sp@-       /* save registers */
51
        jbsr    uart_interrupt
52
        moveml  %sp@+,%d0-%d7/%a0-%a6
53
        rte
54
    ");
55
 
56
/* _fake_trap_1 will continue the UART interrupt (%sr *still*
57
   UART_ISR_LEVEL) as a trap #1 to enter the debugger */
58
asm("   .text
59
        .align 2
60
_fake_trap_1:
61
        unlk %a6                /* clear interrupt frame */
62
        lea %sp@(4),%sp         /* remove jbsr instruction */
63
        moveml %sp@+,%d0-%d7/%a0-%a6 /* pop registers */
64
        jmp (33*6-12+_VBR)      /* jump exception 1 */
65
        ");
66
 
67
/* dispatch UART interrupt */
68
void xmit_interrupt(void);
69
void rcvr_interrupt(void);
70
void modem_status(void);
71
void _fake_trap_1(void);
72
void uart_interrupt(void) {
73
  register char a;
74
 
75
  a=*IIR & (NIP | IID_MASK); /* read interrupt id register */
76
  switch (a) {
77
  case 0x04: case 0x0c:
78
    rcvr_interrupt();
79
    break;
80
  case 0x02:
81
    xmit_interrupt();
82
    break;
83
  case 0x00:
84
    modem_status();
85
    break;
86
  default:
87
    break;
88
  }
89
  if (_debug_flag) {
90
    _debug_flag = 0;             /* reset the flag */
91
    _fake_trap_1();             /* fake a trap #1 */
92
  }
93
}
94
 
95
/* transfer received character to the buffer */
96
void rcvr_interrupt(void) {
97
  register char *a, c;
98
  register int length;
99
 
100
  while ( (*LSR & DR) != 0) {
101
    if ((c=*RBR) == 0x1a)       /* use ctl-z to reboot */
102
      reboot();
103
    else if (c == 0x03) {       /* use ctl-c to enter debugger */
104
      _debug_flag = 1;
105
      continue;
106
    }
107
    *(char *)((int)rcv.offset +(int)
108
              (a=(char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1)))) = c;
109
    if ((char *)(((int)rcv.in+2) & ((int)BUFFER_LENGTH-1)) != rcv.out)
110
      rcv.in=a;
111
  }
112
  length = (BUFFER_LENGTH -1) & (
113
    ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out
114
    + (int)rcv.in + 1);
115
  if (length >= RTS_STOP_SIZE)
116
    *MCR &= (char) (~RTS);
117
}
118
 
119
/* tranfer buffered characters to the UART */
120
void xmit_interrupt(void) {
121
  register short int i, oldsr;
122
 
123
  _CPU_ISR_Disable( oldsr ); /* for when outbyte calls */
124
  if ( (*LSR & THRE) != 0 && _tx_stop == 0 )
125
    for (i=0;i<16;i++) {
126
      if ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1))== xmt.out)
127
        break;
128
      *THR=*(char *)((int)xmt.offset+(int)xmt.out);
129
      xmt.out= (char *)(((int)xmt.out+1) & ((int)BUFFER_LENGTH-1));
130
    }
131
  _CPU_ISR_Enable( oldsr );
132
}
133
 
134
void modem_status(void) {
135
  register char a;
136
 
137
  if ( ((a=*MDSR) & DCTS) != 0 )
138
    if ( (a & CTS) == 0)
139
      _tx_stop = 1;
140
    else {
141
      _tx_stop = 0;
142
      xmit_interrupt();
143
    }
144
}
145
 
146
/* transfer character from the buffer */
147
char inbyte(void) {
148
  register char a;
149
  register int length;
150
 
151
  while ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out);
152
  a=*(char *)((int)rcv.offset+(int)rcv.out);
153
  rcv.out= (char *)(((int)rcv.out+1) & ((int)BUFFER_LENGTH-1));
154
  length = (BUFFER_LENGTH -1) & (
155
    ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out
156
    + (int)rcv.in + 1);
157
  if (length < RTS_START_SIZE)
158
    *MCR |= (char) RTS;
159
  return (a);
160
}
161
 
162
/* once room is avaliable in the buffer, transfer
163
   the character into the buffer and enable
164
   the xmtr interrupt */
165
void outbyte(char c) {
166
  register char *a;
167
 
168
  while ((char *)(((int)xmt.in+2) & ((int)BUFFER_LENGTH-1)) == xmt.out);
169
  *(char *)((int)xmt.offset+(int)
170
            (a=(char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1))))=c;
171
  xmt.in=a;
172
 
173
  if ( (*LSR & THRE) != 0 )      /* if THRE, uart has already interrupted */
174
    xmit_interrupt();           /*   and was ignored. Need to restart. */
175
}
176
 
177
void _UART_flush(void) {
178
  /* loop till xmt buffer empty. Works with interrupts disabled */
179
  while ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1)) != xmt.out)
180
    xmit_interrupt();
181
  /* loop till UART buffer empty */
182
  while ( (*LSR & TEMT) == 0 );
183
}
184
 
185
/*  console_initialize
186
 *
187
 *  This routine initializes the console IO driver.
188
 *
189
 *  Input parameters: NONE
190
 *
191
 *  Output parameters:  NONE
192
 *
193
 *  Return values:
194
 */
195
 
196
void console_init()
197
{
198
  /* set clock divisor */
199
  *LCR = (char)(DLAB);
200
  *DLL = (char)((int)(CLK_FREQ/BAUD/16.0+0.5) & 0xFF);
201
  *DLM = (char)(((int)(CLK_FREQ/BAUD/16.0+0.5) & 0xFF00) >> 8);
202
 
203
  /* Line control setup */
204
  *LCR = (char)(WL_8 | NSB);
205
 
206
  /* Interrupt setup */
207
  *IER = (char) 0x0b;           /* enable transmit, receive, modem stat int */
208
 
209
  /* FIFO setup */
210
  *FCR = (char)(FIFO_E | 0xc0);
211
 
212
  /* Modem control setup */
213
  *MCR = (char) RTS;
214
 
215
  /* init tx_stop with CTS */
216
  _tx_stop = ( (*MDSR & CTS) ? 0 : 1);
217
 
218
  set_vector(_catchUARTint, UART_ISR_LEVEL+24, 0);
219
}
220
 
221
rtems_device_driver console_initialize(
222
  rtems_device_major_number  major,
223
  rtems_device_minor_number  minor,
224
  void                      *arg
225
)
226
{
227
  rtems_status_code status;
228
 
229
  status = rtems_io_register_name(
230
    "/dev/console",
231
    major,
232
    (rtems_device_minor_number) 0
233
  );
234
 
235
  if (status != RTEMS_SUCCESSFUL)
236
    rtems_fatal_error_occurred(status);
237
 
238
  return RTEMS_SUCCESSFUL;
239
 
240
}
241
 
242
 
243
/*  is_character_ready
244
 *
245
 *  This routine returns TRUE if a character is available.
246
 *
247
 *  Input parameters: NONE
248
 *
249
 *  Output parameters:  NONE
250
 *
251
 *  Return values:
252
 */
253
 
254
rtems_boolean is_character_ready(
255
  char *ch
256
)
257
{
258
  if ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out)
259
    return(FALSE);
260
  else
261
    return(TRUE);
262
}
263
 
264
/*
265
 *  Open entry point
266
 */
267
 
268
rtems_device_driver console_open(
269
  rtems_device_major_number major,
270
  rtems_device_minor_number minor,
271
  void                    * arg
272
)
273
{
274
  return RTEMS_SUCCESSFUL;
275
}
276
 
277
/*
278
 *  Close entry point
279
 */
280
 
281
rtems_device_driver console_close(
282
  rtems_device_major_number major,
283
  rtems_device_minor_number minor,
284
  void                    * arg
285
)
286
{
287
  return RTEMS_SUCCESSFUL;
288
}
289
 
290
/*
291
 * read bytes from the serial port. We only have stdin.
292
 */
293
 
294
rtems_device_driver console_read(
295
  rtems_device_major_number major,
296
  rtems_device_minor_number minor,
297
  void                    * arg
298
)
299
{
300
  rtems_libio_rw_args_t *rw_args;
301
  char *buffer;
302
  int maximum;
303
  int count = 0;
304
 
305
  rw_args = (rtems_libio_rw_args_t *) arg;
306
 
307
  buffer = rw_args->buffer;
308
  maximum = rw_args->count;
309
 
310
  for (count = 0; count < maximum; count++) {
311
    buffer[ count ] = inbyte();
312
    if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
313
      buffer[ count++ ]  = '\n';
314
      break;
315
    }
316
  }
317
 
318
  rw_args->bytes_moved = count;
319
  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
320
}
321
 
322
/*
323
 * write bytes to the serial port. Stdout and stderr are the same.
324
 */
325
 
326
rtems_device_driver console_write(
327
  rtems_device_major_number major,
328
  rtems_device_minor_number minor,
329
  void                    * arg
330
)
331
{
332
  int count;
333
  int maximum;
334
  rtems_libio_rw_args_t *rw_args;
335
  char *buffer;
336
 
337
  rw_args = (rtems_libio_rw_args_t *) arg;
338
 
339
  buffer = rw_args->buffer;
340
  maximum = rw_args->count;
341
 
342
  for (count = 0; count < maximum; count++) {
343
    if ( buffer[ count ] == '\n') {
344
      outbyte('\r');
345
    }
346
    outbyte( buffer[ count ] );
347
  }
348
 
349
  rw_args->bytes_moved = maximum;
350
  return 0;
351
}
352
 
353
/*
354
 *  IO Control entry point
355
 */
356
 
357
rtems_device_driver console_control(
358
  rtems_device_major_number major,
359
  rtems_device_minor_number minor,
360
  void                    * arg
361
)
362
{
363
  return RTEMS_SUCCESSFUL;
364
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.