[rtems commit] Add MIPS/Malta BSP.

Joel Sherrill joel at rtems.org
Wed Apr 4 17:20:48 UTC 2012


Module:    rtems
Branch:    upstream
Commit:    a36d1b435808d6daef1a9641c8ab707e5feeb7c8
Changeset: http://git.rtems.org/rtems/commit/?id=a36d1b435808d6daef1a9641c8ab707e5feeb7c8

Author:    Jennifer Averett <jennifer.averett at OARcorp.com>
Date:      Wed Apr  4 12:21:15 2012 -0500

Add MIPS/Malta BSP.

---

 c/src/lib/libbsp/mips/acinclude.m4                 |    2 +
 c/src/lib/libbsp/mips/malta/ChangeLog              |   23 +
 c/src/lib/libbsp/mips/malta/Makefile.am            |   91 ++
 c/src/lib/libbsp/mips/malta/STATUS                 |   46 +
 c/src/lib/libbsp/mips/malta/bsp_specs              |   13 +
 c/src/lib/libbsp/mips/malta/configure.ac           |   21 +
 c/src/lib/libbsp/mips/malta/console/conscfg.c      |  158 +++
 .../lib/libbsp/mips/malta/console/printk_support.c |   53 +
 c/src/lib/libbsp/mips/malta/include/bsp.h          |  108 ++
 c/src/lib/libbsp/mips/malta/include/irq.h          |  131 +++
 c/src/lib/libbsp/mips/malta/include/pci.h          |  171 +++
 c/src/lib/libbsp/mips/malta/irq/interruptmask.c    |   36 +
 c/src/lib/libbsp/mips/malta/irq/maxvectors.c       |   24 +
 c/src/lib/libbsp/mips/malta/irq/vectorisrs.c       |   90 ++
 c/src/lib/libbsp/mips/malta/make/custom/malta.cfg  |   15 +
 c/src/lib/libbsp/mips/malta/pci/pci.c              | 1105 ++++++++++++++++++++
 c/src/lib/libbsp/mips/malta/pci/pcifinddevice.c    |  279 +++++
 c/src/lib/libbsp/mips/malta/pci/pcilistdevices.c   |  105 ++
 c/src/lib/libbsp/mips/malta/preinstall.am          |   91 ++
 c/src/lib/libbsp/mips/malta/start/start.S          |  220 ++++
 c/src/lib/libbsp/mips/malta/startup/bspreset.c     |   35 +
 c/src/lib/libbsp/mips/malta/startup/bspstart.c     |  113 ++
 c/src/lib/libbsp/mips/malta/startup/inittlb.c      |   26 +
 c/src/lib/libbsp/mips/malta/startup/linkcmds       |  181 ++++
 .../lib/libbsp/mips/malta/startup/simple_access.c  |  133 +++
 25 files changed, 3270 insertions(+), 0 deletions(-)

diff --git a/c/src/lib/libbsp/mips/acinclude.m4 b/c/src/lib/libbsp/mips/acinclude.m4
index 4730443..6a7814f 100644
--- a/c/src/lib/libbsp/mips/acinclude.m4
+++ b/c/src/lib/libbsp/mips/acinclude.m4
@@ -10,6 +10,8 @@ AC_DEFUN([RTEMS_CHECK_BSPDIR],
     AC_CONFIG_SUBDIRS([hurricane]);;
   jmr3904 )
     AC_CONFIG_SUBDIRS([jmr3904]);;
+  malta )
+    AC_CONFIG_SUBDIRS([malta]);;
   rbtx4925 )
     AC_CONFIG_SUBDIRS([rbtx4925]);;
   rbtx4938 )
