summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/ppcn_60x/console
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-02-18 16:48:14 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-02-18 16:48:14 +0000
commit0c04c377bc8ac177d28bd0e0096d7c6940d33cd4 (patch)
treeba3062eb819e89de2eee14397ffe61b202ad10de /c/src/lib/libbsp/powerpc/ppcn_60x/console
parent./clock/Makefile.in,v (diff)
downloadrtems-0c04c377bc8ac177d28bd0e0096d7c6940d33cd4.tar.bz2
./clock/Makefile.in,v
./clock/clock.c,v ./console/Makefile.in,v ./console/config.c,v ./console/console.c,v ./console/console.h,v ./console/debugio.c,v ./console/i8042.c,v ./console/i8042_p.h,v ./console/i8042vga.c,v ./console/i8042vga.h,v ./console/ns16550.c,v ./console/ns16550.h,v ./console/ns16550_p.h,v ./console/ns16550cfg.c,v ./console/ns16550cfg.h,v ./console/vga.c,v ./console/vga_p.h,v ./console/z85c30.c,v ./console/z85c30.h,v ./console/z85c30_p.h,v ./console/z85c30cfg.c,v ./console/z85c30cfg.h,v ./include/Makefile.in,v ./include/bsp.h,v ./include/chain.h,v ./include/coverhd.h,v ./include/extisrdrv.h,v ./include/nvram.h,v ./include/pci.h,v ./include/tod.h,v ./network/Makefile.in,v ./network/amd79c970.c,v ./network/amd79c970.h,v ./nvram/Makefile.in,v ./nvram/ds1385.h,v ./nvram/mk48t18.h,v ./nvram/nvram.c,v ./nvram/prepnvr.h,v ./nvram/stk11c68.h,v ./pci/Makefile.in,v ./pci/pci.c,v ./start/Makefile.in,v ./start/start.s,v ./startup/Makefile.in,v ./startup/bspclean.c,v ./startup/bspstart.c,v ./startup/bsptrap.s,v ./startup/device-tree,v ./startup/genpvec.c,v ./startup/linkcmds,v ./startup/rtems-ctor.cc,v ./startup/sbrk.c,v ./startup/setvec.c,v ./startup/spurious.c,v ./startup/swap.c,v ./timer/Makefile.in,v ./timer/timer.c,v ./tod/Makefile.in,v ./tod/cmos.h,v ./tod/tod.c,v ./universe/Makefile.in,v ./universe/universe.c,v ./vectors/Makefile.in,v ./vectors/README,v ./vectors/align_h.s,v ./vectors/vectors.s,v ./wrapup/Makefile.in,v ./Makefile.in,v ./README,v ./STATUS,v ./bsp_specs,v
Diffstat (limited to 'c/src/lib/libbsp/powerpc/ppcn_60x/console')
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/Makefile.in54
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/console.c358
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/console.h67
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042.c1073
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042_p.h196
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042vga.c46
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042vga.h34
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.c632
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.h40
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550_p.h196
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.c53
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.h55
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/vga.c368
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/vga_p.h70
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30.c917
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30.h52
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30_p.h385
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30cfg.c96
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30cfg.h64
19 files changed, 4756 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/console/Makefile.in
new file mode 100644
index 0000000000..4c05c37698
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/Makefile.in
@@ -0,0 +1,54 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+PGM=${ARCH}/console.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=console ns16550 z85c30 i8042vga i8042 vga
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+SRCS=$(C_FILES) $(H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+all: ${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install: all
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/console.c b/c/src/lib/libbsp/powerpc/ppcn_60x/console/console.c
new file mode 100644
index 0000000000..6b60503ec9
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/console.c
@@ -0,0 +1,358 @@
+/*
+ * This file contains the TTY driver for the PPCn_60x
+ *
+ * This driver uses the termios pseudo driver.
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <termios.h>
+
+#include "console.h"
+
+/*
+ * Load configuration table
+ */
+#include "config.c"
+
+#define NUM_CONSOLE_PORTS (sizeof(Console_Port_Tbl)/sizeof(console_tbl))
+
+console_data Console_Port_Data[NUM_CONSOLE_PORTS];
+unsigned long Console_Port_Count;
+rtems_device_minor_number Console_Port_Minor;
+
+/* PAGE
+ *
+ * console_open
+ *
+ * open a port as a termios console.
+ *
+ */
+rtems_device_driver console_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_status_code status;
+ rtems_libio_open_close_args_t *args = arg;
+ rtems_libio_ioctl_args_t IoctlArgs;
+ struct termios Termios;
+ rtems_termios_callbacks Callbacks;
+ console_fns *c;
+
+ /*
+ * Verify the port number is valid.
+ */
+ if(minor>Console_Port_Count)
+ {
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ /*
+ * open the port as a termios console driver.
+ */
+ c = Console_Port_Tbl[minor].pDeviceFns;
+ Callbacks.firstOpen = c->deviceFirstOpen;
+ Callbacks.lastClose = c->deviceLastClose;
+ Callbacks.pollRead = c->deviceRead;
+ Callbacks.write = c->deviceWrite;
+ Callbacks.setAttributes = c->deviceSetAttributes;
+ Callbacks.stopRemoteTx =
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx;
+ Callbacks.startRemoteTx =
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx;
+ Callbacks.outputUsesInterrupts = c->deviceOutputUsesInterrupts;
+ status = rtems_termios_open ( major, minor, arg, &Callbacks);
+ Console_Port_Data[minor].termios_data = args->iop->data1;
+
+ /*
+ * Patch in flow control routines
+ */
+/* XXX */
+#if 0
+ if((status==RTEMS_SUCCESSFUL) &&
+ (Console_Port_Tbl[minor].pDeviceFlow))
+ {
+ status=rtems_termios_flow_control(
+ major, minor, arg,
+ Console_Port_Tbl[minor].pDeviceFlow->
+ deviceStartRemoteTx,
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx,
+ Console_Port_Tbl[minor].ulMargin,
+ Console_Port_Tbl[minor].ulHysteresis);
+ }
+#endif
+
+ if(minor!=Console_Port_Minor)
+ {
+ /*
+ * If this is not the console we do not want ECHO and
+ * so forth
+ */
+ IoctlArgs.iop=args->iop;
+ IoctlArgs.command=RTEMS_IO_GET_ATTRIBUTES;
+ IoctlArgs.buffer=&Termios;
+ rtems_termios_ioctl(&IoctlArgs);
+ Termios.c_lflag=ICANON;
+ IoctlArgs.command=RTEMS_IO_SET_ATTRIBUTES;
+ rtems_termios_ioctl(&IoctlArgs);
+ }
+
+ if((args->iop->flags&LIBIO_FLAGS_READ) &&
+ Console_Port_Tbl[minor].pDeviceFlow &&
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx)
+ {
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx(minor);
+ }
+
+ return status;
+}
+
+void console_reserve_resources(
+ rtems_configuration_table *configuration
+)
+{
+ rtems_termios_reserve_resources( configuration, 2 );
+}
+
+
+rtems_device_driver console_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_libio_open_close_args_t *args = arg;
+
+ if((args->iop->flags&LIBIO_FLAGS_READ) &&
+ Console_Port_Tbl[minor].pDeviceFlow &&
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx)
+ {
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx(minor);
+ }
+
+ return rtems_termios_close (arg);
+}
+
+rtems_device_driver console_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_read (arg);
+}
+
+rtems_device_driver console_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_write (arg);
+}
+
+rtems_device_driver console_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_ioctl (arg);
+}
+
+/* PAGE
+ *
+ * console_initialize
+ *
+ * Routine called to initialize the console device driver.
+ */
+rtems_device_driver console_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_status_code status;
+
+ /*
+ * initialize the termio interface.
+ */
+ rtems_termios_initialize();
+
+ Console_Port_Count=NUM_CONSOLE_PORTS;
+
+ for(minor=0;
+ minor<Console_Port_Count;
+ minor++)
+ {
+ /*
+ * First perform the configuration dependant probe, then the
+ * device dependant probe
+ */
+ if((!Console_Port_Tbl[minor].deviceProbe ||
+ Console_Port_Tbl[minor].deviceProbe(minor)) &&
+ Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor))
+ {
+ /*
+ * Use this device for the console
+ */
+ break;
+ }
+ }
+ if(minor==Console_Port_Count)
+ {
+ /*
+ * Failed to find a working device
+ */
+ rtems_fatal_error_occurred(RTEMS_IO_ERROR);
+ }
+
+ Console_Port_Minor=minor;
+
+ /*
+ * Register Device Names
+ */
+ status = rtems_io_register_name("/dev/console",
+ major,
+ Console_Port_Minor );
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_fatal_error_occurred(status);
+ }
+ Console_Port_Tbl[minor].pDeviceFns->deviceInitialize(
+ Console_Port_Minor);
+
+ for(minor++;minor<Console_Port_Count;minor++)
+ {
+ /*
+ * First perform the configuration dependant probe, then the
+ * device dependant probe
+ */
+ if((!Console_Port_Tbl[minor].deviceProbe ||
+ Console_Port_Tbl[minor].deviceProbe(minor)) &&
+ Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor))
+ {
+ status = rtems_io_register_name(
+ Console_Port_Tbl[minor].sDeviceName,
+ major,
+ minor );
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_fatal_error_occurred(status);
+ }
+
+ /*
+ * Initialize the hardware device.
+ */
+ Console_Port_Tbl[minor].pDeviceFns->deviceInitialize(
+ minor);
+
+ }
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/* PAGE
+ *
+ * DEBUG_puts
+ *
+ * This should be safe in the event of an error. It attempts to ensure
+ * that no TX empty interrupts occur while it is doing polled IO. Then
+ * it restores the state of that external interrupt.
+ *
+ * Input parameters:
+ * string - pointer to debug output string
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void DEBUG_puts(
+ char *string
+)
+{
+ char *s;
+ unsigned32 Irql;
+
+ rtems_interrupt_disable(Irql);
+
+ for ( s = string ; *s ; s++ )
+ {
+ Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
+ deviceWritePolled(Console_Port_Minor, *s);
+ }
+
+ rtems_interrupt_enable(Irql);
+}
+
+/* PAGE
+ *
+ * DEBUG_puth
+ *
+ * This should be safe in the event of an error. It attempts to ensure
+ * that no TX empty interrupts occur while it is doing polled IO. Then
+ * it restores the state of that external interrupt.
+ *
+ * Input parameters:
+ * ulHexNum - value to display
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+void
+DEBUG_puth(
+ unsigned32 ulHexNum
+ )
+{
+ unsigned long i,d;
+ unsigned32 Irql;
+
+ rtems_interrupt_disable(Irql);
+
+ Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
+ deviceWritePolled(Console_Port_Minor, '0');
+ Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
+ deviceWritePolled(Console_Port_Minor, 'x');
+
+ for(i=32;i;)
+ {
+ i-=4;
+ d=(ulHexNum>>i)&0xf;
+ Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
+ deviceWritePolled(Console_Port_Minor,
+ (d<=9) ? d+'0' : d+'a'-0xa);
+ }
+
+ rtems_interrupt_enable(Irql);
+}
+
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/console.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/console.h
new file mode 100644
index 0000000000..1d6b6fc2b1
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/console.h
@@ -0,0 +1,67 @@
+/*
+ * This file contains the TTY driver table definition for the PPCn_60x
+ *
+ * This driver uses the termios pseudo driver.
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * $Id$
+ */
+
+#include <ringbuf.h>
+
+typedef struct _console_fns {
+ boolean (*deviceProbe)(int minor);
+ int (*deviceFirstOpen)(int major, int minor, void *arg);
+ int (*deviceLastClose)(int major, int minor, void *arg);
+ int (*deviceRead)(int minor);
+ int (*deviceWrite)(int minor, const char *buf, int len);
+ void (*deviceInitialize)(int minor);
+ int (*deviceSetAttributes)(int minor, const struct termios *);
+ void (*deviceWritePolled)(int minor, char cChar);
+ int deviceOutputUsesInterrupts;
+} console_fns;
+
+typedef struct _console_flow {
+ int (*deviceStopRemoteTx)(int minor);
+ int (*deviceStartRemoteTx)(int minor);
+} console_flow;
+
+typedef struct _console_tbl {
+ char *sDeviceName;
+ console_fns *pDeviceFns;
+ boolean (*deviceProbe)(int minor);
+ console_flow *pDeviceFlow;
+ unsigned32 ulMargin;
+ unsigned32 ulHysteresis;
+ void *pDeviceParams;
+ unsigned32 ulCtrlPort1;
+ unsigned32 ulCtrlPort2;
+ unsigned32 ulDataPort;
+ unsigned int ulIntVector;
+} console_tbl;
+
+typedef struct _console_data {
+ void *termios_data;
+ volatile boolean bActive;
+ volatile Ring_buffer_t TxBuffer;
+ /*
+ * This field may be used for any purpose required by the driver
+ */
+ void *pDeviceContext;
+} console_data;
+
+extern console_tbl Console_Port_Tbl[];
+extern console_data Console_Port_Data[];
+extern unsigned long Console_Port_Count;
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042.c b/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042.c
new file mode 100644
index 0000000000..dcfd68e72d
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042.c
@@ -0,0 +1,1073 @@
+/*
+ * This file contains the PS2 keyboard driver for the i8042
+ *
+ * Note that this driver will only handle a single i8042 device
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * This driver uses the termios pseudo driver.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <ringbuf.h>
+
+#include "console.h"
+#include "i8042_p.h"
+#include "vga_p.h"
+
+/*
+ * UK style keyboard
+ */
+char pcUKNormalLookup[] = "1234567890-=\b\tqwertyuiop[]\n\0asdfghjkl;\'"
+ "`\0#zxcvbnm,./\0*\0 \0\0\0\0\0\0\0\0\0\0\0\0"
+ "\000789-456+1230.\0\0\\";
+char pcUKShiftedLookup[]= "!\"£$%^&*()_+\b\tQWERTYUIOP{}\n\0ASDFGHJKL:"
+ "@\0\0~ZXCVBNM<>?\0*\0 \0\0\0\0\0\0\0\0\0\0\0"
+ "\0\000789-456+1230.\0\0|";
+/*
+ * US style keyboard
+ */
+char pcUSNormalLookup[] = "1234567890-=\b\tqwertyuiop[]\n\0asdfghjkl;\'"
+ "`\0\\zxcvbnm,./\0*\0 \0\0\0\0\0\0\0\0\0\0\0"
+ "\0\000789-456+1230.\0\0\\";
+char pcUSShiftedLookup[]= "!@#$%^&*()_+\b\tQWERTYUIOP{}\n\0ASDFGHJKL:@~"
+ "\0|ZXCVBNM<>?\0*\0 \0\0\0\0\0\0\0\0\0\0\0\0"
+ "\000789-456+1230.\0\0|";
+
+static char *pcNormalLookup;
+static char *pcShiftedLookup;
+
+/*
+ * This is exported to vga.c to provide flow control
+ */
+volatile boolean bScrollLock=FALSE;
+
+/*
+ * If multiple devices are to be supported then a private copy of
+ * the following will be required for each instance
+ */
+static boolean bCtrlPressed=FALSE;
+static boolean bAltPressed=FALSE;
+static boolean bAltGrPressed=FALSE;
+static boolean bLShiftPressed=FALSE;
+static boolean bRShiftPressed=FALSE;
+static boolean bCapsLock=FALSE;
+static boolean bNumLock=FALSE;
+static boolean bTwoCode=FALSE;
+
+#if CONSOLE_USE_INTERRUPTS
+static volatile Ring_buffer_t KbdOutputBuffer;
+static volatile boolean bProcessInterruptInput=FALSE;
+static boolean bInterruptsEnabled=FALSE;
+static volatile boolean bReceivedAck=TRUE;
+
+static void i8042_process(
+ int minor
+);
+
+static void i8042_scan_code(
+ int minor,
+ unsigned8 ucScan
+);
+#endif
+
+static volatile Ring_buffer_t KbdInputBuffer;
+
+/*
+ * The following routines enable an interrupt driver to switch
+ * to polled mode as required for command processing
+ */
+void i8042_polled_on(
+ int minor
+)
+{
+#if CONSOLE_USE_INTERRUPTS
+ bProcessInterruptInput=FALSE;
+#endif
+}
+
+void i8042_polled_off(
+ int minor
+)
+{
+#if CONSOLE_USE_INTERRUPTS
+ unsigned32 Irql;
+ unsigned8 ucScan;
+
+ /*
+ * Make sure we have processed everything outstanding
+ */
+ rtems_interrupt_disable(Irql);
+ while(!Ring_buffer_Is_empty(&KbdInputBuffer))
+ {
+ rtems_interrupt_enable(Irql);
+ Ring_buffer_Remove_character(&KbdInputBuffer,
+ ucScan);
+ i8042_scan_code(minor, ucScan);
+ rtems_interrupt_disable(Irql);
+ }
+ bProcessInterruptInput=TRUE;
+ rtems_interrupt_enable(Irql);
+#endif
+}
+
+/*
+ * Send data to the keyboard
+ */
+static rtems_status_code
+i8042_outbyte_raw(
+ int minor,
+ unsigned8 ucData
+)
+{
+ unsigned32 i;
+ unsigned8 Status;
+
+#if CONSOLE_USE_INTERRUPTS
+ unsigned32 Irql;
+
+ if(bInterruptsEnabled)
+ {
+ Ring_buffer_Add_character(&KbdOutputBuffer,
+ ucData);
+ if(!Console_Port_Data[minor].bActive)
+ {
+ /*
+ * Wake up the device
+ */
+ rtems_interrupt_disable(Irql);
+ Console_Port_Data[minor].bActive=TRUE;
+ i8042_process(minor);
+ rtems_interrupt_enable(Irql);
+
+ }
+ return RTEMS_SUCCESSFUL;
+ }
+#endif
+ for (i=0; i<KBD_TIMEOUT; i++)
+ {
+ inport_byte(Console_Port_Tbl[minor].ulCtrlPort1, Status);
+ if((Status & KBD_IBF_MASK)==0)
+ {
+ outport_byte(Console_Port_Tbl[minor].ulDataPort,
+ ucData);
+ return RTEMS_SUCCESSFUL;
+ }
+ }
+ return RTEMS_TIMEOUT;
+}
+
+/*
+ * Read data from the keyboard
+ */
+static rtems_status_code
+i8042_inbyte_polled(
+ int minor,
+ unsigned8 *pucData
+)
+{
+ unsigned8 Status;
+
+ inport_byte(Console_Port_Tbl[minor].ulCtrlPort1, Status);
+ if(Status & KBD_OBF_MASK)
+ {
+ inport_byte(Console_Port_Tbl[minor].ulDataPort,
+ *pucData);
+ return RTEMS_SUCCESSFUL;
+ }
+ return RTEMS_TIMEOUT;
+}
+
+/*
+ * Blocking read data from the keyboard
+ */
+static rtems_status_code
+i8042_inbyte_raw(
+ int minor,
+ unsigned8 *pucData
+)
+{
+ int i;
+
+#if CONSOLE_USE_INTERRUPTS
+ if(bInterruptsEnabled)
+ {
+ i=0;
+ while(Ring_buffer_Is_empty(&KbdInputBuffer))
+ {
+ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+ if(i++==KBD_TIMEOUT)
+ {
+ return RTEMS_TIMEOUT;
+ }
+ }
+ Ring_buffer_Remove_character(&KbdInputBuffer,
+ *pucData);
+ }
+ else
+#endif
+ {
+ for (i=0; i<KBD_TIMEOUT; i++)
+ {
+ if(i8042_inbyte_polled(minor, pucData)==
+ RTEMS_SUCCESSFUL)
+ {
+ return RTEMS_SUCCESSFUL;
+ }
+ /*
+ * Wait for a character to be recieved
+ */
+ }
+
+ return RTEMS_TIMEOUT;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * Send a command to the keyboard controller
+ */
+static rtems_status_code
+i8042_outbyte_cmd_polled(
+ int minor,
+ unsigned8 ucCommand
+)
+{
+ unsigned32 i;
+ unsigned8 Status;
+
+ /*
+ * This routine may be called when no clock driver is available
+ * so the timeout is dependant on the ISA bus timing used to access
+ * the i8042 which will not vary (much) across platforms.
+ */
+ for (i=0; i<KBD_TIMEOUT; i++)
+ {
+ inport_byte(Console_Port_Tbl[minor].ulCtrlPort1, Status);
+ if((Status & KBD_IBF_MASK)==0)
+ {
+ outport_byte(Console_Port_Tbl[minor].ulCtrlPort1,
+ ucCommand);
+ return RTEMS_SUCCESSFUL;
+ }
+ }
+ return RTEMS_TIMEOUT;
+}
+
+void EnqueueKbdChar(
+ int minor,
+ char cChar
+)
+{
+#if CONSOLE_USE_INTERRUPTS
+ rtems_termios_enqueue_raw_characters(
+ Console_Port_Data[minor].termios_data,
+ &cChar,
+ 1);
+#else
+ Ring_buffer_Add_character(&KbdInputBuffer, cChar);
+#endif
+}
+/*
+ * Process second code in a two code sequence
+ */
+static void i8042_process_two_code(
+ int minor,
+ unsigned8 ucScan,
+ boolean bMakenBreak
+)
+{
+ char cASCIICtrlCode;
+ char cASCIICode;
+
+ cASCIICtrlCode='\0';
+ cASCIICode='\0';
+
+ switch(ucScan)
+ {
+ case KEY_ALT:
+ {
+ bAltGrPressed=bMakenBreak;
+ break;
+ }
+
+ case KEY_CONTROL:
+ {
+ bCtrlPressed=bMakenBreak;
+ break;
+ }
+
+ case KEY_INSERT:
+ {
+ cASCIICtrlCode='@';
+ break;
+ }
+
+ case KEY_DELETE:
+ {
+ cASCIICode=ASCII_DEL;
+ break;
+ }
+
+ case KEY_LEFT_ARROW:
+ {
+ cASCIICtrlCode='D';
+ break;
+ }
+
+ case KEY_HOME:
+ {
+ cASCIICtrlCode='H';
+ break;
+ }
+
+ case KEY_END:
+ {
+ cASCIICtrlCode='K';
+ break;
+ }
+
+ case KEY_UP_ARROW:
+ {
+ cASCIICtrlCode='A';
+ break;
+ }
+
+ case KEY_DOWN_ARROW:
+ {
+ cASCIICtrlCode='B';
+ break;
+ }
+
+ case KEY_PAGE_UP:
+ {
+ cASCIICtrlCode='?';
+ break;
+ }
+
+ case KEY_PAGE_DOWN:
+ {
+ cASCIICtrlCode='/';
+ break;
+ }
+
+ case KEY_RIGHT_ARROW:
+ {
+ cASCIICtrlCode='C';
+ break;
+ }
+
+ case KEY_KEYPAD_SLASH:
+ {
+ cASCIICode='/';
+ break;
+ }
+
+ case KEY_KEYPAD_ENTER:
+ {
+ cASCIICode=ASCII_CR;
+ break;
+ }
+
+ case KEY_PRINT_SCREEN:
+ {
+ cASCIICode=ASCII_SYSRQ;
+ break;
+ }
+
+ default:
+ {
+ /*
+ * Ignore this code
+ */
+ break;
+ }
+ }
+
+ if(bMakenBreak && cASCIICode)
+ {
+ EnqueueKbdChar(minor, cASCIICode);
+ }
+ else if(bMakenBreak && cASCIICtrlCode)
+ {
+ EnqueueKbdChar(minor, ASCII_CSI);
+ EnqueueKbdChar(minor, cASCIICtrlCode);
+ }
+}
+
+static boolean i8042_process_qualifiers(
+ unsigned8 ucScan,
+ boolean bMakenBreak
+)
+{
+ boolean bProcessed;
+
+ /*
+ * Check for scan codes for shift, control, or alt keys.
+ */
+ bProcessed=TRUE;
+
+ switch (ucScan)
+ {
+ case KEY_LEFT_SHIFT:
+ {
+ bLShiftPressed=bMakenBreak;
+ break;
+ }
+
+ case KEY_RIGHT_SHIFT:
+ {
+ bRShiftPressed=bMakenBreak;
+ break;
+ }
+
+ case KEY_CONTROL:
+ {
+ bCtrlPressed=bMakenBreak;
+ break;
+ }
+
+ case KEY_ALT:
+ {
+ bAltPressed=bMakenBreak;
+ break;
+ }
+
+ default:
+ {
+ /*
+ * Something else needs to process this code
+ */
+ bProcessed=FALSE;
+ break;
+ }
+ }
+
+ return(bProcessed);
+}
+
+static boolean i8042_process_top_row(
+ int minor,
+ unsigned8 ucScan
+)
+{
+ boolean bProcessed;
+ char cASCIIFnCode;
+#if CONSOLE_USE_INTERRUPTS==0
+ unsigned8 ucKeyboardAck;
+#endif
+
+ /*
+ * Check for keys on the top row
+ */
+ bProcessed=TRUE;
+ cASCIIFnCode='\0';
+
+ switch (ucScan)
+ {
+ case KEY_ESC:
+ {
+ EnqueueKbdChar(minor, ASCII_ESC);
+ break;
+ }
+
+ case KEY_F1:
+ {
+ cASCIIFnCode='P';
+ break;
+ }
+
+ case KEY_F2:
+ {
+ cASCIIFnCode='Q';
+ break;
+ }
+
+ case KEY_F3:
+ {
+ cASCIIFnCode='w';
+ break;
+ }
+
+ case KEY_F4:
+ {
+ cASCIIFnCode='x';
+ break;
+ }
+
+ case KEY_F5:
+ {
+ cASCIIFnCode='t';
+ break;
+ }
+
+ case KEY_F6:
+ {
+ cASCIIFnCode='u';
+ break;
+ }
+
+ case KEY_F7:
+ {
+ cASCIIFnCode='q';
+ break;
+ }
+
+ case KEY_F8:
+ {
+ cASCIIFnCode='r';
+ break;
+ }
+
+ case KEY_F9:
+ {
+ cASCIIFnCode='p';
+ break;
+ }
+
+ case KEY_F10:
+ {
+ cASCIIFnCode='M';
+ break;
+ }
+
+ case KEY_F11:
+ {
+ cASCIIFnCode='A';
+ break;
+ }
+
+ case KEY_F12:
+ {
+ cASCIIFnCode='B';
+ break;
+ }
+
+ case KEY_SYS_REQUEST:
+ {
+ EnqueueKbdChar(minor, ASCII_SYSRQ);
+ break;
+ }
+
+ case KEY_CAPS_LOCK:
+ case KEY_NUM_LOCK:
+ case KEY_SCROLL_LOCK:
+ {
+ switch(ucScan)
+ {
+ case KEY_CAPS_LOCK:
+ {
+ bCapsLock=!bCapsLock;
+ break;
+ }
+
+ case KEY_NUM_LOCK:
+ {
+ bNumLock=!bNumLock;
+ break;
+ }
+
+ case KEY_SCROLL_LOCK:
+ {
+#if CONSOLE_USE_INTERRUPTS
+ bScrollLock=!bScrollLock;
+#endif
+ break;
+ }
+ }
+
+ i8042_outbyte_raw(minor, KBD_CMD_SET_LEDS);
+#if CONSOLE_USE_INTERRUPTS==0
+ i8042_inbyte_raw(minor, &ucKeyboardAck);
+#endif
+ i8042_outbyte_raw(minor,
+ (bCapsLock ? KBD_LED_CAPS : 0) |
+ (bNumLock ? KBD_LED_NUM : 0) |
+ (bScrollLock ? KBD_LED_SCROLL : 0));
+#if CONSOLE_USE_INTERRUPTS==0
+ i8042_inbyte_raw(minor, &ucKeyboardAck);
+#endif
+
+ break;
+ }
+
+ default:
+ {
+ /*
+ * Something else needs to process this code
+ */
+ bProcessed=FALSE;
+ break;
+ }
+ }
+
+ if(cASCIIFnCode)
+ {
+ EnqueueKbdChar(minor, ASCII_CSI);
+ EnqueueKbdChar(minor, 'O');
+ EnqueueKbdChar(minor, cASCIIFnCode);
+ }
+
+ return(bProcessed);
+}
+
+static boolean i8042_process_keypad(
+ int minor,
+ unsigned8 ucScan
+)
+{
+ char cASCIICtrlCode;
+
+ /*
+ * Process keys on the keypad
+ */
+ cASCIICtrlCode='\0';
+
+ switch(ucScan)
+ {
+ case KEY_UP_ARROW:
+ {
+ cASCIICtrlCode='A';
+ break;
+ }
+
+ case KEY_DOWN_ARROW:
+ {
+ cASCIICtrlCode='B';
+ break;
+ }
+
+ case KEY_RIGHT_ARROW:
+ {
+ cASCIICtrlCode='C';
+ break;
+ }
+
+ case KEY_LEFT_ARROW:
+ {
+ cASCIICtrlCode='D';
+ break;
+ }
+
+ case KEY_HOME:
+ {
+ cASCIICtrlCode='H';
+ break;
+ }
+
+ case KEY_END:
+ {
+ cASCIICtrlCode='K';
+ break;
+ }
+
+ case KEY_PAGE_UP:
+ {
+ cASCIICtrlCode='?';
+ break;
+ }
+
+ case KEY_PAGE_DOWN:
+ {
+ cASCIICtrlCode='/';
+ break;
+ }
+
+ case KEY_INSERT:
+ {
+ cASCIICtrlCode='@';
+ break;
+ }
+
+ case KEY_DELETE:
+ {
+ /*
+ * This is a special case not requiring an ASCII_CSI
+ */
+ EnqueueKbdChar(minor, ASCII_DEL);
+ return(TRUE);
+ }
+
+ default:
+ {
+ /*
+ * Something else needs to process this code
+ */
+ break;
+ }
+ }
+
+ if(cASCIICtrlCode)
+ {
+ EnqueueKbdChar(minor, ASCII_CSI);
+ EnqueueKbdChar(minor, cASCIICtrlCode);
+ return(TRUE);
+ }
+ else
+ {
+ return(FALSE);
+ }
+}
+
+/*
+ * This routine translates the keyboard scan code into an
+ * ASCII character (or sequence) and queues it
+ */
+static void i8042_scan_code(
+ int minor,
+ unsigned8 ucScan
+)
+{
+ char cChar;
+ boolean bMakenBreak;
+
+ /*
+ * Check for code 0xe0, which introduces a two key sequence.
+ */
+
+ if(ucScan==KEY_TWO_KEY)
+ {
+ bTwoCode=TRUE;
+ return;
+ }
+
+ /*
+ * Bit 7 of scan code indicates make or break
+ */
+ if(ucScan & 0x80)
+ {
+ bMakenBreak=FALSE;
+ ucScan&=0x7f;
+ }
+ else
+ {
+ bMakenBreak=TRUE;
+ }
+
+ /*
+ * If we are in a multikey sequence then process the second keypress
+ */
+ if(bTwoCode)
+ {
+ i8042_process_two_code(minor, ucScan, bMakenBreak);
+
+ /*
+ * Revert to prcessing single key sequences
+ */
+ bTwoCode=FALSE;
+ return;
+ }
+
+ if(i8042_process_qualifiers(ucScan, bMakenBreak))
+ {
+ /*
+ * We are all done
+ */
+ return;
+ }
+
+ /*
+ * The remaining keys are only processed for make
+ */
+ if(!bMakenBreak)
+ {
+ return;
+ }
+
+ if(i8042_process_top_row(minor, ucScan))
+ {
+ /*
+ * We are all done
+ */
+ return;
+ }
+
+ if(!bNumLock && i8042_process_keypad(minor, ucScan))
+ {
+ /*
+ * We are all done
+ */
+ return;
+ }
+
+ /*
+ * Process "normal" keys
+ */
+
+ cChar=0;
+
+ /*
+ * Check to see if the scan code corresponds to an ASCII
+ * character.
+ */
+ if(((ucScan >= 16) && (ucScan <= 25)) ||
+ ((ucScan >= 30) && (ucScan <= 38)) ||
+ ((ucScan >= 44) && (ucScan <= 50)))
+ {
+ if(bCtrlPressed)
+ {
+ cChar=pcNormalLookup[ucScan - 2]-'a'+1;
+ }
+ else
+ {
+ if(((bLShiftPressed || bRShiftPressed) && !bCapsLock) ||
+ (!(bLShiftPressed || bRShiftPressed) && bCapsLock))
+ {
+ cChar=pcShiftedLookup[ucScan - 2];
+ }
+ else
+ {
+ cChar=pcNormalLookup[ucScan - 2];
+ }
+ }
+ }
+ else if((ucScan > 1) && (ucScan <= 0x56))
+ {
+ /*
+ * Its ASCII but not alpha, so don't shift on CapsLock.
+ */
+ if(bLShiftPressed || bRShiftPressed)
+ {
+ cChar=pcShiftedLookup[ucScan - 2];
+ }
+ else
+ {
+ cChar=pcNormalLookup[ucScan - 2];
+ }
+ }
+
+ /*
+ * If we got a character then queue it
+ */
+ if(cChar)
+ {
+ EnqueueKbdChar(minor, cChar);
+ }
+}
+
+/*
+ * Console Device Driver Entry Points
+ */
+boolean i8042_probe(int minor)
+{
+ unsigned8 ucKeyboardAck;
+ unsigned8 ucKeyboardID1, ucKeyboardID2;
+
+ if(!vga_probe(minor))
+ {
+ /*
+ * There is no VGA adaptor so fail probe
+ */
+ return(FALSE);
+ }
+
+ Ring_buffer_Initialize(&KbdInputBuffer);
+#if CONSOLE_USE_INTERRUPTS
+ Ring_buffer_Initialize(&KbdOutputBuffer);
+#endif
+
+ i8042_polled_on(minor);
+ /*
+ * Determine keyboard type
+ */
+ i8042_outbyte_raw(minor, KBD_CMD_READ_ID);
+ ucKeyboardAck=0;
+ if((i8042_inbyte_raw(minor, &ucKeyboardAck)==RTEMS_TIMEOUT) ||
+ (ucKeyboardAck==KBD_CMD_RESEND))
+ {
+ /*
+ * No or incorrect keyboard response so fail probe
+ */
+ return(FALSE);
+ }
+
+ i8042_inbyte_raw(minor, &ucKeyboardID1);
+ i8042_inbyte_raw(minor, &ucKeyboardID2);
+ if((ucKeyboardID1==0xab) && (ucKeyboardID2==0x41))
+ {
+ pcNormalLookup=&pcUKNormalLookup[0];
+ pcShiftedLookup=&pcUKShiftedLookup[0];
+ }
+ else
+ {
+ pcNormalLookup=&pcUSNormalLookup[0];
+ pcShiftedLookup=&pcUSShiftedLookup[0];
+ }
+ i8042_polled_off(minor);
+
+ return(TRUE);
+}
+
+void i8042_init(int minor)
+{
+ unsigned8 ucKeyboardAck;
+
+ vga_init(minor);
+
+ i8042_polled_on(minor);
+ /*
+ * Switch all LEDs off
+ */
+ i8042_outbyte_raw(minor, KBD_CMD_SET_LEDS);
+ i8042_inbyte_raw(minor, &ucKeyboardAck);
+ i8042_outbyte_raw(minor, 0);
+ i8042_inbyte_raw(minor, &ucKeyboardAck);
+ /*
+ * Select scan code set 1
+ */
+ i8042_outbyte_raw(minor, KBD_CMD_SEL_SCAN_CODE);
+ i8042_inbyte_raw(minor, &ucKeyboardAck);
+ i8042_outbyte_raw(minor, 1);
+ i8042_inbyte_raw(minor, &ucKeyboardAck);
+ i8042_polled_off(minor);
+}
+
+/* PAGE
+ *
+ * i8042_inbyte_nonblocking_polled
+ *
+ * Console Termios polling input entry point.
+ */
+
+int i8042_inbyte_nonblocking_polled(
+ int minor
+)
+{
+ unsigned8 ucScan;
+ char ucData;
+
+ if(i8042_inbyte_polled(minor, &ucScan)==RTEMS_SUCCESSFUL)
+ {
+ i8042_scan_code(minor, ucScan);
+ }
+
+ if(!Ring_buffer_Is_empty(&KbdInputBuffer))
+ {
+ Ring_buffer_Remove_character(&KbdInputBuffer,
+ ucData);
+ return(ucData);
+ }
+
+ return(-1);
+}
+
+#if CONSOLE_USE_INTERRUPTS
+/*
+ * i8042_isr
+ *
+ * This routine is the console interrupt handler for the keyboard
+ *
+ * Input parameters:
+ * vector - vector number
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+static void i8042_process(
+ int minor
+)
+{
+ unsigned8 Status;
+ unsigned8 ucData;
+
+ inport_byte(Console_Port_Tbl[minor].ulCtrlPort1, Status);
+
+ if(Status & KBD_OBF_MASK)
+ {
+ inport_byte(Console_Port_Tbl[minor].ulDataPort, ucData);
+
+ if(bProcessInterruptInput)
+ {
+ /*
+ * Every byte written to the keyboard should be followed
+ * by an acknowledge
+ */
+ if(ucData==KBD_CMD_ACK)
+ {
+ bReceivedAck=TRUE;
+ }
+ else
+ {
+ i8042_scan_code(minor, ucData);
+ }
+ }
+ else
+ {
+ /*
+ * Store the scan code into the ring buffer where it
+ * can be read using i8042_inbyte_raw()
+ */
+ Ring_buffer_Add_character(&KbdInputBuffer, ucData);
+ }
+ }
+
+ if(((Status & KBD_IBF_MASK)==0) &&
+ bReceivedAck)
+ {
+ if(Ring_buffer_Is_empty(&KbdOutputBuffer))
+ {
+ Console_Port_Data[minor].bActive=FALSE;
+ }
+ else
+ {
+ Ring_buffer_Remove_character(&KbdOutputBuffer,
+ ucData);
+ outport_byte(Console_Port_Tbl[minor].ulDataPort,
+ ucData);
+ bReceivedAck=FALSE;
+ }
+ }
+}
+
+static rtems_isr i8042_isr(
+ rtems_vector_number vector
+)
+{
+ int minor;
+
+ for(minor=0;minor<Console_Port_Count;minor++)
+ {
+ if(vector==Console_Port_Tbl[minor].ulIntVector)
+ {
+ i8042_process(minor);
+ }
+ }
+}
+
+void i8042_initialize_interrupts(int minor)
+{
+ i8042_init(minor);
+
+ Console_Port_Data[minor].bActive=FALSE;
+
+ set_vector(i8042_isr,
+ Console_Port_Tbl[minor].ulIntVector,
+ 1);
+
+ i8042_outbyte_cmd_polled(minor, KBD_CTR_WRITE_COMMAND);
+ i8042_outbyte_raw(minor, KBD_CMD_ENABLE_KBD_INT);
+
+ /*
+ * At this point interrupts should spring into life
+ */
+ bInterruptsEnabled=TRUE;
+}
+
+#endif /* CONSOLE_USE_INTERRUPTS */
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042_p.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042_p.h
new file mode 100644
index 0000000000..57273fbe7f
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042_p.h
@@ -0,0 +1,196 @@
+/*
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ */
+
+#ifndef _I8042_P_H_
+#define _I8042_P_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define KBD_CTR_WRITE_COMMAND 0x60
+#define KBD_CTR_READ_COMMAND 0x20
+#define KBD_CTR_TEST_PASSWORD 0xA4
+#define KBD_CTR_LOAD_PASSWORD 0xA5
+#define KBD_CTR_ENABLE_PASSWORD 0xA6
+#define KBD_CTR_DISABLE_AUX 0xA7
+#define KBD_CTR_ENABLE_AUX 0xA8
+#define KBD_CTR_AUXLINES_TEST 0xA9
+#define KBD_CTR_SELFTEST 0xAA
+#define KBD_CTR_KBDLINES_TEST 0xAB
+#define KBD_CTR_DISABLE_KBD 0xAD
+#define KBD_CTR_ENABLE_KBD 0xAE
+#define KBD_CTR_WRITE_AUX 0xD4
+#define KBD_CTR_READ_REV 0xD5
+#define KBD_CTR_READ_VER 0xD6
+#define KBD_CTR_READ_MODEL 0xD7
+
+/* Keyboard Controller Data */
+#define KBD_CTR_SELFTEST_PASSED 0x55
+#define KBD_CTR_PASSWORD_INSTALLED 0xFA
+#define KBD_CTR_PASSWORD_NOT_INSTALLED 0xF1
+
+/* Controller Command Byte bit definitions. */
+#define KBD_CMD_BYTE_DISABLE_AUX 0x20
+#define KBD_CMD_BYTE_DISABLE_KBD 0x10
+#define KBD_CMD_ENABLE_AUX_INT 0x02
+#define KBD_CMD_ENABLE_KBD_INT 0x01
+
+/* Keyboard Controller Status byte masks */
+#define KBD_OBF_MASK 0x1 /* Output buffer full */
+#define KBD_IBF_MASK 0x2 /* Input buffer full */
+#define KBD_FROM_AUX_MASK 0x20 /* Byte from Aux Port. */
+
+/* Interface Test Results */
+#define INTERFACE_NO_ERROR 0x00
+#define CLOCK_STUCK_LOW 0x01
+#define CLOCK_STUCK_HIGH 0x02
+#define DATA_STUCK_LOW 0x03
+#define DATA_STUCK_HIGH 0x04
+
+/* Timeout */
+#define KBD_TIMEOUT 500000 /* Effectively ISA read access times */
+
+/* Keyboard Commands */
+#define KBD_CMD_SET_LEDS 0xed /* Set/Reset LEDs */
+#define KBD_CMD_ECHO 0xee /* request keyboard echo resp. "EE" */
+#define KBD_CMD_SEL_SCAN_CODE 0xf0 /* Scan codes 1,2,3 or 0 = rquest current. */
+#define KBD_CMD_READ_ID 0xf2 /* Request for two byte response */
+#define KBD_CMD_SET_RATE 0xf3 /* Set tellematic Rate */
+#define KBD_CMD_ENABLE 0xf4 /* Clears Buffer and Starts Scanning. */
+#define KBD_CMD_DISABLE 0xf5 /* reset to power up */
+
+#define KBD_CMD_SET_DEFAULT 0xf6
+#define KBD_CMD_SET_ALL_TLMTIC 0xf7 /* Set all keys telematic */
+#define KBD_CMD_SET_ALL_MKBR 0xf8 /* Set all keys Make /Break */
+#define KBD_CMD_SET_ALL_MAKE 0xf9 /* Set all keys Make only */
+#define KBD_CMD_SET_KEY_TLMTIC 0xfb /* Set individual key telemativ */
+#define KBD_CMD_SET_KEY_MKBR 0xfc /* set individual key make/break */
+#define KBD_CMD_SET_KEY_MK 0xfd /* set individual key make only */
+#define KBD_CMD_RESEND 0xfe /* request to resend last transfer */
+#define KBD_CMD_RESET 0xff /* request to start a program reset */
+#define KBD_CMD_ACK 0xfa /* keyboard ack after reset */
+#define KBD_CMD_BAT 0xaa /* Keyboard Bat completion Response */
+
+/*
+ * Define LED encodings for use with the KbdSetLEDs command
+ */
+#define KBD_LED_CAPS 0x04
+#define KBD_LED_NUM 0x02
+#define KBD_LED_SCROLL 0x01
+
+/*
+ * Define two code scan codes in keycode order
+ */
+#define KEY_TWO_KEY 0xe0
+#define KEY_ALT 0x38
+#define KEY_CONTROL 0x1d
+#define KEY_INSERT 0x52
+#define KEY_DELETE 0x53
+#define KEY_LEFT_ARROW 0x4b
+#define KEY_HOME 0x47
+#define KEY_END 0x4F
+#define KEY_UP_ARROW 0x48
+#define KEY_DOWN_ARROW 0x50
+#define KEY_PAGE_UP 0x49
+#define KEY_PAGE_DOWN 0x51
+#define KEY_RIGHT_ARROW 0x4d
+#define KEY_KEYPAD_SLASH 0x35
+#define KEY_KEYPAD_ENTER 0x1c
+#define KEY_SYS_REQUEST 0x2a
+#define KEY_PRINT_SCREEN 0x37
+
+#define KEY_LEFT_SHIFT 0x2a
+#define KEY_RIGHT_SHIFT 0x36
+#define KEY_TAB 0x0f
+#define KEY_CAPS_LOCK 0x3a
+#define KEY_NUM_LOCK 0x45
+#define KEY_SCROLL_LOCK 0x46
+#define KEY_ESC 0x01
+#define KEY_F1 0x3b
+#define KEY_F2 0x3c
+#define KEY_F3 0x3d
+#define KEY_F4 0x3e
+#define KEY_F5 0x3f
+#define KEY_F6 0x40
+#define KEY_F7 0x41
+#define KEY_F8 0x42
+#define KEY_F9 0x43
+#define KEY_F10 0x44
+#define KEY_F11 0x57
+#define KEY_F12 0x58
+
+/*
+ * ASCII control codes
+ */
+#define ASCII_NUL 0x00
+#define ASCII_SOH 0x01
+#define ASCII_STX 0x02
+#define ASCII_ETX 0x03
+#define ASCII_EOT 0x04
+#define ASCII_ENQ 0x05
+#define ASCII_ACK 0x06
+#define ASCII_BEL 0x07
+#define ASCII_BS 0x08
+#define ASCII_HT 0x09
+#define ASCII_LF 0x0a
+#define ASCII_VT 0x0b
+#define ASCII_FF 0x0c
+#define ASCII_CR 0x0d
+#define ASCII_SO 0x0e
+#define ASCII_SI 0x0f
+#define ASCII_DLE 0x10
+#define ASCII_XON 0x11
+#define ASCII_DC1 0x11
+#define ASCII_DC2 0x12
+#define ASCII_XOFF 0x13
+#define ASCII_DC3 0x13
+#define ASCII_DC4 0x14
+#define ASCII_NAK 0x15
+#define ASCII_SYN 0x16
+#define ASCII_ETB 0x17
+#define ASCII_CAN 0x18
+#define ASCII_EM 0x19
+#define ASCII_SUB 0x1a
+#define ASCII_ESC 0x1b
+#define ASCII_FS 0x1c
+#define ASCII_GS 0x1d
+#define ASCII_RS 0x1e
+#define ASCII_US 0x1f
+#define ASCII_DEL 0x7f
+#define ASCII_SYSRQ 0x80
+#define ASCII_CSI 0x9b
+
+/*
+ * Exported functions
+ */
+extern boolean i8042_probe(int minor);
+
+extern void i8042_init(int minor);
+#if CONSOLE_USE_INTERRUPTS
+extern void i8042_initialize_interrupts(int minor);
+
+#else
+extern int i8042_inbyte_nonblocking_polled(
+ int minor
+);
+#endif /* CONSOLE_USE_INTERRUPTS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _I8042_P_H_ */
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042vga.c b/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042vga.c
new file mode 100644
index 0000000000..59716da49a
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042vga.c
@@ -0,0 +1,46 @@
+/*
+ * This file contains the TTY driver for the VGA/i8042 console
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * This driver uses the termios pseudo driver.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <rtems/libio.h>
+
+#include "console.h"
+#include "vga_p.h"
+#include "i8042_p.h"
+
+console_fns i8042vga_fns =
+{
+ i8042_probe, /* deviceProbe */
+ NULL, /* deviceFirstOpen */
+ NULL, /* deviceLastClose */
+#if CONSOLE_USE_INTERRUPTS
+ NULL, /* deviceRead */
+ vga_write_support, /* deviceWrite */
+ i8042_initialize_interrupts, /* deviceInitialize */
+#else
+ i8042_inbyte_nonblocking_polled, /* deviceRead */
+ vga_write_support, /* deviceWrite */
+ i8042_init, /* deviceInitialize */
+#endif
+ vga_write, /* deviceWritePolled */
+ FALSE, /* deviceOutputUsesInterrupts */
+};
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042vga.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042vga.h
new file mode 100644
index 0000000000..6cbceb92de
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042vga.h
@@ -0,0 +1,34 @@
+/*
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * $Id$
+ */
+
+#ifndef _I8042VGA_H_
+#define _I8042VGA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Driver function table
+ */
+extern console_fns i8042vga_fns;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _I8042VGA_H_ */
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.c b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.c
new file mode 100644
index 0000000000..30c10f73b2
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.c
@@ -0,0 +1,632 @@
+/*
+ * This file contains the TTY driver for the NS16550
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * This driver uses the termios pseudo driver.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <stdlib.h>
+
+#include "console.h"
+#include "ns16550_p.h"
+
+/*
+ * Flow control is only supported when using interrupts
+ */
+console_flow ns16550_flow_RTSCTS =
+{
+ ns16550_negate_RTS, /* deviceStopRemoteTx */
+ ns16550_assert_RTS /* deviceStartRemoteTx */
+};
+
+console_flow ns16550_flow_DTRCTS =
+{
+ ns16550_negate_DTR, /* deviceStopRemoteTx */
+ ns16550_assert_DTR /* deviceStartRemoteTx */
+};
+
+console_fns ns16550_fns =
+{
+ ns16550_probe, /* deviceProbe */
+ ns16550_open, /* deviceFirstOpen */
+ ns16550_flush, /* deviceLastClose */
+ NULL, /* deviceRead */
+ ns16550_write_support_int, /* deviceWrite */
+ ns16550_initialize_interrupts, /* deviceInitialize */
+ ns16550_write_polled, /* deviceWritePolled */
+ FALSE, /* deviceOutputUsesInterrupts */
+};
+
+console_fns ns16550_fns_polled =
+{
+ ns16550_probe, /* deviceProbe */
+ ns16550_open, /* deviceFirstOpen */
+ ns16550_close, /* deviceLastClose */
+ ns16550_inbyte_nonblocking_polled, /* deviceRead */
+ ns16550_write_support_polled, /* deviceWrite */
+ ns16550_init, /* deviceInitialize */
+ ns16550_write_polled, /* deviceWritePolled */
+ FALSE, /* deviceOutputUsesInterrupts */
+};
+
+/*
+ * Console Device Driver Entry Points
+ */
+static boolean ns16550_probe(int minor)
+{
+ /*
+ * If the configuration dependant probe has located the device then
+ * assume it is there
+ */
+ return(TRUE);
+}
+
+static void ns16550_init(int minor)
+{
+ PSP_READ_REGISTERS pNS16550Read;
+ PSP_WRITE_REGISTERS pNS16550Write;
+ unsigned8 ucTrash;
+ unsigned8 ucDataByte;
+ unsigned32 ulBaudDivisor;
+ ns16550_context *pns16550Context;
+
+ pns16550Context=(ns16550_context *)malloc(sizeof(ns16550_context));
+
+ Console_Port_Data[minor].pDeviceContext=(void *)pns16550Context;
+ pns16550Context->ucModemCtrl=SP_MODEM_IRQ;
+
+ pNS16550Read=(PSP_READ_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1;
+ pNS16550Write=(PSP_WRITE_REGISTERS)pNS16550Read;
+
+ /* Clear the divisor latch, clear all interrupt enables,
+ * and reset and
+ * disable the FIFO's.
+ */
+
+ outport_byte(&pNS16550Write->LineControl, 0x0);
+ outport_byte(&pNS16550Write->InterruptEnable, 0x0);
+
+ /* Set the divisor latch and set the baud rate. */
+
+ ulBaudDivisor=NS16550_Baud(
+ (unsigned32)Console_Port_Tbl[minor].pDeviceParams);
+ ucDataByte = SP_LINE_DLAB;
+ outport_byte(&pNS16550Write->LineControl, ucDataByte);
+ outport_byte(&pNS16550Write->TransmitBuffer, ulBaudDivisor&0xff);
+ outport_byte(&pNS16550Write->InterruptEnable, (ulBaudDivisor>>8)&0xff);
+
+ /* Clear the divisor latch and set the character size to eight bits */
+ /* with one stop bit and no parity checking. */
+
+ ucDataByte = EIGHT_BITS;
+ outport_byte(&pNS16550Write->LineControl, ucDataByte);
+
+ /* Enable and reset transmit and receive FIFOs. TJA */
+ ucDataByte = SP_FIFO_ENABLE;
+ outport_byte(&pNS16550Write->FifoControl, ucDataByte);
+
+ ucDataByte = SP_FIFO_ENABLE | SP_FIFO_RXRST | SP_FIFO_TXRST;
+ outport_byte(&pNS16550Write->FifoControl, ucDataByte);
+
+ /*
+ * Disable interrupts
+ */
+ ucDataByte = 0;
+ outport_byte(&pNS16550Write->InterruptEnable, ucDataByte);
+
+ /* Set data terminal ready. */
+ /* And open interrupt tristate line */
+
+ outport_byte(&pNS16550Write->ModemControl,
+ pns16550Context->ucModemCtrl);
+
+ inport_byte(&pNS16550Read->LineStatus, ucTrash);
+ inport_byte(&pNS16550Read->ReceiveBuffer, ucTrash);
+}
+
+static int ns16550_open(
+ int major,
+ int minor,
+ void * arg
+)
+{
+ PSP_WRITE_REGISTERS pNS16550Write;
+
+ pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1;
+
+ /*
+ * Assert DTR
+ */
+ if(Console_Port_Tbl[minor].pDeviceFlow
+ !=&ns16550_flow_DTRCTS)
+ {
+ ns16550_assert_DTR(minor);
+ }
+
+ return(RTEMS_SUCCESSFUL);
+}
+
+static int ns16550_close(
+ int major,
+ int minor,
+ void * arg
+)
+{
+ PSP_WRITE_REGISTERS pNS16550Write;
+
+ pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1;
+
+ /*
+ * Negate DTR
+ */
+ if(Console_Port_Tbl[minor].pDeviceFlow
+ !=&ns16550_flow_DTRCTS)
+ {
+ ns16550_negate_DTR(minor);
+ }
+
+ return(RTEMS_SUCCESSFUL);
+}
+
+/*
+ * ns16550_write_polled
+ */
+static void ns16550_write_polled(
+ int minor,
+ char cChar
+)
+{
+ PSP_READ_REGISTERS pNS16550Read;
+ PSP_WRITE_REGISTERS pNS16550Write;
+ unsigned char ucLineStatus;
+ int iTimeout;
+
+ pNS16550Read=(PSP_READ_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1;
+ pNS16550Write=(PSP_WRITE_REGISTERS)pNS16550Read;
+
+ /*
+ * wait for transmitter holding register to be empty
+ */
+ iTimeout=1000;
+ inport_byte(&pNS16550Read->LineStatus, ucLineStatus);
+ while ((ucLineStatus & SP_LSR_THOLD) == 0)
+ {
+ /*
+ * Yield while we wait
+ */
+ if(_System_state_Is_up(_System_state_Get()))
+ {
+ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+ }
+ inport_byte(&pNS16550Read->LineStatus, ucLineStatus);
+ if(!--iTimeout)
+ {
+ break;
+ }
+ }
+
+ /*
+ * transmit character
+ */
+ outport_byte(&pNS16550Write->TransmitBuffer, cChar);
+}
+
+/*
+ * These routines provide control of the RTS and DTR lines
+ */
+/*
+ * ns16550_assert_RTS
+ */
+static void ns16550_assert_RTS(int minor)
+{
+ PSP_WRITE_REGISTERS pNS16550Write;
+ unsigned32 Irql;
+ ns16550_context *pns16550Context;
+
+ pns16550Context=(ns16550_context *)
+ Console_Port_Data[minor].pDeviceContext;
+
+ pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1;
+
+ /*
+ * Assert RTS
+ */
+ rtems_interrupt_disable(Irql);
+ pns16550Context->ucModemCtrl|=SP_MODEM_RTS;
+ outport_byte(&pNS16550Write->ModemControl,
+ pns16550Context->ucModemCtrl);
+ rtems_interrupt_enable(Irql);
+}
+
+/*
+ * ns16550_negate_RTS
+ */
+static void ns16550_negate_RTS(int minor)
+{
+ PSP_WRITE_REGISTERS pNS16550Write;
+ unsigned32 Irql;
+ ns16550_context *pns16550Context;
+
+ pns16550Context=(ns16550_context *)
+ Console_Port_Data[minor].pDeviceContext;
+
+ pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1;
+
+ /*
+ * Negate RTS
+ */
+ rtems_interrupt_disable(Irql);
+ pns16550Context->ucModemCtrl&=~SP_MODEM_RTS;
+ outport_byte(&pNS16550Write->ModemControl,
+ pns16550Context->ucModemCtrl);
+ rtems_interrupt_enable(Irql);
+}
+
+/*
+ * These flow control routines utilise a connection from the local DTR
+ * line to the remote CTS line
+ */
+/*
+ * ns16550_assert_DTR
+ */
+static void ns16550_assert_DTR(int minor)
+{
+ PSP_WRITE_REGISTERS pNS16550Write;
+ unsigned32 Irql;
+ ns16550_context *pns16550Context;
+
+ pns16550Context=(ns16550_context *)
+ Console_Port_Data[minor].pDeviceContext;
+
+ pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1;
+
+ /*
+ * Assert DTR
+ */
+ rtems_interrupt_disable(Irql);
+ pns16550Context->ucModemCtrl|=SP_MODEM_DTR;
+ outport_byte(&pNS16550Write->ModemControl,
+ pns16550Context->ucModemCtrl);
+ rtems_interrupt_enable(Irql);
+}
+
+/*
+ * ns16550_negate_DTR
+ */
+static void ns16550_negate_DTR(int minor)
+{
+ PSP_WRITE_REGISTERS pNS16550Write;
+ unsigned32 Irql;
+ ns16550_context *pns16550Context;
+
+ pns16550Context=(ns16550_context *)
+ Console_Port_Data[minor].pDeviceContext;
+
+ pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1;
+
+ /*
+ * Negate DTR
+ */
+ rtems_interrupt_disable(Irql);
+ pns16550Context->ucModemCtrl&=~SP_MODEM_DTR;
+ outport_byte(&pNS16550Write->ModemControl,
+ pns16550Context->ucModemCtrl);
+ rtems_interrupt_enable(Irql);
+}
+
+/*
+ * ns16550_isr
+ *
+ * This routine is the console interrupt handler for COM1 and COM2
+ *
+ * Input parameters:
+ * vector - vector number
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+static void ns16550_process(
+ int minor
+)
+{
+ PSP_READ_REGISTERS pNS16550Read;
+ PSP_WRITE_REGISTERS pNS16550Write;
+ volatile unsigned8 ucLineStatus, ucInterruptId;
+ char cChar;
+
+ pNS16550Read=(PSP_READ_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1;
+ pNS16550Write=(PSP_WRITE_REGISTERS)pNS16550Read;
+
+ do
+ {
+ /*
+ * Deal with any received characters
+ */
+ while(TRUE)
+ {
+ inport_byte(&pNS16550Read->LineStatus, ucLineStatus);
+ if(~ucLineStatus & SP_LSR_RDY)
+ {
+ break;
+ }
+ inport_byte(&pNS16550Read->ReceiveBuffer, cChar);
+ rtems_termios_enqueue_raw_characters(
+ Console_Port_Data[minor].termios_data,
+ &cChar, 1 );
+ }
+
+ while(TRUE)
+ {
+ if(Ring_buffer_Is_empty(
+ &Console_Port_Data[minor].TxBuffer))
+ {
+ Console_Port_Data[minor].bActive=FALSE;
+ if(Console_Port_Tbl[minor].pDeviceFlow
+ !=&ns16550_flow_RTSCTS)
+ {
+ ns16550_negate_RTS(minor);
+ }
+ /*
+ * There is no data to transmit
+ */
+ break;
+ }
+
+ inport_byte(&pNS16550Read->LineStatus, ucLineStatus);
+ if(~ucLineStatus & SP_LSR_THOLD)
+ {
+ /*
+ * We'll get another interrupt when
+ * the transmitter holding reg. becomes
+ * free again
+ */
+ break;
+ }
+
+ Ring_buffer_Remove_character(
+ &Console_Port_Data[minor].TxBuffer,
+ cChar);
+ /*
+ * transmit character
+ */
+ outport_byte(&pNS16550Write->TransmitBuffer, cChar);
+ }
+
+ inport_byte(&pNS16550Read->InterruptId, ucInterruptId);
+ }
+ while((ucInterruptId&0xf)!=0x1);
+}
+
+static rtems_isr ns16550_isr(
+ rtems_vector_number vector
+)
+{
+ int minor;
+
+ for(minor=0;minor<Console_Port_Count;minor++)
+ {
+ if(vector==Console_Port_Tbl[minor].ulIntVector)
+ {
+ ns16550_process(minor);
+ }
+ }
+}
+
+/*
+ * ns16550_flush
+ */
+static int ns16550_flush(int major, int minor, void *arg)
+{
+ while(!Ring_buffer_Is_empty(&Console_Port_Data[minor].TxBuffer))
+ {
+ /*
+ * Yield while we wait
+ */
+ if(_System_state_Is_up(_System_state_Get()))
+ {
+ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+ }
+ }
+
+ ns16550_close(major, minor, arg);
+
+ return(RTEMS_SUCCESSFUL);
+}
+
+/*
+ * ns16550_initialize_interrupts
+ *
+ * This routine initializes the console's receive and transmit
+ * ring buffers and loads the appropriate vectors to handle the interrupts.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+static void ns16550_enable_interrupts(
+ int minor
+)
+{
+ PSP_WRITE_REGISTERS pNS16550Write;
+ unsigned8 ucDataByte;
+
+ pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1;
+
+ /*
+ * Enable interrupts
+ */
+ ucDataByte = SP_INT_RX_ENABLE | SP_INT_TX_ENABLE;
+ outport_byte(&pNS16550Write->InterruptEnable, ucDataByte);
+
+}
+
+static void ns16550_initialize_interrupts(int minor)
+{
+ ns16550_init(minor);
+
+ Ring_buffer_Initialize(&Console_Port_Data[minor].TxBuffer);
+
+ Console_Port_Data[minor].bActive = FALSE;
+
+ set_vector(ns16550_isr,
+ Console_Port_Tbl[minor].ulIntVector,
+ 1);
+
+ ns16550_enable_interrupts(minor);
+}
+
+/*
+ * ns16550_write_support_int
+ *
+ * Console Termios output entry point.
+ *
+ */
+static int ns16550_write_support_int(
+ int minor,
+ const char *buf,
+ int len)
+{
+ int i;
+ unsigned32 Irql;
+
+ for(i=0; i<len;)
+ {
+ if(Ring_buffer_Is_full(&Console_Port_Data[minor].TxBuffer))
+ {
+ if(!Console_Port_Data[minor].bActive)
+ {
+ /*
+ * Wake up the device
+ */
+ rtems_interrupt_disable(Irql);
+ Console_Port_Data[minor].bActive = TRUE;
+ if(Console_Port_Tbl[minor].pDeviceFlow
+ !=&ns16550_flow_RTSCTS)
+ {
+ ns16550_assert_RTS(minor);
+ }
+ ns16550_process(minor);
+ rtems_interrupt_enable(Irql);
+ }
+ else
+ {
+ /*
+ * Yield
+ */
+ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+ }
+
+ /*
+ * Wait for ring buffer to empty
+ */
+ continue;
+ }
+ else
+ {
+ Ring_buffer_Add_character(
+ &Console_Port_Data[minor].TxBuffer,
+ buf[i]);
+ i++;
+ }
+ }
+
+ /*
+ * Ensure that characters are on the way
+ */
+ if(!Console_Port_Data[minor].bActive)
+ {
+ /*
+ * Wake up the device
+ */
+ rtems_interrupt_disable(Irql);
+ Console_Port_Data[minor].bActive = TRUE;
+ if(Console_Port_Tbl[minor].pDeviceFlow
+ !=&ns16550_flow_RTSCTS)
+ {
+ ns16550_assert_RTS(minor);
+ }
+ ns16550_process(minor);
+ rtems_interrupt_enable(Irql);
+ }
+
+ return (len);
+}
+
+/*
+ * ns16550_write_support_polled
+ *
+ * Console Termios output entry point.
+ *
+ */
+static int ns16550_write_support_polled(
+ int minor,
+ const char *buf,
+ int len)
+{
+ int nwrite = 0;
+
+ /*
+ * poll each byte in the string out of the port.
+ */
+ while (nwrite < len)
+ {
+ /*
+ * transmit character
+ */
+ ns16550_write_polled(minor, *buf++);
+ nwrite++;
+ }
+
+ /*
+ * return the number of bytes written.
+ */
+ return nwrite;
+}
+
+/*
+ * ns16550_inbyte_nonblocking_polled
+ *
+ * Console Termios polling input entry point.
+ */
+
+static int ns16550_inbyte_nonblocking_polled(
+ int minor
+)
+{
+ PSP_READ_REGISTERS pNS16550Read;
+ unsigned char ucLineStatus;
+ char cChar;
+
+ pNS16550Read=(PSP_READ_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1;
+
+ inport_byte(&pNS16550Read->LineStatus, ucLineStatus);
+ if(ucLineStatus & SP_LSR_RDY)
+ {
+ inport_byte(&pNS16550Read->ReceiveBuffer, cChar);
+ return((int)cChar);
+ }
+ else
+ {
+ return(-1);
+ }
+}
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.h
new file mode 100644
index 0000000000..e797ba2244
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550.h
@@ -0,0 +1,40 @@
+/*
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ */
+
+#ifndef _NS16550_H_
+#define _NS16550_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Driver function table
+ */
+extern console_fns ns16550_fns;
+extern console_fns ns16550_fns_polled;
+
+/*
+ * Flow control function tables
+ */
+extern console_flow ns16550_flow_RTSCTS;
+extern console_flow ns16550_flow_DTRCTS;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NS16550_H_ */
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550_p.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550_p.h
new file mode 100644
index 0000000000..7f7f51afa9
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550_p.h
@@ -0,0 +1,196 @@
+/*
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ */
+
+#ifndef _NS16550_P_H_
+#define _NS16550_P_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Define serial port read registers structure.
+ */
+
+typedef volatile struct _SP_READ_REGISTERS {
+ unsigned char ReceiveBuffer;
+ unsigned char InterruptEnable;
+ unsigned char InterruptId;
+ unsigned char LineControl;
+ unsigned char ModemControl;
+ unsigned char LineStatus;
+ unsigned char ModemStatus;
+ unsigned char ScratchPad;
+} SP_READ_REGISTERS, *PSP_READ_REGISTERS;
+
+/*
+ * Define serial port write registers structure.
+ */
+
+typedef volatile struct _SP_WRITE_REGISTERS {
+ unsigned char TransmitBuffer;
+ unsigned char InterruptEnable;
+ unsigned char FifoControl;
+ unsigned char LineControl;
+ unsigned char ModemControl;
+ unsigned char Reserved1;
+ unsigned char ModemStatus;
+ unsigned char ScratchPad;
+} SP_WRITE_REGISTERS, *PSP_WRITE_REGISTERS;
+
+/*
+ * Define serial port interrupt enable register structure.
+ */
+
+#define SP_INT_RX_ENABLE 0x01
+#define SP_INT_TX_ENABLE 0x02
+#define SP_INT_LS_ENABLE 0x04
+#define SP_INT_MS_ENABLE 0x08
+
+/*
+ * Define serial port interrupt id register structure.
+ */
+
+typedef struct _SP_INTERRUPT_ID {
+ unsigned char InterruptPending : 1;
+ unsigned char Identification : 3;
+ unsigned char Reserved1 : 2;
+ unsigned char FifoEnabled : 2;
+} SP_INTERRUPT_ID, *PSP_INTERRUPT_ID;
+
+/*
+ * Define serial port fifo control register structure.
+ */
+#define SP_FIFO_ENABLE 0x01
+#define SP_FIFO_RXRST 0x02
+#define SP_FIFO_TXRST 0x04
+#define SP_FIFO_DMA 0x08
+#define SP_FIFO_RXLEVEL 0xc0
+
+/*
+ * Define serial port line control register structure.
+ */
+#define SP_LINE_SIZE 0x03
+#define SP_LINE_STOP 0x04
+#define SP_LINE_PAR 0x08
+#define SP_LINE_ODD 0x10
+#define SP_LINE_STICK 0x20
+#define SP_LINE_BREAK 0x40
+#define SP_LINE_DLAB 0x80
+
+/*
+ * Line status register character size definitions.
+ */
+#define FIVE_BITS 0x0 /* five bits per character */
+#define SIX_BITS 0x1 /* six bits per character */
+#define SEVEN_BITS 0x2 /* seven bits per character */
+#define EIGHT_BITS 0x3 /* eight bits per character */
+
+/*
+ * Line speed divisor definition.
+ */
+#define NS16550_Baud(baud_rate) (115200/baud_rate)
+
+/*
+ * Define serial port modem control register structure.
+ */
+#define SP_MODEM_DTR 0x01
+#define SP_MODEM_RTS 0x02
+#define SP_MODEM_IRQ 0x08
+#define SP_MODEM_LOOP 0x10
+#define SP_MODEM_DIV4 0x80
+
+/*
+ * Define serial port line status register structure.
+ */
+#define SP_LSR_RDY 0x01
+#define SP_LSR_EOVRUN 0x02
+#define SP_LSR_EPAR 0x04
+#define SP_LSR_EFRAME 0x08
+#define SP_LSR_BREAK 0x10
+#define SP_LSR_THOLD 0x20
+#define SP_LSR_TX 0x40
+#define SP_LSR_EFIFO 0x80
+
+typedef struct _ns16550_context
+{
+ unsigned8 ucModemCtrl;
+} ns16550_context;
+
+/*
+ * Driver functions
+ */
+static boolean ns16550_probe(int minor);
+
+static void ns16550_init(int minor);
+
+static int ns16550_open(
+ int major,
+ int minor,
+ void * arg
+);
+
+static int ns16550_close(
+ int major,
+ int minor,
+ void * arg
+);
+
+static void ns16550_write_polled(
+ int minor,
+ char cChar
+);
+
+static void ns16550_assert_RTS(
+ int minor
+);
+
+static void ns16550_negate_RTS(
+ int minor
+);
+
+static void ns16550_assert_DTR(
+ int minor
+);
+
+static void ns16550_negate_DTR(
+ int minor
+);
+
+static void ns16550_initialize_interrupts(int minor);
+
+static int ns16550_flush(int major, int minor, void *arg);
+
+static int ns16550_write_support_int(
+ int minor,
+ const char *buf,
+ int len
+);
+
+static int ns16550_write_support_polled(
+ int minor,
+ const char *buf,
+ int len
+ );
+
+static int ns16550_inbyte_nonblocking_polled(
+ int minor
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NS16550_P_H_ */
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.c b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.c
new file mode 100644
index 0000000000..88cbde4bbe
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.c
@@ -0,0 +1,53 @@
+/* nc16550cfg.c
+ *
+ * This include file contains all console driver definations for the nc16550
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+
+unsigned8 Read_ns16550_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum
+)
+{
+ unsigned char *p = (unsigned char *)ulCtrlPort;
+ unsigned char ucData;
+
+ inport_byte( &p[ucRegNum], ucData );
+ return ucData;
+}
+
+void Write_ns16550_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum,
+ unsigned8 ucData
+)
+{
+ unsigned char *p = (unsigned char *)ulCtrlPort;
+
+ outport_byte( &p[ucRegNum], ucData );
+}
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.h
new file mode 100644
index 0000000000..87235a80f2
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/ns16550cfg.h
@@ -0,0 +1,55 @@
+/* nc16550cfg.h
+ *
+ * This include file contains all console driver definations for the nc16550
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#ifndef __NS16550_CONFIG_H
+#define __NS16550_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Board specific register access routines
+ */
+
+unsigned8 Read_ns16550_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum
+);
+
+void Write_ns16550_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum,
+ unsigned8 ucData
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/vga.c b/c/src/lib/libbsp/powerpc/ppcn_60x/console/vga.c
new file mode 100644
index 0000000000..ed7a867d1d
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/vga.c
@@ -0,0 +1,368 @@
+/*
+ * This file contains the TTY driver for VGA
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * This driver uses the termios pseudo driver.
+ */
+/*-------------------------------------------------------------------------+
+| (C) Copyright 1997 -
+| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
+|
+| http://pandora.ist.utl.pt
+|
+| Instituto Superior Tecnico * Lisboa * PORTUGAL
++--------------------------------------------------------------------------+
+| Disclaimer:
+|
+| This file is provided "AS IS" without warranty of any kind, either
+| expressed or implied.
++--------------------------------------------------------------------------+
+| This code is based on:
+| outch.c,v 1.4 1995/12/19 20:07:27 joel Exp - go32 BSP
+| With the following copyright notice:
+| **************************************************************************
+| * 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. *
+| **************************************************************************
++--------------------------------------------------------------------------*/
+
+
+#include <bsp.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "vga_p.h"
+
+/*-------------------------------------------------------------------------+
+| Constants
++--------------------------------------------------------------------------*/
+#define DISPLAY_CELL_COUNT (VGA_NUM_ROWS * VGA_NUM_COLS)
+ /* Number of display cells. */
+#define TABSIZE 4 /* Number of spaces for TAB (\t) char. */
+#define WHITE 0x0007 /* White on Black background colour. */
+#define BLANK (WHITE | (' '<<8)) /* Blank character. */
+
+/*
+ * This is imported from i8042.c to provide flow control
+ */
+extern volatile boolean bScrollLock;
+
+/*-------------------------------------------------------------------------+
+| Global Variables
++--------------------------------------------------------------------------*/
+/* Physical address of start of video text memory. */
+static unsigned16 *videoRam = (unsigned16 *)VGA_FB;
+/* Pointer for current output position in display. */
+static unsigned16 *videoRamPtr = (unsigned16 *)VGA_FB;
+static unsigned8 videoRows = VGA_NUM_ROWS; /* Number of rows in display. */
+static unsigned8 videoCols = VGA_NUM_COLS; /* Number of columns in display. */
+static unsigned8 cursRow = 0; /* Current cursor row. */
+static unsigned8 cursCol = 0; /* Current cursor column. */
+
+
+/*-------------------------------------------------------------------------+
+| Function: setHardwareCursorPos
+| Description: Set hardware video cursor at given offset into video RAM.
+| Global Variables: None.
+| Arguments: videoCursor - Offset into video memory.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static inline void
+setHardwareCursorPos(unsigned16 videoCursor)
+{
+ VGA_WRITE_CRTC(0x0e, (videoCursor >> 8) & 0xff);
+ VGA_WRITE_CRTC(0x0f, videoCursor & 0xff);
+} /* setHardwareCursorPos */
+
+
+/*-------------------------------------------------------------------------+
+| Function: updateVideoRamPtr
+| Description: Updates value of global variable "videoRamPtr" based on
+| current window's cursor position.
+| Global Variables: videoRamPtr, cursRow, cursCol.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static inline void
+updateVideoRamPtr(void)
+{
+ videoRamPtr = videoRam + cursRow * videoCols + cursCol;
+} /* updateVideoRamPtr */
+
+
+/*-------------------------------------------------------------------------+
+| Function: scrollUp
+| Description: Scrolls display up n lines.
+| Global Variables: None.
+| Arguments: lines - number of lines to scroll.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static void
+scrollUp(unsigned8 lines)
+{
+ /* Number of blank display cells on bottom of window. */
+ unsigned16 blankCount;
+
+ /* Source and destination pointers for memory copy operations. */
+ unsigned16 *ptrDst, *ptrSrc;
+
+ if(lines<videoRows) /* Move window's contents up. */
+ {
+ /*
+ * Number of non-blank cells on upper part
+ * of display (total - blank).
+ */
+ unsigned16 nonBlankCount;
+
+ blankCount = lines * videoCols;
+ nonBlankCount = DISPLAY_CELL_COUNT - blankCount;
+ ptrSrc = videoRam + blankCount;
+ ptrDst = videoRam;
+
+ while(nonBlankCount--)
+ {
+ *ptrDst++ = *ptrSrc++;
+ }
+ }
+ else
+ {
+ /*
+ * Clear the whole display.
+ */
+ blankCount = DISPLAY_CELL_COUNT;
+ ptrDst = videoRam;
+ }
+
+ /* Fill bottom with blanks. */
+ while (blankCount-->0)
+ {
+ *ptrDst++ = BLANK;
+ }
+} /* scrollUp */
+
+
+/*-------------------------------------------------------------------------+
+| Function: printCHAR
+| Description: Print printable character to display.
+| Global Variables: videoRamPtr, cursRow, cursCol.
+| Arguments: c - character to write to display.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static void
+printCHAR(char c)
+{
+ *videoRamPtr++ = (c<<8) | WHITE;
+ cursCol++;
+ if(cursCol==videoCols)
+ {
+ cursCol = 0;
+ cursRow++;
+ if(cursRow==videoRows)
+ {
+ cursRow--;
+ scrollUp(1);
+ videoRamPtr -= videoCols;
+ }
+ }
+} /* printCHAR */
+
+/*-------------------------------------------------------------------------+
+| Function: printBS
+| Description: Print BS (BackSpace - '\b') character to display.
+| Global Variables: videoRamPtr, cursRow, cursCol.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static inline void
+printBS(void)
+{
+ /* Move cursor back one cell. */
+ if(cursCol>0)
+ {
+ cursCol--;
+ }
+ else if(cursRow>0)
+ {
+ cursRow--;
+ cursCol = videoCols - 1;
+ }
+ else
+ {
+ return;
+ }
+
+ /* Write a whitespace. */
+ *(--videoRamPtr) = BLANK;
+} /* printBS */
+
+
+/*-------------------------------------------------------------------------+
+| Function: printHT
+| Description: Print HT (Horizontal Tab - '\t') character to display.
+| Global Variables: cursCol.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static inline void
+printHT(void)
+{
+ do
+ {
+ printCHAR(' ');
+ }
+ while (cursCol % TABSIZE);
+} /* printHT */
+
+
+/*-------------------------------------------------------------------------+
+| Function: printLF
+| Description: Print LF (Line Feed - '\n') character to display.
+| Global Variables: cursRow.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static inline void
+printLF(void)
+{
+ cursRow++;
+ if(cursRow==videoRows)
+ {
+ cursRow--;
+ scrollUp(1);
+ }
+ updateVideoRamPtr();
+} /* printLF */
+
+
+/*-------------------------------------------------------------------------+
+| Function: printCR
+| Description: Print CR (Carriage Return - '\r') to display.
+| Global Variables: cursCol.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+static inline void
+printCR(void)
+{
+ cursCol = 0;
+ updateVideoRamPtr();
+} /* printCR */
+
+/*
+ * Console Device Driver Entry Points
+ */
+void
+vga_write(
+ int minor,
+ char cChar)
+{
+ switch (cChar)
+ {
+ case '\b':
+ printBS();
+ break;
+ case '\t':
+ printHT();
+ break;
+ case '\n':
+ printLF();
+ break;
+ case '\r':
+ printCR();
+ break;
+ default:
+ printCHAR(cChar);
+ break;
+ }
+
+ setHardwareCursorPos(videoRamPtr - videoRam);
+} /* vga_write */
+
+/*
+ * vga_write_support
+ *
+ * Console Termios output entry point.
+ *
+ */
+int vga_write_support(
+ int minor,
+ const char *buf,
+ int len
+)
+{
+ int nwrite = 0;
+
+ while(bScrollLock)
+ {
+ /*
+ * The Scroll lock on the keyboard is active
+ */
+ /*
+ * Yield while we wait
+ */
+ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+ }
+
+ /*
+ * Write each byte in the string to the display
+ */
+ while (nwrite<len)
+ {
+ /*
+ * transmit character
+ */
+ vga_write(minor, *buf++);
+ nwrite++;
+ }
+
+ /*
+ * return the number of bytes written.
+ */
+ return nwrite;
+}
+
+boolean vga_probe(int minor)
+{
+ unsigned8 ucMiscIn;
+
+ /*
+ * Check for presence of VGA adaptor
+ */
+ inport_byte(0x3cc, ucMiscIn);
+ if(ucMiscIn!=0xff)
+ {
+ /*
+ * VGA device is present
+ */
+ return(TRUE);
+ }
+ return(FALSE);
+}
+
+void vga_init(int minor)
+{
+ scrollUp(videoRows); /* Clear entire screen */
+ setHardwareCursorPos(0); /* Cursor at upper left corner */
+ /*
+ * Enable the cursor
+ */
+ VGA_WRITE_CRTC(0x0a, 0x0e); /* Crt cursor start */
+}
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/vga_p.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/vga_p.h
new file mode 100644
index 0000000000..591365a94f
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/vga_p.h
@@ -0,0 +1,70 @@
+/*
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ */
+
+#ifndef _VGA_P_H_
+#define _VGA_P_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define VGA_FB ((unsigned32)PCI_MEM_BASE+0xb8000)
+#define VGA_NUM_ROWS 25
+#define VGA_NUM_COLS 80
+
+#define VGA_WRITE_SEQ(reg, val) \
+ outport_byte(0x3c4, reg); \
+ outport_byte(0x3c5, val)
+#define VGA_READ_SEQ(reg, val) \
+ outport_byte(0x3c4, reg); \
+ inport_byte(0x3c5, val)
+#define VGA_WRITE_CRTC(reg, val) \
+ outport_byte(0x3d4, reg); \
+ outport_byte(0x3d5, val)
+#define VGA_WRITE_GRA(reg, val) \
+ outport_byte(0x3ce, reg); \
+ outport_byte(0x3cf, val)
+#define VGA_WRITE_ATT(reg, val) \
+ { \
+ volatile unsigned8 ucDummy; \
+ inport_byte(0x3da, ucDummy); \
+ outport_byte(0x3c0, reg); \
+ outport_byte(0x3c0, val); \
+ }
+
+/*
+ * Exported functions
+ */
+extern boolean vga_probe(int minor);
+
+extern void vga_init(int minor);
+
+extern void vga_write(
+ int minor,
+ char cChar
+);
+
+extern int vga_write_support(
+ int minor,
+ const char *buf,
+ int len
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VGA_P_H_ */
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30.c b/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30.c
new file mode 100644
index 0000000000..720117dc8d
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30.c
@@ -0,0 +1,917 @@
+/*
+ * This file contains the console driver chip level routines for the
+ * z85c30 chip.
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id:
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <stdlib.h>
+
+#include "console.h"
+#include "z85c30_p.h"
+
+/*
+ * Flow control is only supported when using interrupts
+ */
+console_flow z85c30_flow_RTSCTS =
+{
+ z85c30_negate_RTS, /* deviceStopRemoteTx */
+ z85c30_assert_RTS /* deviceStartRemoteTx */
+};
+
+console_flow z85c30_flow_DTRCTS =
+{
+ z85c30_negate_DTR, /* deviceStopRemoteTx */
+ z85c30_assert_DTR /* deviceStartRemoteTx */
+};
+
+/*
+ * Exported driver function table
+ */
+console_fns z85c30_fns =
+{
+ z85c30_probe, /* deviceProbe */
+ z85c30_open, /* deviceFirstOpen */
+ z85c30_flush, /* deviceLastClose */
+ NULL, /* deviceRead */
+ z85c30_write_support_int, /* deviceWrite */
+ z85c30_initialize_interrupts, /* deviceInitialize */
+ z85c30_write_polled, /* deviceWritePolled */
+ FALSE, /* deviceOutputUsesInterrupts */
+};
+
+console_fns z85c30_fns_polled =
+{
+ z85c30_probe, /* deviceProbe */
+ z85c30_open, /* deviceFirstOpen */
+ z85c30_close, /* deviceLastClose */
+ z85c30_inbyte_nonblocking_polled, /* deviceRead */
+ z85c30_write_support_polled, /* deviceWrite */
+ z85c30_init, /* deviceInitialize */
+ z85c30_write_polled, /* deviceWritePolled */
+ FALSE, /* deviceOutputUsesInterrupts */
+};
+
+/*
+ * Read_85c30_register
+ *
+ * Read a Z85c30 register
+ */
+static unsigned8 Read_85c30_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum
+)
+{
+ unsigned8 ucData;
+
+ outport_byte(ulCtrlPort, ucRegNum);
+
+ inport_byte(ulCtrlPort, ucData);
+
+ return ucData;
+}
+
+/*
+ * Write_85c30_register
+ *
+ * Write a Z85c30 register
+ */
+static void Write_85c30_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum,
+ unsigned8 ucData
+)
+{
+ if(ucRegNum!=SCC_WR0_SEL_WR0)
+ {
+ outport_byte(ulCtrlPort, ucRegNum);
+ }
+ outport_byte(ulCtrlPort, ucData);
+}
+
+/*
+ * Read_85c30_data
+ *
+ * Read a Z85c30 data register
+ */
+static unsigned8 Read_85c30_data(
+ unsigned32 ulDataPort
+)
+{
+ unsigned8 ucData;
+
+ inport_byte(ulDataPort, ucData);
+
+ return ucData;
+}
+
+/*
+ * Write_85c30_data
+ *
+ * Write a Z85c30 data register
+ */
+static void Write_85c30_data(
+ unsigned32 ulDataPort,
+ unsigned8 ucData
+)
+{
+ outport_byte(ulDataPort, ucData);
+}
+
+/*
+ * z85c30_initialize_port
+ *
+ * initialize a z85c30 Port
+ */
+static void z85c30_initialize_port(
+ int minor
+)
+{
+ unsigned32 ulCtrlPort;
+ unsigned32 ulBaudDivisor;
+
+ ulCtrlPort=Console_Port_Tbl[minor].ulCtrlPort1;
+
+ /*
+ * Using register 4
+ * Set up the clock rate is 16 times the data
+ * rate, 8 bit sync char, 1 stop bit, no parity
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR4,
+ SCC_WR4_1_STOP |
+ SCC_WR4_16_CLOCK);
+
+ /*
+ * Set up for 8 bits/character on receive with
+ * receiver disable via register 3
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR3,
+ SCC_WR3_RX_8_BITS);
+
+ /*
+ * Set up for 8 bits/character on transmit
+ * with transmitter disable via register 5
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR5,
+ SCC_WR5_TX_8_BITS);
+
+ /*
+ * Clear misc control bits
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR10,
+ 0x00);
+
+ /*
+ * Setup the source of the receive and xmit
+ * clock as BRG output and the transmit clock
+ * as the output source for TRxC pin via register 11
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR11,
+ SCC_WR11_OUT_BR_GEN |
+ SCC_WR11_TRXC_OI |
+ SCC_WR11_TX_BR_GEN |
+ SCC_WR11_RX_BR_GEN);
+
+ ulBaudDivisor=Z85C30_Baud(
+ (unsigned32)Console_Port_Tbl[minor].pDeviceParams);
+ /*
+ * Setup the lower 8 bits time constants=1E.
+ * If the time constans=1E, then the desire
+ * baud rate will be equilvalent to 9600, via register 12.
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR12,
+ ulBaudDivisor&0xff);
+
+ /*
+ * using register 13
+ * Setup the upper 8 bits time constant
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR13,
+ (ulBaudDivisor>>8)&0xff);
+
+ /*
+ * Enable the baud rate generator enable with clock from the
+ * SCC's PCLK input via register 14.
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR14,
+ SCC_WR14_BR_EN |
+ SCC_WR14_BR_SRC |
+ SCC_WR14_NULL);
+
+ /*
+ * We are only interested in CTS state changes
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR15,
+ SCC_WR15_CTS_IE);
+
+ /*
+ * Reset errors
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR0,
+ SCC_WR0_RST_INT);
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR0,
+ SCC_WR0_ERR_RST);
+
+ /*
+ * Enable the receiver via register 3
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR3,
+ SCC_WR3_RX_8_BITS |
+ SCC_WR3_RX_EN);
+
+ /*
+ * Enable the transmitter pins set via register 5.
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR5,
+ SCC_WR5_TX_8_BITS |
+ SCC_WR5_TX_EN);
+
+ /*
+ * Disable interrupts
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR1,
+ 0);
+
+ /*
+ * Reset TX CRC
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR0,
+ SCC_WR0_RST_TX_CRC);
+
+ /*
+ * Reset interrupts
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR0,
+ SCC_WR0_RST_INT);
+}
+
+static int z85c30_open(
+ int major,
+ int minor,
+ void * arg
+)
+{
+ /*
+ * Assert DTR
+ */
+ if(Console_Port_Tbl[minor].pDeviceFlow
+ !=&z85c30_flow_DTRCTS)
+ {
+ z85c30_assert_DTR(minor);
+ }
+
+ return(RTEMS_SUCCESSFUL);
+}
+
+static int z85c30_close(
+ int major,
+ int minor,
+ void * arg
+)
+{
+ /*
+ * Negate DTR
+ */
+ if(Console_Port_Tbl[minor].pDeviceFlow
+ !=&z85c30_flow_DTRCTS)
+ {
+ z85c30_negate_DTR(minor);
+ }
+
+ return(RTEMS_SUCCESSFUL);
+}
+
+/*
+ * z85c30_write_polled
+ *
+ * This routine transmits a character using polling.
+ */
+static void z85c30_write_polled(
+ int minor,
+ char cChar
+)
+{
+ volatile unsigned8 z85c30_status;
+ unsigned32 ulCtrlPort;
+
+ ulCtrlPort=Console_Port_Tbl[minor].ulCtrlPort1;
+
+ /*
+ * Wait for the Transmit buffer to indicate that it is empty.
+ */
+ z85c30_status=Read_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_RD0);
+ while(!Z85C30_Status_Is_TX_buffer_empty(z85c30_status))
+ {
+ /*
+ * Yield while we wait
+ */
+ if(_System_state_Is_up(_System_state_Get()))
+ {
+ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+ }
+ z85c30_status=Read_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_RD0);
+ }
+
+ /*
+ * Write the character.
+ */
+ Write_85c30_data(Console_Port_Tbl[minor].ulDataPort, cChar);
+}
+
+/*
+ * Console Device Driver Entry Points
+ */
+static boolean z85c30_probe(int minor)
+{
+ /*
+ * If the configuration dependant probe has located the device then
+ * assume it is there
+ */
+ return(TRUE);
+}
+
+static void z85c30_init(int minor)
+{
+ unsigned32 ulCtrlPort;
+ unsigned8 dummy;
+ z85c30_context *pz85c30Context;
+
+ pz85c30Context=(z85c30_context *)malloc(sizeof(z85c30_context));
+
+ Console_Port_Data[minor].pDeviceContext=(void *)pz85c30Context;
+ pz85c30Context->ucModemCtrl=SCC_WR5_TX_8_BITS | SCC_WR5_TX_EN;
+
+ ulCtrlPort=Console_Port_Tbl[minor].ulCtrlPort1;
+ if(ulCtrlPort==Console_Port_Tbl[minor].ulCtrlPort2)
+ {
+ /*
+ * This is channel A
+ */
+ /*
+ * Ensure port state machine is reset
+ */
+ inport_byte(ulCtrlPort, dummy);
+
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR9,
+ SCC_WR9_CH_A_RST);
+ }
+ else
+ {
+ /*
+ * This is channel B
+ */
+ /*
+ * Ensure port state machine is reset
+ */
+ inport_byte(ulCtrlPort, dummy);
+
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR9,
+ SCC_WR9_CH_B_RST);
+ }
+
+ z85c30_initialize_port(minor);
+}
+
+/*
+ * These routines provide control of the RTS and DTR lines
+ */
+/*
+ * z85c30_assert_RTS
+ */
+static void z85c30_assert_RTS(int minor)
+{
+ unsigned32 Irql;
+ z85c30_context *pz85c30Context;
+
+ pz85c30Context=(z85c30_context *)
+ Console_Port_Data[minor].pDeviceContext;
+
+ /*
+ * Assert RTS
+ */
+ rtems_interrupt_disable(Irql);
+ pz85c30Context->ucModemCtrl|=SCC_WR5_RTS;
+ Write_85c30_register(
+ Console_Port_Tbl[minor].ulCtrlPort1,
+ SCC_WR0_SEL_WR5,
+ pz85c30Context->ucModemCtrl);
+ rtems_interrupt_enable(Irql);
+}
+
+/*
+ * z85c30_negate_RTS
+ */
+static void z85c30_negate_RTS(int minor)
+{
+ unsigned32 Irql;
+ z85c30_context *pz85c30Context;
+
+ pz85c30Context=(z85c30_context *)
+ Console_Port_Data[minor].pDeviceContext;
+
+ /*
+ * Negate RTS
+ */
+ rtems_interrupt_disable(Irql);
+ pz85c30Context->ucModemCtrl&=~SCC_WR5_RTS;
+ Write_85c30_register(
+ Console_Port_Tbl[minor].ulCtrlPort1,
+ SCC_WR0_SEL_WR5,
+ pz85c30Context->ucModemCtrl);
+ rtems_interrupt_enable(Irql);
+}
+
+/*
+ * These flow control routines utilise a connection from the local DTR
+ * line to the remote CTS line
+ */
+/*
+ * z85c30_assert_DTR
+ */
+static void z85c30_assert_DTR(int minor)
+{
+ unsigned32 Irql;
+ z85c30_context *pz85c30Context;
+
+ pz85c30Context=(z85c30_context *)
+ Console_Port_Data[minor].pDeviceContext;
+
+ /*
+ * Assert DTR
+ */
+ rtems_interrupt_disable(Irql);
+ pz85c30Context->ucModemCtrl|=SCC_WR5_DTR;
+ Write_85c30_register(
+ Console_Port_Tbl[minor].ulCtrlPort1,
+ SCC_WR0_SEL_WR5,
+ pz85c30Context->ucModemCtrl);
+ rtems_interrupt_enable(Irql);
+}
+
+/*
+ * z85c30_negate_DTR
+ */
+static void z85c30_negate_DTR(int minor)
+{
+ unsigned32 Irql;
+ z85c30_context *pz85c30Context;
+
+ pz85c30Context=(z85c30_context *)
+ Console_Port_Data[minor].pDeviceContext;
+
+ /*
+ * Negate DTR
+ */
+ rtems_interrupt_disable(Irql);
+ pz85c30Context->ucModemCtrl&=~SCC_WR5_DTR;
+ Write_85c30_register(
+ Console_Port_Tbl[minor].ulCtrlPort1,
+ SCC_WR0_SEL_WR5,
+ pz85c30Context->ucModemCtrl);
+ rtems_interrupt_enable(Irql);
+}
+
+/*
+ * z85c30_isr
+ *
+ * This routine is the console interrupt handler for COM3 and COM4
+ *
+ * Input parameters:
+ * vector - vector number
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+static void z85c30_process(
+ int minor,
+ unsigned8 ucIntPend
+)
+{
+ unsigned32 ulCtrlPort, ulDataPort;
+ volatile unsigned8 z85c30_status;
+ char cChar;
+
+ ulCtrlPort=Console_Port_Tbl[minor].ulCtrlPort1;
+ ulDataPort=Console_Port_Tbl[minor].ulDataPort;
+
+ /*
+ * Deal with any received characters
+ */
+ while(ucIntPend&SCC_RR3_B_RX_IP)
+ {
+ z85c30_status=Read_85c30_register(ulCtrlPort, SCC_WR0_SEL_RD0);
+ if(!Z85C30_Status_Is_RX_character_available(z85c30_status))
+ {
+ break;
+ }
+
+ /*
+ * Return the character read.
+ */
+ cChar=Read_85c30_data(ulDataPort);
+
+ rtems_termios_enqueue_raw_characters(
+ Console_Port_Data[minor].termios_data,
+ &cChar,
+ 1);
+ }
+
+ while(TRUE)
+ {
+ z85c30_status=Read_85c30_register(ulCtrlPort, SCC_WR0_SEL_RD0);
+ if(!Z85C30_Status_Is_TX_buffer_empty(z85c30_status))
+ {
+ /*
+ * We'll get another interrupt when
+ * the transmitter holding reg. becomes
+ * free again and we are clear to send
+ */
+ break;
+ }
+
+ if(!Z85C30_Status_Is_CTS_asserted(z85c30_status))
+ {
+ /*
+ * We can't transmit yet
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR0,
+ SCC_WR0_RST_TX_INT);
+ /*
+ * The next state change of CTS will wake us up
+ */
+ break;
+ }
+
+ if(Ring_buffer_Is_empty(&Console_Port_Data[minor].TxBuffer))
+ {
+ Console_Port_Data[minor].bActive=FALSE;
+ if(Console_Port_Tbl[minor].pDeviceFlow
+ !=&z85c30_flow_RTSCTS)
+ {
+ z85c30_negate_RTS(minor);
+ }
+ /*
+ * There is no data to transmit
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR0,
+ SCC_WR0_RST_TX_INT);
+ break;
+ }
+
+ Ring_buffer_Remove_character(
+ &Console_Port_Data[minor].TxBuffer,
+ cChar);
+ /*
+ * transmit character
+ */
+ Write_85c30_data(ulDataPort, cChar);
+
+ /*
+ * Interrupt once FIFO has room
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR0,
+ SCC_WR0_RST_TX_INT);
+ break;
+ }
+
+ if(ucIntPend&SCC_RR3_B_EXT_IP)
+ {
+ /*
+ * Clear the external status interrupt
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR0,
+ SCC_WR0_RST_INT);
+ z85c30_status=Read_85c30_register(ulCtrlPort, SCC_WR0_SEL_RD0);
+ }
+
+ /*
+ * Reset interrupts
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR0,
+ SCC_WR0_RST_HI_IUS);
+}
+
+static rtems_isr z85c30_isr(
+ rtems_vector_number vector
+)
+{
+ int minor;
+ unsigned32 ulCtrlPort;
+ volatile unsigned8 ucIntPend;
+ volatile unsigned8 ucIntPendPort;
+
+ for(minor=0;minor<Console_Port_Count;minor++)
+ {
+ if(vector==Console_Port_Tbl[minor].ulIntVector)
+ {
+ ulCtrlPort=Console_Port_Tbl[minor].ulCtrlPort2;
+ do
+ {
+ ucIntPend=Read_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_RD3);
+
+ /*
+ * If this is channel A select channel A status
+ */
+ if(ulCtrlPort==
+ Console_Port_Tbl[minor].ulCtrlPort1)
+ {
+ ucIntPendPort=ucIntPend>>3;
+ ucIntPendPort=ucIntPendPort&=7;
+ }
+ else
+ {
+ ucIntPendPort=ucIntPend&=7;
+ }
+
+ if(ucIntPendPort)
+ {
+ z85c30_process(minor, ucIntPendPort);
+ }
+ } while(ucIntPendPort);
+ }
+ }
+}
+
+/*
+ * z85c30_flush
+ */
+static int z85c30_flush(int major, int minor, void *arg)
+{
+ while(!Ring_buffer_Is_empty(&Console_Port_Data[minor].TxBuffer))
+ {
+ /*
+ * Yield while we wait
+ */
+ if(_System_state_Is_up(_System_state_Get()))
+ {
+ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+ }
+ }
+
+ z85c30_close(major, minor, arg);
+
+ return(RTEMS_SUCCESSFUL);
+}
+
+/*
+ * z85c30_initialize_interrupts
+ *
+ * This routine initializes the console's receive and transmit
+ * ring buffers and loads the appropriate vectors to handle the interrupts.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+static void z85c30_enable_interrupts(
+ int minor
+)
+{
+ unsigned32 ulCtrlPort;
+
+ ulCtrlPort=Console_Port_Tbl[minor].ulCtrlPort1;
+
+ /*
+ * Enable interrupts
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR1,
+ SCC_WR1_EXT_INT_EN |
+ SCC_WR1_TX_INT_EN |
+ SCC_WR1_INT_ALL_RX);
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR2,
+ 0);
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR9,
+ SCC_WR9_MIE);
+
+ /*
+ * Reset interrupts
+ */
+ Write_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_WR0,
+ SCC_WR0_RST_INT);
+}
+
+static void z85c30_initialize_interrupts(
+ int minor
+)
+{
+ z85c30_init(minor);
+
+ Ring_buffer_Initialize(&Console_Port_Data[minor].TxBuffer);
+
+ Console_Port_Data[minor].bActive=FALSE;
+ if(Console_Port_Tbl[minor].pDeviceFlow
+ !=&z85c30_flow_RTSCTS)
+ {
+ z85c30_negate_RTS(minor);
+ }
+
+ if(Console_Port_Tbl[minor].ulCtrlPort1==
+ Console_Port_Tbl[minor].ulCtrlPort2)
+ {
+ /*
+ * Only do this for Channel A
+ */
+ set_vector(z85c30_isr,
+ Console_Port_Tbl[minor].ulIntVector,
+ 1);
+ }
+
+ z85c30_enable_interrupts(minor);
+}
+
+/*
+ * z85c30_write_support_int
+ *
+ * Console Termios output entry point.
+ *
+ */
+static int z85c30_write_support_int(
+ int minor,
+ const char *buf,
+ int len)
+{
+ int i;
+ unsigned32 Irql;
+
+ for(i=0; i<len;)
+ {
+ if(Ring_buffer_Is_full(&Console_Port_Data[minor].TxBuffer))
+ {
+ if(!Console_Port_Data[minor].bActive)
+ {
+ /*
+ * Wake up the device
+ */
+ if(Console_Port_Tbl[minor].pDeviceFlow
+ !=&z85c30_flow_RTSCTS)
+ {
+ z85c30_assert_RTS(minor);
+ }
+ rtems_interrupt_disable(Irql);
+ Console_Port_Data[minor].bActive=TRUE;
+ z85c30_process(minor, SCC_RR3_B_TX_IP);
+ rtems_interrupt_enable(Irql);
+ }
+ else
+ {
+ /*
+ * Yield while we await an interrupt
+ */
+ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+ }
+
+ /*
+ * Wait for ring buffer to empty
+ */
+ continue;
+ }
+ else
+ {
+ Ring_buffer_Add_character(
+ &Console_Port_Data[minor].TxBuffer,
+ buf[i]);
+ i++;
+ }
+ }
+
+ /*
+ * Ensure that characters are on the way
+ */
+ if(!Console_Port_Data[minor].bActive)
+ {
+ /*
+ * Wake up the device
+ */
+ if(Console_Port_Tbl[minor].pDeviceFlow
+ !=&z85c30_flow_RTSCTS)
+ {
+ z85c30_assert_RTS(minor);
+ }
+ rtems_interrupt_disable(Irql);
+ Console_Port_Data[minor].bActive=TRUE;
+ z85c30_process(minor, SCC_RR3_B_TX_IP);
+ rtems_interrupt_enable(Irql);
+ }
+
+ return (len);
+}
+
+/*
+ * z85c30_inbyte_nonblocking_polled
+ *
+ * This routine polls for a character.
+ */
+static int z85c30_inbyte_nonblocking_polled(
+ int minor
+)
+{
+ volatile unsigned8 z85c30_status;
+ unsigned32 ulCtrlPort;
+
+ ulCtrlPort=Console_Port_Tbl[minor].ulCtrlPort1;
+
+ /*
+ * return -1 if a character is not available.
+ */
+ z85c30_status=Read_85c30_register(ulCtrlPort,
+ SCC_WR0_SEL_RD0);
+ if(!Z85C30_Status_Is_RX_character_available(z85c30_status))
+ {
+ return -1;
+ }
+
+ /*
+ * Return the character read.
+ */
+ return Read_85c30_data(Console_Port_Tbl[minor].ulDataPort);
+}
+
+/*
+ * z85c30_write_support_polled
+ *
+ * Console Termios output entry point.
+ *
+ */
+static int z85c30_write_support_polled(
+ int minor,
+ const char *buf,
+ int len)
+{
+ int nwrite=0;
+
+ /*
+ * poll each byte in the string out of the port.
+ */
+ while (nwrite < len)
+ {
+ /*
+ * transmit character
+ */
+ z85c30_write_polled(minor, *buf++);
+ nwrite++;
+ }
+
+ /*
+ * return the number of bytes written.
+ */
+ return nwrite;
+}
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30.h
new file mode 100644
index 0000000000..df05316347
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30.h
@@ -0,0 +1,52 @@
+/* z85c30.h
+ *
+ * This include file contains all console driver definations for the z85c30
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id:
+ */
+
+#ifndef __Z85C30_H
+#define __Z85C30_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Driver function table
+ */
+extern console_fns z85c30_fns;
+extern console_fns z85c30_fns_polled;
+
+/*
+ * Flow control function tables
+ */
+extern console_flow z85c30_flow_RTSCTS;
+extern console_flow z85c30_flow_DTRCTS;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30_p.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30_p.h
new file mode 100644
index 0000000000..985c3b202b
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30_p.h
@@ -0,0 +1,385 @@
+/* z85c30_p.h
+ *
+ * This include file contains all private driver definations for the z85c30
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id:
+ */
+
+#ifndef __Z85C30_P_H
+#define __Z85C30_P_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* bit values for write register 0 */
+/* command register */
+
+#define SCC_WR0_SEL_WR0 0x00
+#define SCC_WR0_SEL_WR1 0x01
+#define SCC_WR0_SEL_WR2 0x02
+#define SCC_WR0_SEL_WR3 0x03
+#define SCC_WR0_SEL_WR4 0x04
+#define SCC_WR0_SEL_WR5 0x05
+#define SCC_WR0_SEL_WR6 0x06
+#define SCC_WR0_SEL_WR7 0x07
+#define SCC_WR0_SEL_WR8 0x08
+#define SCC_WR0_SEL_WR9 0x09
+#define SCC_WR0_SEL_WR10 0x0a
+#define SCC_WR0_SEL_WR11 0x0b
+#define SCC_WR0_SEL_WR12 0x0c
+#define SCC_WR0_SEL_WR13 0x0d
+#define SCC_WR0_SEL_WR14 0x0e
+#define SCC_WR0_SEL_WR15 0x0f
+#define SCC_WR0_SEL_RD0 0x00
+#define SCC_WR0_SEL_RD1 0x01
+#define SCC_WR0_SEL_RD2 0x02
+#define SCC_WR0_SEL_RD3 0x03
+#define SCC_WR0_SEL_RD4 0x04
+#define SCC_WR0_SEL_RD5 0x05
+#define SCC_WR0_SEL_RD6 0x06
+#define SCC_WR0_SEL_RD7 0x07
+#define SCC_WR0_SEL_RD8 0x08
+#define SCC_WR0_SEL_RD9 0x09
+#define SCC_WR0_SEL_RD10 0x0a
+#define SCC_WR0_SEL_RD11 0x0b
+#define SCC_WR0_SEL_RD12 0x0c
+#define SCC_WR0_SEL_RD13 0x0d
+#define SCC_WR0_SEL_RD14 0x0e
+#define SCC_WR0_SEL_RD15 0x0f
+#define SCC_WR0_NULL_CODE 0x00
+#define SCC_WR0_RST_INT 0x10
+#define SCC_WR0_SEND_ABORT 0x18
+#define SCC_WR0_EN_INT_RX 0x20
+#define SCC_WR0_RST_TX_INT 0x28
+#define SCC_WR0_ERR_RST 0x30
+#define SCC_WR0_RST_HI_IUS 0x38
+#define SCC_WR0_RST_RX_CRC 0x40
+#define SCC_WR0_RST_TX_CRC 0x80
+#define SCC_WR0_RST_TX_UND 0xc0
+
+/* write register 2 */
+/* interrupt vector */
+
+/* bit values for write register 1 */
+/* tx/rx interrupt and data transfer mode definition */
+
+#define SCC_WR1_EXT_INT_EN 0x01
+#define SCC_WR1_TX_INT_EN 0x02
+#define SCC_WR1_PARITY 0x04
+#define SCC_WR1_RX_INT_DIS 0x00
+#define SCC_WR1_RX_INT_FIR 0x08
+#define SCC_WR1_INT_ALL_RX 0x10
+#define SCC_WR1_RX_INT_SPE 0x18
+#define SCC_WR1_RDMA_RECTR 0x20
+#define SCC_WR1_RDMA_FUNC 0x40
+#define SCC_WR1_RDMA_EN 0x80
+
+/* bit values for write register 3 */
+/* receive parameters and control */
+
+#define SCC_WR3_RX_EN 0x01
+#define SCC_WR3_SYNC_CHAR 0x02
+#define SCC_WR3_ADR_SEARCH 0x04
+#define SCC_WR3_RX_CRC_EN 0x08
+#define SCC_WR3_ENTER_HUNT 0x10
+#define SCC_WR3_AUTO_EN 0x20
+#define SCC_WR3_RX_5_BITS 0x00
+#define SCC_WR3_RX_7_BITS 0x40
+#define SCC_WR3_RX_6_BITS 0x80
+#define SCC_WR3_RX_8_BITS 0xc0
+
+/* bit values for write register 4 */
+/* tx/rx misc parameters and modes */
+
+#define SCC_WR4_PAR_EN 0x01
+#define SCC_WR4_PAR_EVEN 0x02
+#define SCC_WR4_SYNC_EN 0x00
+#define SCC_WR4_1_STOP 0x04
+#define SCC_WR4_2_STOP 0x0c
+#define SCC_WR4_8_SYNC 0x00
+#define SCC_WR4_16_SYNC 0x10
+#define SCC_WR4_SDLC 0x20
+#define SCC_WR4_EXT_SYNC 0x30
+#define SCC_WR4_1_CLOCK 0x00
+#define SCC_WR4_16_CLOCK 0x40
+#define SCC_WR4_32_CLOCK 0x80
+#define SCC_WR4_64_CLOCK 0xc0
+
+/* bit values for write register 5 */
+/* transmit parameter and controls */
+
+#define SCC_WR5_TX_CRC_EN 0x01
+#define SCC_WR5_RTS 0x02
+#define SCC_WR5_SDLC 0x04
+#define SCC_WR5_TX_EN 0x08
+#define SCC_WR5_SEND_BRK 0x10
+
+#define SCC_WR5_TX_5_BITS 0x00
+#define SCC_WR5_TX_7_BITS 0x20
+#define SCC_WR5_TX_6_BITS 0x40
+#define SCC_WR5_TX_8_BITS 0x60
+#define SCC_WR5_DTR 0x80
+
+/* write register 6 */
+/* sync chars or sdlc address field */
+
+/* write register 7 */
+/* sync char or sdlc flag */
+
+/* write register 8 */
+/* transmit buffer */
+
+/* bit values for write register 9 */
+/* master interrupt control */
+
+#define SCC_WR9_VIS 0x01
+#define SCC_WR9_NV 0x02
+#define SCC_WR9_DLC 0x04
+#define SCC_WR9_MIE 0x08
+#define SCC_WR9_STATUS_HI 0x10
+#define SCC_WR9_NO_RST 0x00
+#define SCC_WR9_CH_B_RST 0x40
+#define SCC_WR9_CH_A_RST 0x80
+#define SCC_WR9_HDWR_RST 0xc0
+
+/* bit values for write register 10 */
+/* misc tx/rx control bits */
+
+#define SCC_WR10_6_BIT_SYNC 0x01
+#define SCC_WR10_LOOP_MODE 0x02
+#define SCC_WR10_ABORT_UND 0x04
+#define SCC_WR10_MARK_IDLE 0x08
+#define SCC_WR10_ACT_POLL 0x10
+#define SCC_WR10_NRZ 0x00
+#define SCC_WR10_NRZI 0x20
+#define SCC_WR10_FM1 0x40
+#define SCC_WR10_FM0 0x60
+#define SCC_WR10_CRC_PRESET 0x80
+
+/* bit values for write register 11 */
+/* clock mode control */
+
+#define SCC_WR11_OUT_XTAL 0x00
+#define SCC_WR11_OUT_TX_CLK 0x01
+#define SCC_WR11_OUT_BR_GEN 0x02
+#define SCC_WR11_OUT_DPLL 0x03
+#define SCC_WR11_TRXC_OI 0x04
+#define SCC_WR11_TX_RTXC 0x00
+#define SCC_WR11_TX_TRXC 0x08
+#define SCC_WR11_TX_BR_GEN 0x10
+#define SCC_WR11_TX_DPLL 0x18
+#define SCC_WR11_RX_RTXC 0x00
+#define SCC_WR11_RX_TRXC 0x20
+#define SCC_WR11_RX_BR_GEN 0x40
+#define SCC_WR11_RX_DPLL 0x60
+#define SCC_WR11_RTXC_XTAL 0x80
+
+/* write register 12 */
+/* lower byte of baud rate generator time constant */
+
+/* write register 13 */
+/* upper byte of baud rate generator time constant */
+
+/* bit values for write register 14 */
+/* misc control bits */
+
+#define SCC_WR14_BR_EN 0x01
+#define SCC_WR14_BR_SRC 0x02
+#define SCC_WR14_DTR_FUNC 0x04
+#define SCC_WR14_AUTO_ECHO 0x08
+#define SCC_WR14_LCL_LOOP 0x10
+#define SCC_WR14_NULL 0x00
+#define SCC_WR14_SEARCH 0x20
+#define SCC_WR14_RST_CLK 0x40
+#define SCC_WR14_DIS_DPLL 0x60
+#define SCC_WR14_SRC_BR 0x80
+#define SCC_WR14_SRC_RTXC 0xa0
+#define SCC_WR14_FM_MODE 0xc0
+#define SCC_WR14_NRZI 0xe0
+
+/* bit values for write register 15 */
+/* external/status interrupt control */
+
+#define SCC_WR15_ZERO_CNT 0x02
+#define SCC_WR15_CD_IE 0x08
+#define SCC_WR15_SYNC_IE 0x10
+#define SCC_WR15_CTS_IE 0x20
+#define SCC_WR15_TX_UND_IE 0x40
+#define SCC_WR15_BREAK_IE 0x80
+
+/* bit values for read register 0 */
+/* tx/rx buffer status and external status */
+
+#define SCC_RR0_RX_AVAIL 0x01
+#define SCC_RR0_ZERO_CNT 0x02
+#define SCC_RR0_TX_EMPTY 0x04
+#define SCC_RR0_CD 0x08
+#define SCC_RR0_SYNC 0x10
+#define SCC_RR0_CTS 0x20
+#define SCC_RR0_TX_UND 0x40
+#define SCC_RR0_BREAK 0x80
+
+/* bit values for read register 1 */
+
+#define SCC_RR1_ALL_SENT 0x01
+#define SCC_RR1_RES_CD_2 0x02
+#define SCC_RR1_RES_CD_1 0x01
+#define SCC_RR1_RES_CD_0 0x08
+#define SCC_RR1_PAR_ERR 0x10
+#define SCC_RR1_RX_OV_ERR 0x20
+#define SCC_RR1_CRC_ERR 0x40
+#define SCC_RR1_END_FRAME 0x80
+
+/* read register 2 */
+/* interrupt vector */
+
+/* bit values for read register 3 */
+/* interrupt pending register */
+
+#define SCC_RR3_B_EXT_IP 0x01
+#define SCC_RR3_B_TX_IP 0x02
+#define SCC_RR3_B_RX_IP 0x04
+#define SCC_RR3_A_EXT_IP 0x08
+#define SCC_RR3_A_TX_IP 0x10
+#define SCC_RR3_A_RX_IP 0x20
+
+/* read register 8 */
+/* receive data register */
+
+/* bit values for read register 10 */
+/* misc status bits */
+
+#define SCC_RR10_ON_LOOP 0x02
+#define SCC_RR10_LOOP_SEND 0x10
+#define SCC_RR10_2_CLK_MIS 0x40
+#define SCC_RR10_1_CLK_MIS 0x80
+
+/* read register 12 */
+/* lower byte of time constant */
+
+/* read register 13 */
+/* upper byte of time constant */
+
+/* bit values for read register 15 */
+/* external/status ie bits */
+
+#define SCC_RR15_ZERO_CNT 0x02
+#define SCC_RR15_CD_IE 0x08
+#define SCC_RR15_SYNC_IE 0x10
+#define SCC_RR15_CTS_IE 0x20
+#define SCC_RR15_TX_UND_IE 0x40
+#define SCC_RR15_BREAK_IE 0x80
+
+typedef struct _z85c30_context
+{
+ unsigned8 ucModemCtrl;
+} z85c30_context;
+
+/*
+ * The following macro calculates the Baud constant. For the Z85C30 chip.
+ *
+ * Note: baud constant = ((clock frequency / Clock_X) / (2 * Baud Rate)) - 2
+ * eg ((10,000,000 / 16) / (2 * Baud Rate)) - 2
+ */
+#define Z85C30_Baud( _baud_rate ) \
+ ( (Z85C30_CLOCK /( 16 * 2 * _baud_rate)) - 2)
+
+#define Z85C30_Status_Is_RX_character_available(_status) \
+ ((_status) & SCC_RR0_RX_AVAIL)
+
+#define Z85C30_Status_Is_TX_buffer_empty(_status) \
+ ((_status) & SCC_RR0_TX_EMPTY)
+
+#define Z85C30_Status_Is_CTS_asserted(_status) \
+ ((_status) & SCC_RR0_CTS)
+
+#define Z85C30_Status_Is_break_abort(_status) \
+ ((_status) & SCC_RR0_BREAK)
+
+/*
+ * Private routines
+ */
+static boolean z85c30_probe(int minor);
+
+static void z85c30_init(int minor);
+
+static int z85c30_open(
+ int major,
+ int minor,
+ void * arg
+);
+
+static int z85c30_close(
+ int major,
+ int minor,
+ void * arg
+);
+
+static void z85c30_write_polled(
+ int minor,
+ char cChar
+);
+
+static void z85c30_assert_RTS(
+ int minor
+);
+
+static void z85c30_negate_RTS(
+ int minor
+);
+
+static void z85c30_assert_DTR(
+ int minor
+);
+
+static void z85c30_negate_DTR(
+ int minor
+);
+
+static void z85c30_initialize_interrupts(int minor);
+
+static int z85c30_flush(int major, int minor, void *arg);
+
+static int z85c30_write_support_int(
+ int minor,
+ const char *buf,
+ int len
+);
+
+static int z85c30_write_support_polled(
+ int minor,
+ const char *buf,
+ int len
+);
+
+static int z85c30_inbyte_nonblocking_polled(
+ int minor
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30cfg.c b/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30cfg.c
new file mode 100644
index 0000000000..3a1a98c720
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30cfg.c
@@ -0,0 +1,96 @@
+/*
+ * This file contains the console driver chip level routines for the
+ * z85c30 chip.
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+
+/*
+ * Read_85c30_register
+ *
+ * Read a Z85c30 register
+ */
+
+unsigned8 Read_85c30_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum
+)
+{
+ unsigned8 ucData;
+
+ outport_byte(ulCtrlPort, ucRegNum);
+ inport_byte(ulCtrlPort, ucData);
+ return ucData;
+}
+
+/*
+ * Write_85c30_register
+ *
+ * Write a Z85c30 register
+ */
+
+void Write_85c30_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum,
+ unsigned8 ucData
+)
+{
+ if(ucRegNum) {
+ outport_byte(ulCtrlPort, ucRegNum);
+ }
+ outport_byte(ulCtrlPort, ucData);
+}
+
+/*
+ * Read_85c30_data
+ *
+ * Read a Z85c30 data register
+ */
+
+unsigned8 Read_85c30_data(
+ unsigned32 ulDataPort
+)
+{
+ unsigned8 ucData;
+
+ inport_byte(ulDataPort, ucData);
+ return ucData;
+}
+
+/*
+ * Write_85c30_data
+ *
+ * Write a Z85c30 data register
+ */
+
+void Write_85c30_data(
+ unsigned32 ulDataPort,
+ unsigned8 ucData
+)
+{
+ outport_byte(ulDataPort, ucData);
+}
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30cfg.h b/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30cfg.h
new file mode 100644
index 0000000000..3dfb96e048
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30cfg.h
@@ -0,0 +1,64 @@
+/* z85c30cfg.h
+ *
+ * This include file contains all console driver definations for the z85c30
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#ifndef __Z85C30_CONFIG_H
+#define __Z85C30_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Board specific register access routines
+ */
+
+unsigned8 Read_85c30_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum
+);
+
+void Write_85c30_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum,
+ unsigned8 ucData
+);
+
+unsigned8 Read_85c30_data(
+ unsigned32 ulDataPort
+);
+
+void Write_85c30_data(
+ unsigned32 ulDataPort,
+ unsigned8 ucData
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif