Index: c/src/lib/libbsp/m68k/efi68k/console/console.c
===================================================================
--- c/src/lib/libbsp/m68k/efi68k/console/console.c	(revision 486c329f2b4f95dbfefdcbefbe6b25adf7895a94)
+++ c/src/lib/libbsp/m68k/efi68k/console/console.c	(revision 486c329f2b4f95dbfefdcbefbe6b25adf7895a94)
@@ -0,0 +1,363 @@
+/*
+ *  This file contains the efi68k console IO package.
+ *
+ *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ *  On-Line Applications Research Corporation (OAR).
+ *  All rights assigned to U.S. Government, 1994.
+ *
+ *  This material may be reproduced by or for the U.S. Government pursuant
+ *  to the copyright license under the clause at DFARS 252.227-7013.  This
+ *  notice must appear in all copies of this file and its derivatives.
+ *
+ *  $Id$
+ */
+
+#include <stdlib.h>
+#include <bsp.h>
+#include <rtems/libio.h>
+
+
+#define BAUD 38400
+#define CLK_FREQ 8000000.0
+
+/* BUFFER_LENGTH must be 2^n for n=1, 2, 3, .... */
+#define BUFFER_LENGTH 256
+#define RTS_STOP_SIZE BUFFER_LENGTH-64
+#define RTS_START_SIZE 16
+
+char xmt_buf[BUFFER_LENGTH];
+char rcv_buf[BUFFER_LENGTH];
+/* in: last entry into the buffer; always on a valid character */
+/* out: points to the next character to be pull from the buffer */
+/*    in+1=out => buffer empty */
+/*    in+2=out => buffer full */
+struct UART_buf {
+  char *offset; 
+  char *in; 
+  char *out;
+};
+static volatile struct UART_buf  xmt = { xmt_buf, (char *)0, (char *)1};
+static volatile struct UART_buf  rcv = { rcv_buf, (char *)0, (char *)1};
+static volatile char _debug_flag = 0;
+static volatile char _tx_stop = 0;
+
+/* _catchUARTint is the interrupt front-end */
+extern void _catchUARTint();
+asm("   .text
+        .align 2
+        .globl _catchUARTint
+_catchUARTint:
+        lea    %sp@(4),%sp                /* pop return address */
+        moveml %d0-%d7/%a0-%a6,%sp@-       /* save registers */
+        jbsr    uart_interrupt
+        moveml  %sp@+,%d0-%d7/%a0-%a6			        
+        rte
+    ");
+
+/* _fake_trap_1 will continue the UART interrupt (%sr *still*
+   UART_ISR_LEVEL) as a trap #1 to enter the debugger */
+asm("   .text
+        .align 2
+_fake_trap_1:
+        unlk %a6		/* clear interrupt frame */
+        lea %sp@(4),%sp		/* remove jbsr instruction */
+        moveml %sp@+,%d0-%d7/%a0-%a6 /* pop registers */
+        jmp (33*6-12+_VBR)	/* jump exception 1 */
+        ");
+
+/* dispatch UART interrupt */
+void xmit_interrupt(void);
+void rcvr_interrupt(void);
+void modem_status(void);
+void _fake_trap_1(void);
+void uart_interrupt(void) {
+  register char a;
+
+  a=*IIR & (NIP | IID_MASK); /* read interrupt id register */
+  switch (a) {
+  case 0x04: case 0x0c:
+    rcvr_interrupt();
+    break;
+  case 0x02:
+    xmit_interrupt();
+    break;
+  case 0x00:
+    modem_status();
+    break;
+  default:
+    break;
+  }
+  if (_debug_flag) {
+    _debug_flag = 0;		/* reset the flag */
+    _fake_trap_1();		/* fake a trap #1 */
+  }
+}
+
+/* transfer received character to the buffer */
+void rcvr_interrupt(void) {
+  register char *a, c;
+  register int length;
+
+  while ( (*LSR & DR) != 0) {
+    if ((c=*RBR) == 0x1a)	/* use ctl-z to reboot */
+      reboot();
+    else if (c == 0x03) {	/* use ctl-c to enter debugger */
+      _debug_flag = 1;
+      continue;
+    }
+    *(char *)((int)rcv.offset +(int)
+	      (a=(char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1)))) = c;
+    if ((char *)(((int)rcv.in+2) & ((int)BUFFER_LENGTH-1)) != rcv.out)
+      rcv.in=a;
+  }
+  length = (BUFFER_LENGTH -1) & ( 
+    ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out 
+    + (int)rcv.in + 1);
+  if (length >= RTS_STOP_SIZE)
+    *MCR &= (char) (~RTS);
+}
+
+/* tranfer buffered characters to the UART */
+void xmit_interrupt(void) {
+  register short int i, oldsr;
+
+  _CPU_ISR_Disable( oldsr ); /* for when outbyte calls */
+  if ( (*LSR & THRE) != 0 && _tx_stop == 0 )
+    for (i=0;i<16;i++) {
+      if ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1))== xmt.out)
+	break;
+      *THR=*(char *)((int)xmt.offset+(int)xmt.out);
+      xmt.out= (char *)(((int)xmt.out+1) & ((int)BUFFER_LENGTH-1));
+    }
+  _CPU_ISR_Enable( oldsr );
+}
+
+void modem_status(void) {
+  register char a;
+  
+  if ( ((a=*MDSR) & DCTS) != 0 )
+    if ( (a & CTS) == 0)
+      _tx_stop = 1;
+    else {
+      _tx_stop = 0;
+      xmit_interrupt();
+    }
+}
+
+/* transfer character from the buffer */
+char inbyte(void) {
+  register char a;
+  register int length;
+
+  while ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out);
+  a=*(char *)((int)rcv.offset+(int)rcv.out);
+  rcv.out= (char *)(((int)rcv.out+1) & ((int)BUFFER_LENGTH-1));
+  length = (BUFFER_LENGTH -1) & ( 
+    ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out 
+    + (int)rcv.in + 1);
+  if (length < RTS_START_SIZE)
+    *MCR |= (char) RTS;
+  return (a);
+}
+
+/* once room is avaliable in the buffer, transfer
+   the character into the buffer and enable 
+   the xmtr interrupt */
+void outbyte(char c) {
+  register char *a;
+  
+  while ((char *)(((int)xmt.in+2) & ((int)BUFFER_LENGTH-1)) == xmt.out);
+  *(char *)((int)xmt.offset+(int)
+	    (a=(char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1))))=c;
+  xmt.in=a;
+
+  if ( (*LSR & THRE) != 0 ) 	/* if THRE, uart has already interrupted */
+    xmit_interrupt();		/*   and was ignored. Need to restart. */
+}
+
+void _UART_flush(void) {
+  /* loop till xmt buffer empty. Works with interrupts disabled */
+  while ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1)) != xmt.out)
+    xmit_interrupt();
+  /* loop till UART buffer empty */
+  while ( (*LSR & TEMT) == 0 );
+}
+
+/*  console_initialize
+ *
+ *  This routine initializes the console IO driver.
+ *
+ *  Input parameters: NONE
+ *
+ *  Output parameters:  NONE
+ *
+ *  Return values:
+ */
+ 
+rtems_device_driver console_initialize(
+  rtems_device_major_number  major,
+  rtems_device_minor_number  minor,
+  void                      *arg
+)
+{
+  rtems_status_code status;
+
+  /* set clock divisor */
+  *LCR = (char)(DLAB);
+  *DLL = (char)((int)(CLK_FREQ/BAUD/16.0+0.5) & 0xFF);
+  *DLM = (char)(((int)(CLK_FREQ/BAUD/16.0+0.5) & 0xFF00) >> 8);
+
+  /* Line control setup */
+  *LCR = (char)(WL_8 | NSB);
+
+  /* Interrupt setup */
+  *IER = (char) 0x0b;		/* enable transmit, receive, modem stat int */
+  
+  /* FIFO setup */
+  *FCR = (char)(FIFO_E | 0xc0);
+
+  /* Modem control setup */
+  *MCR = (char) RTS;
+
+  /* init tx_stop with CTS */
+  _tx_stop = ( (*MDSR & CTS) ? 0 : 1);
+
+  set_vector(_catchUARTint, UART_ISR_LEVEL+24, 0);
+
+  status = rtems_io_register_name(
+    "/dev/console",
+    major,
+    (rtems_device_minor_number) 0
+  );
+ 
+  if (status != RTEMS_SUCCESSFUL)
+    rtems_fatal_error_occurred(status);
+ 
+  return RTEMS_SUCCESSFUL;
+
+}
+
+
+/*  is_character_ready
+ *
+ *  This routine returns TRUE if a character is available.
+ *
+ *  Input parameters: NONE
+ *
+ *  Output parameters:  NONE
+ *
+ *  Return values:
+ */
+
+rtems_boolean is_character_ready(
+  char *ch
+)
+{
+  if ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out)
+    return(FALSE);
+  else
+    return(TRUE);
+}
+
+/*
+ *  Open entry point
+ */
+ 
+rtems_device_driver console_open(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void                    * arg
+)
+{
+  return RTEMS_SUCCESSFUL;
+}
+ 
+/*
+ *  Close entry point
+ */
+ 
+rtems_device_driver console_close(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void                    * arg
+)
+{
+  return RTEMS_SUCCESSFUL;
+}
+ 
+/*
+ * read bytes from the serial port. We only have stdin.
+ */
+ 
+rtems_device_driver console_read(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void                    * arg
+)
+{
+  rtems_libio_rw_args_t *rw_args;
+  char *buffer;
+  int maximum;
+  int count = 0;
+ 
+  rw_args = (rtems_libio_rw_args_t *) arg;
+ 
+  buffer = rw_args->buffer;
+  maximum = rw_args->count;
+ 
+  for (count = 0; count < maximum; count++) {
+    buffer[ count ] = inbyte();
+    if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
+      buffer[ count++ ]  = '\n';
+      buffer[ count ]  = 0;
+      break;
+    }
+  }
+ 
+  rw_args->bytes_moved = count;
+  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
+}
+ 
+/*
+ * write bytes to the serial port. Stdout and stderr are the same.
+ */
+ 
+rtems_device_driver console_write(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void                    * arg
+)
+{
+  int count;
+  int maximum;
+  rtems_libio_rw_args_t *rw_args;
+  char *buffer;
+ 
+  rw_args = (rtems_libio_rw_args_t *) arg;
+ 
+  buffer = rw_args->buffer;
+  maximum = rw_args->count;
+ 
+  for (count = 0; count < maximum; count++) {
+    if ( buffer[ count ] == '\n') {
+      outbyte('\r');
+    }
+    outbyte( buffer[ count ] );
+  }
+ 
+  rw_args->bytes_moved = maximum;
+  return 0;
+}
+ 
+/*
+ *  IO Control entry point
+ */
+ 
+rtems_device_driver console_control(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void                    * arg
+)
+{
+  return RTEMS_SUCCESSFUL;
+}
