Index: bsps/powerpc/virtex/console/consolelite.c
===================================================================
--- bsps/powerpc/virtex/console/consolelite.c	(revision d7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc)
+++ bsps/powerpc/virtex/console/consolelite.c	(revision d7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc)
@@ -0,0 +1,425 @@
+/*
+ *  This file contains the console driver for the xilinx uart lite.
+ *
+ *  Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
+ *  COPYRIGHT (c) 2005 by Linn Products Ltd, Scotland.
+ *
+ *  Derived from libbsp/no_cpu/no_bsp/console.c and therefore also:
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ */
+
+#include <assert.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <bsp/irq.h>
+
+#include <bsp.h>
+#include <libchip/serial.h>
+#include <libchip/sersupp.h>
+
+#include RTEMS_XPARAMETERS_H
+
+/* Status Register Masks */
+#define PARITY_ERROR       0x80 /* Parity Error */
+#define FRAME_ERROR        0x40 /* Frame Error */
+#define OVERRUN_ERROR      0x20 /* Overrun Error */
+#define STATUS_REG_ERROR_MASK ( PARITY_ERROR | FRAME_ERROR | OVERRUN_ERROR )
+
+#define INTR_ENABLED       0x10 /* Interrupts are enabled */
+#define TX_FIFO_FULL       0x08 /* Transmit FIFO is full */
+#define TX_FIFO_EMPTY      0x04 /* Transmit FIFO is empty */
+#define RX_FIFO_FULL       0x02 /* Receive FIFO is full */
+#define RX_FIFO_VALID_DATA 0x01 /* Receive FIFO has valid data */
+/* Control Register Masks*/
+#define ENABLE_INTR        0x10 /* Enable interrupts */
+#define RST_RX_FIFO        0x02 /* Reset and clear RX FIFO */
+#define RST_TX_FIFO        0x01 /* Reset and clear TX FIFO */
+
+/* General Defines */
+#define TX_FIFO_SIZE       16
+#define RX_FIFO_SIZE       16
+
+
+
+
+#define RECV_REG 0
+#define TRAN_REG 4
+#define STAT_REG 8
+#define CTRL_REG 12
+
+
+
+RTEMS_INLINE_ROUTINE uint32_t xlite_uart_control(uint32_t base)
+{
+  uint32_t c = *((volatile uint32_t*)(base+CTRL_REG));
+  return c;
+}
+
+
+RTEMS_INLINE_ROUTINE uint32_t xlite_uart_status(uint32_t base)
+{
+  uint32_t c = *((volatile uint32_t*)(base+STAT_REG));
+  return c;
+}
+
+
+RTEMS_INLINE_ROUTINE uint32_t xlite_uart_read(uint32_t base)
+{
+  uint32_t c = *((volatile uint32_t*)(base+RECV_REG));
+  return c;
+}
+
+
+RTEMS_INLINE_ROUTINE void xlite_uart_write(uint32_t base, char ch)
+{
+  *(volatile uint32_t*)(base+TRAN_REG) = (uint32_t)ch;
+  return;
+}
+
+
+
+static int xlite_write_char(uint32_t base, char ch)
+{
+   uint32_t  retrycount= 0, idler, status;
+
+   while( ((status = xlite_uart_status(base)) & TX_FIFO_FULL) != 0 )
+   {
+      ++retrycount;
+
+      /* uart tx is busy */
+      if( retrycount == 0x4000 )
+      {
+	 /* retrycount is arbitrary- just make it big enough so the uart is sure to be timed out before it trips */
+	 return -1;
+      }
+
+      /* spin for a bit so we can sample the register rather than
+       * continually reading it */
+      for( idler= 0; idler < 0x2000; idler++);
+   }
+
+   xlite_uart_write(base, ch);
+
+   return 1;
+}
+
+static void xlite_init(int minor )
+{
+   /* Nothing to do */
+}
+
+#if VIRTEX_CONSOLE_USE_INTERRUPTS
+static void xlite_interrupt_handler(void *arg)
+{
+   int minor = (int) arg;
+   const console_tbl *ct = Console_Port_Tbl[minor];
+   console_data *cd = &Console_Port_Data[minor];
+   uint32_t base = ct->ulCtrlPort1;
+   uint32_t status = xlite_uart_status(base);
+
+   while ((status & RX_FIFO_VALID_DATA) != 0) {
+      char c = (char) xlite_uart_read(base);
+
+      rtems_termios_enqueue_raw_characters(cd->termios_data, &c, 1);
+
+      status = xlite_uart_status(base);
+   }
+
+   if (cd->bActive) {
+      rtems_termios_dequeue_characters(cd->termios_data, 1);
+   }
+}
+#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */
+
+static int xlite_open(
+  int      major,
+  int      minor,
+  void    *arg
+)
+{
+   const console_tbl *ct = Console_Port_Tbl[minor];
+   uint32_t base = ct->ulCtrlPort1;
+#if VIRTEX_CONSOLE_USE_INTERRUPTS
+   rtems_status_code sc;
+#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */
+
+   /* clear status register */
+   *((volatile uint32_t*)(base+STAT_REG)) = 0;
+
+   /* clear control register; reset fifos */
+   *((volatile uint32_t*)(base+CTRL_REG)) = RST_RX_FIFO | RST_TX_FIFO;
+
+#if VIRTEX_CONSOLE_USE_INTERRUPTS
+   *((volatile uint32_t*)(base+CTRL_REG)) = ENABLE_INTR;
+
+   sc = rtems_interrupt_handler_install(
+      ct->ulIntVector,
+      "xlite",
+      RTEMS_INTERRUPT_UNIQUE,
+      xlite_interrupt_handler,
+      (void *) minor
+   );
+   assert(sc == RTEMS_SUCCESSFUL);
+#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */
+
+   return 0;
+}
+
+static int xlite_close(
+  int      major,
+  int      minor,
+  void    *arg
+)
+{
+   const console_tbl *ct = Console_Port_Tbl[minor];
+   uint32_t base = ct->ulCtrlPort1;
+#if VIRTEX_CONSOLE_USE_INTERRUPTS
+   rtems_status_code sc;
+#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */
+
+   *((volatile uint32_t*)(base+CTRL_REG)) = 0;
+
+#if VIRTEX_CONSOLE_USE_INTERRUPTS
+   sc = rtems_interrupt_handler_remove(
+      ct->ulIntVector,
+      xlite_interrupt_handler,
+      (void *) minor
+   );
+   assert(sc == RTEMS_SUCCESSFUL);
+#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */
+
+   return 0;
+}
+
+
+
+static int xlite_read_polled (int minor )
+{
+   uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1;
+
+   unsigned int status = xlite_uart_status(base);
+
+   if(status & RX_FIFO_VALID_DATA)
+      return (int)xlite_uart_read(base);
+   else
+      return -1;
+}
+
+#if VIRTEX_CONSOLE_USE_INTERRUPTS
+
+static ssize_t xlite_write_interrupt_driven(
+  int minor,
+  const char *buf,
+  size_t len
+)
+{
+  console_data *cd = &Console_Port_Data[minor];
+
+  if (len > 0) {
+    const console_tbl *ct = Console_Port_Tbl[minor];
+    uint32_t base = ct->ulCtrlPort1;
+
+    xlite_uart_write(base, buf[0]);
+
+    cd->bActive = true;
+  } else {
+    cd->bActive = false;
+  }
+
+  return 0;
+}
+
+#else /* VIRTEX_CONSOLE_USE_INTERRUPTS */
+
+static ssize_t xlite_write_buffer_polled(
+  int         minor,
+  const char *buf,
+  size_t      len
+)
+{
+   uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1;
+   int nwrite = 0;
+
+   /*
+    * poll each byte in the string out of the port.
+    */
+   while (nwrite < len)
+   {
+      if( xlite_write_char(base, *buf++) < 0 ) break;
+      nwrite++;
+   }
+
+   /*
+    * return the number of bytes written.
+    */
+   return nwrite;
+}
+
+#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */
+
+static void xlite_write_char_polled(
+  int   minor,
+  char  c
+)
+{
+   uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1;
+   xlite_write_char(base, c);
+   return;
+}
+
+static int xlite_set_attributes(int minor, const struct termios *t)
+{
+   return RTEMS_SUCCESSFUL;
+}
+
+
+
+
+
+
+
+static const console_fns xlite_fns_polled =
+{
+  .deviceProbe = libchip_serial_default_probe,
+  .deviceFirstOpen = xlite_open,
+  .deviceLastClose = xlite_close,
+  .deviceRead = xlite_read_polled,
+  .deviceInitialize = xlite_init,
+  .deviceWritePolled = xlite_write_char_polled,
+  .deviceSetAttributes = xlite_set_attributes,
+#if VIRTEX_CONSOLE_USE_INTERRUPTS
+  .deviceWrite = xlite_write_interrupt_driven,
+  .deviceOutputUsesInterrupts = true
+#else /* VIRTEX_CONSOLE_USE_INTERRUPTS */
+  .deviceWrite = xlite_write_buffer_polled,
+  .deviceOutputUsesInterrupts = false
+#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */
+};
+
+
+
+
+
+
+/*
+** Set ulCtrlPort1 to the base address of each UART Lite instance.  Set in vhdl model.
+*/
+
+
+console_tbl     Console_Configuration_Ports[] = {
+{
+  "/dev/ttyS0",                             /* sDeviceName */
+   SERIAL_CUSTOM,                           /* deviceType */
+   &xlite_fns_polled,                      /* pDeviceFns */
+   NULL,                                   /* deviceProbe, assume it is there */
+   NULL,                                   /* pDeviceFlow */
+   16,                                     /* ulMargin */
+   8,                                      /* ulHysteresis */
+   (void *) NULL,               /* NULL */ /* pDeviceParams */
+   STDIN_BASEADDRESS,                      /* ulCtrlPort1 */
+   0,                                      /* ulCtrlPort2 */
+   0,                                      /* ulDataPort */
+   NULL,                                   /* getRegister */
+   NULL,                                   /* setRegister */
+   NULL, /* unused */                      /* getData */
+   NULL, /* unused */                      /* setData */
+   0,                                      /* ulClock */
+   #ifdef XPAR_XPS_INTC_0_RS232_UART_INTERRUPT_INTR
+     .ulIntVector = XPAR_XPS_INTC_0_RS232_UART_INTERRUPT_INTR
+   #else
+     .ulIntVector = 0
+   #endif
+},
+#ifdef XPAR_UARTLITE_1_BASEADDR
+{
+  "/dev/ttyS1",                             /* sDeviceName */
+   SERIAL_CUSTOM,                           /* deviceType */
+   &xlite_fns_polled,                       /* pDeviceFns */
+   NULL,                                   /* deviceProbe, assume it is there */
+   NULL,                                   /* pDeviceFlow */
+   16,                                     /* ulMargin */
+   8,                                      /* ulHysteresis */
+   (void *) NULL,               /* NULL */ /* pDeviceParams */
+   XPAR_UARTLITE_1_BASEADDR,               /* ulCtrlPort1 */
+   0,                                      /* ulCtrlPort2 */
+   0,                                      /* ulDataPort */
+   NULL,                                   /* getRegister */
+   NULL,                                   /* setRegister */
+   NULL, /* unused */                      /* getData */
+   NULL, /* unused */                      /* setData */
+   0,                                      /* ulClock */
+   0                                       /* ulIntVector -- base for port */
+},
+#endif
+#ifdef XPAR_UARTLITE_2_BASEADDR
+{
+  "/dev/ttyS2",                             /* sDeviceName */
+   SERIAL_CUSTOM,                           /* deviceType */
+   &xlite_fns_polled,                       /* pDeviceFns */
+   NULL,                                   /* deviceProbe, assume it is there */
+   NULL,                                   /* pDeviceFlow */
+   16,                                     /* ulMargin */
+   8,                                      /* ulHysteresis */
+   (void *) NULL,               /* NULL */ /* pDeviceParams */
+   XPAR_UARTLITE_2_BASEADDR,               /* ulCtrlPort1 */
+   0,                                      /* ulCtrlPort2 */
+   0,                                      /* ulDataPort */
+   NULL,                                   /* getRegister */
+   NULL,                                   /* setRegister */
+   NULL, /* unused */                      /* getData */
+   NULL, /* unused */                      /* setData */
+   0,                                      /* ulClock */
+   0                                       /* ulIntVector -- base for port */
+},
+#endif
+#ifdef XPAR_UARTLITE_2_BASEADDR
+{
+  "/dev/ttyS3",                             /* sDeviceName */
+   SERIAL_CUSTOM,                           /* deviceType */
+   &xlite_fns_polled,                       /* pDeviceFns */
+   NULL,                                   /* deviceProbe, assume it is there */
+   NULL,                                   /* pDeviceFlow */
+   16,                                     /* ulMargin */
+   8,                                      /* ulHysteresis */
+   (void *) NULL,               /* NULL */ /* pDeviceParams */
+   XPAR_UARTLITE_3_BASEADDR,               /* ulCtrlPort1 */
+   0,                                      /* ulCtrlPort2 */
+   0,                                      /* ulDataPort */
+   NULL,                                   /* getRegister */
+   NULL,                                   /* setRegister */
+   NULL, /* unused */                      /* getData */
+   NULL, /* unused */                      /* setData */
+   0,                                      /* ulClock */
+   0                                       /* ulIntVector -- base for port */
+}
+#endif
+};
+
+unsigned long Console_Configuration_Count =
+  RTEMS_ARRAY_SIZE(Console_Configuration_Ports);
+
+
+#include <rtems/bspIo.h>
+
+static void outputChar(char ch)
+{
+   xlite_write_char_polled( 0, ch );
+}
+
+static int inputChar(void)
+{
+   return xlite_read_polled(0);
+}
+
+BSP_output_char_function_type BSP_output_char = outputChar;
+BSP_polling_getchar_function_type BSP_poll_char = inputChar;
+
+
