[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