diff --git a/c/src/lib/libbsp/mips/malta/ChangeLog b/c/src/lib/libbsp/mips/malta/ChangeLog
new file mode 100644
index 0000000..ec3614a
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/ChangeLog
@@ -0,0 +1,23 @@
+2012-03-08	Jennifer Averett <Jennifer.Averett at OARcorp.com>
+
+	* include/bsp.h: Added define for BSP_SHARED_HANDLER_SUPPORT.
+
+2012-03-06	Jennifer Averett <Jennifer.Averett at OARcorp.com>
+
+	PR 1993/bsps
+	* malta/include/bsp.h:
+	Changed interrupt call, removed warnings and did cleanup.
+
+2012-02-27	Jennifer Averett <jennifer.averett at oarcorp.com>
+
+	* MIPS malta initial BSP.  This version was tested using
+	the qemu simulator and may require modifications to work with
+	actual hardware.
+	* ChangeLog, Makefile.am, STATUS, bsp_specs, configure.ac,
+	console/conscfg.c, console/printk_support.c, include/bsp.h,
+	include/irq.h, include/pci.h, irq/interruptmask.c,
+	irq/maxvectors.c, irq/vectorisrs.c, make/custom/malta.cfg,
+	pci/pci.c, pci/pcifinddevice.c, pci/pcilistdevices.c,
+	preinstall.am, start/start.S, startup/bspreset.c,
+	startup/bspstart.c, startup/inittlb.c, startup/linkcmds,
+	startup/simple_access.c: New files.
diff --git a/c/src/lib/libbsp/mips/malta/Makefile.am b/c/src/lib/libbsp/mips/malta/Makefile.am
new file mode 100644
index 0000000..0c5da15
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/Makefile.am
@@ -0,0 +1,91 @@
+##
+##
+
+ACLOCAL_AMFLAGS = -I ../../../../aclocal
+
+include $(top_srcdir)/../../../../automake/compile.am
+
+include_bspdir = $(includedir)/bsp
+
+dist_project_lib_DATA = bsp_specs
+
+include_HEADERS = include/bsp.h
+include_HEADERS += ../../shared/include/tm27.h
+include_bsp_HEADERS = ../shared/liblnk/regs.h
+#isr
+include_bsp_HEADERS += ../../shared/include/irq-generic.h
+include_bsp_HEADERS += ../../shared/include/irq-info.h
+include_bsp_HEADERS += include/irq.h
+#pci
+include_bsp_HEADERS += include/pci.h
+#irq
+include_bsp_HEADERS += ../shared/irq/i8259.h
+nodist_include_HEADERS = include/bspopts.h
+nodist_include_bsp_HEADERS = ../../shared/include/bootcard.h
+DISTCLEANFILES = include/bspopts.h
+
+nodist_include_HEADERS += ../../shared/include/coverhd.h
+
+noinst_LIBRARIES = libbspstart.a
+libbspstart_a_SOURCES = start/start.S ../shared/liblnk/regs.h
+project_lib_DATA = start.$(OBJEXT)
+
+dist_project_lib_DATA += startup/linkcmds
+
+noinst_LIBRARIES += libbsp.a
+libbsp_a_SOURCES =
+
+# startup
+libbsp_a_SOURCES += startup/simple_access.c
+libbsp_a_SOURCES += ../../shared/bspclean.c
+libbsp_a_SOURCES += ../../shared/bsplibc.c
+libbsp_a_SOURCES += ../../shared/bsppredriverhook.c
+libbsp_a_SOURCES += ../../shared/bsppost.c
+libbsp_a_SOURCES += ../../shared/bsppretaskinghook.c
+libbsp_a_SOURCES += ../../shared/bspgetworkarea.c
+libbsp_a_SOURCES += startup/bspstart.c
+libbsp_a_SOURCES += startup/bspreset.c
+libbsp_a_SOURCES += ../../shared/bootcard.c
+libbsp_a_SOURCES += ../../shared/sbrk.c
+libbsp_a_SOURCES += startup/inittlb.c
+libbsp_a_SOURCES += ../shared/startup/idttlb.S
+
+# clock
+libbsp_a_SOURCES += ../shared/clock/clockdrv.c
+libbsp_a_SOURCES += ../shared/clock/mips_timer.S
+libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
+
+# console
+libbsp_a_SOURCES += console/conscfg.c
+libbsp_a_SOURCES += console/printk_support.c
+libbsp_a_SOURCES += ../../shared/console.c
+libbsp_a_SOURCES += ../../shared/console_select.c
+libbsp_a_SOURCES += ../../shared/console_read.c
+libbsp_a_SOURCES += ../../shared/console_write.c
+libbsp_a_SOURCES += ../../shared/console_control.c
+# timer
+libbsp_a_SOURCES += ../../shared/timerstub.c
+
+libbsp_a_LIBADD  = ../../../libcpu/@RTEMS_CPU@/shared/cache.rel
+libbsp_a_LIBADD += ../../../libcpu/@RTEMS_CPU@/shared/interrupts.rel
+
+# pci
+libbsp_a_SOURCES += pci/pci.c
+libbsp_a_SOURCES += pci/pcifinddevice.c
+libbsp_a_SOURCES += pci/pcilistdevices.c
+
+#isr
+libbsp_a_SOURCES += ../../shared/src/irq-generic.c
+libbsp_a_SOURCES += ../../shared/src/irq-legacy.c
+libbsp_a_SOURCES += ../../shared/src/irq-info.c
+libbsp_a_SOURCES += ../../shared/src/irq-shell.c
+libbsp_a_SOURCES += ../../shared/src/irq-server.c
+libbsp_a_SOURCES += ../shared/irq/vectorexceptions.c
+libbsp_a_SOURCES += ../shared/irq/irq.c
+libbsp_a_SOURCES += irq/maxvectors.c
+libbsp_a_SOURCES += irq/vectorisrs.c
+libbsp_a_SOURCES += irq/interruptmask.c
+libbsp_a_SOURCES += ../shared/irq/i8259.c
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/../../../../automake/local.am
diff --git a/c/src/lib/libbsp/mips/malta/STATUS b/c/src/lib/libbsp/mips/malta/STATUS
new file mode 100644
index 0000000..494709c
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/STATUS
@@ -0,0 +1,46 @@
+#
+#  $Id: STATUS,v 1.3 2012/02/17 19:41:51 joel Exp $
+#
+
+17 Februrary 2011
+
+XXX
+
+This is a BSP for the MIPS Malta board with a 24K CPU on it.
+It has ONLY been tested on Qemu.
+
+Anything not mentioned has not been touched at all and will
+most likely not be in the first release of the BSP.
+
+Working
+=======
++ Board initialization and shutdown
++ tty0 working polled
++ tty1 working polled (see note in issues)
++ tty2 working polled (see notes in issues)
++ Clock Tick
+
+
+Issues
+======
++ We have small hack to Qemu so reset will exit.  This needs to be
+  fixed to follow the PC386 Qemu model where a command line argument
+  selects reset or exit on reset.
+
++ tty2 is generating an interrupt which causes a TLB fault. We have
+  disabled the interrupt in the CPU interrupt mask for now.
+
++ tty1 and tty2 are not showing any data on the screen.  This is
+  most likely an issue with qemu since the status bit is changing
+  as the characters are polled out.  
+
+TBD
+===
++ Conversion to Programmable Interrupt Controller IRQ model
+  using shared infrastructure
++ tty0 working interrupt driver
++ tty1 working interrupt driver
++ tty2 working interrupt driver
++ PCI Bus Support
++ AMD AM79C973 NIC
++ Consider moving mips_interrupt_mask() into BSP.
diff --git a/c/src/lib/libbsp/mips/malta/bsp_specs b/c/src/lib/libbsp/mips/malta/bsp_specs
new file mode 100644
index 0000000..c3224e2
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/bsp_specs
@@ -0,0 +1,13 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+%rename link old_link
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: start.o%s crti.o%s crtbegin.o%s -e _start}}
+
+*link:
+%(old_link) %{qrtems: -dc -dp -N}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/c/src/lib/libbsp/mips/malta/configure.ac b/c/src/lib/libbsp/mips/malta/configure.ac
new file mode 100644
index 0000000..b6f5a18
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/configure.ac
@@ -0,0 +1,21 @@
+## Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.68])
+AC_INIT([rtems-c-src-lib-libbsp-mips-malta],[_RTEMS_VERSION],[http://www.rtems.org/bugzilla])
+AC_CONFIG_SRCDIR([bsp_specs])
+RTEMS_TOP(../../../../../..)
+
+RTEMS_CANONICAL_TARGET_CPU
+AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.11.1])
+RTEMS_BSP_CONFIGURE
+
+RTEMS_PROG_CC_FOR_TARGET
+RTEMS_CANONICALIZE_TOOLS
+RTEMS_PROG_CCAS
+
+RTEMS_BSPOPTS_SET([BSP_RESET_BOARD_AT_EXIT],[*],[1])
+RTEMS_BSP_CLEANUP_OPTIONS(0, 1)
+
+# Explicitly list all Makefiles here
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/c/src/lib/libbsp/mips/malta/console/conscfg.c b/c/src/lib/libbsp/mips/malta/console/conscfg.c
new file mode 100644
index 0000000..47535e8
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/console/conscfg.c
@@ -0,0 +1,158 @@
+/**
+ *  @file
+ *
+ *  This file contains the libchip configuration information
+ *  to instantiate the libchip driver for the serial ports.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+#include <unistd.h> /* write */
+
+#include <bsp.h>
+#include <libchip/serial.h>
+#include <libchip/ns16550.h>
+#include <rtems/pci.h>
+#include <bsp/irq.h>
+
+#if 1
+#define COM_CONSOLE_FUNCTIONS  &ns16550_fns_polled
+#else
+#define COM_CONSOLE_FUNCTIONS  &ns16550_fns
+#endif
+
+/*
+ * Base IO for UART
+ */
+#define COM1_BASE_IO  0x3F8
+#define COM2_BASE_IO  0x3E8
+
+// #define CLOCK_RATE     368640
+#define CLOCK_RATE     (115200 * 16)
+
+#define COM_IO_BASE_ADDRESS   (0xa0000000UL | 0x18000000UL)
+
+uint8_t com_get_register(uint32_t addr, uint8_t i);
+void com_set_register(uint32_t addr, uint8_t i, uint8_t val);
+uint8_t tty2_get_register(uint32_t addr, uint8_t i);
+void tty2_set_register(uint32_t addr, uint8_t i, uint8_t val);
+
+
+uint8_t com_get_register(uint32_t addr, uint8_t i)
+{
+  uint8_t val;
+  volatile uint8_t *ptr;
+  ptr = (volatile uint8_t *) COM_IO_BASE_ADDRESS;
+  ptr += addr;
+  ptr += i;
+  val = *ptr;
+
+  return val;
+}
+
+void com_set_register(uint32_t addr, uint8_t i, uint8_t val)
+{
+  volatile uint8_t *ptr;
+
+  ptr = (volatile uint8_t *) COM_IO_BASE_ADDRESS;
+  ptr += addr;
+  ptr += i;
+  *ptr = val;
+}
+
+uint8_t tty2_get_register(uint32_t addr, uint8_t i)
+{
+  uint8_t val;
+  volatile uint8_t *ptr;
+
+  ptr = (volatile uint8_t *) COM_IO_BASE_ADDRESS;
+  ptr += addr;
+  ptr += (i * 8);
+  val = *ptr;
+
+  return val;
+}
+
+void tty2_set_register(uint32_t addr, uint8_t i, uint8_t val)
+{
+  volatile uint8_t *ptr;
+
+  ptr = (volatile uint8_t *) COM_IO_BASE_ADDRESS;
+  ptr += addr;
+  ptr += (i * 8);
+  *ptr = val;
+}
+
+console_tbl     Console_Configuration_Ports[] = {
+  {
+    "/dev/tty0",                          /* sDeviceName */
+    SERIAL_NS16550,                       /* deviceType */
+    COM_CONSOLE_FUNCTIONS,                /* pDeviceFns */
+    NULL,                                 /* deviceProbe, assume it is there */
+    NULL,                                 /* pDeviceFlow */
+    16,                                   /* ulMargin */
+    8,                                    /* ulHysteresis */
+    (void *) 9600,        /* Baud Rate */ /* pDeviceParams */
+    COM1_BASE_IO,                         /* ulCtrlPort1 */
+    0x00000000,                           /* ulCtrlPort2 */
+    COM1_BASE_IO,                         /* ulDataPort */
+    com_get_register,                     /* getRegister */
+    com_set_register,                     /* setRegister */
+    NULL,/* unused */                     /* getData */
+    NULL,/* unused */                     /* setData */
+    CLOCK_RATE,                           /* ulClock */
+    MALTA_IRQ_TTY0                        /* ulIntVector -- base for port */
+  },
+  {
+    "/dev/tty1",                          /* sDeviceName */
+    SERIAL_NS16550,                       /* deviceType */
+    COM_CONSOLE_FUNCTIONS,                /* pDeviceFns */
+    NULL,                                 /* deviceProbe, assume it is there */
+    NULL,                                 /* pDeviceFlow */
+    16,                                   /* ulMargin */
+    8,                                    /* ulHysteresis */
+    (void *) 9600,        /* Baud Rate */ /* pDeviceParams */
+    COM2_BASE_IO,                         /* ulCtrlPort1 */
+    0x00000000,                           /* ulCtrlPort2 */
+    COM2_BASE_IO,                         /* ulDataPort */
+    com_get_register,                     /* getRegister */
+    com_set_register,                     /* setRegister */
+    NULL,/* unused */                     /* getData */
+    NULL,/* unused */                     /* setData */
+    CLOCK_RATE,                           /* ulClock */
+    MALTA_IRQ_TTY1                        /* ulIntVector -- base for port */
+  },
+  {
+    "/dev/tty2",                          /* sDeviceName */
+    SERIAL_NS16550,                       /* deviceType */
+    COM_CONSOLE_FUNCTIONS,                /* pDeviceFns */
+    NULL,                                 /* deviceProbe, assume it is there */
+    NULL,                                 /* pDeviceFlow */
+    16,                                   /* ulMargin */
+    8,                                    /* ulHysteresis */
+    (void *) 9600,        /* Baud Rate */ /* pDeviceParams */
+    0,                    /* IGNORED */   /* ulCtrlPort1 */
+    0,                    /* IGNORED */   /* ulCtrlPort2 */
+    0,                    /* IGNORED */   /* ulDataPort */
+    tty2_get_register,                    /* getRegister */
+    tty2_set_register,                    /* setRegister */
+    NULL,/* unused */                     /* getData */
+    NULL,/* unused */                     /* setData */
+    CLOCK_RATE,                           /* ulClock */
+    MALTA_CPU_INT2                        /* ulIntVector -- base for port */
+  },
+};
+
+/*
+ *  Define a variable that contains the number of statically configured
+ *  console devices.
+ */
+unsigned long  Console_Configuration_Count = \
+    (sizeof(Console_Configuration_Ports)/sizeof(console_tbl));
diff --git a/c/src/lib/libbsp/mips/malta/console/printk_support.c b/c/src/lib/libbsp/mips/malta/console/printk_support.c
new file mode 100644
index 0000000..1383448
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/console/printk_support.c
@@ -0,0 +1,53 @@
+/**
+ *  @file
+ *
+ *  This file contains a stub for the required printk support.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <libchip/serial.h>
+#include <libchip/ns16550.h>
+
+rtems_device_minor_number         BSPPrintkPort = 0;
+
+void BSP_com_outch(char ch);
+int BSP_com_inch( void );
+
+/*
+ *  Following assume all are ns16650
+ */
+void BSP_com_outch(char ch)
+{
+  console_tbl                   *cptr;
+
+  cptr = &Console_Configuration_Ports[BSPPrintkPort];
+
+  return ns16550_outch_polled( cptr, ch );
+}
+
+int BSP_com_inch( void )
+{
+  int           result;
+  console_tbl   *cptr;
+
+  cptr = &Console_Configuration_Ports[BSPPrintkPort];
+
+  do {
+    result = ns16550_inch_polled( cptr );
+  } while (result == -1);
+
+  return result;
+}
+
+BSP_output_char_function_type     BSP_output_char = BSP_com_outch;
+BSP_polling_getchar_function_type BSP_poll_char = BSP_com_inch;
diff --git a/c/src/lib/libbsp/mips/malta/include/bsp.h b/c/src/lib/libbsp/mips/malta/include/bsp.h
new file mode 100644
index 0000000..b05b2c4
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/include/bsp.h
@@ -0,0 +1,108 @@
+/**
+ *  @file
+ *
+ *  This include file contains some definitions specific to the
+ *  MIPS Malta Board.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+#ifndef _BSP_H
+#define _BSP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bspopts.h>
+
+#include <rtems.h>
+#include <rtems/iosupp.h>
+#include <rtems/console.h>
+#include <rtems/clockdrv.h>
+
+#define BSP_FEATURE_IRQ_EXTENSION
+#define BSP_SHARED_HANDLER_SUPPORT      1
+
+#define REVISION_REGISTER_ADDRESS  0x1fc00010
+#define PRORV_MASK       0x0000000f   /* 4 bit Product Revision */
+#define PROID_MASK       0x000000f0   /* 4 bit Product ID */
+#define CORRV_MASK       0x00000300   /* 2 bit Core Board Revision */
+#define CORID_MASK       0x0000fc00   /* 6 bit Core Board ID */
+#define FPGRV_MASK       0x00ff0000   /* 8 bit CBUS FPGA Revision */
+#define BSP_8259_BASE_ADDRESS    (0x18000000UL | 0xa0000000UL)
+#define BSP_PCI_BASE_ADDRESS     (0x1be00000UL | 0xa0000000UL)
+#define BSP_NIC_IO_BASE          (0x10000000UL | 0xa0000000UL)
+#define PCI0_IO_BASE             (0x18000000UL | 0xa0000000UL)
+#define BSP_NIC_MEM_BASE         (0x00000000UL | 0xa0000000UL)
+
+/* functions */
+#define WRITE_PROTECTED_UINT8( _addr, _value ) \
+        do { \
+          volatile uint8_t *_ptr = _addr | 0x80000000; \
+          *_ptr = _value; \
+        }
+#define WRITE_PROTECTED_UINT16( _addr, _value ) \
+        do { \
+          volatile uint16_t *_ptr = _addr | 0x80000000; \
+          *_ptr = _value; \
+        }
+#define WRITE_PROTECTED_UINT32( _addr, _value ) \
+        do { \
+          volatile uint32_t *_ptr = _addr | 0x80000000; \
+          *_ptr = _value; \
+        }
+#define READ_PROTECTED_UINT8( _addr, _value ) \
+        do { \
+          volatile uint8_t *_ptr = _addr | 0x80000000; \
+         _value = *_ptr; \
+        }
+#define READ_PROTECTED_UINT16( _addr, _value ) \
+        do { \
+          volatile uint16_t *_ptr = _addr | 0x80000000; \
+         _value = *_ptr; \
+        }
+#define READ_PROTECTED_UINT32( _addr, _value ) \
+        do { \
+          volatile uint32_t *_ptr = _addr | 0x80000000; \
+         _value = *_ptr; \
+        }
+
+#define READ_UINT8( _register_, _value_ ) \
+        ((_value_) = *((volatile unsigned char *)(_register_)))
+
+#define WRITE_UINT8( _register_, _value_ ) \
+        (*((volatile unsigned char *)(_register_)) = (_value_))
+
+#define READ_UINT16( _register_, _value_ ) \
+     ((_value_) = *((volatile unsigned short *)(_register_)))
+
+#define WRITE_UINT16( _register_, _value_ ) \
+     (*((volatile unsigned short *)(_register_)) = (_value_))
+
+void simple_out_32(uint32_t base, uint32_t addr, uint32_t val);
+void simple_out_le32(uint32_t base, uint32_t addr, uint32_t val);
+uint8_t simple_in_8( uint32_t base, uint32_t addr );
+void simple_out_8( uint32_t base, uint32_t addr, uint8_t val );
+int16_t simple_in_le16( uint32_t base, uint32_t addr );
+int16_t simple_in_16( uint32_t base, uint32_t addr );
+uint32_t simple_in_le32( uint32_t base, uint32_t addr );
+uint32_t simple_in_32( uint32_t base, uint32_t addr );
+void simple_out_le16( uint32_t base, uint32_t addr, uint16_t val );
+void simple_out_16( uint32_t base, uint32_t addr, uint16_t val );
+
+rtems_isr_entry set_vector(
+  rtems_isr_entry, rtems_vector_number, int );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/mips/malta/include/irq.h b/c/src/lib/libbsp/mips/malta/include/irq.h
new file mode 100644
index 0000000..996d986
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/include/irq.h
@@ -0,0 +1,131 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_interrupt
+ *
+ * @brief Malta Interrupt Definitions
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+#ifndef LIBBSP_MIPS_MALTA_IRQ_H
+#define LIBBSP_MIPS_MALTA_IRQ_H
+
+#ifndef ASM
+  #include <rtems.h>
+  #include <rtems/irq.h>
+  #include <rtems/irq-extension.h>
+  #include <rtems/score/mips.h>
+#endif
+
+/**
+ * @addtogroup bsp_interrupt
+ *
+ * @{
+ */
+
+#define BSP_INTERRUPT_VECTOR_MIN 0
+
+/*
+ *  Interrupt Vector Numbers
+ *
+ *  NOTE: Numbers 0-15 directly map to levels on the IRC.
+ *        Number 16 is "1xxxx" per p. 164 of the TX3904 manual.
+ */
+#define MALTA_CPU_INT_START           MIPS_INTERRUPT_BASE+0
+#define MALTA_CPU_INT_SW0             MALTA_CPU_INT_START+0
+#define MALTA_CPU_INT_SW2             MALTA_CPU_INT_START+1
+#define MALTA_CPU_INT0                MALTA_CPU_INT_START+2
+#define MALTA_CPU_INT1                MALTA_CPU_INT_START+3
+#define MALTA_CPU_INT2                MALTA_CPU_INT_START+4
+#define MALTA_CPU_INT3                MALTA_CPU_INT_START+5
+#define MALTA_CPU_INT4                MALTA_CPU_INT_START+6
+#define MALTA_CPU_INT5                MALTA_CPU_INT_START+7
+#define MALTA_CPU_INT_LAST            MALTA_CPU_INT5
+
+#define MALTA_SB_IRQ_START            MALTA_CPU_INT_LAST+1
+#define MALTA_SB_IRQ_0                MALTA_SB_IRQ_START+0
+#define MALTA_SB_IRQ_1                MALTA_SB_IRQ_START+1
+#define MALTA_SB_IRQ_2                MALTA_SB_IRQ_START+2
+#define MALTA_SB_IRQ_3                MALTA_SB_IRQ_START+3
+#define MALTA_SB_IRQ_4                MALTA_SB_IRQ_START+4
+#define MALTA_SB_IRQ_5                MALTA_SB_IRQ_START+5
+#define MALTA_SB_IRQ_6                MALTA_SB_IRQ_START+6
+#define MALTA_SB_IRQ_7                MALTA_SB_IRQ_START+7
+#define MALTA_SB_IRQ_8                MALTA_SB_IRQ_START+8
+#define MALTA_SB_IRQ_9                MALTA_SB_IRQ_START+9
+#define MALTA_SB_IRQ_10               MALTA_SB_IRQ_START+10
+#define MALTA_SB_IRQ_11               MALTA_SB_IRQ_START+11
+#define MALTA_SB_IRQ_12               MALTA_SB_IRQ_START+12
+#define MALTA_SB_IRQ_13               MALTA_SB_IRQ_START+13
+#define MALTA_SB_IRQ_14               MALTA_SB_IRQ_START+14
+#define MALTA_SB_IRQ_15               MALTA_SB_IRQ_START+15
+#define MALTA_SB_IRQ_LAST             MALTA_SB_IRQ_15
+
+#define MALTA_PCI_ADP_START           MALTA_SB_IRQ_LAST+1
+#define MALTA_PCI_ADP20               MALTA_PCI_ADP_START+0
+#define MALTA_PCI_ADP21               MALTA_PCI_ADP_START+1
+#define MALTA_PCI_ADP22               MALTA_PCI_ADP_START+2
+#define MALTA_PCI_ADP27               MALTA_PCI_ADP_START+3
+#define MALTA_PCI_ADP28               MALTA_PCI_ADP_START+4
+#define MALTA_PCI_ADP29               MALTA_PCI_ADP_START+5
+#define MALTA_PCI_ADP30               MALTA_PCI_ADP_START+6
+#define MALTA_PCI_ADP31               MALTA_PCI_ADP_START+7
+#define MALTA_PCI_ADP_LAST            MALTA_PCI_ADP31
+#
+
+#define BSP_INTERRUPT_VECTOR_MAX   MALTA_PCI_ADP_LAST
+
+/*
+ * Redefine interrupts with more descriptive names.
+ * The Generic ones above match the hardware name,
+ * where these match the device name.
+ */
+#define MALTA_INT_SOUTHBRIDGE_INTR             MALTA_CPU_INT0
+#define MALTA_INT_SOUTHBRIDGE_SMI              MALTA_CPU_INT1
+#define MALTA_INT_TTY2                         MALTA_CPU_INT2
+#define MALTA_INT_COREHI                       MALTA_CPU_INT3
+#define MALTA_INT_CORELO                       MALTA_CPU_INT4
+#define MALTA_INT_TICKER                       MALTA_CPU_INT5
+
+#define MALTA_IRQ_TIMER_SOUTH_BRIDGE           MALTA_SB_IRQ_0
+#define MALTA_IRQ_KEYBOARD_SUPERIO             MALTA_SB_IRQ_1
+#define MALTA_IRQ_RESERVED1_SOUTH_BRIDGE       MALTA_SB_IRQ_2
+#define MALTA_IRQ_TTY1                         MALTA_SB_IRQ_3
+#define MALTA_IRQ_TTY0                         MALTA_SB_IRQ_4
+#define MALTA_IRQ_NOT_USED                     MALTA_SB_IRQ_5
+#define MALTA_IRQ_FLOPPY_SUPERIO               MALTA_SB_IRQ_6
+#define MALTA_IRQ_PARALLEL_PORT_SUPERIO        MALTA_SB_IRQ_7
+#define MALTA_IRQ_REALTIME_CLOCK_SOUTH_BRIDGE  MALTA_SB_IRQ_8
+#define MALTA_IRQ_I2C_SOUTH_BRIDGE             MALTA_SB_IRQ_9
+/* PCI A, PCI B (including Ethernet) PCI slot 1..4, Ethernet */
+#define MALTA_IRQ_PCI_A_B                      MALTA_SB_IRQ_10
+/* PCI slot 1..4 (audio, USB)  */
+#define MALTA_IRQ_PCI_C_D                      MALTA_SB_IRQ_11
+#define MALTA_IRQ_MOUSE_SUPERIO                MALTA_SB_IRQ_12
+#define MALTA_IRQ_RESERVED2_SOUTH_BRIDGE       MALTA_SB_IRQ_13
+#define MALTA_IRQ_PRIMARY_IDE                  MALTA_SB_IRQ_14
+#define MALTA_IRQ_SECONDARY_IDE                MALTA_SB_IRQ_15
+#define MALTA_IRQ_SOUTH_BRIDGE    MALTA_PCI_ADP20
+#define MALTA_IRQ_ETHERNET        MALTA_IRQ_PCI_A_B
+#define MALTA_IRQ_AUDIO           MALTA_PCI_ADP22
+#define MALTA_IRQ_CORE_CARD       MALTA_PCI_ADP27
+#define MALTA_IRQ_PCI_CONNECTOR_1 MALTA_PCI_ADP28
+#define MALTA_IRQ_PCI_CONNECTOR_2 MALTA_PCI_ADP29
+#define MALTA_IRQ_PCI_CONNECTOR_3 MALTA_PCI_ADP30
+#define MALTA_IRQ_PCI_CONNECTOR_4 MALTA_PCI_ADP31
+
+#ifndef ASM
+
+#endif /* ASM */
+
+/** @} */
+
+#endif /* LIBBSP_MIPS_MALTA_IRQ_H */
diff --git a/c/src/lib/libbsp/mips/malta/include/pci.h b/c/src/lib/libbsp/mips/malta/include/pci.h
new file mode 100644
index 0000000..b5c0e60
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/include/pci.h
@@ -0,0 +1,171 @@
+/**
+ *  @file
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+/*
+ *
+ *	PCI defines and function prototypes
+ *	Copyright 1994, Drew Eckhardt
+ *	Copyright 1997, 1998 Martin Mares <mj at atrey.karlin.mff.cuni.cz>
+ *
+ *	For more information, please consult the following manuals (look at
+ *	http://www.pcisig.com/ for how to get them):
+ *
+ *	PCI BIOS Specification
+ *	PCI Local Bus Specification
+ *	PCI to PCI Bridge Specification
+ *	PCI System Design Guide
+ */
+
+#ifndef BSP_PCI_H
+#define BSP_PCI_H
+
+#include <rtems/pci.h>
+#include <bsp.h>
+#include <stdio.h>
+
+struct _pin_routes
+{
+      int pin, int_name[4];
+};
+struct _int_map
+{
+      int bus, slot, opts;
+      struct _pin_routes pin_route[5];
+};
+struct pcibridge
+{
+  int bus;
+  int slot;
+};
+
+/* If there's a conflict between a name in the routing table and
+ * what's already set on the device, reprogram the device setting
+ * to reflect int_name[0] for the routing table entry
+ */
+#define PCI_FIXUP_OPT_OVERRIDE_NAME	(1<<0)
+
+void FixupPCI( const struct _int_map *, int (*swizzler)(int,int) );
+
+/* FIXME: This probably belongs into rtems/pci.h */
+extern unsigned char pci_bus_count();
+
+/* FIXME: This also is generic and could go into rtems/pci.h */
+
+/* Scan pci config space and run a user callback on each
+ * device present; the user callback may return 0 to
+ * continue the scan or a value > 0 to abort the scan.
+ * Return values < 0 are reserved and must not be used.
+ *
+ * RETURNS: a (opaque) handle pointing to the bus/slot/fn-triple
+ *          just after where the scan was aborted by a callback
+ *          returning 1 (see above) or NULL if all devices were
+ *          scanned.
+ *          The handle may be passed to this routine to resume the
+ *          scan continuing with the device after the one causing the
+ *          abort.
+ *          Pass a NULL 'handle' argument to start scanning from
+ *          the beginning (bus/slot/fn = 0/0/0).
+ */
+typedef void *BSP_PciScanHandle;
+typedef int (*BSP_PciScannerCb)(int bus, int slot, int fun, void *uarg);
+
+
+BSP_PciScanHandle
+BSP_pciScan(BSP_PciScanHandle handle, BSP_PciScannerCb cb, void *uarg);
+
+/* Dump basic config. space info to a file. The argument may
+ * be NULL in which case 'stdout' is used.
+ * NOTE: the C-library must be functional before you can use
+ *       this routine.
+ */
+void BSP_pciConfigDump(FILE *fp);
+
+int indirect_pci_read_config_byte(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint8_t       *val
+);
+
+int indirect_pci_read_config_word(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint16_t      *val
+);
+
+int indirect_pci_read_config_dword(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint32_t *val
+);
+
+int indirect_pci_write_config_byte(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint8_t       val
+);
+
+int indirect_pci_write_config_word(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint16_t      val
+);
+
+int indirect_pci_write_config_dword(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint32_t      val
+);
+
+/* Can these be moved to the rtems pci.h? */
+int FindPCIbridge( int mybus, struct pcibridge *pb );
+void pci_list_devices( void );
+
+const pci_config_access_functions pci_indirect_functions;
+
+void     pci_out_le32( uint32_t base, uint32_t addr, uint32_t val);
+void     pci_out_32( uint32_t base, uint32_t addr, uint32_t val);
+uint8_t  pci_in_8    ( uint32_t base, uint32_t addr );
+int16_t  pci_in_le16 ( uint32_t base, uint32_t addr );
+uint32_t pci_in_le32 ( uint32_t base, uint32_t addr );
+int16_t  pci_in_16 ( uint32_t base, uint32_t addr );
+uint32_t pci_in_32 ( uint32_t base, uint32_t addr );
+void     pci_out_8   ( uint32_t base, uint32_t addr, uint8_t val );
+void     pci_out_le16( uint32_t base, uint32_t addr, uint16_t val );
+void     pci_out_16( uint32_t base, uint32_t addr, uint16_t val );
+void     pci_out_32  ( uint32_t base, uint32_t addr, uint32_t val);
+
+#define out_32(_addr, _val)   pci_out_32(BSP_PCI_BASE_ADDRESS, _addr, _val)
+#define out_le32(_addr, _val) pci_out_le32(BSP_PCI_BASE_ADDRESS, _addr, _val)
+#define out_32(_addr, _val)   pci_out_32(BSP_PCI_BASE_ADDRESS, _addr, _val)
+#define in_8(_addr)           pci_in_8( BSP_PCI_BASE_ADDRESS, _addr )
+#define in_le16(_addr)        pci_in_le16( BSP_PCI_BASE_ADDRESS, _addr )
+#define in_le32(_addr)        pci_in_le32( BSP_PCI_BASE_ADDRESS, _addr )
+#define in_16(_addr)          pci_in_16( BSP_PCI_BASE_ADDRESS, _addr )
+#define in_32(_addr)          pci_in_32( BSP_PCI_BASE_ADDRESS, _addr )
+#define out_8(_addr,_val)     pci_out_8( BSP_PCI_BASE_ADDRESS, _addr, _val )
+#define out_le16(_addr,_val)  pci_out_le16( BSP_PCI_BASE_ADDRESS, _addr, _val )
+#define out_16(_addr,_val)    pci_out_16( BSP_PCI_BASE_ADDRESS, _addr, _val )
+
+#endif /* BSP_PCI_H */
diff --git a/c/src/lib/libbsp/mips/malta/irq/interruptmask.c b/c/src/lib/libbsp/mips/malta/irq/interruptmask.c
new file mode 100644
index 0000000..1eb667a
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/irq/interruptmask.c
@@ -0,0 +1,36 @@
+/**
+ *  @file
+ *
+ *  This file contains the implementation of the MIPS port
+ *  support routine which provides the BSP specific default
+ *  interrupt mask.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+#include <rtems.h>
+
+/*
+ *  This function returns a mask value which is used to select the bits
+ *  in the processor status register that can be set to enable interrupts.
+ *  The mask value should not include the 2 software interrupt enable bits.
+ */
+
+uint32_t mips_interrupt_mask( void )
+{
+  uint32_t interrupt_mask;
+
+  /*
+   * This has only been tested with qemu for the mips malta and
+   * may not be correct for the 24k on real hardware.
+   */
+  interrupt_mask = 0x0000ff00;
+  return(interrupt_mask);
+}
diff --git a/c/src/lib/libbsp/mips/malta/irq/maxvectors.c b/c/src/lib/libbsp/mips/malta/irq/maxvectors.c
new file mode 100644
index 0000000..77b9854
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/irq/maxvectors.c
@@ -0,0 +1,24 @@
+/**
+ *  @file
+ *
+ *  This file contains the maximum number of vectors.  This can not
+ *  be determined without knowing the RTEMS CPU model.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+/*
+ *  Reserve first 32 for exceptions.
+ */
+
+#include <rtems.h>
+
+unsigned int mips_interrupt_number_of_vectors = 13;
+
diff --git a/c/src/lib/libbsp/mips/malta/irq/vectorisrs.c b/c/src/lib/libbsp/mips/malta/irq/vectorisrs.c
new file mode 100644
index 0000000..1588eec
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/irq/vectorisrs.c
@@ -0,0 +1,90 @@
+/**
+ *  @file
+ *
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <stdlib.h>
+#include <bsp/irq-generic.h>
+#include <bsp/pci.h>
+#include <bsp/i8259.h>
+#include <bsp.h>
+
+void mips_default_isr( int vector );
+void mips_vector_isr_handlers( CPU_Interrupt_frame *frame );
+
+#include <rtems/bspIo.h>  /* for printk */
+
+void mips_vector_isr_handlers( CPU_Interrupt_frame *frame )
+{
+  unsigned int sr;
+  unsigned int cause;
+  unsigned int pending;
+
+  mips_get_sr( sr );
+  mips_get_cause( cause );
+
+  pending = (cause & sr & 0xff00) >> CAUSE_IPSHIFT;
+
+  /* SW Bits */
+  if ( pending & 0x01) {
+    printk("Pending IRQ Q 0x%x\n", pending );
+  }
+
+  if ( pending & 0x02) {
+    printk("Pending IRQ Q 0x%x\n", pending );
+  }
+
+  /* South Bridge Interrupt */
+  if ( pending & 0x04) {
+     BSP_i8259s_int_process();
+  }
+
+  /* South Bridge SMI */
+  if (pending & 0x08){
+    printk( "Pending IRQ 0x%x\n", pending );
+  }
+
+  /* TTY 2 */
+  if (pending & 0x10) {
+    printk( "Pending IRQ 0x%x\n", pending );
+  }
+  /* Core HI */
+  if (pending & 0x20) {
+    printk( "Pending IRQ 0x%x\n", pending );
+  }
+   /* Core LO */
+  if (pending & 0x40) {
+    printk( "Pending IRQ 0x%x\n", pending );
+  }
+
+  if ( pending & 0x80 ) {
+    bsp_interrupt_handler_dispatch( MALTA_INT_TICKER );
+  }
+}
+
+void mips_default_isr( int vector )
+{
+  unsigned int sr;
+  unsigned int cause;
+
+  mips_get_sr( sr );
+  mips_get_cause( cause );
+
+  printk( "Unhandled isr exception: vector 0x%02x, cause 0x%08X, sr 0x%08X\n",
+      vector, cause, sr );
+
+  while(1);      /* Lock it up */
+
+  rtems_fatal_error_occurred(1);
+}
+
diff --git a/c/src/lib/libbsp/mips/malta/make/custom/malta.cfg b/c/src/lib/libbsp/mips/malta/make/custom/malta.cfg
new file mode 100644
index 0000000..f44b5e9
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/make/custom/malta.cfg
@@ -0,0 +1,15 @@
+#
+#  Config file for the MIPS Malta board with 24kf CPU
+#
+
+include $(RTEMS_ROOT)/make/custom/default.cfg
+
+RTEMS_CPU=mips
+RTEMS_CPU_MODEL=mips24kf
+
+#  This contains the compiler options necessary to select the CPU model
+#  and (hopefully) optimize for it.
+CPU_CFLAGS = -march=24kf1_1 -Wa,-xgot -G0
+
+# optimize flag: typically -O2
+CFLAGS_OPTIMIZE_V = -O0 -g
diff --git a/c/src/lib/libbsp/mips/malta/pci/pci.c b/c/src/lib/libbsp/mips/malta/pci/pci.c
new file mode 100644
index 0000000..ab8949b
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/pci/pci.c
@@ -0,0 +1,1105 @@
+/**
+ *  @file
+ *
+ *  This file was based on the powerpc.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+
+#include <bsp/pci.h>
+#include <bsp/irq.h>
+#include <rtems/bspIo.h>
+#include <rtems/endian.h>
+
+/*
+ * DEFINES
+ */
+
+#undef SHOW_PCI_SETTING
+
+// #define DEBUG_PCI 1
+
+/* allow for overriding these definitions */
+#ifndef PCI_CONFIG_ADDR
+#define PCI_CONFIG_ADDR      0xcf8
+#endif
+#ifndef PCI_CONFIG_DATA
+#define PCI_CONFIG_DATA      0xcfc
+#endif
+
+#define PCI_INVALID_VENDORDEVICEID  0xffffffff
+#define PCI_MULTI_FUNCTION    0x80
+
+/* define a shortcut */
+#define pci  BSP_pci_configuration
+
+#ifndef  PCI_CONFIG_ADDR_VAL
+#define  PCI_CONFIG_ADDR_VAL(bus, slot, funcion, offset) \
+     (0x80000000|((bus)<<16)|(PCI_DEVFN((slot),(function))<<8)|(((offset)&~3)))
+#endif
+
+#ifdef DEBUG_PCI
+  #define JPRINTK(fmt, ...) printk("%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
+#else
+  #define JPRINTK(fmt, ...)
+#endif
+
+#ifndef  PCI_CONFIG_WR_ADDR
+#define  PCI_CONFIG_WR_ADDR( addr, val ) out_le32((uint32_t)(addr), (val))
+#endif
+
+/* Bit encode for PCI_CONFIG_HEADER_TYPE register */
+#define PCI_CONFIG_SET_ADDR(addr, bus, slot,function,offset) \
+  PCI_CONFIG_WR_ADDR( \
+    (addr), \
+    PCI_CONFIG_ADDR_VAL((bus), (slot), (function), (offset))\
+  )
+
+#define PRINT_MSG() \
+  printk("pci : Device %d:0x%02x:%d routed to interrupt_line %d\n", \
+    pbus, pslot, pfun, int_name )
+
+/*
+ * STRUCTURES
+ */
+
+/*
+ * PROTOTYPES
+ */
+void print_bars(
+  unsigned char slot,
+  unsigned char func
+);
+int direct_pci_read_config_byte(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint8_t      *val
+);
+int direct_pci_read_config_word(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint16_t     *val
+);
+int direct_pci_read_config_dword(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint32_t     *val
+);
+int direct_pci_write_config_byte(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint8_t       val
+);
+int direct_pci_write_config_word(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint16_t      val
+);
+int direct_pci_write_config_dword(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint32_t      val
+);
+int test_intname(
+  const struct _int_map *row,
+  int pbus,
+  int pslot,
+  int pfun,
+  int int_pin,
+  int int_name
+);
+void pci_memory_enable(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function
+);
+void pci_io_enable(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function
+);
+void pci_busmaster_enable(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function
+);
+
+/*
+ * GLOBALS
+ */
+unsigned char ucMaxPCIBus;
+const pci_config_access_functions pci_indirect_functions = {
+  indirect_pci_read_config_byte,
+  indirect_pci_read_config_word,
+  indirect_pci_read_config_dword,
+  indirect_pci_write_config_byte,
+  indirect_pci_write_config_word,
+  indirect_pci_write_config_dword
+};
+
+rtems_pci_config_t BSP_pci_configuration = {
+  (volatile unsigned char*)PCI_CONFIG_ADDR,
+  (volatile unsigned char*)PCI_CONFIG_DATA,
+  &pci_indirect_functions
+};
+
+const pci_config_access_functions pci_direct_functions = {
+  direct_pci_read_config_byte,
+  direct_pci_read_config_word,
+  direct_pci_read_config_dword,
+  direct_pci_write_config_byte,
+  direct_pci_write_config_word,
+  direct_pci_write_config_dword
+};
+
+/*
+ * PCI specific accesses.  Note these are made on 32 bit
+ * boundries.
+ */
+void pci_out_32(uint32_t base, uint32_t addr, uint32_t val)
+{
+  volatile uint32_t *ptr;
+
+  ptr = (volatile uint32_t *) (base + addr);
+  *ptr = val;
+
+  JPRINTK( "%p data: 0x%x\n", ptr, val);
+}
+
+void pci_out_le32(uint32_t base, uint32_t addr, uint32_t val)
+{
+  volatile uint32_t *ptr;
+  uint32_t           data = 0;
+
+  ptr = (volatile uint32_t *) (base + addr);
+  rtems_uint32_to_little_endian( val, (uint8_t *) &data);
+  *ptr = data;
+
+  JPRINTK( "%p data: 0x%x\n", ptr, data);
+}
+
+uint8_t pci_in_8( uint32_t base, uint32_t addr ) {
+  volatile uint32_t *ptr;
+  uint8_t            val;
+  uint32_t           data;
+
+  data = addr/4;
+  ptr = (volatile uint32_t *) (base + (data*4));
+  data = *ptr;
+
+  switch ( addr%4 ) {
+    case 0: val = (data & 0x000000ff) >>  0; break;
+    case 1: val = (data & 0x0000ff00) >>  8; break;
+    case 2: val = (data & 0x00ff0000) >> 16; break;
+    case 3: val = (data & 0xff000000) >> 24; break;
+   }
+
+   JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, data);
+
+  return val;
+}
+
+int16_t pci_in_le16( uint32_t base, uint32_t addr ) {
+  volatile uint32_t *ptr;
+  uint16_t           val;
+  uint16_t           rval;
+  uint32_t           data;
+
+  data = addr/4;
+  ptr = (volatile uint32_t *) (base + (data*4));
+  data = *ptr;
+  if ( addr%4 == 0 )
+    val = data & 0xffff;
+  else
+    val = (data>>16) & 0xffff;
+
+  rval = rtems_uint16_from_little_endian( (uint8_t *) &val);
+  JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, rval, data);
+  return rval;
+}
+
+int16_t pci_in_16( uint32_t base, uint32_t addr ) {
+  volatile uint32_t *ptr;
+  uint16_t           val;
+  uint32_t           data;
+
+  data = addr/4;
+  ptr = (volatile uint32_t *) (base + (data*4));
+  data = *ptr;
+  if ( addr%4 == 0 )
+    val = data & 0xffff;
+  else
+    val = (data>>16) & 0xffff;
+
+  JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, data);
+  return val;
+}
+
+uint32_t pci_in_32( uint32_t base, uint32_t addr ) {
+  volatile uint32_t *ptr;
+  uint32_t           val;
+
+  ptr = (volatile uint32_t *) (base + addr);
+  val = *ptr;
+
+  JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, val);
+  return val;
+}
+uint32_t pci_in_le32( uint32_t base, uint32_t addr ) {
+  volatile uint32_t *ptr;
+  uint32_t           val;
+  uint32_t           rval;
+
+  ptr = (volatile uint32_t *) (base + addr);
+  val = *ptr;
+  rval = rtems_uint32_from_little_endian( (uint8_t *) &val);
+
+  JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, rval, val);
+  return rval;
+}
+
+void pci_out_8( uint32_t base, uint32_t addr, uint8_t val ) {
+  volatile uint32_t *ptr;
+
+  ptr = (volatile uint32_t *) (base + addr);
+  JPRINTK("Address: %p\n", ptr);
+  *ptr = val;
+  JPRINTK( "%p data: 0x%x\n", ptr, val);
+}
+
+void pci_out_le16( uint32_t base, uint32_t addr, uint16_t val ) {
+  volatile uint32_t *ptr;
+  uint32_t           out_data;
+  uint32_t           data;
+
+  ptr = (volatile uint32_t *) (base + (addr & ~0x3));
+  data = *ptr;
+  if ( addr%4 == 0 )
+    out_data = (data & 0xffff0000) | val;
+  else
+    out_data = ((val << 16)&0xffff0000) | (data & 0xffff);
+  rtems_uint32_to_little_endian( out_data, (uint8_t *) &data);
+  *ptr = data;
+
+  JPRINTK( "0x%x data: 0x%x\n", ptr, data);
+}
+
+void pci_out_16( uint32_t base, uint32_t addr, uint16_t val ) {
+  volatile uint32_t *ptr;
+  uint32_t           out_data;
+  uint32_t           data;
+
+  ptr = (volatile uint32_t *) (base + (addr & ~0x3));
+  data = *ptr;
+  if ( addr%4 == 0 )
+    out_data = (data & 0xffff0000) | val;
+  else
+    out_data = ((val << 16)&0xffff0000) | (data & 0xffff);
+  *ptr = out_data;
+
+  JPRINTK( "0x%x data: 0x%x\n", ptr, out_data);
+}
+
+/*
+ * INDIRECT PCI CONFIGURATION ACCESSES
+ */
+int indirect_pci_read_config_byte(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint8_t       *val
+) {
+
+  JPRINTK("==>\n");
+  PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
+  *val = in_8((uint32_t) (pci.pci_config_data +  (offset&3)) );
+  JPRINTK("\n\n");
+
+  return PCIBIOS_SUCCESSFUL;
+}
+
+int indirect_pci_read_config_word(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint16_t      *val
+) {
+
+  JPRINTK("==>\n");
+
+  *val = 0xffff;
+  if (offset&1)
+    return PCIBIOS_BAD_REGISTER_NUMBER;
+
+  PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
+  *val = in_16((uint32_t)(pci.pci_config_data + (offset&3)));
+
+  JPRINTK("\n\n");
+
+  return PCIBIOS_SUCCESSFUL;
+}
+
+int indirect_pci_read_config_dword(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint32_t *val
+) {
+  uint32_t v;
+  JPRINTK("==>\n");
+
+  *val = 0xffffffff;
+  if (offset&3)
+    return PCIBIOS_BAD_REGISTER_NUMBER;
+  PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
+  v = in_32( (uint32_t) pci.pci_config_data );
+  *val = v;
+   if ( offset == 0x0b )
+     JPRINTK( "%x:%x %x ==> 0x%08x, 0x%08x\n", bus, slot, function, v, *val );
+
+  JPRINTK("\n\n");
+
+  return PCIBIOS_SUCCESSFUL;
+}
+
+int indirect_pci_write_config_byte(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint8_t       val
+) {
+
+  JPRINTK("==>\n");
+
+  PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
+  out_8( (uint32_t) (pci.pci_config_data + (offset&3)), val);
+
+  JPRINTK("\n\n");
+
+  return PCIBIOS_SUCCESSFUL;
+}
+
+int indirect_pci_write_config_word(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint16_t      val
+) {
+
+  JPRINTK("==>\n");
+
+  if (offset&1)
+    return PCIBIOS_BAD_REGISTER_NUMBER;
+
+  PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
+  out_16((uint32_t)(pci.pci_config_data + (offset&3)), val);
+
+  JPRINTK("\n\n");
+
+  return PCIBIOS_SUCCESSFUL;
+}
+
+int indirect_pci_write_config_dword(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint32_t      val
+) {
+
+  if (offset&3)
+    return PCIBIOS_BAD_REGISTER_NUMBER;
+
+  JPRINTK("==>\n");
+
+  /*
+   * The Base Address Registers get accessed big endian while the
+   * other registers are little endian.
+   */
+  PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
+  if ( bus == 0 && slot == 0x0b &&
+       (offset >= PCI_BASE_ADDRESS_0 && offset <= PCI_BASE_ADDRESS_5) ) {
+    out_32((uint32_t)pci.pci_config_data, val);
+  } else {
+    out_le32((uint32_t)pci.pci_config_data, val);
+  }
+
+  JPRINTK("\n\n");
+
+  return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * DIRECT CONFIGUREATION ACCESSES.
+ */
+int direct_pci_read_config_byte(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint8_t      *val
+) {
+  if (bus != 0 || (1<<slot & 0xff8007fe)) {
+    *val=0xff;
+     return PCIBIOS_DEVICE_NOT_FOUND;
+  }
+
+  JPRINTK("==>\n");
+
+  *val=in_8((uint32_t) (pci.pci_config_data + ((1<<slot)&~1)
+   + (function<<8) + offset));
+
+  JPRINTK("\n\n");
+
+  return PCIBIOS_SUCCESSFUL;
+}
+
+int direct_pci_read_config_word(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint16_t     *val
+) {
+  *val = 0xffff;
+  if (offset&1)
+    return PCIBIOS_BAD_REGISTER_NUMBER;
+  if (bus != 0 || (1<<slot & 0xff8007fe))
+     return PCIBIOS_DEVICE_NOT_FOUND;
+
+  JPRINTK("==>\n");
+
+  *val=in_le16((uint32_t)
+      (pci.pci_config_data + ((1<<slot)&~1)
+       + (function<<8) + offset));
+
+  JPRINTK("\n\n");
+
+  return PCIBIOS_SUCCESSFUL;
+}
+
+int direct_pci_read_config_dword(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint32_t     *val
+) {
+  *val = 0xffffffff;
+  if (offset&3)
+    return PCIBIOS_BAD_REGISTER_NUMBER;
+  if (bus != 0 || (1<<slot & 0xff8007fe))
+     return PCIBIOS_DEVICE_NOT_FOUND;
+
+  JPRINTK("==>\n");
+
+  *val=in_le32((uint32_t)(pci.pci_config_data +
+    ((1<<slot)&~1)+(function<<8) + offset));
+
+  JPRINTK("\n\n");
+
+  return PCIBIOS_SUCCESSFUL;
+}
+
+int direct_pci_write_config_byte(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint8_t       val
+) {
+  if (bus != 0 || (1<<slot & 0xff8007fe))
+     return PCIBIOS_DEVICE_NOT_FOUND;
+
+  JPRINTK("==>\n");
+
+  out_8((uint32_t) (pci.pci_config_data + ((1<<slot)&~1) +
+    (function<<8) + offset),
+     val);
+
+  JPRINTK("\n\n");
+
+  return PCIBIOS_SUCCESSFUL;
+}
+
+int direct_pci_write_config_word(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint16_t      val
+) {
+  if (offset&1)
+    return PCIBIOS_BAD_REGISTER_NUMBER;
+  if (bus != 0 || (1<<slot & 0xff8007fe))
+     return PCIBIOS_DEVICE_NOT_FOUND;
+
+  JPRINTK("==>\n");
+
+  out_le16((uint32_t)(pci.pci_config_data + ((1<<slot)&~1) +
+    (function<<8) + offset),
+    val);
+
+  JPRINTK("\n\n");
+
+  return PCIBIOS_SUCCESSFUL;
+}
+
+int direct_pci_write_config_dword(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function,
+  unsigned char offset,
+  uint32_t      val
+) {
+  if (offset&3)
+    return PCIBIOS_BAD_REGISTER_NUMBER;
+  if (bus != 0 || (1<<slot & 0xff8007fe))
+     return PCIBIOS_DEVICE_NOT_FOUND;
+
+  JPRINTK("direct_pci_write_config_dword==>\n");
+
+  out_le32((uint32_t)
+     (pci.pci_config_data + ((1<<slot)&~1)
+   + (function<<8) + offset),
+     val);
+
+  JPRINTK("\n\n");
+
+  return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * Validate a test interrupt name and print a warning if its not one of
+ * the names defined in the routing record.
+ */
+int test_intname(
+  const struct _int_map *row,
+  int pbus,
+  int pslot,
+  int pfun,
+  int int_pin,
+  int int_name
+) {
+  int j, k;
+  int _nopin= -1, _noname= -1;
+
+  for (j=0; row->pin_route[j].pin > -1; j++) {
+    if ( row->pin_route[j].pin == int_pin ) {
+   _nopin = 0;
+
+   for (k=0; k<4 && row->pin_route[j].int_name[k] > -1; k++ ) {
+     if ( row->pin_route[j].int_name[k] == int_name ) {
+       _noname=0; break;
+     }
+   }
+   break;
+    }
+  }
+
+   if( _nopin  )
+   {
+      printk(
+        "pci : Device %d:0x%02x:%d supplied a bogus interrupt_pin %d\n",
+        pbus,
+        pslot,
+        pfun,
+        int_pin
+      );
+      return -1;
+   }
+   else
+   {
+     if( _noname ) {
+       unsigned char v = row->pin_route[j].int_name[0];
+       printk(
+         "pci : Device %d:0x%02x:%d supplied a suspicious interrupt_line %d, ",
+         pbus,
+         pslot,
+         pfun,
+         int_name
+       );
+       if ((row->opts & PCI_FIXUP_OPT_OVERRIDE_NAME) && 255 !=
+           (v = row->pin_route[j].int_name[0])
+          ) {
+         printk("OVERRIDING with %d from fixup table\n", v);
+         pci_write_config_byte(pbus,pslot,pfun,PCI_INTERRUPT_LINE,v);
+       } else {
+        printk("using it anyway\n");
+       }
+     }
+   }
+   return 0;
+}
+
+int FindPCIbridge( int mybus, struct pcibridge *pb )
+{
+  int          pbus, pslot;
+  uint8_t      bussec, buspri;
+  uint16_t     devid, vendorid, dclass;
+
+  for(pbus=0; pbus< pci_bus_count(); pbus++) {
+    for(pslot=0; pslot< PCI_MAX_DEVICES; pslot++) {
+      pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
+      if ( devid == 0xffff ) continue;
+
+      pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &vendorid);
+      if ( vendorid == 0xffff ) continue;
+
+      pci_read_config_word(pbus, pslot, 0, PCI_CLASS_DEVICE, &dclass);
+
+      if ( dclass == PCI_CLASS_BRIDGE_PCI ) {
+        pci_read_config_byte(pbus, pslot, 0, PCI_PRIMARY_BUS,    &buspri);
+        pci_read_config_byte(pbus, pslot, 0, PCI_SECONDARY_BUS,  &bussec);
+
+        #ifdef SHOW_PCI_SETTING
+          JPRINTK(
+            "pci : Found bridge at %d:0x%02x, mybus %d, pribus %d, secbus %d ",
+            pbus,
+            pslot,
+            mybus,
+            buspri,
+            bussec
+          );
+        #endif
+        if ( bussec == mybus ) {
+          #ifdef SHOW_PCI_SETTING
+            JPRINTK("match\n");
+          #endif
+          /* found our nearest bridge going towards the root */
+          pb->bus = pbus;
+          pb->slot = pslot;
+          return 0;
+        }
+        #ifdef SHOW_PCI_SETTING
+          JPRINTK("no match\n");
+        #endif
+      }
+
+     }
+   }
+   return -1;
+}
+
+void FixupPCI( const struct _int_map *bspmap, int (*swizzler)(int,int) )
+{
+  unsigned char cvalue;
+  uint16_t      devid;
+  int           ismatch, i, j, pbus, pslot, pfun, int_pin, int_name, nfuns;
+
+  /*
+   * If the device has a non-zero INTERRUPT_PIN, assign a bsp-specific
+   * INTERRUPT_NAME if one isn't already in place.  Then, drivers can
+   * trivially use INTERRUPT_NAME to hook up with devices.
+   */
+
+  for (pbus=0; pbus< pci_bus_count(); pbus++) {
+    for (pslot=0; pslot< PCI_MAX_DEVICES; pslot++) {
+      pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
+      if ( devid == 0xffff ) continue;
+
+      /* got a device */
+      pci_read_config_byte(pbus, pslot, 0, PCI_HEADER_TYPE, &cvalue);
+      nfuns = cvalue & PCI_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1;
+      for (pfun=0; pfun< nfuns; pfun++) {
+
+        pci_read_config_word(pbus, pslot, pfun, PCI_DEVICE_ID, &devid);
+        if( devid == 0xffff ) continue;
+
+        pci_read_config_byte( pbus, pslot, pfun, PCI_INTERRUPT_PIN, &cvalue);
+        int_pin = cvalue;
+
+        pci_read_config_byte( pbus, pslot, pfun, PCI_INTERRUPT_LINE, &cvalue);
+        int_name = cvalue;
+
+        #ifdef SHOW_PCI_SETTING
+        {
+          unsigned short cmd,stat;
+          unsigned char  lat, seclat, csize;
+
+          pci_read_config_word(pbus,pslot,pfun,PCI_COMMAND, &cmd );
+          pci_read_config_word(pbus,pslot,pfun,PCI_STATUS, &stat );
+          pci_read_config_byte(pbus,pslot,pfun,PCI_LATENCY_TIMER, &lat );
+          pci_read_config_byte(pbus,pslot,pfun,PCI_SEC_LATENCY_TIMER, &seclat);
+          pci_read_config_byte(pbus,pslot,pfun,PCI_CACHE_LINE_SIZE, &csize );
+
+          JPRINTK(
+            "pci : device %d:0x%02x:%d  cmd %04X, stat %04X, latency %d, "
+            " sec_latency %d, clsize %d\n",
+            pbus,
+            pslot,
+            pfun,
+            cmd,
+            stat,
+            lat,
+            seclat,
+            csize
+          );
+        }
+        #endif
+
+        if ( int_pin > 0 ) {
+          ismatch = 0;
+
+          /*
+           * first run thru the bspmap table and see if we have an
+           * explicit configuration
+           */
+          for (i=0; bspmap[i].bus > -1; i++) {
+            if ( bspmap[i].bus == pbus && bspmap[i].slot == pslot ) {
+              ismatch = -1;
+
+              /* we have a record in the table that gives specific
+               * pins and interrupts for devices in this slot
+               */
+              if ( int_name == 255 ) {
+
+                /* find the vector associated with whatever pin the
+                 * device gives us
+                 */
+                for ( int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++ ){
+                  if ( bspmap[i].pin_route[j].pin == int_pin ) {
+                    int_name = bspmap[i].pin_route[j].int_name[0];
+                    break;
+                  }
+                }
+
+                if ( int_name == -1 ) {
+                  printk(
+                    "pci : Unable to resolve device %d:0x%02x:%d w/ "
+                    "swizzled int pin %i to an interrupt_line.\n",
+                    pbus,
+                    pslot,
+                    pfun,
+                    int_pin
+                  );
+                } else {
+                  PRINT_MSG();
+                  pci_write_config_byte(
+                    pbus,
+                    pslot,
+                    pfun,
+                    PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue)
+                  );
+                }
+              } else {
+                test_intname( &bspmap[i],pbus,pslot,pfun,int_pin,int_name);
+              }
+              break;
+            }
+          }
+
+          if ( !ismatch ) {
+            /*
+             * no match, which means we're on a bus someplace.  Work
+             * backwards from it to one of our defined busses,
+             * swizzling thru each bridge on the way.
+             */
+
+            /* keep pbus, pslot pointed to the device being
+             * configured while we track down the bridges using
+             * tbus,tslot.  We keep searching the routing table because
+             * we may end up finding our bridge in it
+             */
+
+            int tbus= pbus, tslot= pslot;
+            for (;;) {
+              for (i=0; bspmap[i].bus > -1; i++) {
+                if ( bspmap[i].bus == tbus &&
+                    (bspmap[i].slot == tslot || bspmap[i].slot == -1))
+                {
+                  ismatch = -1;
+
+                  /* found a record for this bus, so swizzle the
+                   * int_pin which we then use to find the
+                   * interrupt_name.
+                   */
+                  if ( int_name == 255 ) {
+                    /*
+                     * FIXME.  I can't believe this little hack
+                     * is right.  It does not yield an error in
+                     * convienently simple situations.
+                     */
+                    if ( tbus ) int_pin = (*swizzler)(tslot,int_pin);
+
+                    /*
+                     * int_pin points to the interrupt channel
+                     * this card ends up delivering interrupts
+                     * on.  Find the int_name servicing it.
+                     */
+                    for (int_name=-1, j=0;
+                         bspmap[i].pin_route[j].pin > -1;
+                         j++)
+                    {
+                      if ( bspmap[i].pin_route[j].pin == int_pin ) {
+                        int_name = bspmap[i].pin_route[j].int_name[0];
+                        break;
+                      }
+                    }
+
+                    if ( int_name == -1 ) {
+                      printk(
+                        "pci : Unable to resolve device %d:0x%02x:%d w/ "
+                        "swizzled int pin %i to an interrupt_line.\n",
+                        pbus,
+                        pslot,
+                        pfun,
+                        int_pin
+                      );
+                    } else {
+                      PRINT_MSG();
+                      pci_write_config_byte(pbus,pslot,pfun,
+                      PCI_INTERRUPT_LINE,(cvalue=int_name, cvalue));
+                    }
+                  } else {
+                    test_intname(
+                      &bspmap[i],
+                      pbus,
+                      pslot,
+                      pfun,
+                      int_pin,
+                      int_name
+                    );
+                  }
+                  goto donesearch;
+                }
+              }
+              if ( !ismatch ) {
+                struct pcibridge   pb;
+
+                /*
+                 * Haven't found our bus in the int map, so work
+                 * upwards thru the bridges till we find it.
+                 */
+                if ( FindPCIbridge( tbus, &pb )== 0 ) {
+                  int_pin = (*swizzler)(tslot,int_pin);
+
+                  /* our next bridge up is on pb.bus, pb.slot- now
+                   * instead of pointing to the device we're
+                   * trying to configure, we move from bridge to
+                   * bridge.
+                   */
+                  tbus = pb.bus;
+                  tslot = pb.slot;
+                } else {
+                  printk(
+                    "pci : No bridge from bus %i towards root found\n",
+                    tbus
+                  );
+                  goto donesearch;
+                }
+              }
+            }
+          }
+
+          donesearch:
+          if ( !ismatch && int_pin != 0 && int_name == 255 ) {
+            printk(
+              "pci : Unable to match device %d:0x%02x:%d with an int "
+              "routing table entry\n",
+              pbus,
+              pslot,
+              pfun
+            );
+          }
+        }
+      }
+    }
+  }
+}
+
+void print_bars(
+  unsigned char slot,
+  unsigned char func
+)
+{
+  uint32_t addr;
+
+  printk( "*** BARs for slot=%d func=%d\n", slot, func );
+  pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_0, &addr);
+  printk("***    PCI DEVICE BAR0: 0x%x\n", addr);
+  pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_1, &addr);
+  printk("***    PCI DEVICE BAR1: 0x%x\n", addr);
+  pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_2, &addr);
+  printk("***    PCI DEVICE BAR2: 0x%x\n", addr);
+  pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_3, &addr);
+  printk("***    PCI DEVICE BAR3: 0x%x\n", addr);
+  pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_4, &addr);
+  printk("***    PCI DEVICE BAR4: 0x%x\n", addr);
+  pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_5, &addr);
+  printk("***    PCI DEVICE BAR5: 0x%x\n", addr);
+}
+
+void pci_memory_enable(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function
+)
+{
+  uint16_t data;
+
+  pci_read_config_word(0, slot, function, PCI_COMMAND, &data);
+  data |= PCI_COMMAND_MEMORY;
+  pci_write_config_word(0, slot, function, PCI_COMMAND, data );
+  pci_read_config_word(0, slot, function, PCI_COMMAND, &data);
+}
+
+void pci_io_enable(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function
+)
+{
+  uint16_t data;
+
+  pci_read_config_word(0, slot, function, PCI_COMMAND, &data);
+  data |= PCI_COMMAND_IO;
+  pci_write_config_word(0, slot, function, PCI_COMMAND, data );
+}
+
+void pci_busmaster_enable(
+  unsigned char bus,
+  unsigned char slot,
+  unsigned char function
+)
+{
+  uint16_t data;
+
+  pci_read_config_word(0, slot, function, PCI_COMMAND, &data);
+  data |= PCI_COMMAND_MASTER;
+  pci_write_config_word(0, slot, function, PCI_COMMAND, data );
+}
+
+/*
+ * This routine determines the maximum bus number in the system
+ */
+int pci_initialize(void)
+{
+  unsigned char slot, func, ucNumFuncs;
+  unsigned char ucHeader;
+  uint32_t class;
+  uint32_t device;
+  uint32_t vendor;
+
+  /*
+   * Initialize GT_PCI0IOREMAP
+   */
+  pci_out_32( BSP_PCI_BASE_ADDRESS, 0xf0, 0 );
+
+  /*
+   *  According to Linux and BSD sources, this is needed to cover up a bug
+   *  in some versions of the hardware.
+   */
+  out_le32( PCI_CONFIG_ADDR, 0x80000020 );
+  out_le32( PCI_CONFIG_DATA, 0x1be00000 );
+
+  /*
+   * Scan PCI bus 0 looking for the known Network devices and
+   * initializing the PCI for them.
+   */
+  for (slot=0;slot<PCI_MAX_DEVICES;slot++) {
+    pci_read_config_dword(0, slot, 0, PCI_VENDOR_ID, &device);
+    if (device == PCI_INVALID_VENDORDEVICEID) {
+      /* This slot is empty */
+      continue;
+    }
+
+    pci_read_config_byte(0, slot, 0, PCI_HEADER_TYPE, &ucHeader);
+    if (ucHeader & PCI_MULTI_FUNCTION)  {
+      ucNumFuncs = PCI_MAX_FUNCTIONS;
+    } else {
+      ucNumFuncs=1;
+    }
+    for (func=0;func<ucNumFuncs;func++) {
+      pci_read_config_dword(0, slot, func, PCI_VENDOR_ID, &device);
+       if (device==PCI_INVALID_VENDORDEVICEID) {
+        /* This slot/function is empty */
+        continue;
+      }
+      vendor = device & 0xffff;
+      device = device >> 16;
+
+      /* This slot/function has a device fitted. */
+      pci_read_config_dword(0, slot, func, PCI_CLASS_REVISION, &class);
+      class >>= 16;
+
+      // printk( "FOUND DEVICE 0x%04x/0x%04x class 0x%x\n",
+      //          vendor, device, class );
+      if (class == PCI_CLASS_NETWORK_ETHERNET) {
+        JPRINTK("FOUND ETHERNET\n");
+
+        pci_write_config_byte(
+            0, slot, func, PCI_INTERRUPT_LINE, MALTA_IRQ_ETHERNET );
+
+        /*
+         * Rewrite BAR1 for RTL8139
+         */
+        if ( vendor == PCI_VENDOR_ID_REALTEK &&
+             device == PCI_DEVICE_ID_REALTEK_8139 ) {
+
+          pci_memory_enable(0, slot, func);
+          pci_io_enable(0, slot, func);
+          pci_busmaster_enable(0, slot, func);
+
+          // BAR0: IO at 0x0000_1001
+          pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_0, 0x00001001);
+
+          // BAR1: Memory at 0x1203_1000
+          pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_1, 0x12031000);
+
+          // print_bars( slot, func );
+       } else if ( vendor == PCI_VENDOR_ID_AMD &&
+                   device == PCI_DEVICE_ID_AMD_LANCE ) {
+         print_bars( slot, func );
+         pci_memory_enable(0, slot, func);
+         pci_io_enable(0, slot, func);
+         pci_busmaster_enable(0, slot, func);
+
+         // BAR0: IO at 0x0000_1041
+         pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_0, 0x00001041);
+
+         // BAR1: Memory at 0x1201_1020
+         pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_1, 0x12011020);
+         print_bars( slot, func );
+       }
+
+      }
+    }
+  }
+  return PCIB_ERR_SUCCESS;
+}
+
+/*
+ * Return the number of PCI busses in the system
+ */
+unsigned char pci_bus_count(void)
+{
+  return (ucMaxPCIBus+1);
+}
diff --git a/c/src/lib/libbsp/mips/malta/pci/pcifinddevice.c b/c/src/lib/libbsp/mips/malta/pci/pcifinddevice.c
new file mode 100644
index 0000000..2ef4eaf
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/pci/pcifinddevice.c
@@ -0,0 +1,279 @@
+/**
+ *  @file
+ *
+ *  This file was copied from the powerpc and modified slightly.
+ *  I think this file could be made generic and put in a general pci
+ *  area.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+/* find a particular PCI device
+ * (we assume, the firmware configured the PCI bus[es] for us)
+ */
+
+/*
+ * Authorship
+ * ----------
+ * This software was created by
+ *     Till Straumann <strauman at slac.stanford.edu>, 2001,
+ *      Stanford Linear Accelerator Center, Stanford University.
+ *
+ * Acknowledgement of sponsorship
+ * ------------------------------
+ * This software was produced by
+ *     the Stanford Linear Accelerator Center, Stanford University,
+ *      under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ *
+ * Government disclaimer of liability
+ * ----------------------------------
+ * Neither the United States nor the United States Department of Energy,
+ * nor any of their employees, makes any warranty, express or implied, or
+ * assumes any legal liability or responsibility for the accuracy,
+ * completeness, or usefulness of any data, apparatus, product, or process
+ * disclosed, or represents that its use would not infringe privately owned
+ * rights.
+ *
+ * Stanford disclaimer of liability
+ * --------------------------------
+ * Stanford University makes no representations or warranties, express or
+ * implied, nor assumes any liability for the use of this software.
+ *
+ * Stanford disclaimer of copyright
+ * --------------------------------
+ * Stanford University, owner of the copyright, hereby disclaims its
+ * copyright and all other rights in this software.  Hence, anyone may
+ * freely use it for any purpose without restriction.
+ *
+ * Maintenance of notices
+ * ----------------------
+ * In the interest of clarity regarding the origin and status of this
+ * SLAC software, this and all the preceding Stanford University notices
+ * are to remain affixed to any copy or derivative of this software made
+ * or distributed by the recipient and are to be affixed to any copy of
+ * software made or distributed by the recipient that contains a copy or
+ * derivative of this software.
+ *
+ * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
+ */
+#define PCI_INVALID_VENDORDEVICEID  0xffffffff
+#define PCI_MULTI_FUNCTION      0x80
+
+#define PCI_DEBUG
+
+#include <inttypes.h>
+#include <bsp/pci.h>
+#include <rtems/bspIo.h>
+#include <stdio.h>
+
+/* Stolen from i386... */
+
+/*
+ * Make device signature from bus number, device number and function
+ * number
+ */
+#define PCIB_DEVSIG_MAKE(b,d,f) ((b<<8)|(d<<3)|(f))
+
+/*
+ * Extract various parts from device signature
+ */
+#define PCIB_DEVSIG_BUS(x) (((x)>>8) &0xff)
+#define PCIB_DEVSIG_DEV(x) (((x)>>3) & 0x1f)
+#define PCIB_DEVSIG_FUNC(x) ((x) & 0x7)
+
+typedef struct {
+  unsigned short  vid,did;
+  int             inst;
+} fd_arg;
+
+static int find_dev_cb(
+  int bus,
+  int dev,
+  int fun,
+  void *uarg
+)
+{
+  fd_arg         *a = uarg;
+  unsigned short  vendor;
+  unsigned short  device;
+
+  pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&vendor);
+  pci_read_config_word(bus,dev,fun,PCI_DEVICE_ID,&device);
+  printk("  FOUND: Vendor 0x%x Device: 0x%x\n", vendor, device);
+
+  if (a->vid == vendor) {
+    if (a->did == device && 0 == a->inst-- ) {
+      a->inst = PCIB_DEVSIG_MAKE( bus, dev, fun );
+      return 1;
+    }
+  }
+  return 0;
+}
+
+int  pci_find_device(
+  unsigned short vendorid,
+  unsigned short deviceid,
+  int instance,
+  int *pbus,
+  int *pdev,
+  int *pfun
+)
+{
+  fd_arg a;
+  void   *h;
+
+  a.vid  = vendorid;
+  a.did  = deviceid;
+  a.inst = instance;
+
+  if ( (h = BSP_pciScan(0, find_dev_cb, (void*)&a)) ) {
+    *pbus = PCIB_DEVSIG_BUS(  a.inst );
+    *pdev = PCIB_DEVSIG_DEV(  a.inst );
+    *pfun = PCIB_DEVSIG_FUNC( a.inst );
+    return 0;
+  }
+
+  return -1;
+}
+
+static int dump_dev_cb(
+  int  bus,
+  int  dev,
+  int  fun,
+  void *uarg
+)
+{
+  uint16_t vi,di;
+  uint16_t cd,st;
+  uint32_t b1,b2;
+  uint8_t  il,ip;
+  FILE     *f = uarg;
+
+  pci_read_config_word (bus, dev, fun, PCI_VENDOR_ID,      &vi);
+  pci_read_config_word (bus, dev, fun, PCI_DEVICE_ID,      &di);
+  pci_read_config_word (bus, dev, fun, PCI_COMMAND,        &cd);
+  pci_read_config_word (bus, dev, fun, PCI_STATUS,         &st);
+  pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_0, &b1);
+  pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_1, &b2);
+  pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_LINE, &il);
+  pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_PIN,  &ip);
+
+  fprintf(
+    f,
+    "%3d:0x%02x:%d    0x%04x-0x%04x:  0x%04x 0x%04x 0x%08" PRIx32
+    " 0x%08" PRIx32 "       %d -> %3d (=0x%02x)\n",
+    bus,
+    dev,
+    fun,
+    vi,
+    di,
+    cd,
+    st,
+    b1,
+    b2,
+    ip,
+    il,
+    il
+  );
+  return 0;
+}
+
+void BSP_pciConfigDump(FILE *f)
+{
+  if ( !f )
+    f = stdout;
+  fprintf(
+    f,
+    "BUS:SLOT:FUN  VENDOR-DEV_ID: COMMAND STATUS BASE_ADDR0 BASE_ADDR1 "
+    "IRQ_PIN -> IRQ_LINE\n"
+  );
+  BSP_pciScan(0, dump_dev_cb, f);
+}
+
+BSP_PciScanHandle BSP_pciScan(
+  BSP_PciScanHandle handle,
+  BSP_PciScannerCb cb,
+  void *uarg
+) {
+
+  uint32_t d;
+  unsigned char bus,dev,fun,hd;
+
+  bus = PCIB_DEVSIG_BUS(  (unsigned long)handle );
+  dev = PCIB_DEVSIG_DEV(  (unsigned long)handle );
+  fun = PCIB_DEVSIG_FUNC( (unsigned long)handle );
+
+  hd = fun > 0 ? PCI_MAX_FUNCTIONS : 1;
+
+  for (; bus<pci_bus_count(); bus++, dev=0) {
+    for (; dev<PCI_MAX_DEVICES; dev++, fun=0) {
+      for (; fun<hd; fun++) {
+        /*
+         * The last devfn id/slot is special; must skip it
+         */
+        if (PCI_MAX_DEVICES-1==dev && PCI_MAX_FUNCTIONS-1 == fun)
+          break;
+
+        (void)pci_read_config_dword(bus,dev,0,PCI_VENDOR_ID,&d);
+        if (PCI_INVALID_VENDORDEVICEID == d)
+          continue;
+        #ifdef PCI_DEBUG
+          printk(
+            "BSP_pciScan: Read _config_dword bus %d "
+            "dev 0x%x value 0x%2x\n",
+            bus,
+            dev,
+            d
+          );
+        #endif
+
+        if ( 0 == fun ) {
+          pci_read_config_byte(bus,dev,0, PCI_HEADER_TYPE, &hd);
+          #ifdef PCI_DEBUG
+            printk(
+              "BSP_pciScan: Read _config_byte bus %d dev 0x%x "
+              "fun %d value 0x%2x\n",
+              bus,
+              dev,
+              fun,
+              d
+            );
+          #endif
+          hd = (hd & PCI_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1);
+        }
+
+        (void)pci_read_config_dword(bus,dev,fun,PCI_VENDOR_ID,&d);
+        if (PCI_INVALID_VENDORDEVICEID == d)
+          continue;
+        #ifdef PCI_DEBUG
+          printk("BSP_pciScan: found 0x%08x at %d/x%02x/%d\n",d,bus,dev,fun);
+        #endif
+        if ( cb(bus,dev,fun,uarg) > 0 ) {
+          if ( ++fun >= hd ) {
+            fun = 0;
+            if ( ++dev >= PCI_MAX_DEVICES ) {
+              dev = 0;
+              bus++;
+            }
+          }
+          #ifdef PCI_DEBUG
+            printk(
+              "BSP_pciScan: Going to Return: bus %d dev 0x%x fun %d\n",
+              bus,
+              dev,
+              fun
+            );
+          #endif
+          return (void*) PCIB_DEVSIG_MAKE(bus,dev,fun);
+        }
+      }
+    }
+  }
+  return 0;
+}
diff --git a/c/src/lib/libbsp/mips/malta/pci/pcilistdevices.c b/c/src/lib/libbsp/mips/malta/pci/pcilistdevices.c
new file mode 100644
index 0000000..bc9907e
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/pci/pcilistdevices.c
@@ -0,0 +1,105 @@
+/**
+ *  @file
+ *
+ *  I think this file could be made generic and put in a general pci
+ *  area.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+/*
+ * List all PCI Devices
+ */
+
+#define PCI_INVALID_VENDORDEVICEID  0xffffffff
+#define PCI_MULTI_FUNCTION      0x80
+
+#define PCI_DEBUG
+
+#include <inttypes.h>
+#include <bsp/pci.h>
+#include <rtems/bspIo.h>
+#include <stdio.h>
+
+/*
+ * Make device signature from bus number, device number and function
+ * number
+ */
+#define PCIB_DEVSIG_MAKE(b,d,f) ((b<<8)|(d<<3)|(f))
+
+/*
+ * Extract various parts from device signature
+ */
+#define PCIB_DEVSIG_BUS(x) (((x)>>8) &0xff)
+#define PCIB_DEVSIG_DEV(x) (((x)>>3) & 0x1f)
+#define PCIB_DEVSIG_FUNC(x) ((x) & 0x7)
+
+static int print_device_config(
+   int bus,
+   int dev,
+   int fun
+)
+{
+  uint16_t vi,di;
+  uint16_t cd,st;
+  uint32_t b1,b2;
+  uint8_t  il,ip;
+
+  pci_read_config_word (bus, dev, fun, PCI_VENDOR_ID,      &vi);
+  pci_read_config_word (bus, dev, fun, PCI_DEVICE_ID,      &di);
+  pci_read_config_word (bus, dev, fun, PCI_COMMAND,        &cd);
+  pci_read_config_word (bus, dev, fun, PCI_STATUS,         &st);
+  pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_0, &b1);
+  pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_1, &b2);
+  pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_LINE, &il);
+  pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_PIN,  &ip);
+
+  printk(
+    "%3d:0x%02x:%d    0x%04x-0x%04x:  0x%04x 0x%04x 0x%08" PRIx32
+        " 0x%08" PRIx32 "       %d -> %3d (=0x%02x)\n",
+     bus, dev, fun, vi, di, cd, st, b1, b2, ip, il, il);
+  return 0;
+}
+
+void pci_list_devices( void )
+{
+   uint32_t d;
+   unsigned char bus,dev,fun,hd;
+
+  printk(
+    "BUS:SLOT:FUN  VENDOR-DEV_ID: COMMAND STATUS BASE_ADDR0 "
+    "BASE_ADDR1 IRQ_PIN -> IRQ_LINE\n"
+  );
+  for (bus=0 ; bus<pci_bus_count(); bus++) {
+    for (dev=0 ; dev<PCI_MAX_DEVICES; dev++) {
+      for (fun=0 ; fun<PCI_MAX_FUNCTIONS; fun++) {
+        /*
+         * The last devfn id/slot is special; must skip it
+         */
+        if (PCI_MAX_DEVICES-1==dev && PCI_MAX_FUNCTIONS-1 == fun)
+          break;
+
+        (void) pci_read_config_dword(bus,dev,0,PCI_VENDOR_ID,&d);
+        if (PCI_INVALID_VENDORDEVICEID == d)
+          continue;
+
+        if ( 0 == fun ) {
+          pci_read_config_byte(bus,dev,0, PCI_HEADER_TYPE, &hd);
+          hd = (hd & PCI_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1);
+        }
+
+        (void)pci_read_config_dword(bus,dev,fun,PCI_VENDOR_ID,&d);
+        if (PCI_INVALID_VENDORDEVICEID == d)
+          continue;
+        print_device_config( bus, dev, fun );
+      }
+    }
+  }
+}
diff --git a/c/src/lib/libbsp/mips/malta/preinstall.am b/c/src/lib/libbsp/mips/malta/preinstall.am
new file mode 100644
index 0000000..8d22a8c
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/preinstall.am
@@ -0,0 +1,91 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+	$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES += $(PREINSTALL_DIRS)
+
+all-local: $(TMPINSTALL_FILES)
+
+TMPINSTALL_FILES =
+CLEANFILES = $(TMPINSTALL_FILES)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES += $(PREINSTALL_FILES)
+
+$(PROJECT_LIB)/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_LIB)
+	@: > $(PROJECT_LIB)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
+
+$(PROJECT_INCLUDE)/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_INCLUDE)
+	@: > $(PROJECT_INCLUDE)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
+
+$(PROJECT_INCLUDE)/bsp/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_INCLUDE)/bsp
+	@: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+
+$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs
+PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs
+
+$(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h
+
+$(PROJECT_INCLUDE)/tm27.h: ../../shared/include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h
+
+$(PROJECT_INCLUDE)/bsp/regs.h: ../shared/liblnk/regs.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/regs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/regs.h
+
+$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
+
+$(PROJECT_INCLUDE)/bsp/irq-info.h: ../../shared/include/irq-info.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-info.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h
+
+$(PROJECT_INCLUDE)/bsp/irq.h: include/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
+
+$(PROJECT_INCLUDE)/bsp/pci.h: include/pci.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/pci.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/pci.h
+
+$(PROJECT_INCLUDE)/bsp/i8259.h: ../shared/irq/i8259.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/i8259.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/i8259.h
+
+$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bspopts.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h
+
+$(PROJECT_INCLUDE)/bsp/bootcard.h: ../../shared/include/bootcard.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bootcard.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bootcard.h
+
+$(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
+
+$(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT)
+TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT)
+
+$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds
+PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds
+
diff --git a/c/src/lib/libbsp/mips/malta/start/start.S b/c/src/lib/libbsp/mips/malta/start/start.S
new file mode 100644
index 0000000..468a43b
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/start/start.S
@@ -0,0 +1,220 @@
+/*
+ * start.S -- startup file for JMR3904 BSP based upon crt0.S from
+ * newlib-1.8.2/libgloss/mips and adapted for RTEMS.
+ *
+ * crt0.S -- startup file for MIPS.
+ *
+ * Copyright (c) 1995, 1996, 1997 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <rtems/asm.h>
+#include <bsp/regs.h>
+
+#ifdef __mips16
+/* This file contains 32 bit assembly code.  */
+	.set nomips16
+#endif
+
+/* This is for referencing addresses that are not in the .sdata or
+   .sbss section under embedded-pic, or before we've set up gp.  */
+#ifdef __mips_embedded_pic
+# ifdef __mips64
+#  define LA(t,x) la t,x-PICBASE ; daddu t,s0,t
+# else
+#  define LA(t,x) la t,x-PICBASE ; addu t,s0,t
+# endif
+#else /* __mips_embedded_pic */
+# define LA(t,x) la t,x
+#endif /* __mips_embedded_pic */
+
+	.text
+	.align	2
+
+/* Without the following nop, GDB thinks _start is a data variable.
+ * This is probably a bug in GDB in handling a symbol that is at the
+ * start of the .text section.
+ */
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	.globl	_start
+	.ent	_start
+_start:
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	.set	noreorder
+	/* Get the address of start into $5 in a position independent fashion.
+	** This lets us know whether we have been relocated or not.
+	*/
+	$LF1 = . + 8
+	bal     $LF1
+	nop
+_branch:
+#if 0
+	move	$5, $31				# $5 == where are we
+	li	$6, 0x8800000c			# $6 == where we want to be
+/*	#la      $6,_branch */
+	beq	$5, $6, _start_in_ram
+	nop
+	/* relocate the code from EEPROM to RAM */
+        la	$7, _edata
+relocate:
+        nop
+	lw	$8, ($5)			# $8 = *EEPROM
+	addu	$5, $5, 4			# EEPROM++
+        sw      $8, ($6)			# *RAM = $8
+	addu	$6, $6, 4			# RAM++
+	bne	$6, $7, relocate		# copied all the way to edata?
+	nop
+	la	$6, _start_in_ram
+	jr	$6
+	nop
+	.end _start
+
+	.globl	_start_in_ram
+	.ent _start_in_ram
+#endif
+_start_in_ram:
+	nop
+#if 0
+#ifdef __mips_embedded_pic
+	PICBASE = .+8
+        bal	PICBASE
+	nop
+	move	s0,$31
+#endif
+#endif
+	li	v0, SR_CU1|SR_PE|SR_FR|SR_KX|SR_SX|SR_UX
+	mtc0	v0, C0_SR
+	mtc0	zero, C0_CAUSE
+
+#if 0
+/* Check for FPU presence */
+#ifndef __mips_soft_float
+/* This doesn't work if there is no FPU.  We get illegal instruction
+   exceptions.  */
+	li	t2,0xAAAA5555
+	mtc1	t2,fp0		/* write to FPR 0 */
+	mtc1	zero,fp1	/* write to FPR 1 */
+	mfc1	t0,fp0
+	mfc1	t1,fp1
+	nop
+	bne	t0,t2,1f	/* check for match */
+	nop
+	bne	t1,zero,1f	/* double check */
+	nop
+#ifndef __mips64  /* Clear the FR bit */
+	li	v0, SR_CU1|SR_PE|SR_KX|SR_SX|SR_UX
+	mtc0	v0, C0_SR
+#endif
+	j	2f
+	nop
+#endif
+#endif
+
+1:
+	li	v0, SR_PE|SR_FR|SR_KX|SR_SX|SR_UX
+	mtc0	v0, C0_SR
+2:
+/* Fix high bits, if any, of the PC so that exception handling
+   doesn't get confused.  */
+	LA (v0, 3f)
+	jr	v0
+	nop
+3:
+	LA (gp, _gp)				# set the global data pointer
+#if 0
+	.end _start_in_ram
+#else
+	.end _start
+#endif
+
+/*
+ * zero out the bss section.
+ */
+	.globl	__memsize
+	.globl	zerobss
+	.ent	zerobss
+zerobss:
+	LA (v0, _fbss)
+	LA (v1, _end)
+3:
+	sw	zero,0(v0)
+	bltu	v0,v1,3b
+	addiu	v0,v0,4				# executed in delay slot
+
+	la	t0, _stack_init			# initialize stack so we
+	/* We must subtract 24 bytes for the 3 8 byte arguments to main, in
+	   case main wants to write them back to the stack.  The caller is
+	   supposed to allocate stack space for parameters in registers in
+	   the old MIPS ABIs.  We must do this even though we aren't passing
+	   arguments, because main might be declared to have them.
+
+	   Some ports need a larger alignment for the stack, so we subtract
+	   32, which satisifes the stack for the arguments and keeps the
+	   stack pointer better aligned.  */
+	subu	t0,t0,32
+	move	sp,t0				# set stack pointer
+	.end	zerobss
+
+	.globl	exit .text
+	.globl	init
+	.ent	init
+init:
+        nop
+	jal	init_tlb		/* clear the tlb */
+	move	a0,zero				# set command line to 0
+	jal	boot_card			# call the program start function
+	nop
+
+dead:
+	b	dead
+	nop
+	.end	init
+
+/*
+ * _sys_exit -- Exit from the application. Normally we cause a user trap
+ *          to return to the ROM monitor for another run. NOTE: This is
+ *	    the only other routine we provide in the crt0.o object, since
+ *          it may be tied to the "_start" routine. It also allows
+ *          executables that contain a complete world to be linked with
+ *          just the crt0.o object.
+ */
+	.globl	_sys_exit
+	.ent _sys_exit
+_sys_exit:
+7:
+#ifdef GCRT0
+	jal	_mcleanup
+	nop
+#endif
+	/* break instruction can cope with 0xfffff, but GAS limits the range: */
+	break	1023
+	nop
+	b	7b				# but loop back just in-case
+	nop
+	.end _sys_exit
+
+/* EOF crt0.S */
diff --git a/c/src/lib/libbsp/mips/malta/startup/bspreset.c b/c/src/lib/libbsp/mips/malta/startup/bspreset.c
new file mode 100644
index 0000000..519dd28
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/startup/bspreset.c
@@ -0,0 +1,35 @@
+/**
+ *  @file
+ *
+ *  This file contains the code necessary to reset the Malta board.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+#include <rtems.h>
+
+void bsp_reset(void);
+
+void bsp_reset(void)
+{
+  uint32_t *reset;
+
+  reset= (uint32_t *)0x9F000500;
+  /*
+   * Qemu understands 0x42 to reset simulated machine.
+   * We added code to recognize 0xFF to exit simulator.
+   *
+   * TBD: Qemu PC simulation has option to exit on reset.
+   *      find processing of that command line option and
+   *      use it to change behaviour of 0x42.
+   */
+  // *reset = 0x42;
+  *reset = 0xFF;
+}
diff --git a/c/src/lib/libbsp/mips/malta/startup/bspstart.c b/c/src/lib/libbsp/mips/malta/startup/bspstart.c
new file mode 100644
index 0000000..3767e09
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/startup/bspstart.c
@@ -0,0 +1,113 @@
+/**
+ *  @file
+ *
+ *  This file contains the bsp_start() method and support.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <libcpu/isr_entries.h>
+#include <bsp/bootcard.h>
+#include <rtems/pci.h>
+#include <bsp/irq-generic.h>
+#include <bsp/i8259.h>
+
+/*
+ * STRUCTURES
+ */
+
+/* Structure filled in by get_mem_info.  Only the size field is
+ * actually used (to clear bss), so the others aren't even filled in.
+ */
+struct s_mem
+{
+  unsigned int size;
+  unsigned int icsize;
+  unsigned int dcsize;
+};
+
+
+/*
+ * GLOBALS
+ */
+uint32_t bsp_clicks_per_microsecond;
+
+
+/*
+ * PROTOTYPES
+ */
+void clear_cache( void *address, size_t n );
+void get_mem_info( struct s_mem *mem );
+
+/*
+ * EXTERNs
+ */
+extern int RamSize;
+
+/*
+ *  bsp_start
+ *
+ *  This routine does the bulk of the system initialization.
+ */
+void bsp_start( void )
+{
+  /* uint32_t  board_ID = 0x420; */
+  static    int j = 1;
+  int       pci_init_retval;
+
+  /*
+   * Note: This is the value that works for qemu, and it was
+   * unable to be validated on the actual hardware.
+   */
+  mips_set_sr( 0x04100000 );
+
+  bsp_interrupt_initialize();
+
+  /*
+   *  XXX need to figure out a real value. :)
+   *  This works for the qemu simulation, but timeing may
+   *  be off for the actual hardware.
+   */
+  bsp_clicks_per_microsecond = 100;
+
+  #if 1
+  while ( j != 1 ) {
+    int i;
+    printk (".");
+    for (i=0; i<1000; i++);
+  }
+  #endif
+
+  /*
+   * init PCI Bios interface...
+   */
+  pci_init_retval = pci_initialize();
+  if (pci_init_retval != PCIB_ERR_SUCCESS) {
+      printk("PCI bus: could not initialize PCI BIOS interface\n");
+  }
+
+  BSP_i8259s_init();
+
+}
+
+/*
+ *  Required routine by some gcc run-times.
+ */
+void clear_cache( void *address, size_t n )
+{
+}
+
+void get_mem_info(
+  struct s_mem *mem
+)
+{
+  mem->size = (int) (&RamSize); /* Normally 128 or 256 MB */
+}
diff --git a/c/src/lib/libbsp/mips/malta/startup/inittlb.c b/c/src/lib/libbsp/mips/malta/startup/inittlb.c
new file mode 100644
index 0000000..413783c
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/startup/inittlb.c
@@ -0,0 +1,26 @@
+/**
+ *  @file
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+#include <rtems/mips/idtcpu.h>
+
+extern void resettlb( int i );
+
+void init_tlb(void);
+
+void init_tlb(void)
+{
+  int i;
+
+  for (i = 0; i < N_TLB_ENTRIES; i++ )
+    resettlb(i);
+}
diff --git a/c/src/lib/libbsp/mips/malta/startup/linkcmds b/c/src/lib/libbsp/mips/malta/startup/linkcmds
new file mode 100644
index 0000000..e52d3b8
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/startup/linkcmds
@@ -0,0 +1,181 @@
+/*
+ *  MIPS Malta Linker Script
+ */
+
+/*
+ * Declare some sizes.
+ */
+RamBase = DEFINED(RamBase) ? RamBase : 0x80000000;
+RamSize = DEFINED(RamSize) ? RamSize : 128M;
+HeapSize = DEFINED(HeapSize) ? HeapSize : 0x0;
+_StackSize = DEFINED(_StackSize) ? _StackSize : 0x2000;
+
+SECTIONS
+{ 
+    . = 0x80010000;
+    .text : 
+    { 
+       _ftext = . ;
+       eprol  =  .;
+      *(.text*)
+      *(.gnu.linkonce.t*)
+      *(.mips16.fn.*)
+      *(.mips16.call.*)
+      PROVIDE (__runtime_reloc_start = .);
+      *(.rel.sdata)
+      PROVIDE (__runtime_reloc_stop = .);
+
+      /*
+       * Special FreeBSD sysctl sections.
+       */
+      . = ALIGN (16);
+      __start_set_sysctl_set = .;
+      *(set_sysctl_*);
+      __stop_set_sysctl_set = ABSOLUTE(.);
+      *(set_domain_*);
+      *(set_pseudo_*);
+
+      *(.gcc_except_table*)
+      *(.eh_frame_hdr)
+      *(.eh_frame)
+    }
+
+  .init :
+  {
+	KEEP(*(.init))
+  }
+
+  .fini :
+  {
+	KEEP(*(.fini))
+  }
+
+  .ctors    :
+  {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+
+    KEEP (*crtbegin.o(.ctors))
+
+    /* We don't want to include the .ctor section from
+       from the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+
+  .dtors    :
+  {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+
+    etext  =  .;
+    _etext  =  .;
+  }
+
+  .rdata : {
+    *(.rdata)
+    *(.rodata)
+    *(.rodata.*)
+    *(.gnu.linkonce.r*)
+  }
+   _fdata = ALIGN(16);
+
+  .data : {
+    *(.data)
+    *(.data.*)
+    *(.gnu.linkonce.d*)
+    SORT(CONSTRUCTORS)
+  }
+  . = ALIGN(8);
+
+  .jcr : {
+	KEEP (*(.jcr))
+  }
+
+  _gp = ALIGN(16) + 0x7440;
+  __global = _gp;
+
+  .sdata : {
+    *(.sdata)
+    *(.sdata.*)
+    *(.gnu.linkonce.s*)
+  }
+  .lit8 : {
+    *(.lit8)
+  }
+  .lit4 : {
+    *(.lit4)
+  }
+
+   edata  =  .;
+   _edata  =  .;
+   _fbss = .;
+
+  .sbss : {
+    *(.sbss*)
+    *(.scommon)
+  }
+  .bss : {
+    _bss_start = . ;
+    *(.bss*)
+    *(COMMON)
+    . = ALIGN (64);
+    _stack_limit = .;
+    . += _StackSize;
+    __stack = .;
+    _stack_init = .;
+    WorkAreaBase = .;
+    _clear_end = .;
+  }
+  . = 0x88400000; /* reserve some memory for Work Area */
+ end = .;
+ _end = .;
+
+
+/* Put starting stack in SRAM (8 Kb); this size is the same as the stack from
+      the original script (when everything was in SRAM). */
+   /* __stack = 0x8000A000; */
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to
+     the beginning of the section so we begin them at 0.  */
+
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+}
diff --git a/c/src/lib/libbsp/mips/malta/startup/simple_access.c b/c/src/lib/libbsp/mips/malta/startup/simple_access.c
new file mode 100644
index 0000000..abc1f88
--- /dev/null
+++ b/c/src/lib/libbsp/mips/malta/startup/simple_access.c
@@ -0,0 +1,133 @@
+/**
+ *  @file
+ *
+ *  This file contains the code to do simple memory and io accesses.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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.com/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+
+#include <bsp/pci.h>
+#include <bsp/irq.h>
+#include <rtems/bspIo.h>
+#include <rtems/endian.h>
+// #define DEBUG_ACCESSES   1
+
+#ifdef DEBUG_ACCESSES
+  #define JPRINTK(fmt, ...) printk("%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
+#else
+  #define JPRINTK(fmt, ...)
+#endif
+
+/*
+ *  *  Simple accesses
+ *   */
+void simple_out_32(uint32_t base, uint32_t addr, uint32_t val)
+{
+  volatile uint32_t *ptr;
+
+  ptr = (volatile uint32_t *) (base + addr);
+  *ptr = val;
+
+  JPRINTK( "%p data: 0x%x\n", ptr, val);
+}
+
+void simple_out_le32(uint32_t base, uint32_t addr, uint32_t val)
+{
+  volatile uint32_t *ptr;
+  uint32_t           data = 0;
+
+  ptr = (volatile uint32_t *) (base + addr);
+  rtems_uint32_to_little_endian( val, (uint8_t *) &data);
+  *ptr = data;
+
+  JPRINTK( "%p data: 0x%x\n", ptr, data);
+}
+
+uint8_t simple_in_8( uint32_t base, uint32_t addr ) {
+  volatile uint8_t *ptr;
+  uint8_t           val;
+
+  ptr = (volatile uint8_t *) (base + addr);
+  val = *ptr;
+  JPRINTK( "0x%x data: 0x%x\n", ptr, val);
+
+  return val;
+}
+
+int16_t simple_in_le16( uint32_t base, uint32_t addr ) {
+  volatile uint16_t *ptr;
+  uint16_t           val;
+  uint16_t           rval;
+
+  ptr = (volatile uint16_t *) (base + addr);
+  val = *ptr;
+  rval = rtems_uint16_from_little_endian( (uint8_t *) &val);
+  JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, rval, val);
+  return rval;
+}
+
+int16_t simple_in_16( uint32_t base, uint32_t addr ) {
+  volatile uint16_t *ptr;
+  uint16_t           val;
+
+  ptr = (volatile uint16_t *) (base + addr);
+  val = *ptr;
+  JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, val);
+  return val;
+}
+
+uint32_t simple_in_le32( uint32_t base, uint32_t addr ) {
+  volatile uint32_t *ptr;
+  uint32_t           val;
+  uint32_t           rval;
+
+  ptr = (volatile uint32_t *) (base + addr);
+  val = *ptr;
+  rval = rtems_uint32_from_little_endian( (uint8_t *) &val);
+  JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, rval, val);
+  return rval;
+}
+
+uint32_t simple_in_32( uint32_t base, uint32_t addr ) {
+  volatile uint32_t *ptr;
+  uint32_t           val;
+
+  ptr = (volatile uint32_t *) (base + addr);
+  val = *ptr;
+  JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, val);
+  return val;
+}
+
+void simple_out_8( uint32_t base, uint32_t addr, uint8_t val ) {
+  volatile uint8_t *ptr;
+
+  ptr = (volatile uint8_t *) (base | addr);
+  JPRINTK( "0x%x data: 0x%x\n", ptr, val);
+  *ptr = val;
+}
+
+void simple_out_le16( uint32_t base, uint32_t addr, uint16_t val ) {
+  volatile uint16_t *ptr;
+  uint16_t           data;
+  ptr = (volatile uint16_t *) (base + addr);
+  rtems_uint16_to_little_endian( val, (uint8_t *) &data);
+  *ptr = data;
+  JPRINTK( "0x%x data: 0x%x\n", ptr, data);
+}
+
+void simple_out_16( uint32_t base, uint32_t addr, uint16_t val ) {
+  volatile uint16_t *ptr;
+  ptr = (volatile uint16_t *) (base + addr);
+  *ptr = val;
+  JPRINTK( "0x%x data: 0x%x\n", ptr, val);
+}




More information about the vc mailing list