summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2007-07-04 12:37:36 +0000
committerThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2007-07-04 12:37:36 +0000
commit862c231785024acbd6c830fb30e0a6a64e6c3318 (patch)
treefc09530e45e5436192c6286e70b912fbff8bcf16 /c
parentmerged individual exception handler code to a common one. (diff)
downloadrtems-862c231785024acbd6c830fb30e0a6a64e6c3318.tar.bz2
added virtex BSP support and some missing files for common PPC
exception handling
Diffstat (limited to '')
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/ChangeLog13
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/Makefile.am99
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/README91
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/bsp_specs15
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/bsp_specs.dl23
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/console/consolelite.c366
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/dlentry/dlentry.S156
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/include/bsp.h123
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/include/bspopts.h.in33
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/include/coverhd.h133
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/include/opbintctrl.h90
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/include/tm27.h32
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/include/xparameters_dflt.h193
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/irq/irq.h99
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/irq/irq_init.c421
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/network/xiltemac.c966
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/network/xiltemac.h375
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/opbintctrl/opbintctrl.c143
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/preinstall.am79
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/startup/bspclean.c43
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c277
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/startup/linkcmds169
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/startup/linkcmds.dl154
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/startup/setvec.c56
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/asm_utils.S63
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.c501
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.h324
-rw-r--r--c/src/lib/libcpu/powerpc/ppc403/irq/ictrl.c292
-rw-r--r--c/src/lib/libcpu/powerpc/ppc403/irq/ictrl.h95
29 files changed, 5424 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/virtex/ChangeLog b/c/src/lib/libbsp/powerpc/virtex/ChangeLog
new file mode 100644
index 0000000000..89b08f5ef0
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/ChangeLog
@@ -0,0 +1,13 @@
+2007-04-1 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+
+ * bsp_specs, bsp_specs.dl, ChangeLog, configure.ac,
+ * console/consolelite.c, dlentry/dlentry.S, include/bsp.h,
+ * include/coverhd.h, include/opbintctrl.h, include/tm27.h,
+ * include/xparameters_dflt.h, irq/irq.h, irq/irq_init.c,
+ * Makefile.am, network/xiltemac.c, network/xiltemac.h,
+ * opbintctrl/opbintctrl.c, preinstall.am, README,
+ * startup/bspclean.c, startup/bspstart.c, startup/linkcmds,
+ * startup/linkcmds.dl, startup/setvec.c;
+
+ integration of virtex BSP into RTEMS source tree
+
diff --git a/c/src/lib/libbsp/powerpc/virtex/Makefile.am b/c/src/lib/libbsp/powerpc/virtex/Makefile.am
new file mode 100644
index 0000000000..a0695cc434
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/Makefile.am
@@ -0,0 +1,99 @@
+##
+## $Id$
+##
+
+ACLOCAL_AMFLAGS = -I ../../../../aclocal
+
+include $(top_srcdir)/../../../../automake/compile.am
+include $(top_srcdir)/../../bsp.am
+
+dist_project_lib_DATA = bsp_specs
+
+include_HEADERS = include/bsp.h
+include_HEADERS += include/tm27.h
+
+nodist_include_HEADERS = include/bspopts.h
+DISTCLEANFILES = include/bspopts.h
+
+noinst_PROGRAMS =
+
+include_bspdir = $(includedir)/bsp
+
+include_HEADERS += include/coverhd.h
+
+dist_project_lib_DATA += startup/linkcmds startup/linkcmds.dl
+
+noinst_PROGRAMS += startup.rel
+startup_rel_SOURCES = startup/bspclean.c ../../shared/bsplibc.c \
+ ../../shared/bsppost.c startup/bspstart.c ../../shared/bootcard.c \
+ ../../shared/sbrk.c startup/setvec.c \
+ ../../shared/gnatinstallhandler.c
+startup_rel_CPPFLAGS = $(AM_CPPFLAGS)
+startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_PROGRAMS += dlentry.rel
+dlentry_rel_SOURCES = dlentry/dlentry.S
+dlentry_rel_CPPFLAGS = $(AM_CPPFLAGS)
+dlentry_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_PROGRAMS += bspconsole.rel
+bspconsole_rel_SOURCES = console/consolelite.c ../../shared/console.c
+bspconsole_rel_CPPFLAGS = $(AM_CPPFLAGS)
+bspconsole_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+include_bsp_HEADERS = include/opbintctrl.h
+noinst_PROGRAMS += opbintctrl.rel
+opbintctrl_rel_SOURCES = opbintctrl/opbintctrl.c
+opbintctrl_rel_CPPFLAGS = $(AM_CPPFLAGS)
+opbintctrl_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+include_bsp_HEADERS += irq/irq.h
+noinst_PROGRAMS += irq.rel
+irq_rel_SOURCES = irq/irq_init.c ../shared/irq/irq_asm.S
+irq_rel_CPPFLAGS = $(AM_CPPFLAGS)
+irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+include_bsp_HEADERS += ../../powerpc/shared/vectors/vectors.h
+noinst_PROGRAMS += vectors.rel
+vectors_rel_SOURCES = ../../powerpc/shared/vectors/vectors.h \
+ ../../powerpc/shared/vectors/vectors_init.c \
+ ../../powerpc/shared/vectors/vectors.S
+vectors_rel_CPPFLAGS = $(AM_CPPFLAGS)
+vectors_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+if HAS_NETWORKING
+network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
+network_CPPFLAGS += -D__BSD_VISIBLE
+noinst_PROGRAMS += network.rel
+network_rel_SOURCES = network/xiltemac.c
+network_rel_CPPFLAGS = $(AM_CPPFLAGS)
+network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+
+##RSG Start
+## include_HEADERS += include/xiltemac.h
+#noinst_PROGRAMS += xiltemac.rel
+#xiltemac_rel_SOURCES = network/xiltemac.c
+#xiltemac_rel_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ $(AM_CPPFLAGS) -O0 -g
+#xiltemac_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+##RSG End
+
+endif
+
+noinst_LIBRARIES = libbsp.a
+libbsp_a_SOURCES =
+
+libbsp_a_LIBADD = startup.rel dlentry.rel bspconsole.rel opbintctrl.rel \
+ vectors.rel irq.rel network.rel
+
+libbsp_a_LIBADD += ../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \
+ ../../../libcpu/@RTEMS_CPU@/@exceptions@/raw_exception.rel \
+ ../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel \
+ ../../../libcpu/@RTEMS_CPU@/ppc403/clock.rel \
+ ../../../libcpu/@RTEMS_CPU@/ppc403/timer.rel \
+ ../../../libcpu/@RTEMS_CPU@/ppc403/tty_drv.rel
+
+EXTRA_DIST = times
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/../../../../automake/local.am
diff --git a/c/src/lib/libbsp/powerpc/virtex/README b/c/src/lib/libbsp/powerpc/virtex/README
new file mode 100644
index 0000000000..8c91efa9a6
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/README
@@ -0,0 +1,91 @@
+#
+# $Id$
+#
+
+# Adapted from vitex BSP
+
+BSP NAME: Virtex
+BOARD: Xilinx ML-403 and (hopefully) any vitex/PPC based board
+BUS: N/A
+CPU FAMILY: ppc
+CPU: PowerPC 405GP
+COPROCESSORS: N/A
+MODE: 32 bit mode
+
+DEBUG MONITOR:
+
+PERIPHERALS
+===========
+TIMERS: 405GP internal
+SERIAL PORTS: Xilinx consolelite
+REAL-TIME CLOCK: none
+DMA: Xilinx vitex internal
+VIDEO: none
+SCSI: none
+NETWORKING: Xilinx TEMAC
+
+DRIVER INFORMATION
+==================
+CLOCK DRIVER: PPC Decrementer
+IOSUPP DRIVER: N/A
+SHMSUPP: N/A
+TIMER DRIVER: N/A
+TTY DRIVER: consoleelite
+
+STDIO
+=====
+PORT: Console port 0
+ELECTRICAL: RS-232
+BAUD: as defined in FPGA design
+BITS PER CHARACTER: 8
+PARITY: None
+STOP BITS: 1
+
+Notes
+=====
+
+Board description
+-----------------
+clock rate: 234 MHz
+ROM: 16MByte FLASH
+RAM: 64MByte DRAM
+
+virtex only supports single processor operations.
+
+Porting
+-------
+This board support package is written for a typical virtex/PPC FPGA
+system. The rough features of such a board are described above.
+
+When a new virtex FPGA system is created (using the Xilinx design
+software), a parameter file "xparameters.h" is also created, which
+describes the basic features of the hardware (like peripherals
+inculded, interrupt routing etc).
+
+This BSP normally takes its basic HW description for the file
+"xparameters_dflt.h", which describes my FPGA system. When this BSP
+should run on a different hardware, a path to the proper
+"xparameters.h" can be provided on the "configure" command line.
+
+For adapting this BSP to other boards,
+
+the following files should be
+modified:
+
+- c/src/lib/libbsp/powerpc/virtex/startup/linkcmds
+ for the memory layout required
+
+- c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c
+ for adaption of BSP_Configuration. here you can select
+ the clock source for the timers and the serial interface
+ (system clock or external clock pin), the clock rates, initial
+ baud rate and other stuff
+
+- c/src/lib/libbsp/powerpc/virtex/include/bsp.h
+ some BSP-related constants
+
+- c/src/lib/libbsp/powerpc/virtex/*
+ well, they should be generic, so there _should_ be no reason
+ to mess around there (but who knows...)
+
+
diff --git a/c/src/lib/libbsp/powerpc/virtex/bsp_specs b/c/src/lib/libbsp/powerpc/virtex/bsp_specs
new file mode 100644
index 0000000000..b0c18cde77
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/bsp_specs
@@ -0,0 +1,15 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+%rename link old_link
+
+*startfile:
+%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems: \
+%{!qrtems_debug: } \
+%{qrtems_debug: }ecrti%O%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: ecrtn%O%s}
+
+*link:
+%{!qrtems: %(old_link)} %{qrtems: -dc -dp -u __vectors -u download_entry -N }
+
diff --git a/c/src/lib/libbsp/powerpc/virtex/bsp_specs.dl b/c/src/lib/libbsp/powerpc/virtex/bsp_specs.dl
new file mode 100644
index 0000000000..24804479a0
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/bsp_specs.dl
@@ -0,0 +1,23 @@
+%rename cpp old_cpp
+%rename lib old_lib
+%rename endfile old_endfile
+%rename startfile old_startfile
+%rename link old_link
+
+*cpp:
+%(old_cpp) %{qrtems: -D__embedded__} -Asystem(embedded)
+
+*lib:
+%{!qrtems: %(old_lib)} %{qrtems: ecrti%O%s --start-group \
+%{!qrtems_debug: -lrtemsall} %{qrtems_debug: -lrtemsall_g} \
+-lc -lgcc --end-group \
+%{!qnolinkcmds: -T linkcmds%s}}
+
+*startfile:
+%{!qrtems: %(old_startfile)} %{qrtems: \
+%{!qrtems_debug: } \
+%{qrtems_debug: }}
+
+*link:
+%{!qrtems: %(old_link)} %{qrtems: -dc -dp -u __vectors -u download_entry -N }
+
diff --git a/c/src/lib/libbsp/powerpc/virtex/console/consolelite.c b/c/src/lib/libbsp/powerpc/virtex/console/consolelite.c
new file mode 100644
index 0000000000..99f40bca02
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/console/consolelite.c
@@ -0,0 +1,366 @@
+/*
+ * This file contains the console driver for the xilinx uart lite.
+ *
+ * Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
+ * COPYRIGHT (c) 2005 by Linn Products Ltd, Scotland.
+ *
+ * Derived from libbsp/no_cpu/no_bsp/console.c and therefore also:
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ */
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <bsp/irq.h>
+
+#include <bsp.h>
+#include <libchip/serial.h>
+#include <libchip/sersupp.h>
+
+
+/* Status Register Masks */
+#define PARITY_ERROR 0x80 /* Parity Error */
+#define FRAME_ERROR 0x40 /* Frame Error */
+#define OVERRUN_ERROR 0x20 /* Overrun Error */
+#define STATUS_REG_ERROR_MASK ( PARITY_ERROR | FRAME_ERROR | OVERRUN_ERROR )
+
+#define INTR_ENABLED 0x10 /* Interrupts are enabled */
+#define TX_FIFO_FULL 0x08 /* Transmit FIFO is full */
+#define TX_FIFO_EMPTY 0x04 /* Transmit FIFO is empty */
+#define RX_FIFO_FULL 0x02 /* Receive FIFO is full */
+#define RX_FIFO_VALID_DATA 0x01 /* Receive FIFO has valid data */
+/* Control Register Masks*/
+#define ENABLE_INTR 0x10 /* Enable interrupts */
+#define RST_RX_FIFO 0x02 /* Reset and clear RX FIFO */
+#define RST_TX_FIFO 0x01 /* Reset and clear TX FIFO */
+
+/* General Defines */
+#define TX_FIFO_SIZE 16
+#define RX_FIFO_SIZE 16
+
+
+
+
+#define RECV_REG 0
+#define TRAN_REG 4
+#define STAT_REG 8
+#define CTRL_REG 12
+
+
+
+RTEMS_INLINE_ROUTINE uint32_t xlite_uart_control(uint32_t base)
+{
+ uint32_t c = *((volatile uint32_t*)(base+CTRL_REG));
+ return c;
+}
+
+
+RTEMS_INLINE_ROUTINE uint32_t xlite_uart_status(uint32_t base)
+{
+ uint32_t c = *((volatile uint32_t*)(base+STAT_REG));
+ return c;
+}
+
+
+RTEMS_INLINE_ROUTINE uint32_t xlite_uart_read(uint32_t base)
+{
+ uint32_t c = *((volatile uint32_t*)(base+RECV_REG));
+ return c;
+}
+
+
+RTEMS_INLINE_ROUTINE void xlite_uart_write(uint32_t base, char ch)
+{
+ *(volatile uint32_t*)(base+TRAN_REG) = (uint32_t)ch;
+ return;
+}
+
+
+
+int xlite_write_char(uint32_t base, char ch)
+{
+ uint32_t retrycount= 0, idler, status;
+
+ while( ((status = xlite_uart_status(base)) & TX_FIFO_FULL) != 0 )
+ {
+ ++retrycount;
+
+ /* uart tx is busy */
+ if( retrycount == 0x4000 )
+ {
+ /* retrycount is arbitrary- just make it big enough so the uart is sure to be timed out before it trips */
+ return -1;
+ }
+
+ /* spin for a bit so we can sample the register rather than
+ * continually reading it */
+ for( idler= 0; idler < 0x2000; idler++);
+ }
+
+ xlite_uart_write(base, ch);
+
+ return 1;
+}
+
+
+
+
+
+
+
+
+
+
+
+void xlite_init (int minor )
+{
+ uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
+
+ /* clear status register */
+ *((volatile uint32_t*)(base+STAT_REG)) = 0;
+
+ /* clear control register; reset fifos & interrupt enable */
+ *((volatile uint32_t*)(base+CTRL_REG)) = RST_RX_FIFO | RST_TX_FIFO;
+}
+
+
+int xlite_open(
+ int major,
+ int minor,
+ void *arg
+)
+{
+ uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
+
+ /* the lite uarts have hardcoded baud & serial parms so no port
+ * conditioning is needed. We're running polled so no interrupt
+ * enables either */
+
+ /* clear status register */
+ *((volatile uint32_t*)(base+STAT_REG)) = 0;
+
+ /* clear control register; reset fifos & disable interrupts */
+ *((volatile uint32_t*)(base+CTRL_REG)) = RST_RX_FIFO | RST_TX_FIFO;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+int xlite_close(
+ int major,
+ int minor,
+ void *arg
+)
+{
+ /* no shutdown protocol necessary */
+ return RTEMS_SUCCESSFUL;
+}
+
+
+
+int xlite_read_polled (int minor )
+{
+ uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
+
+ unsigned int status = xlite_uart_status(base);
+
+ if(status & RX_FIFO_VALID_DATA)
+ return (int)xlite_uart_read(base);
+ else
+ return -1;
+}
+
+
+
+
+int xlite_write_buffer_polled(
+ int minor,
+ const char *buf,
+ int len
+)
+{
+ uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
+ int nwrite = 0;
+
+ /*
+ * poll each byte in the string out of the port.
+ */
+ while (nwrite < len)
+ {
+ if( xlite_write_char(base, *buf++) < 0 ) break;
+ nwrite++;
+ }
+
+ /*
+ * return the number of bytes written.
+ */
+ return nwrite;
+}
+
+
+void xlite_write_char_polled(
+ int minor,
+ char c
+)
+{
+ uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
+ xlite_write_char(base, c);
+ return;
+}
+
+
+
+int xlite_set_attributes(int minor, const struct termios *t)
+{
+ return RTEMS_SUCCESSFUL;
+}
+
+
+
+
+
+
+
+console_fns xlite_fns_polled =
+{
+ libchip_serial_default_probe, /* deviceProbe */
+ xlite_open, /* deviceFirstOpen */
+ xlite_close, /* deviceLastClose */
+ xlite_read_polled, /* deviceRead */
+ xlite_write_buffer_polled, /* deviceWrite */
+ xlite_init, /* deviceInitialize */
+ xlite_write_char_polled, /* deviceWritePolled */
+ xlite_set_attributes, /* deviceSetAttributes */
+ FALSE, /* deviceOutputUsesInterrupts */
+};
+
+
+
+
+
+
+/*
+** Set ulCtrlPort1 to the base address of each UART Lite instance. Set in vhdl model.
+*/
+
+
+console_tbl Console_Port_Tbl[] = {
+{
+ "/dev/ttyS0", /* sDeviceName */
+ SERIAL_CUSTOM, /* deviceType */
+ &xlite_fns_polled, /* pDeviceFns */
+ NULL, /* deviceProbe, assume it is there */
+ NULL, /* pDeviceFlow */
+ 16, /* ulMargin */
+ 8, /* ulHysteresis */
+ (void *) NULL, /* NULL */ /* pDeviceParams */
+ 0x40600000, /* ulCtrlPort1 */
+ 0, /* ulCtrlPort2 */
+ 0, /* ulDataPort */
+ NULL, /* getRegister */
+ NULL, /* setRegister */
+ NULL, /* unused */ /* getData */
+ NULL, /* unused */ /* setData */
+ 0, /* ulClock */
+ 0 /* ulIntVector -- base for port */
+},
+{
+ "/dev/ttyS1", /* sDeviceName */
+ SERIAL_CUSTOM, /* deviceType */
+ &xlite_fns_polled, /* pDeviceFns */
+ NULL, /* deviceProbe, assume it is there */
+ NULL, /* pDeviceFlow */
+ 16, /* ulMargin */
+ 8, /* ulHysteresis */
+ (void *) NULL, /* NULL */ /* pDeviceParams */
+ 0x40610000, /* ulCtrlPort1 */
+ 0, /* ulCtrlPort2 */
+ 0, /* ulDataPort */
+ NULL, /* getRegister */
+ NULL, /* setRegister */
+ NULL, /* unused */ /* getData */
+ NULL, /* unused */ /* setData */
+ 0, /* ulClock */
+ 0 /* ulIntVector -- base for port */
+},
+{
+ "/dev/ttyS2", /* sDeviceName */
+ SERIAL_CUSTOM, /* deviceType */
+ &xlite_fns_polled, /* pDeviceFns */
+ NULL, /* deviceProbe, assume it is there */
+ NULL, /* pDeviceFlow */
+ 16, /* ulMargin */
+ 8, /* ulHysteresis */
+ (void *) NULL, /* NULL */ /* pDeviceParams */
+ 0x40620000, /* ulCtrlPort1 */
+ 0, /* ulCtrlPort2 */
+ 0, /* ulDataPort */
+ NULL, /* getRegister */
+ NULL, /* setRegister */
+ NULL, /* unused */ /* getData */
+ NULL, /* unused */ /* setData */
+ 0, /* ulClock */
+ 0 /* ulIntVector -- base for port */
+},
+{
+ "/dev/ttyS3", /* sDeviceName */
+ SERIAL_CUSTOM, /* deviceType */
+ &xlite_fns_polled, /* pDeviceFns */
+ NULL, /* deviceProbe, assume it is there */
+ NULL, /* pDeviceFlow */
+ 16, /* ulMargin */
+ 8, /* ulHysteresis */
+ (void *) NULL, /* NULL */ /* pDeviceParams */
+ 0x40630000, /* ulCtrlPort1 */
+ 0, /* ulCtrlPort2 */
+ 0, /* ulDataPort */
+ NULL, /* getRegister */
+ NULL, /* setRegister */
+ NULL, /* unused */ /* getData */
+ NULL, /* unused */ /* setData */
+ 0, /* ulClock */
+ 0 /* ulIntVector -- base for port */
+}
+};
+
+
+
+
+#define NUM_CONSOLE_PORTS (sizeof(Console_Port_Tbl)/sizeof(console_tbl))
+
+unsigned long Console_Port_Count = NUM_CONSOLE_PORTS;
+console_data Console_Port_Data[NUM_CONSOLE_PORTS];
+rtems_device_minor_number Console_Port_Minor;
+
+
+
+
+
+
+
+
+#include <rtems/bspIo.h>
+
+void outputChar(char ch)
+{
+ if (ch == '\n') {
+ xlite_write_char_polled( 0, '\r' );
+ }
+ xlite_write_char_polled( 0, ch );
+}
+
+char inputChar()
+{
+ return (char)xlite_read_polled(0);
+}
+
+BSP_output_char_function_type BSP_output_char = outputChar;
+BSP_polling_getchar_function_type BSP_poll_char = inputChar;
+
+
diff --git a/c/src/lib/libbsp/powerpc/virtex/dlentry/dlentry.S b/c/src/lib/libbsp/powerpc/virtex/dlentry/dlentry.S
new file mode 100644
index 0000000000..afca899ef4
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/dlentry/dlentry.S
@@ -0,0 +1,156 @@
+/* dlentry.s
+ *
+ * This file contains the entry code for RTEMS programs starting
+ * after download to RAM
+ *
+ * Author: Thomas Doerfler <td@imd.m.isar.de>
+ * IMD Ingenieurbuero fuer Microcomputertechnik
+ *
+ * COPYRIGHT (c) 1998 by IMD
+ *
+ * Changes from IMD are covered by the original distributions terms.
+ * This file has been derived from the papyrus BSP:
+ *
+ * This file contains the entry veneer for RTEMS programs
+ * downloaded to Papyrus.
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * $Id$
+ *
+ * derived from "helas403/dlentry.S":
+ * Id: dlentry.S,v 1.2 2000/08/02 16:30:57 joel Exp
+ */
+
+#include <rtems/asm.h>
+
+/*
+ * The virtex ELF link scripts support three special sections:
+ * .entry The actual entry point
+ * .vectors The section containing the interrupt entry veneers.
+ */
+
+/*
+ * Downloaded code loads the vectors separately to 0x00000100,
+ * so .entry can be over 256 bytes.
+ *
+ * The other sections are linked in the following order:
+ * .entry
+ * .text
+ * .data
+ * .bss
+ * see linker command file for section placement
+ *
+ * The initial stack is set to stack.end
+ *
+ * All the entry veneer has to do is to clear the BSS.
+ */
+
+/*
+ * GDB likes to have debugging information for the entry veneer.
+ * Here was some DWARF information. IMD removed it, because we
+ * could not check, whether it was still correct. Sorry.
+
+ */
+
+ .section .entry
+
+ PUBLIC_VAR (start)
+ PUBLIC_VAR (download_entry)
+ PUBLIC_VAR (__rtems_entry_point)
+SYM(start):
+SYM(download_entry):
+SYM(__rtems_entry_point):
+ bl .startup
+base_addr:
+
+/*---------------------------------------------------------------------------
+ * Parameters from linker
+ *--------------------------------------------------------------------------*/
+toc_pointer:
+ .long s.got
+bss_length:
+ .long bss.size
+bss_addr:
+ .long bss.start
+stack_top:
+ .long stack.end
+PUBLIC_VAR (text_addr)
+text_addr:
+ .long text.start
+
+PUBLIC_VAR (text_length)
+text_length:
+ .long text.size
+/*---------------------------------------------------------------------------
+ * Reset_entry.
+ *--------------------------------------------------------------------------*/
+.startup:
+ /* Get start address, stack grows down from here... */
+ mflr r1
+
+ /* Assume Bank regs set up..., cache etc. */
+ bl bssclr
+
+#if 0
+ .extern SYM(__vectors)
+
+ lis r2,__vectors@h /* set EVPR exc. vector prefix */
+#else
+ lis r2,0
+#endif
+ mtspr evpr,r2
+
+ /*-------------------------------------------------------------------
+ * C_setup.
+ *------------------------------------------------------------------*/
+ lwz r2,toc_pointer-base_addr(r1) /* set r2 to toc */
+ lwz r1,stack_top-base_addr(r1) /* set r1 to stack_top */
+
+ addi r1,r1,-56-4 /* start stack at text_addr - 56 */
+ addi r3,r0,0x0 /* clear r3 */
+ stw r3, 0(r1) /* Clear stack chain */
+ stw r3, 4(r1)
+ stw r3, 8(r1)
+ stw r3, 12(r1)
+ lis r5,environ@ha
+ la r5,environ@l(r5) /* environp */
+ li r4, 0 /* argv */
+ li r3, 0 /* argc */
+ .extern SYM (boot_card)
+ b SYM (boot_card) /* call the first C routine */
+
+/*---------------------------------------------------------------------------
+ * bssclr.
+ *--------------------------------------------------------------------------*/
+bssclr:
+ /*-------------------------------------------------------------------
+ * Data move finished, zero out bss.
+ *------------------------------------------------------------------*/
+ lwz r2,bss_addr-base_addr(r1) /* start of bss set by loader */
+ lwz r3,bss_length-base_addr(r1) /* bss length */
+ rlwinm. r3,r3,30,0x3FFFFFFF /* form length/4 */
+ beqlr /* no bss */
+ mtctr r3 /* set ctr reg */
+ xor r6,r6,r6 /* r6 = 0 */
+clear_bss:
+ stswi r6,r2,0x4 /* store r6 */
+ addi r2,r2,0x4 /* update r2 */
+ bdnz clear_bss /* decrement counter and loop */
+ blr /* return */
+.L_text_e:
+
+ .comm environ,4,4
diff --git a/c/src/lib/libbsp/powerpc/virtex/include/bsp.h b/c/src/lib/libbsp/powerpc/virtex/include/bsp.h
new file mode 100644
index 0000000000..6ce4d4b1bc
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/include/bsp.h
@@ -0,0 +1,123 @@
+/* bsp.h
+ *
+ * This include file contains all GEN405 board IO definitions.
+ *
+ * derived from helas403/include/bsp.h:
+ * Id: bsp.h,v 1.4 2001/06/18 17:01:48 joel Exp
+ * Author: Thomas Doerfler <td@imd.m.isar.de>
+ * IMD Ingenieurbuero fuer Microcomputertechnik
+ *
+ * COPYRIGHT (c) 1998 by IMD
+ *
+ * Changes from IMD are covered by the original distributions terms.
+ * This file has been derived from the papyrus BSP.
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libbsp/no_cpu/no_bsp/include/bsp.h
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef _BSP_H
+#define _BSP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bspopts.h>
+
+/*
+ * confdefs.h overrides for this BSP:
+ * - number of termios serial ports (defaults to 1)
+ * - Interrupt stack space is not minimum if defined.
+ */
+
+/* #define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2 */
+#define CONFIGURE_INTERRUPT_STACK_MEMORY (16 * 1024)
+
+#ifdef ASM
+/* Definition of where to store registers in alignment handler */
+#define ALIGN_REGS 0x0140
+
+#else
+#include <rtems.h>
+#include <rtems/console.h>
+#include <rtems/clockdrv.h>
+#include <rtems/console.h>
+#include <rtems/iosupp.h>
+#include <rtems/rtems_bsdnet.h>
+
+
+
+/* Constants */
+
+extern uint32_t _HeapSize;
+extern uint32_t _heap_start;
+extern uint32_t _heap_end;
+extern uint32_t _top_of_ram;
+
+/* miscellaneous stuff assumed to exist */
+
+extern rtems_configuration_table BSP_Configuration; /* owned by BSP */
+extern rtems_cpu_table Cpu_table; /* owned by BSP */
+
+
+/* Network Defines */
+#if 1 /* EB/doe changes */
+#define RTEMS_BSP_NETWORK_DRIVER_NAME "eth0"
+#else
+#include "xiltemac.h"
+#define RTEMS_BSP_NETWORK_DRIVER_NAME XILTEMAC_DRIVER_PREFIX
+#endif
+extern xilTemac_driver_attach(struct rtems_bsdnet_ifconfig*, int );
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH xilTemac_driver_attach
+
+/*
+ * Device Driver Table Entries
+ */
+
+/*
+ * NOTE: Use the standard Console driver entry
+ */
+
+/*
+ * NOTE: Use the standard Clock driver entry
+ */
+
+/* functions */
+
+rtems_isr_entry set_vector( /* returns old vector */
+ rtems_isr_entry handler, /* isr routine */
+ rtems_vector_number vector, /* vector number */
+ int type /* RTEMS or RAW intr */
+);
+#endif /* ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/powerpc/virtex/include/bspopts.h.in b/c/src/lib/libbsp/powerpc/virtex/include/bspopts.h.in
new file mode 100644
index 0000000000..72e76868df
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/include/bspopts.h.in
@@ -0,0 +1,33 @@
+/* include/bspopts.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* If defined, then the PowerPC specific code in RTEMS will use some of the
+ special purpose registers to slightly optimize interrupt response time. The
+ use of these registers can conflict with other tools like debuggers. */
+#undef PPC_USE_SPRG
+
+/* This defines the base address of the exception table. NOTE: Vectors are
+ actually at 0xFFF00000 but file starts at offset. */
+#undef PPC_VECTOR_FILE_BASE
+
+/* This defines the location of the hardware specific "xparameters.h" file. in
+ the file system. Specify an absolute path. Don't forget the double quotes
+ */
+#undef RTEMS_XPARAMETERS_H
+
+/* Defines path to Xilinx XPS PPC libraries. */
+#undef RTEMS_XPPC_BASE
diff --git a/c/src/lib/libbsp/powerpc/virtex/include/coverhd.h b/c/src/lib/libbsp/powerpc/virtex/include/coverhd.h
new file mode 100644
index 0000000000..f39d324eaa
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/include/coverhd.h
@@ -0,0 +1,133 @@
+/* coverhd.h
+ *
+ * This include file has defines to represent the overhead associated
+ * with calling a particular directive from C. These are used in the
+ * Timing Test Suite to ignore the overhead required to pass arguments
+ * to directives. On some CPUs and/or target boards, this overhead
+ * is significant and makes it difficult to distinguish internal
+ * RTEMS execution time from that used to call the directive.
+ * This file should be updated after running the C overhead timing
+ * test. Once this update has been performed, the RTEMS Time Test
+ * Suite should be rebuilt to account for these overhead times in the
+ * timing results.
+ *
+ * NOTE: If these are all zero, then the times reported include
+ * all calling overhead including passing of arguments.
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+/*
+ * Updated for a 25MHz Papyrus by Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * Units are 100ns.
+ *
+ * These numbers are of questionable use, as they are developed by calling
+ * the routine many times, thus getting its entry veneer into the (small)
+ * cache on the 403GA. This in general is not true of the RTEMS timing
+ * tests, which usually call a routine only once, thus having no cache loaded
+ * advantage.
+ *
+ * Whether the directive times are useful after deducting the function call
+ * overhead is also questionable. The user is more interested generally
+ * in the total cost of a directive, not the cost if the procedure call
+ * is inlined! (In general this is not true).
+ *
+ * Andrew Bray 18/08/1995
+ *
+ */
+
+#ifndef __COVERHD_h
+#define __COVERHD_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 1
+#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 1
+#define CALLING_OVERHEAD_TASK_CREATE 3
+#define CALLING_OVERHEAD_TASK_IDENT 1
+#define CALLING_OVERHEAD_TASK_START 1
+#define CALLING_OVERHEAD_TASK_RESTART 1
+#define CALLING_OVERHEAD_TASK_DELETE 1
+#define CALLING_OVERHEAD_TASK_SUSPEND 1
+#define CALLING_OVERHEAD_TASK_RESUME 1
+#define CALLING_OVERHEAD_TASK_SET_PRIORITY 1
+#define CALLING_OVERHEAD_TASK_MODE 1
+#define CALLING_OVERHEAD_TASK_GET_NOTE 1
+#define CALLING_OVERHEAD_TASK_SET_NOTE 1
+#define CALLING_OVERHEAD_TASK_WAKE_WHEN 4
+#define CALLING_OVERHEAD_TASK_WAKE_AFTER 1
+#define CALLING_OVERHEAD_INTERRUPT_CATCH 1
+#define CALLING_OVERHEAD_CLOCK_GET 4
+#define CALLING_OVERHEAD_CLOCK_SET 3
+#define CALLING_OVERHEAD_CLOCK_TICK 1
+
+#define CALLING_OVERHEAD_TIMER_CREATE 1
+#define CALLING_OVERHEAD_TIMER_IDENT 1
+#define CALLING_OVERHEAD_TIMER_DELETE 1
+#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 2
+#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 5
+#define CALLING_OVERHEAD_TIMER_RESET 1
+#define CALLING_OVERHEAD_TIMER_CANCEL 1
+#define CALLING_OVERHEAD_SEMAPHORE_CREATE 2
+#define CALLING_OVERHEAD_SEMAPHORE_IDENT 1
+#define CALLING_OVERHEAD_SEMAPHORE_DELETE 1
+#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 1
+#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 1
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 2
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 1
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 1
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 1
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 1
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 1
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 2
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 1
+
+#define CALLING_OVERHEAD_EVENT_SEND 1
+#define CALLING_OVERHEAD_EVENT_RECEIVE 2
+#define CALLING_OVERHEAD_SIGNAL_CATCH 1
+#define CALLING_OVERHEAD_SIGNAL_SEND 1
+#define CALLING_OVERHEAD_PARTITION_CREATE 3
+#define CALLING_OVERHEAD_PARTITION_IDENT 1
+#define CALLING_OVERHEAD_PARTITION_DELETE 1
+#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 1
+#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 1
+#define CALLING_OVERHEAD_REGION_CREATE 3
+#define CALLING_OVERHEAD_REGION_IDENT 1
+#define CALLING_OVERHEAD_REGION_DELETE 1
+#define CALLING_OVERHEAD_REGION_GET_SEGMENT 2
+#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 1
+#define CALLING_OVERHEAD_PORT_CREATE 2
+#define CALLING_OVERHEAD_PORT_IDENT 1
+#define CALLING_OVERHEAD_PORT_DELETE 1
+#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 1
+#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 2
+
+#define CALLING_OVERHEAD_IO_INITIALIZE 2
+#define CALLING_OVERHEAD_IO_OPEN 2
+#define CALLING_OVERHEAD_IO_CLOSE 2
+#define CALLING_OVERHEAD_IO_READ 2
+#define CALLING_OVERHEAD_IO_WRITE 2
+#define CALLING_OVERHEAD_IO_CONTROL 2
+#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 1
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 1
+#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 1
+#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 1
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 1
+#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 1
+#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 1
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/powerpc/virtex/include/opbintctrl.h b/c/src/lib/libbsp/powerpc/virtex/include/opbintctrl.h
new file mode 100644
index 0000000000..f4a1c39bbc
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/include/opbintctrl.h
@@ -0,0 +1,90 @@
+/* opbintctrl.h
+ *
+ * This file contains definitions and declarations for the
+ * Xilinx Off Processor Bus (OPB) Interrupt Controller
+ *
+ * Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
+ * COPYRIGHT (c) 2005 by Linn Products Ltd, Scotland
+ *
+ * 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 _INCLUDE_OPBINTCTRL_H
+#define _INCLUDE_OPBINTCTRL_H
+
+#include <rtems.h>
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/irq.h>
+#include <bspopts.h>
+#include RTEMS_XPARAMETERS_H
+
+#define USE_GREG_INTERRUPTS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* extern XIntc InterruptController;
+ */
+
+
+/* Maximum number of IRQs. Defined in vhdl model */
+#define OPB_INTC_IRQ_MAX XPAR_INTC_MAX_NUM_INTR_INPUTS
+
+/* Width of INTC registers. Defined in vhdl model */
+#define OPB_INTC_REGISTER_WIDTH 32
+
+/* Base Register address and register offsets. Defined in vhdl model */
+#define OPB_INTC_BASE XPAR_INTC_BASEADDR
+
+
+
+
+
+/* Interrupt Status Register */
+#define OPB_INTC_ISR 0x0
+/* Interrupt Pending Register (ISR && IER) */
+#define OPB_INTC_IPR 0x4
+/* Interrupt Enable Register */
+#define OPB_INTC_IER 0x8
+/* Interrupt Acknowledge Register */
+#define OPB_INTC_IAR 0xC
+/* Set Interrupt Enable (same as read/mask/write to IER) */
+#define OPB_INTC_SIE 0x10
+/* Clear Interrupt Enable (same as read/mask/write to IER) */
+#define OPB_INTC_CIE 0x14
+/* Interrupt Vector Address (highest priority vector number from IPR) */
+#define OPB_INTC_IVR 0x18
+/* Master Enable Register */
+#define OPB_INTC_MER 0x1C
+
+/* Master Enable Register: Hardware Interrupt Enable */
+#define OPB_INTC_MER_HIE 0x2
+
+/* Master Enable Register: Master IRQ Enable */
+#define OPB_INTC_MER_ME 0x1
+
+ /*
+ * make this fast: is this a opbintc interrupt?
+ */
+ void BSP_irq_enable_at_opbintc (rtems_irq_number irqnum);
+
+ void BSP_irq_disable_at_opbintc (rtems_irq_number irqnum);
+ /*
+ * IRQ Handler: this is called from the primary exception dispatcher
+ */
+ void BSP_irq_handle_at_opbintc(void);
+ /*
+ * activate the interrupt controller
+ */
+ rtems_status_code opb_intc_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _INCLUDE_OPBINTCTRL_H */
diff --git a/c/src/lib/libbsp/powerpc/virtex/include/tm27.h b/c/src/lib/libbsp/powerpc/virtex/include/tm27.h
new file mode 100644
index 0000000000..18f3b6b32b
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/include/tm27.h
@@ -0,0 +1,32 @@
+/*
+ * tm27.h
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_TMTEST27
+#error "This is an RTEMS internal file you must not include directly."
+#endif
+
+#ifndef __tm27_h
+#define __tm27_h
+
+/*
+ * Stuff for Time Test 27
+ */
+
+#define MUST_WAIT_FOR_INTERRUPT 0
+
+#define Install_tm27_vector( handler ) set_vector( (handler), PPC_IRQ_SCALL, 1 )
+
+#define Cause_tm27_intr() asm volatile ("sc")
+
+#define Clear_tm27_intr() /* empty */
+
+#define Lower_tm27_intr() /* empty */
+
+#endif
diff --git a/c/src/lib/libbsp/powerpc/virtex/include/xparameters_dflt.h b/c/src/lib/libbsp/powerpc/virtex/include/xparameters_dflt.h
new file mode 100644
index 0000000000..6dc91751e0
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/include/xparameters_dflt.h
@@ -0,0 +1,193 @@
+
+/*******************************************************************
+*
+* CAUTION: This file is automatically generated by libgen.
+* Version: Xilinx EDK 8.2.02 EDK_Im_Sp2.4
+* DO NOT EDIT.
+*
+* Copyright (c) 2005 Xilinx, Inc. All rights reserved.
+*
+* Description: Driver parameters
+*
+*******************************************************************/
+
+#define STDIN_BASEADDRESS 0x40600000
+#define STDOUT_BASEADDRESS 0x40600000
+
+/******************************************************************/
+
+/* Definitions for driver PLBARB */
+#define XPAR_XPLBARB_NUM_INSTANCES 1
+
+/* Definitions for peripheral PLB */
+#define XPAR_PLB_BASEADDR 0x00000000
+#define XPAR_PLB_HIGHADDR 0x00000000
+#define XPAR_PLB_DEVICE_ID 0
+#define XPAR_PLB_PLB_NUM_MASTERS 3
+
+
+/******************************************************************/
+
+/* Definitions for driver OPBARB */
+#define XPAR_XOPBARB_NUM_INSTANCES 1
+
+/* Definitions for peripheral OPB */
+#define XPAR_OPB_BASEADDR 0xFFFFFFFF
+#define XPAR_OPB_HIGHADDR 0x00000000
+#define XPAR_OPB_DEVICE_ID 0
+#define XPAR_OPB_NUM_MASTERS 1
+
+
+/******************************************************************/
+
+/* Definitions for driver UARTLITE */
+#define XPAR_XUARTLITE_NUM_INSTANCES 1
+
+/* Definitions for peripheral CONSOLE */
+#define XPAR_CONSOLE_BASEADDR 0x40600000
+#define XPAR_CONSOLE_HIGHADDR 0x4060FFFF
+#define XPAR_CONSOLE_DEVICE_ID 0
+#define XPAR_CONSOLE_BAUDRATE 115200
+#define XPAR_CONSOLE_USE_PARITY 0
+#define XPAR_CONSOLE_ODD_PARITY 0
+#define XPAR_CONSOLE_DATA_BITS 8
+
+
+/******************************************************************/
+
+/* Definitions for driver GPIO */
+#define XPAR_XGPIO_NUM_INSTANCES 3
+
+/* Definitions for peripheral LEDS */
+#define XPAR_LEDS_BASEADDR 0x40000000
+#define XPAR_LEDS_HIGHADDR 0x4000FFFF
+#define XPAR_LEDS_DEVICE_ID 0
+#define XPAR_LEDS_INTERRUPT_PRESENT 0
+#define XPAR_LEDS_IS_DUAL 0
+
+
+/* Definitions for peripheral PBLEDS */
+#define XPAR_PBLEDS_BASEADDR 0x40020000
+#define XPAR_PBLEDS_HIGHADDR 0x4002FFFF
+#define XPAR_PBLEDS_DEVICE_ID 1
+#define XPAR_PBLEDS_INTERRUPT_PRESENT 0
+#define XPAR_PBLEDS_IS_DUAL 0
+
+
+/* Definitions for peripheral PUSHBUTTONS */
+#define XPAR_PUSHBUTTONS_BASEADDR 0x40040000
+#define XPAR_PUSHBUTTONS_HIGHADDR 0x4004FFFF
+#define XPAR_PUSHBUTTONS_DEVICE_ID 2
+#define XPAR_PUSHBUTTONS_INTERRUPT_PRESENT 1
+#define XPAR_PUSHBUTTONS_IS_DUAL 0
+
+
+/******************************************************************/
+
+/* Definitions for driver TMRCTR */
+#define XPAR_XTMRCTR_NUM_INSTANCES 1
+
+/* Definitions for peripheral OPBTIMER */
+#define XPAR_OPBTIMER_BASEADDR 0x41C00000
+#define XPAR_OPBTIMER_HIGHADDR 0x41C0FFFF
+#define XPAR_OPBTIMER_DEVICE_ID 0
+
+
+/******************************************************************/
+
+#define XPAR_INTC_MAX_NUM_INTR_INPUTS 3
+#define XPAR_XINTC_HAS_IPR 1
+#define XPAR_XINTC_USE_DCR 0
+/* Definitions for driver INTC */
+#define XPAR_XINTC_NUM_INSTANCES 1
+
+/* Definitions for peripheral INTC */
+#define XPAR_INTC_BASEADDR 0x41200000
+#define XPAR_INTC_HIGHADDR 0x4120FFFF
+#define XPAR_INTC_DEVICE_ID 0
+#define XPAR_INTC_KIND_OF_INTR 0x00000000
+
+
+/******************************************************************/
+
+#define XPAR_INTC_SINGLE_BASEADDR 0x41200000
+#define XPAR_INTC_SINGLE_HIGHADDR 0x4120FFFF
+#define XPAR_INTC_SINGLE_DEVICE_ID XPAR_INTC_DEVICE_ID
+#define XPAR_OPBTIMER_INTERRUPT_MASK 0X000001
+#define XPAR_INTC_OPBTIMER_INTERRUPT_INTR 0
+#define XPAR_ETHERNET_IP2INTC_IRPT_MASK 0X000002
+#define XPAR_INTC_ETHERNET_IP2INTC_IRPT_INTR 1
+#define XPAR_PUSHBUTTONS_IP2INTC_IRPT_MASK 0X000004
+#define XPAR_INTC_PUSHBUTTONS_IP2INTC_IRPT_INTR 2
+
+/******************************************************************/
+
+/* Definitions for driver DDR */
+#define XPAR_XDDR_NUM_INSTANCES 1
+
+/* Definitions for peripheral DDR_SDRAM_64MX32 */
+#define XPAR_DDR_SDRAM_64MX32_ECC_BASEADDR 0xFFFFFFFF
+#define XPAR_DDR_SDRAM_64MX32_ECC_HIGHADDR 0x00000000
+#define XPAR_DDR_SDRAM_64MX32_DEVICE_ID 0
+#define XPAR_DDR_SDRAM_64MX32_INCLUDE_ECC_INTR 0
+
+
+/******************************************************************/
+
+/* Definitions for peripheral DDR_SDRAM_64MX32 */
+#define XPAR_DDR_SDRAM_64MX32_MEM0_BASEADDR 0x00000000
+#define XPAR_DDR_SDRAM_64MX32_MEM0_HIGHADDR 0x03FFFFFF
+
+/******************************************************************/
+
+
+/* Definitions for peripheral HARD_TEMAC_0 */
+#define XPAR_HARD_TEMAC_0_PHY_TYPE 1
+
+
+/******************************************************************/
+
+/* Definitions for driver TEMAC */
+#define XPAR_XTEMAC_NUM_INSTANCES 1
+
+/* Definitions for peripheral ETHERNET */
+#define XPAR_ETHERNET_DEVICE_ID 0
+#define XPAR_ETHERNET_BASEADDR 0x81200000
+#define XPAR_ETHERNET_HIGHADDR 0x8120FFFF
+#define XPAR_ETHERNET_RXFIFO_DEPTH 32768
+#define XPAR_ETHERNET_TXFIFO_DEPTH 32768
+#define XPAR_ETHERNET_MAC_FIFO_DEPTH 64
+#define XPAR_ETHERNET_DMA_TYPE 1
+#define XPAR_ETHERNET_TX_DRE_TYPE 0
+#define XPAR_ETHERNET_RX_DRE_TYPE 0
+#define XPAR_ETHERNET_INCLUDE_TX_CSUM 0
+#define XPAR_ETHERNET_INCLUDE_RX_CSUM 0
+
+
+/******************************************************************/
+
+
+/* Definitions for peripheral FLASH */
+#define XPAR_FLASH_NUM_BANKS_MEM 1
+
+
+/******************************************************************/
+
+/* Definitions for peripheral FLASH */
+#define XPAR_FLASH_MEM0_BASEADDR 0x06000000
+#define XPAR_FLASH_MEM0_HIGHADDR 0x067FFFFF
+
+/******************************************************************/
+
+
+/* Definitions for peripheral PLB_BRAM_IF_CNTLR_1 */
+#define XPAR_PLB_BRAM_IF_CNTLR_1_BASEADDR 0xffff8000
+#define XPAR_PLB_BRAM_IF_CNTLR_1_HIGHADDR 0xffffffff
+
+
+/******************************************************************/
+
+#define XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ 300000000
+
+/******************************************************************/
+
diff --git a/c/src/lib/libbsp/powerpc/virtex/irq/irq.h b/c/src/lib/libbsp/powerpc/virtex/irq/irq.h
new file mode 100644
index 0000000000..815fd3e87a
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/irq/irq.h
@@ -0,0 +1,99 @@
+/*===============================================================*\
+| Project: RTEMS virtex BSP |
++-----------------------------------------------------------------+
+| Copyright (c) 2007 |
+| Embedded Brains GmbH |
+| Obere Lagerstr. 30 |
+| D-82178 Puchheim |
+| Germany |
+| rtems@embedded-brains.de |
++-----------------------------------------------------------------+
+| 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. |
+| |
++-----------------------------------------------------------------+
+| this file declares constants of the interrupt controller |
+\*===============================================================*/
+#ifndef VIRTEX_IRQ_IRQ_H
+#define VIRTEX_IRQ_IRQ_H
+
+#include <rtems/irq.h>
+#include <bsp/opbintctrl.h>
+
+/*
+ * the following definitions specify the indices used
+ * to interface the interrupt handler API
+ */
+
+/*
+ * Base index for the module specific irq handlers
+ */
+#define BSP_ASM_IRQ_VECTOR_BASE 0x0
+#define BSP_OPBINTC_VECTOR_BASE BSP_ASM_IRQ_VECTOR_BASE
+
+/*
+ * Peripheral IRQ handlers related definitions
+ */
+#define BSP_OPBINTC_PER_IRQ_NUMBER XPAR_INTC_MAX_NUM_INTR_INPUTS
+#define BSP_OPBINTC_IRQ_LOWEST_OFFSET BSP_OPBINTC_VECTOR_BASE /* 0 */
+#define BSP_OPBINTC_IRQ_MAX_OFFSET (BSP_OPBINTC_IRQ_LOWEST_OFFSET\
+ +BSP_OPBINTC_PER_IRQ_NUMBER-1)
+
+#define BSP_IS_OPBINTC_IRQ(irqnum) \
+ (((irqnum) >= BSP_OPBINTC_IRQ_LOWEST_OFFSET) && \
+ ((irqnum) <= BSP_OPBINTC_IRQ_MAX_OFFSET))
+/*
+ * Processor IRQ handlers related definitions
+ */
+#define BSP_PROCESSOR_IRQ_NUMBER 3
+#define BSP_PROCESSOR_IRQ_LOWEST_OFFSET (BSP_OPBINTC_IRQ_MAX_OFFSET+1)
+#define BSP_PROCESSOR_IRQ_MAX_OFFSET (BSP_PROCESSOR_IRQ_LOWEST_OFFSET\
+ +BSP_PROCESSOR_IRQ_NUMBER-1)
+
+#define BSP_IS_PROCESSOR_IRQ(irqnum) \
+ (((irqnum) >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET) && \
+ ((irqnum) <= BSP_PROCESSOR_IRQ_MAX_OFFSET))
+/*
+ * Summary
+ */
+#define BSP_IRQ_NUMBER (BSP_PROCESSOR_IRQ_MAX_OFFSET+1)
+#define BSP_LOWEST_OFFSET BSP_OPBINTC_IRQ_LOWEST_OFFSET
+#define BSP_MAX_OFFSET BSP_PROCESSOR_IRQ_MAX_OFFSET
+
+#define BSP_IS_VALID_IRQ(irqnum) \
+ (BSP_IS_PROCESSOR_IRQ(irqnum) \
+ || BSP_IS_OPBINTC_IRQ(irqnum))
+
+#ifndef ASM
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * index table for the module specific handlers, a few entries are only placeholders
+ */
+ typedef enum {
+ BSP_OPBINTC_IRQ_FIRST = BSP_OPBINTC_IRQ_LOWEST_OFFSET,
+ /*
+ * Note: for this BSP, the peripheral names are derived
+ * from the Xilinx parameter file
+ */
+ BSP_OPBINTC_IRQ_LAST = BSP_OPBINTC_IRQ_MAX_OFFSET,
+ BSP_EXT = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 0,
+ BSP_PIT = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 1,
+ BSP_CRIT = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 2
+ } rtems_irq_symbolic_name;
+
+#define BSP_OPBINTC_XPAR(xname) (BSP_OPBINTC_IRQ_LOWEST_OFFSET+xname)
+
+ extern rtems_irq_connect_data *BSP_rtems_irq_tbl;
+ void BSP_rtems_irq_mng_init(unsigned cpuId);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ASM */
+
+#endif /* VIRTEX_IRQ_IRQ_H */
diff --git a/c/src/lib/libbsp/powerpc/virtex/irq/irq_init.c b/c/src/lib/libbsp/powerpc/virtex/irq/irq_init.c
new file mode 100644
index 0000000000..a3bd21cd31
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/irq/irq_init.c
@@ -0,0 +1,421 @@
+/*===============================================================*\
+| Project: RTEMS virtex BSP |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below. |
+| Adaptions, modifications, enhancements and any recent parts of |
+| the code are: |
+| Copyright (c) 2007 |
+| Embedded Brains GmbH |
+| Obere Lagerstr. 30 |
+| D-82178 Puchheim |
+| Germany |
+| rtems@embedded-brains.de |
++-----------------------------------------------------------------+
+| 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. |
+| |
++-----------------------------------------------------------------+
+| this file contains the irq controller handler |
+\*===============================================================*/
+#include <libcpu/spr.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <libcpu/raw_exception.h>
+#include <rtems/bspIo.h>
+#include <rtems/powerpc/powerpc.h>
+#include <bsp/vectors.h>
+
+static rtems_irq_connect_data rtemsIrqTbl[BSP_IRQ_NUMBER];
+rtems_irq_connect_data *BSP_rtems_irq_tbl;
+rtems_irq_global_settings* BSP_rtems_irq_config;
+
+/***********************************************************
+ * dummy functions for on/off/isOn calls
+ * these functions just do nothing fulfill the semantic
+ * requirements to enable/disable a certain interrupt or exception
+ */
+void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
+{
+ /*
+ * nothing to do
+ */
+}
+
+void BSP_irq_nop_hdl(void *hdl)
+{
+ /*
+ * nothing to do
+ */
+}
+
+int BSP_irq_true_func(const rtems_irq_connect_data *unused)
+{
+ /*
+ * nothing to do
+ */
+ return TRUE;
+}
+
+/***********************************************************
+ * interrupt handler and its enable/disable functions
+ ***********************************************************/
+
+/***********************************************************
+ * functions to enable/disable/query external/critical interrupts
+ */
+void BSP_irqexc_on_fnc(rtems_irq_connect_data *conn_data)
+{
+ uint32_t msr_value;
+ /*
+ * get current MSR value
+ */
+ _CPU_MSR_GET(msr_value);
+
+
+ msr_value |= PPC_MSR_EE;
+ _CPU_MSR_SET(msr_value);
+}
+
+void BSP_irqexc_off_fnc(rtems_irq_connect_data *unused)
+{
+ /*
+ * nothing to do
+ */
+}
+
+/***********************************************************
+ * High level IRQ handler called from shared_raw_irq_code_entry
+ */
+void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
+{
+
+
+ /*
+ * Handle interrupt
+ */
+ switch(excNum) {
+#if 0
+ case ASM_DEC_VECTOR:
+ _CPU_MSR_GET(msr);
+ new_msr = msr | MSR_EE;
+ _CPU_MSR_SET(new_msr);
+
+ BSP_rtems_irq_tbl[BSP_DECREMENTER].hdl
+ (BSP_rtems_irq_tbl[BSP_DECREMENTER].handle);
+
+ _CPU_MSR_SET(msr);
+
+ break;
+#endif
+ case ASM_EXT_VECTOR:
+ BSP_irq_handle_at_opbintc();
+ break;
+ case ASM_PIT_VECTOR:
+ BSP_rtems_irq_tbl[BSP_PIT].hdl
+ (BSP_rtems_irq_tbl[BSP_PIT].handle);
+ break;
+#if 0 /* Critical interrupts not yet supported */
+ case ASM_CRIT_VECTOR:
+ break;
+#endif
+ }
+}
+
+void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
+{
+ /*
+ * Process pending signals that have not already been
+ * processed by _Thread_Displatch. This happens quite
+ * unfrequently : the ISR must have posted an action
+ * to the current running thread.
+ */
+ if ( _Thread_Do_post_task_switch_extension ||
+ _Thread_Executing->do_post_task_switch_extension ) {
+ _Thread_Executing->do_post_task_switch_extension = FALSE;
+ _API_extensions_Run_postswitch();
+ }
+}
+
+/***********************************************************
+ * functions to set/get/remove interrupt handlers
+ ***********************************************************/
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ unsigned int level;
+ /*
+ * check for valid irq name
+ * if invalid, print error and return 0
+ */
+ if (!BSP_IS_VALID_IRQ(irq->name)) {
+ printk("Invalid interrupt vector %d\n",irq->name);
+ return 0;
+ }
+
+ /*
+ * disable interrupts
+ */
+ _CPU_ISR_Disable(level);
+ /*
+ * check, that default handler is installed now
+ */
+ if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
+ _CPU_ISR_Enable(level);
+ printk("IRQ vector %d already connected\n",irq->name);
+ return 0;
+ }
+ /*
+ * store new handler data
+ */
+ rtemsIrqTbl[irq->name] = *irq;
+
+ /*
+ * enable irq at interrupt controller
+ */
+ if (BSP_IS_OPBINTC_IRQ(irq->name)) {
+ BSP_irq_enable_at_opbintc(irq->name);
+ }
+ /*
+ * call "on" function to enable interrupt at device
+ */
+ irq->on(irq);
+ /*
+ * reenable interrupts
+ */
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
+{
+ unsigned int level;
+
+ /*
+ * check for valid IRQ name
+ */
+ if (!BSP_IS_VALID_IRQ(irq->name)) {
+ return 0;
+ }
+ _CPU_ISR_Disable(level);
+ /*
+ * return current IRQ entry
+ */
+ *irq = rtemsIrqTbl[irq->name];
+ _CPU_ISR_Enable(level);
+ return 1;
+}
+
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ unsigned int level;
+
+ /*
+ * check for valid IRQ name
+ */
+ if (!BSP_IS_VALID_IRQ(irq->name)) {
+ return 0;
+ }
+ _CPU_ISR_Disable(level);
+ /*
+ * check, that specified handler is really connected now
+ */
+ if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
+ _CPU_ISR_Enable(level);
+ return 0;
+ }
+ /*
+ * disable interrupt at interrupt controller
+ */
+ if (BSP_IS_OPBINTC_IRQ(irq->name)) {
+ BSP_irq_disable_at_opbintc(irq->name);
+ }
+ /*
+ * disable interrupt at source
+ */
+ irq->off(irq);
+ /*
+ * restore default interrupt handler
+ */
+ rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
+
+ /*
+ * reenable interrupts
+ */
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+/***********************************************************
+ * functions to set/get the basic interrupt management setup
+ ***********************************************************/
+/*
+ * (Re) get info on current RTEMS interrupt management.
+ */
+int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
+{
+ *ret_ptr = BSP_rtems_irq_config;
+ return 0;
+}
+
+
+/*
+ * set management stuff
+ */
+int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
+{
+ int i;
+ unsigned int level;
+
+ _CPU_ISR_Disable(level);
+ /*
+ * store given configuration
+ */
+ BSP_rtems_irq_config = config;
+ BSP_rtems_irq_tbl = BSP_rtems_irq_config->irqHdlTbl;
+ /*
+ * enable any non-empty IRQ entries at OPBINTC
+ */
+ for (i = BSP_OPBINTC_IRQ_LOWEST_OFFSET;
+ i <= BSP_OPBINTC_IRQ_MAX_OFFSET;
+ i++) {
+ if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
+ BSP_irq_enable_at_opbintc(i);
+ BSP_rtems_irq_tbl[i].on((&BSP_rtems_irq_tbl[i]));
+ }
+ else {
+ BSP_rtems_irq_tbl[i].off(&(BSP_rtems_irq_tbl[i]));
+ BSP_irq_disable_at_opbintc(i);
+ }
+ }
+ /*
+ * store any irq-like processor exceptions
+ */
+ for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
+ i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
+ i++) {
+ if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
+ if (BSP_rtems_irq_tbl[i].on != NULL) {
+ BSP_rtems_irq_tbl[i].on
+ (&(BSP_rtems_irq_tbl[i]));
+ }
+ }
+ else {
+ if (BSP_rtems_irq_tbl[i].off != NULL) {
+ BSP_rtems_irq_tbl[i].off
+ (&(BSP_rtems_irq_tbl[i]));
+ }
+ }
+ }
+ _CPU_ISR_Enable(level);
+ return 1;
+}
+/**********************************************
+ * list of exception vectors to tap for interrupt handlers
+ */
+static rtems_raw_except_connect_data BSP_vec_desc[] = {
+#if 0 /* ppc405 has no decrementer */
+ {ASM_DEC_VECTOR,
+ {ASM_DEC_VECTOR,
+ decrementer_exception_vector_prolog_code,
+ (size_t)decrementer_exception_vector_prolog_code_size
+ },
+ exception_nop_enable,
+ exception_nop_enable,
+ exception_always_enabled
+ },
+#endif
+ {ASM_EXT_VECTOR,
+ {ASM_EXT_VECTOR,
+ external_exception_vector_prolog_code,
+ (size_t)&external_exception_vector_prolog_code_size
+ },
+ exception_nop_enable,
+ exception_nop_enable,
+ exception_always_enabled
+ },
+ {ASM_PIT_VECTOR,
+ {ASM_PIT_VECTOR,
+ pit_exception_vector_prolog_code,
+ (size_t)&pit_exception_vector_prolog_code_size
+ },
+ exception_nop_enable,
+ exception_nop_enable,
+ exception_always_enabled
+ }
+#if 0 /* Critical interrupts not yet supported */
+ ,{ASM_CRIT_VECTOR,
+ {ASM_CRIT_VECTOR,
+ critical_exception_vector_prolog_code,
+ critical_exception_vector_prolog_code_size
+ }
+ BSP_irq_nop_func,
+ BSP_irq_nop_func,
+ BSP_irq_true_func
+ }
+#endif
+};
+
+/*
+ * dummy for an empty IRQ handler entry
+ */
+static rtems_irq_connect_data emptyIrq = {
+ 0, /* Irq Name */
+ BSP_irq_nop_hdl, /* handler function */
+ NULL, /* handle passed to handler */
+ BSP_irq_nop_func, /* on function */
+ BSP_irq_nop_func, /* off function */
+ BSP_irq_true_func /* isOn function */
+};
+
+static rtems_irq_global_settings initialConfig = {
+ BSP_IRQ_NUMBER, /* irqNb */
+ { 0, /* Irq Name */
+ BSP_irq_nop_hdl, /* handler function */
+ NULL, /* handle passed to handler */
+ BSP_irq_nop_func, /* on function */
+ BSP_irq_nop_func, /* off function */
+ BSP_irq_true_func /* isOn function */
+ }, /* emptyIrq */
+ rtemsIrqTbl, /* irqHdlTbl */
+ 0, /* irqBase */
+ NULL /* irqPrioTbl */
+};
+
+void BSP_rtems_irq_mng_init(unsigned cpuId)
+{
+ int i;
+ /*
+ * connect all exception vectors needed
+ */
+ for (i = 0;
+ i < (sizeof(BSP_vec_desc) /
+ sizeof(BSP_vec_desc[0]));
+ i++) {
+ if (!ppc_set_exception (&BSP_vec_desc[i])) {
+ BSP_panic("Unable to initialize RTEMS raw exception\n");
+ }
+ }
+ /*
+ * setup interrupt handlers table
+ */
+ for (i = 0;
+ i < BSP_IRQ_NUMBER;
+ i++) {
+ rtemsIrqTbl[i] = emptyIrq;
+ rtemsIrqTbl[i].name = i;
+ }
+ /*
+ * init interrupt controller
+ */
+ opb_intc_init();
+ /*
+ * initialize interrupt management
+ */
+ if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
+ BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
+ }
+}
+
diff --git a/c/src/lib/libbsp/powerpc/virtex/network/xiltemac.c b/c/src/lib/libbsp/powerpc/virtex/network/xiltemac.c
new file mode 100644
index 0000000000..a4316148c2
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/network/xiltemac.c
@@ -0,0 +1,966 @@
+/*
+ * Driver for Xilinx plb temac v3.00a
+ *
+ * Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
+ * Copyright (c) 2007 Linn Products Ltd, Scotland.
+ *
+ * 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.
+ *
+ */
+#define PPC_HAS_CLASSIC_EXCEPTIONS FALSE
+
+#ifndef __INSIDE_RTEMS_BSD_TCPIP_STACK__
+#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
+#endif
+
+#ifndef __BSD_VISIBLE
+#define __BSD_VISIBLE
+#endif
+
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <string.h>
+#include <assert.h>
+
+#include <xiltemac.h>
+#include <rtems/irq.h>
+
+/* Reading/Writing memory mapped i/o */
+#define IN32(aPtr) ((uint32_t)( *((volatile uint32_t *)(aPtr))) )
+#define OUT32(aPtr, aValue) (*((volatile uint32_t *)(aPtr)) = (uint32_t)aValue)
+#define NUM_XILTEMAC_UNITS 2
+
+extern void printk(char*, ...);
+
+/* Why isn't this defined in stdio.h like it's supposed to be? */
+extern int snprintf(char*, size_t, const char*, ...);
+
+void xilTemacInit( void *voidptr );
+void xilTemacReset(struct ifnet *ifp);
+void xilTemacStop(struct ifnet *ifp);
+void xilTemacSend(struct ifnet *ifp);
+void xilTemacStart(struct ifnet *ifp);
+void xilTemacSetMacAddress(struct ifnet *ifp, unsigned char* aAddr);
+void xilTemacPrintStats(struct ifnet *ifp);
+
+void xilTemacRxThread( void *ignore );
+void xilTemacTxThread( void *ignore );
+
+static struct XilTemac gXilTemac[ NUM_XILTEMAC_UNITS ];
+
+static rtems_id gXilRxThread = 0;
+static rtems_id gXilTxThread = 0;
+
+/*
+** Events, one per unit. The event is sent to the rx task from the isr
+** or from the stack to the tx task whenever a unit needs service. The
+** rx/tx tasks identify the requesting unit(s) by their particular
+** events so only requesting units are serviced.
+*/
+
+static rtems_event_set gUnitSignals[ NUM_XILTEMAC_UNITS ]= { RTEMS_EVENT_1,
+ RTEMS_EVENT_2 };
+
+uint32_t xilTemacTxFifoVacancyBytes(uint32_t aBaseAddr)
+{
+ uint32_t ipisr = IN32(aBaseAddr + XTE_IPISR_OFFSET);
+ uint32_t bytes = 0;
+ if(ipisr & XTE_IPXR_XMIT_LFIFO_FULL_MASK) {
+ /* If there's no room in the transmit length fifo, then any room in the
+ * data fifo is irrelevant, return 0 */
+ } else {
+ bytes = IN32(aBaseAddr + XTE_PFIFO_TX_VACANCY_OFFSET);
+ bytes &= XTE_PFIFO_COUNT_MASK;
+ bytes *= 8;
+ }
+ return bytes;
+}
+
+void xilTemacFifoRead64(uint32_t aBaseAddr, uint32_t* aBuf, uint32_t aBytes)
+{
+ uint32_t numqwords = aBytes / 8;
+ uint32_t xtrabytes = aBytes % 8;
+ uint32_t i;
+
+ for(i = 0; i < numqwords; i++)
+ {
+ aBuf[ (i*2) ] = IN32(aBaseAddr + XTE_PFIFO_RX_DATA_OFFSET);
+ aBuf[ (i*2)+1 ] = IN32(aBaseAddr + XTE_PFIFO_RX_DATA_OFFSET + 4);
+ }
+
+ /* If there was a non qword sized read */
+ if( xtrabytes != 0 )
+ {
+ uint32_t lastdwordMS = IN32(aBaseAddr + XTE_PFIFO_RX_DATA_OFFSET);
+ uint32_t lastdwordLS = IN32(aBaseAddr + XTE_PFIFO_RX_DATA_OFFSET + 4);
+ uint8_t* finalbytes = (uint8_t *)&aBuf[ (numqwords*2) ];
+ uint8_t* ptr8;
+ int32_t offset = 0;
+
+ ptr8 = (uint8_t *)&lastdwordMS;
+ if( xtrabytes >= 4 )
+ {
+ finalbytes[ offset++ ] = ptr8[0];
+ finalbytes[ offset++ ] = ptr8[1];
+ finalbytes[ offset++ ] = ptr8[2];
+ finalbytes[ offset++ ] = ptr8[3];
+
+ xtrabytes -= 4;
+ ptr8 = (uint8_t *)&lastdwordLS;
+ }
+
+ if( xtrabytes == 1 )
+ {
+ finalbytes[ offset++ ] = ptr8[0];
+ }
+ else if ( xtrabytes == 2 )
+ {
+ finalbytes[ offset++ ] = ptr8[0];
+ finalbytes[ offset++ ] = ptr8[1];
+ }
+ else if ( xtrabytes == 3 )
+ {
+ finalbytes[ offset++ ] = ptr8[0];
+ finalbytes[ offset++ ] = ptr8[1];
+ finalbytes[ offset++ ] = ptr8[2];
+ }
+ }
+}
+
+void xilTemacFifoWrite64(uint32_t aBaseAddr, uint32_t* aBuf, uint32_t aBytes)
+{
+ uint32_t numqwords = aBytes / 8;
+ uint32_t xtrabytes = aBytes % 8;
+ uint32_t i;
+
+ for(i = 0; i < numqwords; i++ ) {
+ OUT32(aBaseAddr + XTE_PFIFO_TX_DATA_OFFSET , aBuf[ (i*2) ]);
+ OUT32(aBaseAddr + XTE_PFIFO_TX_DATA_OFFSET + 4, aBuf[ (i*2)+1 ]);
+ }
+
+ /* If there was a non word sized write */
+ if( xtrabytes != 0 ) {
+ uint32_t lastdwordMS = 0;
+ uint32_t lastdwordLS = 0;
+ uint8_t* finalbytes = (uint8_t *)&aBuf[ (numqwords*2) ];
+ uint8_t* ptr8;
+ int32_t offset = 0;
+
+ ptr8 = (uint8_t *)&lastdwordMS;
+
+ if( xtrabytes >= 4 ) {
+ ptr8[0] = finalbytes[ offset++ ];
+ ptr8[1] = finalbytes[ offset++ ];
+ ptr8[2] = finalbytes[ offset++ ];
+ ptr8[3] = finalbytes[ offset++ ];
+
+ xtrabytes -= 4;
+
+ ptr8 = (uint8_t *)&lastdwordLS;
+ }
+
+ if( xtrabytes == 1 ) {
+ ptr8[0] = finalbytes[ offset++ ];
+ }
+ else if ( xtrabytes == 2 ) {
+ ptr8[0] = finalbytes[ offset++ ];
+ ptr8[1] = finalbytes[ offset++ ];
+ }
+ else if ( xtrabytes == 3 ) {
+ ptr8[0] = finalbytes[ offset++ ];
+ ptr8[1] = finalbytes[ offset++ ];
+ ptr8[2] = finalbytes[ offset++ ];
+ }
+
+ OUT32(aBaseAddr + XTE_PFIFO_TX_DATA_OFFSET, lastdwordMS);
+ OUT32(aBaseAddr + XTE_PFIFO_TX_DATA_OFFSET + 4, lastdwordLS);
+ }
+}
+
+void xilTemacStop(struct ifnet *ifp)
+{
+ struct XilTemac* xilTemac = ifp->if_softc;
+ uint32_t base = xilTemac->iAddr;
+
+ /* Disable ipif interrupts */
+ OUT32(base + XTE_DGIE_OFFSET, 0);
+
+ /* Disable the receiver */
+ uint32_t rxc1 = IN32(base + XTE_ERXC1_OFFSET);
+ rxc1 &= ~XTE_ERXC1_RXEN_MASK;
+ OUT32(base + XTE_ERXC1_OFFSET, rxc1);
+
+ /* If receiver was receiving a packet when we disabled it, it will be
+ * rejected, clear appropriate status bit */
+ uint32_t ipisr = IN32(base + XTE_IPISR_OFFSET);
+ if( ipisr & XTE_IPXR_RECV_REJECT_MASK ) {
+ OUT32(base + XTE_IPISR_OFFSET, XTE_IPXR_RECV_REJECT_MASK);
+ }
+
+#if PPC_HAS_CLASSIC_EXCEPTIONS
+ if( xilTemac->iOldHandler )
+ {
+ opb_intc_set_vector( xilTemac->iOldHandler, xilTemac->iIsrVector, NULL );
+ xilTemac->iOldHandler = 0;
+ }
+#else
+ if( xilTemac->iOldHandler.name != 0)
+ {
+ BSP_install_rtems_irq_handler (&xilTemac->iOldHandler);
+ }
+#endif
+
+ ifp->if_flags &= ~IFF_RUNNING;
+}
+
+void xilTemacStart(struct ifnet *ifp)
+{
+ if( (ifp->if_flags & IFF_RUNNING) == 0 )
+ {
+ struct XilTemac* xilTemac = ifp->if_softc;
+ uint32_t base = xilTemac->iAddr;
+
+ /* Reset plb temac */
+ OUT32(base + XTE_DSR_OFFSET, XTE_DSR_RESET_MASK);
+ /* Don't have usleep on rtems 4.6
+ usleep(1);
+ */
+ /* @ fastest ppc clock of 500 MHz = 2ns clk */
+ uint32_t i = 0;
+ for( i = 0; i < 1 * 500; i++) {
+ }
+
+ /* Reset hard temac */
+ OUT32(base + XTE_CR_OFFSET, XTE_CR_HTRST_MASK);
+ /* Don't have usleep on rtems 4.6
+ usleep(4);
+ */
+ for( i = 0; i < 4 * 500; i++) {
+ }
+
+ /* Disable the receiver -- no need to disable xmit as we control that ;) */
+ uint32_t rxc1 = IN32(base + XTE_ERXC1_OFFSET);
+ rxc1 &= ~XTE_ERXC1_RXEN_MASK;
+ OUT32(base + XTE_ERXC1_OFFSET, rxc1);
+
+ /* If receiver was receiving a packet when we disabled it, it will be
+ * rejected, clear appropriate status bit */
+ uint32_t ipisr = IN32(base + XTE_IPISR_OFFSET);
+ if( ipisr & XTE_IPXR_RECV_REJECT_MASK ) {
+ OUT32(base + XTE_IPISR_OFFSET, XTE_IPXR_RECV_REJECT_MASK);
+ }
+
+ /* Setup IPIF interrupt enables */
+ uint32_t dier = XTE_DXR_CORE_MASK | XTE_DXR_DPTO_MASK | XTE_DXR_TERR_MASK;
+ dier |= XTE_DXR_RECV_FIFO_MASK | XTE_DXR_SEND_FIFO_MASK;
+ OUT32(base + XTE_DIER_OFFSET, dier);
+
+ /* Set the mac address */
+ xilTemacSetMacAddress( ifp, xilTemac->iArpcom.ac_enaddr);
+
+ /* Set the link speed */
+ uint32_t emcfg = IN32(base + XTE_ECFG_OFFSET);
+ printk("xiltemacStart, default linkspeed: %08x\n", emcfg);
+ emcfg |= XTE_ECFG_LINKSPD_100;
+ OUT32(base + XTE_ECFG_OFFSET, emcfg);
+
+ /* Set phy divisor and enable mdio. For a plb bus freq of 150MHz (the
+ maximum as of Virtex4 Fx), a divisor of 29 gives a mdio clk freq of
+ 2.5MHz (see Xilinx docs for equation), the maximum in the phy standard.
+ For slower plb frequencies, slower mkdio clks will result. They may not
+ be optimal, but they should work. */
+ uint32_t divisor = 29;
+ OUT32(base + XTE_EMC_OFFSET, divisor | XTE_EMC_MDIO_MASK);
+
+#if PPC_HAS_CLASSIC_EXCEPTIONS /* old connect code */
+ /* Connect isr vector */
+ rtems_status_code sc;
+ extern rtems_isr xilTemacIsr( rtems_vector_number aVector );
+ sc = opb_intc_set_vector( xilTemacIsr, xilTemac->iIsrVector, &xilTemac->iOldHandler );
+ if( sc != RTEMS_SUCCESSFUL )
+ {
+ xilTemac->iOldHandler = 0;
+ printk("%s: Could not set interrupt vector for interface '%s' opb_intc_set_vector ret: %d\n", DRIVER_PREFIX, xilTemac->iUnitName, sc );
+ assert(0);
+ }
+#else
+ {
+ extern rtems_isr xilTemacIsr( void *handle );
+ extern void xilTemacIsrOn(const rtems_irq_connect_data *);
+ extern void xilTemacIsrOff(const rtems_irq_connect_data *);
+ extern int xilTemacIsrIsOn(const rtems_irq_connect_data *);
+ rtems_irq_connect_data IrqConnData;
+
+ /*
+ *get old irq handler
+ */
+ xilTemac->iOldHandler.name = xilTemac->iIsrVector;
+ if (!BSP_get_current_rtems_irq_handler (&xilTemac->iOldHandler)) {
+ xilTemac->iOldHandler.name = 0;
+ printk("%s: Unable to detect previous Irq handler\n",DRIVER_PREFIX);
+ rtems_fatal_error_occurred(1);
+ }
+
+ IrqConnData.on = xilTemacIsrOn;
+ IrqConnData.off = xilTemacIsrOff;
+ IrqConnData.isOn = xilTemacIsrIsOn;
+ IrqConnData.name = xilTemac->iIsrVector;
+ IrqConnData.hdl = xilTemacIsr;
+ IrqConnData.handle = xilTemac;
+
+ if (!BSP_install_rtems_irq_handler (&IrqConnData)) {
+ printk("%s: Unable to connect Irq handler\n",DRIVER_PREFIX);
+ rtems_fatal_error_occurred(1);
+ }
+ }
+#endif
+ /* Enable promiscuous mode -- The temac only supports full duplex, which
+ means we're plugged into a switch. Thus promiscuous mode simply means
+ we get all multicast addresses*/
+ OUT32(base + XTE_EAFM_OFFSET, XTE_EAFM_EPPRM_MASK);
+
+ /* Setup and enable receiver */
+ rxc1 = XTE_ERXC1_RXFCS_MASK | XTE_ERXC1_RXEN_MASK | XTE_ERXC1_RXVLAN_MASK;
+ OUT32(base + XTE_ERXC1_OFFSET, rxc1);
+
+ /* Setup and enable transmitter */
+ uint32_t txc = XTE_ETXC_TXEN_MASK | XTE_ETXC_TXVLAN_MASK;
+ OUT32(base + XTE_ETXC_OFFSET, txc);
+
+ /* Enable interrupts for temac */
+ uint32_t ipier = IN32(base + XTE_IPIER_OFFSET);
+ ipier |= (XTE_IPXR_XMIT_ERROR_MASK);
+ ipier |= (XTE_IPXR_RECV_ERROR_MASK | XTE_IPXR_RECV_DONE_MASK);
+ ipier |= (XTE_IPXR_AUTO_NEG_MASK);
+ OUT32(base + XTE_IPIER_OFFSET, ipier);
+
+ printk("%s: xiltemacStart, ipier: %08x\n",DRIVER_PREFIX, ipier);
+
+ /* Enable device global interrutps */
+ OUT32(base + XTE_DGIE_OFFSET, XTE_DGIE_ENABLE_MASK);
+ ifp->if_flags |= IFF_RUNNING;
+ }
+}
+
+void xilTemacInit( void *voidptr )
+{
+}
+
+void xilTemacReset(struct ifnet *ifp)
+{
+ xilTemacStop( ifp );
+ xilTemacStart( ifp );
+}
+
+void xilTemacSetMacAddress(struct ifnet *ifp, unsigned char* aAddr)
+{
+ struct XilTemac* xilTemac = ifp->if_softc;
+ uint32_t base = xilTemac->iAddr;
+
+ /* You can't change the mac address while the card is in operation */
+ if( (ifp->if_flags & IFF_RUNNING) != 0 ) {
+ printk("%s: attempted to change MAC while up, interface '%s'\n", DRIVER_PREFIX, xilTemac->iUnitName );
+ assert(0);
+ }
+ uint32_t mac;
+ mac = aAddr[0] & 0x000000FF;
+ mac |= aAddr[1] << 8;
+ mac |= aAddr[2] << 16;
+ mac |= aAddr[3] << 24;
+ OUT32(base + XTE_EUAW0_OFFSET, mac);
+
+ mac = IN32(base + XTE_EUAW1_OFFSET);
+ mac &= ~XTE_EUAW1_MASK;
+ mac |= aAddr[4] & 0x000000FF;
+ mac |= aAddr[5] << 8;
+ OUT32(base + XTE_EUAW1_OFFSET, mac);
+}
+
+void xilTemacPrintStats( struct ifnet *ifp )
+{
+ struct XilTemac* xilTemac = ifp->if_softc;
+
+ printf("\n");
+ printf("%s: Statistics for interface '%s'\n", DRIVER_PREFIX, xilTemac->iUnitName );
+
+ printf("%s: Ipif Interrupts: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iInterrupts);
+ printf("%s: Rx Interrupts: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxInterrupts);
+ printf("%s: Rx Rejected Interrupts: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxRejectedInterrupts);
+ printf("%s: Rx Rej Invalid Frame: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxRejectedInvalidFrame);
+ printf("%s: Rx Rej Data Fifo Full: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxRejectedDataFifoFull);
+ printf("%s:Rx Rej Length Fifo Full: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxRejectedLengthFifoFull);
+ printf("%s: Rx Stray Events: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxStrayEvents);
+ printf("%s: Rx Max Drained: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxMaxDrained);
+ printf("%s: Tx Interrupts: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iTxInterrupts);
+ printf("%s: Tx Max Drained: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iTxMaxDrained);
+
+ printf("\n");
+}
+
+void xilTemacIsrSingle(struct XilTemac* xilTemac)
+{
+ uint32_t base = xilTemac->iAddr;
+ uint32_t disr = IN32( base + XTE_DISR_OFFSET );
+ struct ifnet* ifp = xilTemac->iIfp;
+
+ if( disr && (ifp->if_flags & IFF_RUNNING) == 0 ) {
+ /* some interrupt status bits are asserted but card is down */
+ printk("%s: Fatal error, disr 0 or this emac not running\n", DRIVER_PREFIX);
+ /*assert(0);*/
+ } else {
+ /* Handle all error conditions first */
+ if( disr & (XTE_DXR_DPTO_MASK | XTE_DXR_TERR_MASK |
+ XTE_DXR_RECV_FIFO_MASK | XTE_DXR_SEND_FIFO_MASK) ) {
+ printk("%s: Fatal Bus error, disr: %08x\n", DRIVER_PREFIX, disr);
+ /*assert(0);*/
+ }
+ if( disr & XTE_DXR_CORE_MASK ) {
+ /* Normal case, temac interrupt */
+ uint32_t ipisr = IN32(base + XTE_IPISR_OFFSET);
+ uint32_t ipier = IN32(base + XTE_IPIER_OFFSET);
+ uint32_t newipier = ipier;
+ uint32_t pending = ipisr & ipier;
+ xilTemac->iStats.iInterrupts++;
+
+ /* Check for all fatal errors, even if that error is not enabled in ipier */
+ if(ipisr & XTE_IPXR_FIFO_FATAL_ERROR_MASK) {
+ printk("%s: Fatal Fifo Error ipisr: %08x\n", DRIVER_PREFIX, ipisr);
+ /*assert(0);*/
+ }
+
+ if(pending & XTE_IPXR_RECV_DONE_MASK) {
+ /* We've received a packet
+ - inc stats
+ - disable rx interrupt
+ - signal rx thread to empty out fifo
+ (rx thread must renable interrupt)
+ */
+ xilTemac->iStats.iRxInterrupts++;
+
+ newipier &= ~XTE_IPXR_RECV_DONE_MASK;
+
+ rtems_event_send(gXilRxThread, xilTemac->iIoEvent);
+ }
+ if(pending & XTE_IPXR_XMIT_DONE_MASK) {
+ /* We've transmitted a packet. This interrupt is only ever enabled in
+ the ipier if the tx thread didn't have enough space in the data fifo
+ or the tplr fifo. If that's the case, we:
+ - inc stats
+ - disable tx interrupt
+ - signal tx thread that a transmit has completed and thus there is now
+ room to send again.
+ */
+ xilTemac->iStats.iTxInterrupts++;
+
+ newipier &= ~XTE_IPXR_XMIT_DONE_MASK;
+
+ rtems_event_send(gXilTxThread, xilTemac->iIoEvent);
+ }
+ if(pending & XTE_IPXR_RECV_DROPPED_MASK) {
+ /* A packet was dropped (because it was invalid, or receiving it
+ have overflowed one of the rx fifo's).
+ - Increment stats.
+ - Clear interrupt condition.
+ */
+ uint32_t toggle = 0;
+ if(pending & XTE_IPXR_RECV_REJECT_MASK) {
+ xilTemac->iStats.iRxRejectedInvalidFrame++;
+ toggle |= XTE_IPXR_RECV_REJECT_MASK;
+ }
+ if(pending & XTE_IPXR_RECV_PFIFO_ABORT_MASK) {
+ xilTemac->iStats.iRxRejectedDataFifoFull++;
+ toggle |= XTE_IPXR_RECV_PFIFO_ABORT_MASK;
+ }
+ if(pending & XTE_IPXR_RECV_LFIFO_ABORT_MASK) {
+ xilTemac->iStats.iRxRejectedLengthFifoFull++;
+ toggle |= XTE_IPXR_RECV_LFIFO_ABORT_MASK;
+ }
+ xilTemac->iStats.iRxRejectedInterrupts++;
+ OUT32(base + XTE_IPISR_OFFSET, toggle);
+ }
+ if(pending & XTE_IPXR_AUTO_NEG_MASK) {
+ printk("%s: Autonegotiation finished\n", DRIVER_PREFIX);
+ OUT32(base + XTE_IPISR_OFFSET, XTE_IPXR_AUTO_NEG_MASK);
+ }
+ if(newipier != ipier) {
+ OUT32(base + XTE_IPIER_OFFSET, newipier);
+ }
+ }
+ }
+}
+
+#if PPC_HAS_CLASSIC_EXCEPTIONS
+rtems_isr xilTemacIsr( rtems_vector_number aVector )
+{
+ struct XilTemac* xilTemac;
+ int i;
+
+ for( i=0; i< NUM_XILTEMAC_UNITS; i++ ) {
+ xilTemac = &gXilTemac[i];
+
+ if( xilTemac->iIsPresent ) {
+ xilTemacIsrSingle(xilTemac);
+ }
+ }
+}
+#else
+rtems_isr xilTemacIsr(void *handle )
+{
+ struct XilTemac* xilTemac = (struct XilTemac*)handle;
+
+ xilTemacIsrSingle(xilTemac);
+}
+
+void xilTemacIsrOn(const rtems_irq_connect_data *unused)
+{
+}
+
+void xilTemacIsrOff(const rtems_irq_connect_data *unused)
+{
+}
+
+int xilTemacIsrIsOn(const rtems_irq_connect_data *unused)
+{
+ return 1;
+}
+#endif
+
+
+int32_t xilTemacSetMulticastFilter(struct ifnet *ifp)
+{
+ return 0;
+}
+
+int xilTemacIoctl(struct ifnet* ifp, ioctl_command_t aCommand, caddr_t aData)
+{
+ struct XilTemac* xilTemac = ifp->if_softc;
+ int32_t error = 0;
+
+ switch(aCommand) {
+ case SIOCGIFADDR:
+ case SIOCSIFADDR:
+ ether_ioctl(ifp, aCommand, aData);
+ break;
+
+ case SIOCSIFFLAGS:
+ switch(ifp->if_flags & (IFF_UP | IFF_RUNNING))
+ {
+ case IFF_RUNNING:
+ xilTemacStop(ifp);
+ break;
+
+ case IFF_UP:
+ xilTemacStart(ifp);
+ break;
+
+ case IFF_UP | IFF_RUNNING:
+ xilTemacReset(ifp);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case SIOCADDMULTI:
+ case SIOCDELMULTI: {
+ struct ifreq* ifr = (struct ifreq*) aData;
+ error = ((aCommand == SIOCADDMULTI) ?
+ ( ether_addmulti(ifr, &(xilTemac->iArpcom)) ) :
+ ( ether_delmulti(ifr, &(xilTemac->iArpcom)))
+ );
+ /* ENETRESET indicates that driver should update its multicast filters */
+ if(error == ENETRESET)
+ {
+ error = xilTemacSetMulticastFilter( ifp );
+ }
+ break;
+ }
+
+ case SIO_RTEMS_SHOW_STATS:
+ xilTemacPrintStats( ifp );
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+ return error;
+}
+
+void xilTemacSend(struct ifnet* ifp)
+{
+ struct XilTemac* xilTemac = ifp->if_softc;
+
+ /* wake up tx thread w/ outbound interface's signal */
+ rtems_event_send( gXilTxThread, xilTemac->iIoEvent );
+
+ ifp->if_flags |= IFF_OACTIVE;
+}
+
+/* align the tx buffer to 32 bytes just for kicks, should make it more
+ * cache friendly */
+static unsigned char gTxBuf[2048] __attribute__ ((aligned (32)));
+
+void xilTemacSendPacket(struct ifnet *ifp, struct mbuf* aMbuf)
+{
+ struct XilTemac *xilTemac = ifp->if_softc;
+ struct mbuf *n = aMbuf;
+ uint32_t len = 0;
+
+#ifdef DEBUG
+ printk("SendPacket\n");
+ printk("TXD: 0x%08x\n", (int32_t) n->m_data);
+#endif
+
+ /* assemble the packet into the tx buffer */
+ for(;;) {
+#ifdef DEBUG
+ uint32_t i = 0;
+ printk("MBUF: 0x%08x : ", (int32_t) n->m_data);
+ for (i=0;i<n->m_len;i+=2) {
+ printk("%02x%02x ", mtod(n, unsigned char*)[i], mtod(n, unsigned char*)[i+1]);
+ }
+ printk("\n");
+#endif
+
+ if( n->m_len > 0 ) {
+ memcpy( &gTxBuf[ len ], (char *)n->m_data, n->m_len);
+ len += n->m_len;
+ }
+ if( (n = n->m_next) == 0) {
+ break;
+ }
+ }
+
+ xilTemacFifoWrite64( xilTemac->iAddr, (uint32_t*)gTxBuf, len );
+ /* Set the Transmit Packet Length Register which registers the packet
+ * length, enqueues the packet and signals the xmit unit to start
+ * sending. */
+ OUT32(xilTemac->iAddr + XTE_TPLR_OFFSET, len);
+
+#ifdef DEBUG
+ printk("%s: txpkt, len %d\n", DRIVER_PREFIX, len );
+ memset(gTxBuf, 0, len);
+#endif
+}
+
+void xilTemacTxThreadSingle(struct ifnet* ifp)
+{
+ struct XilTemac* xilTemac = ifp->if_softc;
+ struct mbuf* m;
+ uint32_t base = xilTemac->iAddr;
+
+#ifdef DEBUG
+ printk("%s: tx send packet, interface '%s'\n", DRIVER_PREFIX, xilTemac->iUnitName );
+#endif
+
+ /* Send packets till mbuf queue empty or tx fifo full */
+ for(;;) {
+ uint32_t i = 0;
+
+ /* 1) clear out any statuses from previously sent tx frames */
+ while( IN32(base + XTE_IPISR_OFFSET) & XTE_IPXR_XMIT_DONE_MASK ) {
+ IN32(base + XTE_TSR_OFFSET);
+ OUT32(base + XTE_IPISR_OFFSET, XTE_IPXR_XMIT_DONE_MASK);
+ i++;
+ }
+ if( i > xilTemac->iStats.iTxMaxDrained ) {
+ xilTemac->iStats.iTxMaxDrained = i;
+ }
+
+ /* 2) Check if enough space in tx data fifo _and_ tx tplr for an entire
+ ethernet frame */
+ if( xilTemacTxFifoVacancyBytes( xilTemac->iAddr ) <= ifp->if_mtu ) {
+ /* 2a) If not, enable transmit done interrupt and break out of loop to
+ wait for space */
+ uint32_t ipier = IN32(base + XTE_IPIER_OFFSET);
+ ipier |= (XTE_IPXR_XMIT_DONE_MASK);
+ OUT32(base + XTE_IPIER_OFFSET, ipier);
+ break;
+ }
+
+ /* 3) Contuine to dequeue mbuf chains till none left */
+ IF_DEQUEUE( &(ifp->if_snd), m);
+ if( !m ) {
+ break;
+ }
+
+ /* 4) Send dequeued mbuf chain */
+ xilTemacSendPacket( ifp, m );
+
+ /* 5) Free mbuf chain */
+ m_freem( m );
+ }
+ ifp->if_flags &= ~IFF_OACTIVE;
+}
+
+void xilTemacTxThread( void *ignore )
+{
+ struct XilTemac *xilTemac;
+ struct ifnet *ifp;
+
+ rtems_event_set events;
+ int i;
+
+ for(;;) {
+ /* Wait for:
+ - notification from stack of packet to send OR
+ - notification from interrupt handler that there is space available to
+ send already queued packets
+ */
+ rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &events );
+
+ for(i=0; i< NUM_XILTEMAC_UNITS; i++) {
+ xilTemac = &gXilTemac[i];
+
+ if( xilTemac->iIsPresent ) {
+ ifp = xilTemac->iIfp;
+
+ if( (ifp->if_flags & IFF_RUNNING) ) {
+
+ if( events & xilTemac->iIoEvent ) {
+ xilTemacTxThreadSingle(ifp);
+ }
+
+ } else {
+ printk("%s: xilTemacTxThread: event received for device: %s, but device not active\n",
+ DRIVER_PREFIX, xilTemac->iUnitName);
+ assert(0);
+ }
+ }
+ }
+ }
+}
+
+void xilTemacRxThreadSingle(struct ifnet* ifp)
+{
+ struct XilTemac* xilTemac = ifp->if_softc;
+
+ uint32_t npkts = 0;
+#ifdef DEBUG
+ printk("%s: rxthread, packet rx on interface %s\n", DRIVER_PREFIX, xilTemac->iUnitName );
+#endif
+
+ uint32_t base = xilTemac->iAddr;
+
+ /* While RECV_DONE_MASK in ipisr stays set */
+ while( IN32(base + XTE_IPISR_OFFSET) & XTE_IPXR_RECV_DONE_MASK ) {
+
+ /* 1) Read the length of the packet */
+ uint32_t bytes = IN32(base + XTE_RPLR_OFFSET);
+
+ /* 2) Read the Read Status Register (which contains no information). When
+ * all of these in the fifo have been read, then XTE_IPXR_RECV_DONE_MASK
+ * will stay turned off, after it's written to */
+ IN32(base + XTE_RSR_OFFSET);
+ npkts++;
+
+ struct mbuf* m;
+ struct ether_header* eh;
+
+ /* 3) Get some memory from the ip stack to store the packet in */
+ MGETHDR(m, M_WAIT, MT_DATA);
+ MCLGET(m, M_WAIT);
+
+ m->m_pkthdr.rcvif = ifp;
+
+ /* 4) Copy the packet into the ip stack's memory */
+ xilTemacFifoRead64( base, mtod(m, uint32_t*), bytes);
+
+ m->m_len = bytes - sizeof(struct ether_header);
+ m->m_pkthdr.len = bytes - sizeof(struct ether_header);
+
+ eh = mtod(m, struct ether_header*);
+
+ m->m_data += sizeof(struct ether_header);
+
+ /* 5) Tell the ip stack about the received packet */
+ ether_input(ifp, eh, m);
+
+ /* 6) Try and turn off XTE_IPXR_RECV_DONE bit in the ipisr. If there's
+ * still more packets (ie RSR ! empty), then it will stay asserted. If
+ * there's no more packets, this will turn it off.
+ */
+ OUT32(base + XTE_IPISR_OFFSET, XTE_IPXR_RECV_DONE_MASK);
+ }
+
+ /* End) All Rx packets serviced, renable rx interrupt */
+ uint32_t ipier = IN32(base + XTE_IPIER_OFFSET);
+ ipier |= XTE_IPXR_RECV_DONE_MASK;
+ OUT32(base + XTE_IPIER_OFFSET, ipier);
+
+#ifdef DEBUG
+ printk("%s: rxthread, retrieved %d packets\n", DRIVER_PREFIX, npkts );
+#endif
+ if(npkts > xilTemac->iStats.iRxMaxDrained) {
+ xilTemac->iStats.iRxMaxDrained = npkts;
+ }
+ /* ??) Very very occasionally, under extremely high stress, I get a situation
+ * where we process no packets. That is, the rx thread was evented, but
+ * there was no packet available. I'm not sure how this happens. Ideally,
+ * it shouldn't ocurr, and I suspect a minor bug in the driver. However, for
+ * me it's happenning 3 times in several hunderd million interrupts. Nothing
+ * bad happens, as long as we don't read from the rx fifo's if nothing is
+ * there. It is just not as efficient as possible (rx thread being evented
+ * pointlessly) and a bit disconcerting about how it's ocurring.
+ * The best way to reproduce this is to have two clients run:
+ * $ ping <host> -f -s 65507
+ * This flood pings the device from two clients with the maximum size ping
+ * packet. It absolutely hammers the device under test. Eventually, (if
+ * you leave it running overnight for instance), you'll get a couple of these
+ * stray rx events. */
+ if(npkts == 0) {
+ /*printk("%s: RxThreadSingle: fatal error: event received, but no packets available\n", DRIVER_PREFIX);
+ assert(0); */
+ xilTemac->iStats.iRxStrayEvents++;
+ }
+}
+
+void xilTemacRxThread( void *ignore )
+{
+ struct XilTemac* xilTemac;
+ struct ifnet* ifp;
+ int i;
+ rtems_event_set events;
+
+#ifdef DEBUG
+ printk("%s: xilTemacRxThread running\n", DRIVER_PREFIX );
+#endif
+
+ for(;;) {
+ rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
+ RTEMS_WAIT | RTEMS_EVENT_ANY,
+ RTEMS_NO_TIMEOUT,
+ &events);
+
+#ifdef DEBUG
+ printk("%s: rxthread, wakeup\n", DRIVER_PREFIX );
+#endif
+
+ for(i=0; i< NUM_XILTEMAC_UNITS; i++) {
+ xilTemac = &gXilTemac[i];
+
+ if( xilTemac->iIsPresent ) {
+ ifp = xilTemac->iIfp;
+
+ if( (ifp->if_flags & IFF_RUNNING) != 0 ) {
+ if( events & xilTemac->iIoEvent ) {
+ xilTemacRxThreadSingle(ifp);
+ }
+ }
+ else {
+ printk("%s: rxthread, interface %s present but not running\n", DRIVER_PREFIX, xilTemac->iUnitName );
+ assert(0);
+ }
+ }
+ }
+ }
+}
+
+int32_t xilTemac_driver_attach(struct rtems_bsdnet_ifconfig* aBsdConfig, int aDummy)
+{
+ struct ifnet* ifp;
+ int32_t mtu;
+ int32_t unit;
+ char* unitName;
+ struct XilTemac* xilTemac;
+
+ unit = rtems_bsdnet_parse_driver_name(aBsdConfig, &unitName);
+ if(unit < 0 )
+ {
+ printk("%s: Interface Unit number < 0\n", DRIVER_PREFIX );
+ return 0;
+ }
+
+ if( aBsdConfig->bpar == 0 )
+ {
+ printk("%s: Did not specify base address for device '%s'", DRIVER_PREFIX, unitName );
+ return 0;
+ }
+
+ if( aBsdConfig->hardware_address == NULL )
+ {
+ printk("%s: No MAC address given for interface '%s'\n", DRIVER_PREFIX, unitName );
+ return 0;
+ }
+
+ xilTemac = &gXilTemac[ unit ];
+ memset(xilTemac, 0, sizeof(struct XilTemac));
+
+ xilTemac->iIsPresent = 1;
+
+ snprintf( xilTemac->iUnitName, MAX_UNIT_BYTES, "%s%d", unitName, unit );
+
+ xilTemac->iIfp = &(xilTemac->iArpcom.ac_if);
+ ifp = &(xilTemac->iArpcom.ac_if);
+ xilTemac->iAddr = aBsdConfig->bpar;
+ xilTemac->iIoEvent = gUnitSignals[ unit ];
+ xilTemac->iIsrVector = aBsdConfig->irno;
+
+ memcpy( xilTemac->iArpcom.ac_enaddr, aBsdConfig->hardware_address, ETHER_ADDR_LEN);
+
+ if( aBsdConfig->mtu )
+ {
+ mtu = aBsdConfig->mtu;
+ }
+ else
+ {
+ mtu = ETHERMTU;
+ }
+
+ ifp->if_softc = xilTemac;
+ ifp->if_unit = unit;
+ ifp->if_name = unitName;
+ ifp->if_mtu = mtu;
+ ifp->if_init = xilTemacInit;
+ ifp->if_ioctl = xilTemacIoctl;
+ ifp->if_start = xilTemacSend;
+ ifp->if_output = ether_output;
+
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+
+ if(ifp->if_snd.ifq_maxlen == 0)
+ {
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ }
+
+ if_attach(ifp);
+ ether_ifattach(ifp);
+
+ /* create shared rx & tx threads */
+ if( (gXilRxThread == 0) && (gXilTxThread == 0) )
+ {
+ printk("%s: Creating shared RX/TX threads\n", DRIVER_PREFIX );
+ gXilRxThread = rtems_bsdnet_newproc("xerx", 4096, xilTemacRxThread, NULL );
+ gXilTxThread = rtems_bsdnet_newproc("xetx", 4096, xilTemacTxThread, NULL );
+ }
+
+ printk("%s: Initializing driver for '%s'\n", DRIVER_PREFIX, xilTemac->iUnitName );
+
+ printk("%s: base address 0x%08X, intnum 0x%02X, \n",
+ DRIVER_PREFIX,
+ aBsdConfig->bpar,
+ aBsdConfig->irno );
+
+ return 1;
+}
+
diff --git a/c/src/lib/libbsp/powerpc/virtex/network/xiltemac.h b/c/src/lib/libbsp/powerpc/virtex/network/xiltemac.h
new file mode 100644
index 0000000000..6a0c821b01
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/network/xiltemac.h
@@ -0,0 +1,375 @@
+/*
+ * Driver for plb inteface of the xilinx temac 3.00a
+ *
+ * Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
+ * Copyright (c) 2007 Linn Products Ltd, Scotland.
+ *
+ * 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 _XILINX_TEMAC_
+#define _XILINX_TEMAC_
+#include <rtems/irq.h>
+
+
+#define XILTEMAC_DRIVER_PREFIX "xiltemac"
+
+#define DRIVER_PREFIX XILTEMAC_DRIVER_PREFIX
+
+
+/** IPIF interrupt and reset registers
+ */
+#define XTE_DISR_OFFSET 0x00000000 /**< Device interrupt status */
+#define XTE_DIPR_OFFSET 0x00000004 /**< Device interrupt pending */
+#define XTE_DIER_OFFSET 0x00000008 /**< Device interrupt enable */
+#define XTE_DIIR_OFFSET 0x00000018 /**< Device interrupt ID */
+#define XTE_DGIE_OFFSET 0x0000001C /**< Device global interrupt enable */
+#define XTE_IPISR_OFFSET 0x00000020 /**< IP interrupt status */
+#define XTE_IPIER_OFFSET 0x00000028 /**< IP interrupt enable */
+#define XTE_DSR_OFFSET 0x00000040 /**< Device software reset (write) */
+
+/** IPIF transmit fifo
+ */
+#define XTE_PFIFO_TX_BASE_OFFSET 0x00002000 /**< Packet FIFO Tx channel */
+#define XTE_PFIFO_TX_VACANCY_OFFSET 0x00002004 /**< Packet Fifo Tx Vacancy */
+#define XTE_PFIFO_TX_DATA_OFFSET 0x00002100 /**< IPIF Tx packet fifo port */
+
+/** IPIF receive fifo
+ */
+#define XTE_PFIFO_RX_BASE_OFFSET 0x00002010 /**< Packet FIFO Rx channel */
+#define XTE_PFIFO_RX_VACANCY_OFFSET 0x00002014 /**< Packet Fifo Rx Vacancy */
+#define XTE_PFIFO_RX_DATA_OFFSET 0x00002200 /**< IPIF Rx packet fifo port */
+
+/** IPIF fifo masks
+ */
+#define XTE_PFIFO_COUNT_MASK 0x00FFFFFF
+
+/** IPIF transmit and recieve DMA offsets
+ */
+#define XTE_DMA_SEND_OFFSET 0x00002300 /**< DMA Tx channel */
+#define XTE_DMA_RECV_OFFSET 0x00002340 /**< DMA Rx channel */
+
+/** IPIF IPIC_TO_TEMAC Core Registers
+ */
+#define XTE_CR_OFFSET 0x00001000 /**< Control */
+#define XTE_TPLR_OFFSET 0x00001004 /**< Tx packet length (FIFO) */
+#define XTE_TSR_OFFSET 0x00001008 /**< Tx status (FIFO) */
+#define XTE_RPLR_OFFSET 0x0000100C /**< Rx packet length (FIFO) */
+#define XTE_RSR_OFFSET 0x00001010 /**< Receive status */
+#define XTE_IFGP_OFFSET 0x00001014 /**< Interframe gap */
+#define XTE_TPPR_OFFSET 0x00001018 /**< Tx pause packet */
+
+/** TEMAC Core Registers
+ * These are registers defined within the device's hard core located in the
+ * processor block. They are accessed with the host interface. These registers
+ * are addressed offset by XTE_HOST_IPIF_OFFSET or by the DCR base address
+ * if so configured.
+ */
+#define XTE_HOST_IPIF_OFFSET 0x00003000 /**< Offset of host registers when
+ memory mapped into IPIF */
+#define XTE_ERXC0_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000200) /**< Rx configuration word 0 */
+#define XTE_ERXC1_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000240) /**< Rx configuration word 1 */
+#define XTE_ETXC_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000280) /**< Tx configuration */
+#define XTE_EFCC_OFFSET (XTE_HOST_IPIF_OFFSET + 0x000002C0) /**< Flow control configuration */
+#define XTE_ECFG_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000300) /**< EMAC configuration */
+#define XTE_EGMIC_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000320) /**< RGMII/SGMII configuration */
+#define XTE_EMC_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000340) /**< Management configuration */
+#define XTE_EUAW0_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000380) /**< Unicast address word 0 */
+#define XTE_EUAW1_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000384) /**< Unicast address word 1 */
+#define XTE_EMAW0_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000388) /**< Multicast address word 0 */
+#define XTE_EMAW1_OFFSET (XTE_HOST_IPIF_OFFSET + 0x0000038C) /**< Multicast address word 1 */
+#define XTE_EAFM_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000390) /**< Promisciuous mode */
+#define XTE_EIRS_OFFSET (XTE_HOST_IPIF_OFFSET + 0x000003A0) /**< IRstatus */
+#define XTE_EIREN_OFFSET (XTE_HOST_IPIF_OFFSET + 0x000003A4) /**< IRenable */
+#define XTE_EMIID_OFFSET (XTE_HOST_IPIF_OFFSET + 0x000003B0) /**< MIIMwrData */
+#define XTE_EMIIC_OFFSET (XTE_HOST_IPIF_OFFSET + 0x000003B4) /**< MiiMcnt */
+
+/* Register masks. The following constants define bit locations of various
+ * control bits in the registers. Constants are not defined for those registers
+ * that have a single bit field representing all 32 bits. For further
+ * information on the meaning of the various bit masks, refer to the HW spec.
+ */
+
+/** Interrupt status bits for top level interrupts
+ * These bits are associated with the XTE_DISR_OFFSET, XTE_DIPR_OFFSET,
+ * and XTE_DIER_OFFSET registers.
+ */
+#define XTE_DXR_SEND_FIFO_MASK 0x00000040 /**< Send FIFO channel */
+#define XTE_DXR_RECV_FIFO_MASK 0x00000020 /**< Receive FIFO channel */
+#define XTE_DXR_RECV_DMA_MASK 0x00000010 /**< Receive DMA channel */
+#define XTE_DXR_SEND_DMA_MASK 0x00000008 /**< Send DMA channel */
+#define XTE_DXR_CORE_MASK 0x00000004 /**< Core */
+#define XTE_DXR_DPTO_MASK 0x00000002 /**< Data phase timeout */
+#define XTE_DXR_TERR_MASK 0x00000001 /**< Transaction error */
+
+/** Interrupt status bits for MAC interrupts
+ * These bits are associated with XTE_IPISR_OFFSET and XTE_IPIER_OFFSET
+ * registers.
+ */
+#define XTE_IPXR_XMIT_DONE_MASK 0x00000001 /**< Tx complete */
+#define XTE_IPXR_RECV_DONE_MASK 0x00000002 /**< Rx complete */
+#define XTE_IPXR_AUTO_NEG_MASK 0x00000004 /**< Auto negotiation complete */
+#define XTE_IPXR_RECV_REJECT_MASK 0x00000008 /**< Rx packet rejected */
+#define XTE_IPXR_XMIT_SFIFO_EMPTY_MASK 0x00000010 /**< Tx status fifo empty */
+#define XTE_IPXR_RECV_LFIFO_EMPTY_MASK 0x00000020 /**< Rx length fifo empty */
+#define XTE_IPXR_XMIT_LFIFO_FULL_MASK 0x00000040 /**< Tx length fifo full */
+#define XTE_IPXR_RECV_LFIFO_OVER_MASK 0x00000080 /**< Rx length fifo overrun
+ Note that this signal is
+ no longer asserted by HW
+ */
+#define XTE_IPXR_RECV_LFIFO_UNDER_MASK 0x00000100 /**< Rx length fifo underrun */
+#define XTE_IPXR_XMIT_SFIFO_OVER_MASK 0x00000200 /**< Tx status fifo overrun */
+#define XTE_IPXR_XMIT_SFIFO_UNDER_MASK 0x00000400 /**< Tx status fifo underrun */
+#define XTE_IPXR_XMIT_LFIFO_OVER_MASK 0x00000800 /**< Tx length fifo overrun */
+#define XTE_IPXR_XMIT_LFIFO_UNDER_MASK 0x00001000 /**< Tx length fifo underrun */
+#define XTE_IPXR_RECV_PFIFO_ABORT_MASK 0x00002000 /**< Rx packet rejected due to
+ full packet FIFO */
+#define XTE_IPXR_RECV_LFIFO_ABORT_MASK 0x00004000 /**< Rx packet rejected due to
+ full length FIFO */
+
+#define XTE_IPXR_RECV_DROPPED_MASK \
+ (XTE_IPXR_RECV_REJECT_MASK | \
+ XTE_IPXR_RECV_PFIFO_ABORT_MASK | \
+ XTE_IPXR_RECV_LFIFO_ABORT_MASK) /**< IPXR bits that indicate a dropped
+ receive frame */
+#define XTE_IPXR_XMIT_ERROR_MASK \
+ (XTE_IPXR_XMIT_SFIFO_OVER_MASK | \
+ XTE_IPXR_XMIT_SFIFO_UNDER_MASK | \
+ XTE_IPXR_XMIT_LFIFO_OVER_MASK | \
+ XTE_IPXR_XMIT_LFIFO_UNDER_MASK) /**< IPXR bits that indicate transmit
+ errors */
+
+#define XTE_IPXR_RECV_ERROR_MASK \
+ (XTE_IPXR_RECV_DROPPED_MASK | \
+ XTE_IPXR_RECV_LFIFO_UNDER_MASK) /**< IPXR bits that indicate receive
+ errors */
+
+#define XTE_IPXR_FIFO_FATAL_ERROR_MASK \
+ (XTE_IPXR_XMIT_SFIFO_OVER_MASK | \
+ XTE_IPXR_XMIT_SFIFO_UNDER_MASK | \
+ XTE_IPXR_XMIT_LFIFO_OVER_MASK | \
+ XTE_IPXR_XMIT_LFIFO_UNDER_MASK | \
+ XTE_IPXR_RECV_LFIFO_UNDER_MASK) /**< IPXR bits that indicate errors with
+ one of the length or status FIFOs
+ that is fatal in nature. These bits
+ can only be cleared by a device
+ reset */
+
+/** Software reset register (DSR)
+ */
+#define XTE_DSR_RESET_MASK 0x0000000A /**< Write this value to DSR to
+ reset entire core */
+
+
+/** Global interrupt enable register (DGIE)
+ */
+#define XTE_DGIE_ENABLE_MASK 0x80000000 /**< Write this value to DGIE to
+ enable interrupts from this
+ device */
+
+/** Control Register (CR)
+ */
+#define XTE_CR_HTRST_MASK 0x00000008 /**< Reset hard temac */
+#define XTE_CR_BCREJ_MASK 0x00000004 /**< Disable broadcast address
+ filtering */
+#define XTE_CR_MCREJ_MASK 0x00000002 /**< Disable multicast address
+ filtering */
+#define XTE_CR_HDUPLEX_MASK 0x00000001 /**< Enable half duplex operation */
+
+
+/** Transmit Packet Length Register (TPLR)
+ */
+#define XTE_TPLR_TXPL_MASK 0x00003FFF /**< Tx packet length in bytes */
+
+
+/** Transmit Status Register (TSR)
+ */
+#define XTE_TSR_TXED_MASK 0x80000000 /**< Excess deferral error */
+#define XTE_TSR_PFIFOU_MASK 0x40000000 /**< Packet FIFO underrun */
+#define XTE_TSR_TXA_MASK 0x3E000000 /**< Transmission attempts */
+#define XTE_TSR_TXLC_MASK 0x01000000 /**< Late collision error */
+#define XTE_TSR_TPCF_MASK 0x00000001 /**< Transmit packet complete
+ flag */
+
+#define XTE_TSR_ERROR_MASK \
+ (XTE_TSR_TXED_MASK | \
+ XTE_TSR_PFIFOU_MASK | \
+ XTE_TSR_TXLC_MASK) /**< TSR bits that indicate an
+ error */
+
+
+/** Receive Packet Length Register (RPLR)
+ */
+#define XTE_RPLR_RXPL_MASK 0x00003FFF /**< Rx packet length in bytes */
+
+
+/** Receive Status Register (RSR)
+ */
+#define XTE_RSR_RPCF_MASK 0x00000001 /**< Receive packet complete
+ flag */
+
+/** Interframe Gap Register (IFG)
+ */
+#define XTE_IFG_IFGD_MASK 0x000000FF /**< IFG delay */
+
+
+/** Transmit Pause Packet Register (TPPR)
+ */
+#define XTE_TPPR_TPPD_MASK 0x0000FFFF /**< Tx pause packet data */
+
+
+/** Receiver Configuration Word 1 (ERXC1)
+ */
+#define XTE_ERXC1_RXRST_MASK 0x80000000 /**< Receiver reset */
+#define XTE_ERXC1_RXJMBO_MASK 0x40000000 /**< Jumbo frame enable */
+#define XTE_ERXC1_RXFCS_MASK 0x20000000 /**< FCS not stripped */
+#define XTE_ERXC1_RXEN_MASK 0x10000000 /**< Receiver enable */
+#define XTE_ERXC1_RXVLAN_MASK 0x08000000 /**< VLAN enable */
+#define XTE_ERXC1_RXHD_MASK 0x04000000 /**< Half duplex */
+#define XTE_ERXC1_RXLT_MASK 0x02000000 /**< Length/type check disable */
+#define XTE_ERXC1_ERXC1_MASK 0x0000FFFF /**< Pause frame source address
+ bits [47:32]. Bits [31:0]
+ are stored in register
+ ERXC0 */
+
+
+/** Transmitter Configuration (ETXC)
+ */
+#define XTE_ETXC_TXRST_MASK 0x80000000 /**< Transmitter reset */
+#define XTE_ETXC_TXJMBO_MASK 0x40000000 /**< Jumbo frame enable */
+#define XTE_ETXC_TXFCS_MASK 0x20000000 /**< Generate FCS */
+#define XTE_ETXC_TXEN_MASK 0x10000000 /**< Transmitter enable */
+#define XTE_ETXC_TXVLAN_MASK 0x08000000 /**< VLAN enable */
+#define XTE_ETXC_TXHD_MASK 0x04000000 /**< Half duplex */
+#define XTE_ETXC_TXIFG_MASK 0x02000000 /**< IFG adjust enable */
+
+
+/** Flow Control Configuration (EFCC)
+ */
+#define XTE_EFCC_TXFLO_MASK 0x40000000 /**< Tx flow control enable */
+#define XTE_EFCC_RXFLO_MASK 0x20000000 /**< Rx flow control enable */
+
+
+/** EMAC Configuration (ECFG)
+ */
+#define XTE_ECFG_LINKSPD_MASK 0xC0000000 /**< Link speed */
+#define XTE_ECFG_RGMII_MASK 0x20000000 /**< RGMII mode enable */
+#define XTE_ECFG_SGMII_MASK 0x10000000 /**< SGMII mode enable */
+#define XTE_ECFG_1000BASEX_MASK 0x08000000 /**< 1000BaseX mode enable */
+#define XTE_ECFG_HOSTEN_MASK 0x04000000 /**< Host interface enable */
+#define XTE_ECFG_TX16BIT 0x02000000 /**< 16 bit Tx client enable */
+#define XTE_ECFG_RX16BIT 0x01000000 /**< 16 bit Rx client enable */
+
+#define XTE_ECFG_LINKSPD_10 0x00000000 /**< XTE_ECFG_LINKSPD_MASK for
+ 10 Mbit */
+#define XTE_ECFG_LINKSPD_100 0x40000000 /**< XTE_ECFG_LINKSPD_MASK for
+ 100 Mbit */
+#define XTE_ECFG_LINKSPD_1000 0x80000000 /**< XTE_ECFG_LINKSPD_MASK for
+ 1000 Mbit */
+
+/** EMAC RGMII/SGMII Configuration (EGMIC)
+ */
+#define XTE_EGMIC_RGLINKSPD_MASK 0xC0000000 /**< RGMII link speed */
+#define XTE_EGMIC_SGLINKSPD_MASK 0x0000000C /**< SGMII link speed */
+#define XTE_EGMIC_RGSTATUS_MASK 0x00000002 /**< RGMII link status */
+#define XTE_EGMIC_RGHALFDUPLEX_MASK 0x00000001 /**< RGMII half duplex */
+
+#define XTE_EGMIC_RGLINKSPD_10 0x00000000 /**< XTE_EGMIC_RGLINKSPD_MASK
+ for 10 Mbit */
+#define XTE_EGMIC_RGLINKSPD_100 0x40000000 /**< XTE_EGMIC_RGLINKSPD_MASK
+ for 100 Mbit */
+#define XTE_EGMIC_RGLINKSPD_1000 0x80000000 /**< XTE_EGMIC_RGLINKSPD_MASK
+ for 1000 Mbit */
+#define XTE_EGMIC_SGLINKSPD_10 0x00000000 /**< XTE_SGMIC_RGLINKSPD_MASK
+ for 10 Mbit */
+#define XTE_EGMIC_SGLINKSPD_100 0x00000004 /**< XTE_SGMIC_RGLINKSPD_MASK
+ for 100 Mbit */
+#define XTE_EGMIC_SGLINKSPD_1000 0x00000008 /**< XTE_SGMIC_RGLINKSPD_MASK
+ for 1000 Mbit */
+
+/** EMAC Management Configuration (EMC)
+ */
+#define XTE_EMC_MDIO_MASK 0x00000040 /**< MII management enable */
+#define XTE_EMC_CLK_DVD_MAX 0x3F /**< Maximum MDIO divisor */
+
+
+/** EMAC Unicast Address Register Word 1 (EUAW1)
+ */
+#define XTE_EUAW1_MASK 0x0000FFFF /**< Station address bits [47:32]
+ Station address bits [31:0]
+ are stored in register
+ EUAW0 */
+
+
+/** EMAC Multicast Address Register Word 1 (EMAW1)
+ */
+#define XTE_EMAW1_CAMRNW_MASK 0x00800000 /**< CAM read/write control */
+#define XTE_EMAW1_CAMADDR_MASK 0x00030000 /**< CAM address mask */
+#define XTE_EUAW1_MASK 0x0000FFFF /**< Multicast address bits [47:32]
+ Multicast address bits [31:0]
+ are stored in register
+ EMAW0 */
+#define XTE_EMAW1_CAMMADDR_SHIFT_MASK 16 /**< Number of bits to shift right
+ to align with
+ XTE_EMAW1_CAMADDR_MASK */
+
+
+/** EMAC Address Filter Mode (EAFM)
+ */
+#define XTE_EAFM_EPPRM_MASK 0x80000000 /**< Promiscuous mode enable */
+
+
+/** EMAC MII Management Write Data (EMIID)
+ */
+#define XTE_EMIID_MIIMWRDATA_MASK 0x0000FFFF /**< Data port */
+
+
+/** EMAC MII Management Control (EMIIC)
+ */
+#define XTE_EMIID_MIIMDECADDR_MASK 0x0000FFFF /**< Address port */
+
+
+struct XilTemacStats
+{
+ volatile uint32_t iInterrupts;
+
+ volatile uint32_t iRxInterrupts;
+ volatile uint32_t iRxRejectedInterrupts;
+ volatile uint32_t iRxRejectedInvalidFrame;
+ volatile uint32_t iRxRejectedDataFifoFull;
+ volatile uint32_t iRxRejectedLengthFifoFull;
+ volatile uint32_t iRxMaxDrained;
+ volatile uint32_t iRxStrayEvents;
+
+ volatile uint32_t iTxInterrupts;
+ volatile uint32_t iTxMaxDrained;
+};
+
+#define MAX_UNIT_BYTES 50
+
+struct XilTemac
+{
+ struct arpcom iArpcom;
+ struct XilTemacStats iStats;
+ struct ifnet* iIfp;
+
+ char iUnitName[MAX_UNIT_BYTES];
+
+ uint32_t iAddr;
+ rtems_event_set iIoEvent;
+
+ int iIsrVector;
+
+#if PPC_HAS_CLASSIC_EXCEPTIONS
+ rtems_isr_entry iOldHandler;
+#else
+ rtems_irq_connect_data iOldHandler;
+#endif
+ int iIsPresent;
+};
+
+
+#endif /* _XILINX_EMAC_*/
diff --git a/c/src/lib/libbsp/powerpc/virtex/opbintctrl/opbintctrl.c b/c/src/lib/libbsp/powerpc/virtex/opbintctrl/opbintctrl.c
new file mode 100644
index 0000000000..9d2ed9ac4b
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/opbintctrl/opbintctrl.c
@@ -0,0 +1,143 @@
+/* opbintctrl.c
+ *
+ * This file contains definitions and declarations for the
+ * Xilinx Off Processor Bus (OPB) Interrupt Controller
+ *
+ * Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
+ * COPYRIGHT (c) 2005 Linn Products Ltd, Scotland.
+ *
+ * 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/opbintctrl.h>
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <bsp/irq.h>
+#include <rtems/powerpc/powerpc.h>
+
+/*
+ * Acknowledge a mask of interrupts.
+ */
+RTEMS_INLINE_ROUTINE void set_iar(uint32_t mask)
+{
+ *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IAR)) = mask;
+}
+
+/*
+ * Set IER state. Used to (dis)enable a mask of vectors.
+ * If you only have to do one, use enable/disable_vector.
+ */
+RTEMS_INLINE_ROUTINE void set_ier(uint32_t mask)
+{
+ *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IER)) = mask;
+}
+
+/*
+ * Retrieve contents of Interrupt Pending Register
+ */
+RTEMS_INLINE_ROUTINE uint32_t get_ipr()
+{
+ uint32_t c = *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IPR));
+ return c;
+}
+
+void BSP_irq_enable_at_opbintc (rtems_irq_number irqnum)
+{
+ *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_SIE))
+ = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET);
+}
+
+void BSP_irq_disable_at_opbintc (rtems_irq_number irqnum)
+{
+ *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_CIE))
+ = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET);
+}
+
+/*
+ * IRQ Handler: this is called from the primary exception dispatcher
+ */
+void BSP_irq_handle_at_opbintc(void)
+{
+ uint32_t ipr, iprcopy, mask, i, c;
+ rtems_irq_connect_data *tbl_entry;
+ iprcopy = ipr = get_ipr();
+
+ c = 0;
+ mask = 0;
+
+ for (i = 0;
+ (i < BSP_OPBINTC_PER_IRQ_NUMBER)
+ && (ipr != 0);
+ i++) {
+ c = (1 << i);
+
+ if ((ipr & c) != 0) {
+ /* interrupt is asserted */
+ mask |= c;
+ ipr &= ~c;
+
+ tbl_entry = &BSP_rtems_irq_tbl[i+BSP_OPBINTC_IRQ_LOWEST_OFFSET];
+ if (tbl_entry->hdl != NULL) {
+ (tbl_entry->hdl) (tbl_entry->handle);
+ } else {
+ printk("opbintctrl: Spurious interrupt; IPR 0x%08X, vector 0x%x\n\r",
+ iprcopy, i);
+ }
+ }
+ }
+
+ if (mask) {
+ /* ack all the interrupts we serviced */
+ set_iar(mask);
+ }
+}
+
+
+/*
+ * activate the interrupt controller
+ */
+rtems_status_code opb_intc_init(void)
+{
+ uint32_t msr_value;
+ uint32_t i, mask = 0;
+
+ /* mask off all interrupts */
+ set_ier(0x0);
+
+ for (i = 0; i < OPB_INTC_IRQ_MAX; i++) {
+ mask |= (1 << i);
+ }
+ printk("opb_intc_init: mask = 0x%x\n", (unsigned) mask);
+
+ /* make sure interupt status register is clear before we enable the interrupt controller */
+ *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_ISR)) = 0;
+
+ /* acknowledge all interrupt sources */
+ set_iar(mask);
+
+ /* Turn on normal hardware operation of interrupt controller */
+ *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
+ (OPB_INTC_MER_HIE);
+
+ /* Enable master interrupt switch for the interrupt controller */
+ *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
+ (OPB_INTC_MER_HIE | OPB_INTC_MER_ME);
+
+#if 0 /* EB: we do it somewhere else */
+ /*
+ * enable (non-critical) exceptions
+ */
+
+ _CPU_MSR_GET(msr_value);
+ msr_value |= PPC_MSR_EE;
+ _CPU_MSR_SET(msr_value);
+
+ /* install exit handler to close opb_intc when program atexit called */
+ /* atexit(opb_intc_exit); */
+#endif
+
+ return RTEMS_SUCCESSFUL;
+}
+
diff --git a/c/src/lib/libbsp/powerpc/virtex/preinstall.am b/c/src/lib/libbsp/powerpc/virtex/preinstall.am
new file mode 100644
index 0000000000..31983c24d1
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/preinstall.am
@@ -0,0 +1,79 @@
+## 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-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_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)/bsp/opbintctrl.h: include/opbintctrl.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/opbintctrl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/opbintctrl.h
+
+$(PROJECT_INCLUDE)/bsp/irq.h: irq/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
+
+$(PROJECT_INCLUDE)/bsp/vectors.h: ../../powerpc/shared/vectors/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h
+
+
+$(PROJECT_INCLUDE)/xiltemac.h: network/xiltemac.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/xiltemac.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/xiltemac.h
+
+$(PROJECT_INCLUDE)/xparameters_dflt.h: include/xparameters_dflt.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/xparameters_dflt.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/xparameters_dflt.h
+
+$(PROJECT_INCLUDE)/tm27.h: include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.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)/coverhd.h: include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
+
+$(PROJECT_INCLUDE)/bsp/$(dirstamp):
+ @$(MKDIR_P) $(PROJECT_INCLUDE)/bsp
+ @: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+
+$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds
+PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds
+
+$(PROJECT_LIB)/linkcmds.dl: startup/linkcmds.dl $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.dl
+PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.dl
+
diff --git a/c/src/lib/libbsp/powerpc/virtex/startup/bspclean.c b/c/src/lib/libbsp/powerpc/virtex/startup/bspclean.c
new file mode 100644
index 0000000000..56699da354
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/startup/bspclean.c
@@ -0,0 +1,43 @@
+/* bsp_cleanup()
+ *
+ * This routine normally is part of start.s and usually returns
+ * control to a monitor.
+ *
+ * INPUT: NONE
+ *
+ * OUTPUT: NONE
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/bspclean.c:
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+
+void bsp_cleanup( void )
+{
+ rtems_fatal_error_occurred(0);
+}
diff --git a/c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c b/c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c
new file mode 100644
index 0000000000..700ac0c812
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c
@@ -0,0 +1,277 @@
+/* bsp_start()
+ *
+ * This routine starts the application. It includes application,
+ * board, and monitor specific initialization and configuration.
+ * The generic CPU dependent initialization has been performed
+ * before this routine is invoked.
+ *
+ * INPUT: NONE
+ *
+ * OUTPUT: NONE
+ *
+ * Author: Thomas Doerfler <td@imd.m.isar.de>
+ * IMD Ingenieurbuero fuer Microcomputertechnik
+ *
+ * COPYRIGHT (c) 1998 by IMD
+ *
+ * Changes from IMD are covered by the original distributions terms.
+ * This file has been derived from the papyrus BSP:
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Modifications for spooling console driver and control of memory layout
+ * with linker command file by
+ * Thomas Doerfler <td@imd.m.isar.de>
+ * for these modifications:
+ * COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies. IMD makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/bspstart.c:
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Modifications for PPC405GP by Dennis Ehlin
+ *
+ * $Id$
+ */
+#include <string.h>
+#include <fcntl.h>
+
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <rtems/libcsupport.h>
+#include <bsp/irq.h>
+#include <rtems/bspIo.h>
+#include <libcpu/cpuIdent.h>
+#include <libcpu/spr.h>
+#include <rtems/powerpc/powerpc.h>
+
+SPR_RW(SPRG0)
+SPR_RW(SPRG1)
+
+#include RTEMS_XPARAMETERS_H
+#include <stdio.h>
+
+/*
+ * The original table from the application and our copy of it with
+ * some changes.
+ */
+
+extern rtems_configuration_table Configuration;
+
+rtems_configuration_table BSP_Configuration;
+
+rtems_cpu_table Cpu_table;
+
+char *rtems_progname;
+
+uint32_t _heap_start;
+uint32_t _heap_end;
+uint32_t _top_of_ram;
+
+
+/* Initialize whatever libc we are using
+ * called from postdriver hook
+ */
+
+void bsp_XAssertHandler(const char* file, int line);
+void bsp_postdriver_hook(void);
+void bsp_libc_init( void *, uint32_t, int );
+
+
+void bsp_XAssertHandler(const char* file, int line) {
+ printf("\n***\n*** XAssert Failed! File: %s, Line: %d\n***\n", file, line);
+}
+
+/*
+ *
+ * bsp_predriver_hook
+ *
+ * Before drivers are setup.
+ */
+
+void bsp_predriver_hook(void)
+{
+
+}
+
+/*
+ * Function: bsp_pretasking_hook
+ * Created: 95/03/10
+ *
+ * Description:
+ * BSP pretasking hook. Called just before drivers are initialized.
+ * Used to setup libc and install any BSP extensions.
+ *
+ * NOTES:
+ * Must not use libc (to do io) from here, since drivers are
+ * not yet initialized.
+ *
+ */
+
+void bsp_pretasking_hook(void)
+{
+
+
+ uint32_t heap_start;
+ uint32_t heap_size;
+ uint32_t heap_end;
+
+ /* round up from the top of workspace to next 64k boundary, get
+ * default heapsize from linker script */
+ heap_start = (((uint32_t)BSP_Configuration.work_space_start +
+ BSP_Configuration.work_space_size) + 0x18000) & 0xffff0000;
+
+ heap_end = _heap_start + (uint32_t)&_HeapSize;
+
+ heap_size = (heap_end - heap_start);
+
+ _heap_start = heap_start;
+ _heap_end = heap_end;
+
+ _top_of_ram = heap_end;
+
+ bsp_libc_init((void *) heap_start, heap_size, 0); /* 64 * 1024 */
+
+/*
+ XAssertSetCallback((XAssertCallback*)bsp_XAssertHandler);
+*/
+
+#ifdef RTEMS_DEBUG
+ rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
+#endif
+}
+
+/*
+ * bsp_start
+ *
+ * This routine does the bulk of the system initialization.
+ */
+
+
+void bsp_start( void )
+{
+ extern unsigned long *intrStackPtr;
+ register unsigned char* intrStack;
+ ppc_cpu_id_t myCpu;
+ ppc_cpu_revision_t myCpuRevision;
+
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
+ * function store the result in global variables
+ * so that it can be used latter...
+ */
+ myCpu = get_ppc_cpu_type();
+ myCpuRevision = get_ppc_cpu_revision();
+ /*
+ * initialize the CPU table for this BSP
+ * NOTE: this must be before the exception initialization,
+ * because exception code useses some information from Cpu_table
+ */
+
+ Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
+ Cpu_table.predriver_hook = bsp_predriver_hook;
+ Cpu_table.postdriver_hook = bsp_postdriver_hook;
+ Cpu_table.interrupt_stack_size = CONFIGURE_INTERRUPT_STACK_MEMORY;
+
+ /* timebase register ticks/microsecond */
+ Cpu_table.clicks_per_usec = (250000000 / 1000000);
+
+ Cpu_table.serial_per_sec = 14625000; /* = (CPU Clock / UART Internal Clock Divisor) */
+ Cpu_table.serial_external_clock = 0;
+ Cpu_table.timer_internal_clock = 1;
+ Cpu_table.serial_xon_xoff = 0;
+ Cpu_table.serial_cts_rts = 0;
+ Cpu_table.serial_rate = 115200;
+ Cpu_table.timer_average_overhead = 2;
+ Cpu_table.timer_least_valid = 3;
+ Cpu_table.exceptions_in_RAM = TRUE;
+
+ /*
+ * Initialize some SPRG registers related to irq handling
+ */
+
+ intrStack = (((unsigned char*)&intrStackPtr) - PPC_MINIMUM_STACK_FRAME_SIZE);
+ _write_SPRG1((unsigned int)intrStack);
+ /* signal them that we have fixed PR288 - eventually, this should go away */
+ _write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
+
+
+ /*
+ * Initialize default raw exception handlers.
+ * See shared/vectors/vectors_init.c
+ */
+ initialize_exceptions();
+
+ /*
+ * Install our own set of exception vectors
+ */
+ BSP_rtems_irq_mng_init(0);
+
+ /*
+ * Allocate the memory for the RTEMS Work Space. This can come from
+ * a variety of places: hard coded address, malloc'ed from outside
+ * RTEMS world (e.g. simulator or primitive memory manager), or (as
+ * typically done by stock BSPs) by subtracting the required amount
+ * of work space from the last physical address on the CPU board.
+ */
+
+ /*
+ * Need to "allocate" the memory for the RTEMS Workspace and
+ * tell the RTEMS configuration where it is. This memory is
+ * not malloc'ed. It is just "pulled from the air".
+ */
+ /* FIME: plan usage of RAM better:
+ - make top of ram dynamic,
+ - make rest of ram to heap...
+ -remove RAM_END from bsp.h, this cannot be valid...
+ or must be a function call
+ */
+ {
+ extern int _end;
+
+ /* round _end up to next 64k boundary for start of workspace */
+ BSP_Configuration.work_space_start = (void *)((((uint32_t)&_end) + 0x18000) & 0xffff0000);
+ }
+
+}
+
+void BSP_ask_for_reset(void)
+{
+ printk("system stopped, press RESET");
+ while(1) {};
+}
+
+void BSP_panic(char *s)
+{
+ printk("%s PANIC %s\n",_RTEMS_version, s);
+ BSP_ask_for_reset();
+}
+
+void _BSP_Fatal_error(unsigned int v)
+{
+ printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
+ BSP_ask_for_reset();
+}
+
diff --git a/c/src/lib/libbsp/powerpc/virtex/startup/linkcmds b/c/src/lib/libbsp/powerpc/virtex/startup/linkcmds
new file mode 100644
index 0000000000..0e39bf66b7
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/startup/linkcmds
@@ -0,0 +1,169 @@
+/* Greg modifications
+ * This file contains directives for the GNU linker which are specific
+ * to the virtex
+ * This file is intended to be used together with dlentry.s
+ * it will generate downloadable code
+ *
+ * Modifications for gen405 by Dennis Ehlin
+ * Modifications for virtex by Keith, Greg, and Bob
+ *
+ * $Id$
+ */
+
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
+ "elf32-powerpc")
+OUTPUT_ARCH(powerpc)
+
+ENTRY(download_entry)
+
+
+_HeapSize = DEFINED(_HeapSize) ? _HeapSize : 8M;
+
+
+MEMORY
+ {
+ RAM : ORIGIN = 0, LENGTH = 16M
+ /*FLASH : ORIGIN = 0xFFE00000, LENGTH = 16M*/
+ }
+SECTIONS
+{
+ .text 0x10000:
+ {
+ text.start = . ;
+ *(.entry)
+ *(.entry2)
+ *(.text*)
+ *(.rodata*)
+ *(.rodata1)
+
+ /*
+ * Special FreeBSD sysctl sections.
+ */
+ . = ALIGN (16);
+ __start_set_sysctl_set = .;
+ *(set_sysctl_*);
+ __stop_set_sysctl_set = ABSOLUTE(.);
+ *(set_domain_*);
+ *(set_pseudo_*);
+
+ *(.eh_frame)
+ *(.gnu.linkonce.r*)
+ *(.descriptors)
+ *(rom_ver)
+ etext = ALIGN(0x10);
+ _etext = .;
+
+ *(.gnu.linkonce.t*)
+
+ __CTOR_LIST__ = .;
+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
+ *(.ctors)
+ LONG(0)
+ __CTOR_END__ = .;
+
+ __DTOR_LIST__ = .;
+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
+ *(.dtors)
+ LONG(0)
+ __DTOR_END__ = .;
+
+ *(.lit)
+ *(.shdata)
+ _init = .; __init = .; *(.init)
+ _fini = .; __fini = .; *(.fini)
+ _endtext = ALIGN(0x10);
+ text.end = .;
+ } > RAM
+
+ text.size = text.end - text.start;
+
+ /* R/W Data */
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.data.* .gnu.linkonce.d*)
+ PROVIDE (__SDATA_START__ = .);
+ *(.sdata*)
+ *(.gnu.linkonce.s.*)
+ } > RAM
+
+ PROVIDE (__EXCEPT_START__ = .);
+ .gcc_except_table :
+ {
+ *(.gcc_except_table)
+ } >RAM
+ PROVIDE (__EXCEPT_END__ = .);
+
+ __GOT_START__ = .;
+ .got :
+ {
+ s.got = .;
+ *(.got.plt) *(.got)
+ } > RAM
+ __GOT_END__ = .;
+
+ .got1 :
+ {
+ *(.got1)
+ } >RAM
+
+ PROVIDE (__GOT2_START__ = .);
+ PROVIDE (_GOT2_START_ = .);
+ .got2 :
+ {
+ *(.got2)
+ } >RAM
+ PROVIDE (__GOT2_END__ = .);
+ PROVIDE (_GOT2_END_ = .);
+
+ PROVIDE (__FIXUP_START__ = .);
+ PROVIDE (_FIXUP_START_ = .);
+ .fixup : { *(.fixup) } >RAM
+ PROVIDE (_FIXUP_END_ = .);
+ PROVIDE (__FIXUP_END__ = .);
+
+ PROVIDE (__SDATA2_START__ = .);
+ .sdata2 : { *(.sdata2) *(.gnu.linkonce.s2.*) } >RAM
+ .sbss2 : { *(.sbss2) *(.gnu.linkonce.sb2.*) } >RAM
+ PROVIDE (__SBSS2_END__ = .);
+
+ __SBSS_START__ = .;
+ .bss :
+ {
+ bss.start = .;
+ *(.bss .bss* .gnu.linkonce.b*)
+ *(.sbss*) *(COMMON)
+ bss.end = ALIGN(4);
+ bss.size = bss.end - bss.start;
+ } > RAM
+ __SBSS_END__ = .;
+
+ /* align bottom of 32k init stack at a 32k boundary */
+ . = . + 0x4000;
+ . = ALIGN( 0x8000 );
+ stack.start = .;
+ . = . + 0x8000;
+ stack.end = .;
+ /*
+ * Interrupt stack setup
+ */
+ IntrStack_start = ALIGN(0x10);
+ . += 0x4000;
+ intrStack = .;
+ PROVIDE(intrStackPtr = intrStack);
+
+ PROVIDE(_end = intrStack);
+
+ .line 0 : { *(.line) }
+ .debug 0 : { *(.debug) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_aregion 0 : { *(.debug_aregion) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+
+}
diff --git a/c/src/lib/libbsp/powerpc/virtex/startup/linkcmds.dl b/c/src/lib/libbsp/powerpc/virtex/startup/linkcmds.dl
new file mode 100644
index 0000000000..30dd38e63d
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/startup/linkcmds.dl
@@ -0,0 +1,154 @@
+/*
+ * This file contains directives for the GNU linker which are specific
+ * to the helas403
+ * This file is intended to be used together with dlentry.s
+ * it will generate downloadable code
+ *
+ * $Id$
+ */
+
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
+ "elf32-powerpc")
+OUTPUT_ARCH(powerpc)
+
+ENTRY(download_entry)
+
+MEMORY
+ {
+ RAM : ORIGIN = 0, LENGTH = 8M
+ FLASH : ORIGIN = 0xFFF00000, LENGTH = 512K
+ }
+
+SECTIONS
+{
+ .vectors : 0x00010100
+ {
+ *(.vectors)
+ } > RAM
+
+ .text :
+ {
+ text.start = . ;
+ *(.entry)
+ *(.entry2)
+ *(.text*)
+ *(.rodata)
+ *(.rodata1)
+
+ /*
+ * Special FreeBSD sysctl sections.
+ */
+ . = ALIGN (16);
+ __start_set_sysctl_set = .;
+ *(set_sysctl_*);
+ __stop_set_sysctl_set = ABSOLUTE(.);
+ *(set_domain_*);
+ *(set_pseudo_*);
+
+ *.(eh_frame)
+ *(.descriptors)
+ *(rom_ver)
+ etext = ALIGN(0x10);
+ _etext = .;
+
+
+ __CTOR_LIST__ = .;
+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
+ *(.ctors)
+ LONG(0)
+ __CTOR_END__ = .;
+
+ __DTOR_LIST__ = .;
+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
+ *(.dtors)
+ LONG(0)
+ __DTOR_END__ = .;
+
+ *(.lit)
+ *(.shdata)
+ *(.init)
+ *(.fini)
+ _endtext = ALIGN(0x10);
+ text.end = .;
+ } > RAM
+
+ text.size = text.end - text.start;
+
+ /* R/W Data */
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ PROVIDE (__SDATA_START__ = .);
+ *(.sdata*)
+ } > RAM
+
+ PROVIDE (__EXCEPT_START__ = .);
+ .gcc_except_table :
+ {
+ *(.gcc_except_table)
+ } >RAM
+ PROVIDE (__EXCEPT_END__ = .);
+
+ __GOT_START__ = .;
+ .got :
+ {
+ s.got = .;
+ *(.got.plt) *(.got)
+ } > RAM
+ __GOT_END__ = .;
+
+ .got1 :
+ {
+ *(.got1)
+ } >RAM
+
+ PROVIDE (__GOT2_START__ = .);
+ PROVIDE (_GOT2_START_ = .);
+ .got2 :
+ {
+ *(.got2)
+ } >RAM
+ PROVIDE (__GOT2_END__ = .);
+ PROVIDE (_GOT2_END_ = .);
+
+ PROVIDE (__FIXUP_START__ = .);
+ PROVIDE (_FIXUP_START_ = .);
+ .fixup : { *(.fixup) } >RAM
+ PROVIDE (_FIXUP_END_ = .);
+ PROVIDE (__FIXUP_END__ = .);
+
+ PROVIDE (__SDATA2_START__ = .);
+ .sdata2 : { *(.sdata2) } >RAM
+ .sbss2 : { *(.sbss2) } >RAM
+ PROVIDE (__SBSS2_END__ = .);
+
+ .sbss2 : { *(.sbss2) } >RAM
+ PROVIDE (__SBSS2_END__ = .);
+
+ __SBSS_START__ = .;
+ .bss :
+ {
+ bss.start = .;
+ *(.bss .bss* .gnu.linkonce.b*)
+ *(.sbss*) *(COMMON)
+ bss.end = ALIGN(4);
+ } > RAM
+ __SBSS_END__ = .;
+
+ bss.size = bss.end - bss.start;
+ PROVIDE(_end = bss.end);
+
+ .line 0 : { *(.line) }
+ .debug 0 : { *(.debug) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_aregion 0 : { *(.debug_aregion) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+}
+
+
diff --git a/c/src/lib/libbsp/powerpc/virtex/startup/setvec.c b/c/src/lib/libbsp/powerpc/virtex/startup/setvec.c
new file mode 100644
index 0000000000..af6f68b356
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/virtex/startup/setvec.c
@@ -0,0 +1,56 @@
+/* set_vector
+ *
+ * This routine installs an interrupt vector on the target Board/CPU.
+ * This routine is allowed to be as board dependent as necessary.
+ *
+ * INPUT:
+ * handler - interrupt handler entry point
+ * vector - vector number
+ * type - 0 indicates raw hardware connect
+ * 1 indicates RTEMS interrupt connect
+ *
+ * RETURNS:
+ * address of previous interrupt handler
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/setvec.c:
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+
+rtems_isr_entry set_vector( /* returns old vector */
+ rtems_isr_entry handler, /* isr routine */
+ rtems_vector_number vector, /* vector number */
+ int type /* RTEMS or RAW intr */
+)
+{
+ rtems_isr_entry previous_isr;
+
+ rtems_interrupt_catch( handler, vector, (rtems_isr_entry *) &previous_isr );
+
+ return previous_isr;
+}
diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/asm_utils.S b/c/src/lib/libcpu/powerpc/new-exceptions/asm_utils.S
new file mode 100644
index 0000000000..45a0f3ea73
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/asm_utils.S
@@ -0,0 +1,63 @@
+/*
+ * asm_utils.s
+ *
+ * $Id$
+ *
+ * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
+ *
+ * This file contains the low-level support for moving exception
+ * exception code to appropriate location.
+ *
+ */
+
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
+
+ .globl codemove
+codemove:
+ .type codemove,@function
+/* r3 dest, r4 src, r5 length in bytes, r6 cachelinesize */
+ cmplw cr1,r3,r4
+ addi r0,r5,3
+ srwi. r0,r0,2
+ beq cr1,4f /* In place copy is not necessary */
+ beq 7f /* Protect against 0 count */
+ mtctr r0
+ bge cr1,2f
+
+ la r8,-4(r4)
+ la r7,-4(r3)
+1: lwzu r0,4(r8)
+ stwu r0,4(r7)
+ bdnz 1b
+ b 4f
+
+2: slwi r0,r0,2
+ add r8,r4,r0
+ add r7,r3,r0
+3: lwzu r0,-4(r8)
+ stwu r0,-4(r7)
+ bdnz 3b
+
+/* Now flush the cache: note that we must start from a cache aligned
+ * address. Otherwise we might miss one cache line.
+ */
+4: cmpwi r6,0
+ add r5,r3,r5
+ beq 7f /* Always flush prefetch queue in any case */
+ subi r0,r6,1
+ andc r3,r3,r0
+ mr r4,r3
+5: cmplw r4,r5
+ dcbst 0,r4
+ add r4,r4,r6
+ blt 5b
+ sync /* Wait for all dcbst to complete on bus */
+ mr r4,r3
+6: cmplw r4,r5
+ icbi 0,r4
+ add r4,r4,r6
+ blt 6b
+7: sync /* Wait for all icbi to complete on bus */
+ isync
+ blr
diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.c b/c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.c
new file mode 100644
index 0000000000..d412f38008
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.c
@@ -0,0 +1,501 @@
+/*
+ * raw_exception.c - This file contains implementation of C function to
+ * Instantiate 60x ppc primary exception entries.
+ * More detailed information can be found on motorola
+ * site and more precisely in the following book :
+ *
+ * MPC750
+ * Risc Microporcessor User's Manual
+ * Motorola REF : MPC750UM/AD 8/97
+ *
+ * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
+ * Canon Centre Recherche France.
+ *
+ * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
+ * to support 603, 603e, 604, 604e exceptions
+ *
+ * moved to "libcpu/powerpc/new-exceptions and consolidated
+ * by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+ * to be common for all PPCs with new excpetions
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+#include <rtems/system.h>
+#include <rtems/score/powerpc.h>
+#include <rtems/bspIo.h>
+#include <libcpu/raw_exception.h>
+#include <libcpu/cpuIdent.h>
+
+#include <string.h>
+
+static rtems_raw_except_connect_data* raw_except_table;
+static rtems_raw_except_connect_data default_raw_except_entry;
+static rtems_raw_except_global_settings* local_settings;
+
+void * codemove(void *, const void *, unsigned int, unsigned long);
+
+
+static void* ppc_get_vector_addr(rtems_vector vector)
+{
+ unsigned vaddr;
+ extern rtems_cpu_table Cpu_table;
+
+ switch(vector) {
+ /*
+ * some vectors are located at odd addresses and only available
+ * on some CPU derivates. this construct will handle them
+ * if available
+ */
+#if defined(PPC_HAS_60X_VECTORS)
+ /* Special case; altivec unavailable doesn't fit :-( */
+ case ASM_VEC_VECTOR:
+ vaddr = ASM_VEC_VECTOR_OFFSET;
+ break;
+#endif
+#if defined(ASM_PIT_VECTOR)
+ case ASM_PIT_VECTOR:
+ vaddr = ASM_PIT_VECTOR_OFFSET;
+ break;
+#endif
+#if defined(ASM_FIT_VECTOR)
+ case ASM_FIT_VECTOR:
+ vaddr = ASM_FIT_VECTOR_OFFSET;
+ break;
+#endif
+#if defined(ASM_WDOG_VECTOR)
+ case ASM_WDOG_VECTOR:
+ vaddr = ASM_WDOG_VECTOR_OFFSET;
+ break;
+#endif
+ default:
+ vaddr = ((unsigned)vector) << 8;
+ break;
+ }
+ if ( Cpu_table.exceptions_in_RAM )
+ return ((void*) vaddr);
+
+ return ((void*) (vaddr + 0xfff00000));
+}
+
+
+#if ( defined(mpc860) || defined(mpc821) )
+
+int mpc860_vector_is_valid(rtems_vector vector)
+{
+ switch(vector) {
+ case ASM_RESET_VECTOR: /* fall through */
+ case ASM_MACH_VECTOR:
+ case ASM_PROT_VECTOR:
+ case ASM_ISI_VECTOR:
+ case ASM_EXT_VECTOR:
+ case ASM_ALIGN_VECTOR:
+ case ASM_PROG_VECTOR:
+ case ASM_FLOAT_VECTOR:
+ case ASM_DEC_VECTOR:
+
+ case ASM_SYS_VECTOR:
+ case ASM_TRACE_VECTOR:
+ case ASM_FLOATASSIST_VECTOR:
+
+ case ASM_SOFTEMUL_VECTOR:
+ case ASM_ITLBMISS_VECTOR:
+ case ASM_DTLBMISS_VECTOR:
+ case ASM_ITLBERROR_VECTOR:
+ case ASM_DTLBERROR_VECTOR:
+
+ case ASM_DBREAK_VECTOR:
+ case ASM_IBREAK_VECTOR:
+ case ASM_PERIFBREAK_VECTOR:
+ case ASM_DEVPORT_VECTOR:
+ return 1;
+ default: return 0;
+ }
+}
+#endif
+
+#if (defined(mpc555) || defined(mpc505))
+
+int ppc_vector_is_valid(rtems_vector vector)
+{
+ switch (current_ppc_cpu) {
+ case PPC_5XX:
+ switch(vector) {
+ case ASM_RESET_VECTOR:
+ case ASM_MACH_VECTOR:
+
+ case ASM_EXT_VECTOR:
+ case ASM_ALIGN_VECTOR:
+ case ASM_PROG_VECTOR:
+ case ASM_FLOAT_VECTOR:
+ case ASM_DEC_VECTOR:
+
+ case ASM_SYS_VECTOR:
+ case ASM_TRACE_VECTOR:
+ case ASM_FLOATASSIST_VECTOR:
+
+ case ASM_SOFTEMUL_VECTOR:
+
+ case ASM_IPROT_VECTOR:
+ case ASM_DPROT_VECTOR:
+
+ case ASM_DBREAK_VECTOR:
+ case ASM_IBREAK_VECTOR:
+ case ASM_MEBREAK_VECTOR:
+ case ASM_NMEBREAK_VECTOR:
+ return 1;
+ default:
+ return 0;
+ }
+ default:
+ printk("Please complete libcpu/powerpc/shared/new-exceptions/raw_exception.c\n");
+ printk("current_ppc_cpu = %x\n", current_ppc_cpu);
+ return 0;
+ }
+}
+#endif
+
+#if defined(ppc405)
+int ppc405_vector_is_valid(rtems_vector vector)
+
+{
+ switch(vector) {
+ case ASM_RESET_VECTOR: /* fall through */
+ case ASM_MACH_VECTOR:
+ case ASM_PROT_VECTOR:
+ case ASM_ISI_VECTOR:
+ case ASM_EXT_VECTOR:
+ case ASM_ALIGN_VECTOR:
+ case ASM_PROG_VECTOR:
+ case ASM_SYS_VECTOR:
+ case ASM_PIT_VECTOR:
+ case ASM_ITLBMISS_VECTOR:
+ case ASM_DTLBMISS_VECTOR:
+ return 1;
+ default: return 0;
+ }
+}
+#endif /* defined(ppc405) */
+
+#if defined(PPC_HAS_60X_VECTORS) /* 60x style cpu types */
+
+int altivec_vector_is_valid(rtems_vector vector)
+{
+ switch(vector) {
+ case ASM_VEC_VECTOR:
+ case ASM_VEC_ASSIST_VECTOR:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int mpc750_vector_is_valid(rtems_vector vector)
+
+{
+ switch(vector) {
+ case ASM_RESET_VECTOR: /* fall through */
+ case ASM_MACH_VECTOR:
+ case ASM_PROT_VECTOR:
+ case ASM_ISI_VECTOR:
+ case ASM_EXT_VECTOR:
+ case ASM_ALIGN_VECTOR:
+ case ASM_PROG_VECTOR:
+ case ASM_FLOAT_VECTOR:
+ case ASM_DEC_VECTOR:
+ case ASM_SYS_VECTOR:
+ case ASM_TRACE_VECTOR:
+ case ASM_ADDR_VECTOR:
+ case ASM_SYSMGMT_VECTOR:
+ case ASM_ITM_VECTOR:
+ return 1;
+ default: return 0;
+ }
+}
+
+int PSIM_vector_is_valid(rtems_vector vector)
+{
+ switch(vector) {
+ case ASM_RESET_VECTOR: /* fall through */
+ case ASM_MACH_VECTOR:
+ case ASM_PROT_VECTOR:
+ case ASM_ISI_VECTOR:
+ case ASM_EXT_VECTOR:
+ case ASM_ALIGN_VECTOR:
+ case ASM_PROG_VECTOR:
+ case ASM_FLOAT_VECTOR:
+ case ASM_DEC_VECTOR:
+ return 1;
+ case ASM_SYS_VECTOR:
+ return 0;
+ case ASM_TRACE_VECTOR:
+ return 1;
+ case ASM_PERFMON_VECTOR:
+ return 0;
+ case ASM_IMISS_VECTOR: /* fall through */
+ case ASM_DLMISS_VECTOR:
+ case ASM_DSMISS_VECTOR:
+ case ASM_ADDR_VECTOR:
+ case ASM_SYSMGMT_VECTOR:
+ return 1;
+ case ASM_ITM_VECTOR:
+ return 0;
+ }
+ return 0;
+}
+
+int mpc603_vector_is_valid(rtems_vector vector)
+{
+ switch(vector) {
+ case ASM_RESET_VECTOR: /* fall through */
+ case ASM_MACH_VECTOR:
+ case ASM_PROT_VECTOR:
+ case ASM_ISI_VECTOR:
+ case ASM_EXT_VECTOR:
+ case ASM_ALIGN_VECTOR:
+ case ASM_PROG_VECTOR:
+ case ASM_FLOAT_VECTOR:
+ case ASM_DEC_VECTOR:
+ case ASM_SYS_VECTOR:
+ case ASM_TRACE_VECTOR:
+ return 1;
+ case ASM_PERFMON_VECTOR:
+ return 0;
+ case ASM_IMISS_VECTOR: /* fall through */
+ case ASM_DLMISS_VECTOR:
+ case ASM_DSMISS_VECTOR:
+ case ASM_ADDR_VECTOR:
+ case ASM_SYSMGMT_VECTOR:
+ return 1;
+ case ASM_ITM_VECTOR:
+ return 0;
+ }
+ return 0;
+}
+
+int mpc604_vector_is_valid(rtems_vector vector)
+{
+ switch(vector) {
+ case ASM_RESET_VECTOR: /* fall through */
+ case ASM_MACH_VECTOR:
+ case ASM_PROT_VECTOR:
+ case ASM_ISI_VECTOR:
+ case ASM_EXT_VECTOR:
+ case ASM_ALIGN_VECTOR:
+ case ASM_PROG_VECTOR:
+ case ASM_FLOAT_VECTOR:
+ case ASM_DEC_VECTOR:
+ case ASM_SYS_VECTOR:
+ case ASM_TRACE_VECTOR:
+ case ASM_PERFMON_VECTOR:
+ return 1;
+ case ASM_IMISS_VECTOR: /* fall through */
+ case ASM_DLMISS_VECTOR:
+ case ASM_DSMISS_VECTOR:
+ return 0;
+ case ASM_ADDR_VECTOR: /* fall through */
+ case ASM_SYSMGMT_VECTOR:
+ return 1;
+ case ASM_ITM_VECTOR:
+ return 0;
+ }
+ return 0;
+}
+
+#endif /* 60x style cpu types */
+
+int ppc_vector_is_valid(rtems_vector vector)
+{
+ switch (current_ppc_cpu) {
+#if defined(PPC_HAS_60X_VECTORS)
+ case PPC_7400:
+ if ( altivec_vector_is_valid(vector) )
+ return 1;
+ /* else fall thru */
+ case PPC_750:
+ if (!mpc750_vector_is_valid(vector)) {
+ return 0;
+ }
+ break;
+ case PPC_7455: /* Kate Feng */
+ case PPC_7457:
+ if ( altivec_vector_is_valid(vector) )
+ return 1;
+ /* else fall thru */
+ case PPC_604:
+ case PPC_604e:
+ case PPC_604r:
+ if (!mpc604_vector_is_valid(vector)) {
+ return 0;
+ }
+ break;
+ case PPC_603:
+ case PPC_603e:
+ case PPC_603le:
+ case PPC_603ev:
+ case PPC_8260:
+ /* case PPC_8240: -- same value as 8260 */
+ case PPC_8245:
+ if (!mpc603_vector_is_valid(vector)) {
+ return 0;
+ }
+ break;
+ case PPC_PSIM:
+ if (!PSIM_vector_is_valid(vector)) {
+ return 0;
+ }
+ break;
+#endif
+#if ( defined(mpc860) || defined(mpc821) )
+ case PPC_860:
+ if (!mpc860_vector_is_valid(vector)) {
+ return 0;
+ }
+ break;
+#endif
+#if defined(ppc405)
+ case PPC_405:
+ if (!ppc405_vector_is_valid(vector)) {
+ return 0;
+ }
+ break;
+#endif
+ default:
+ printk("Please complete "
+ "libcpu/powerpc/new-exceptions/raw_exception.c\n"
+ "current_ppc_cpu = %x\n", current_ppc_cpu);
+ return 0;
+ }
+ return 1;
+}
+
+int ppc_set_exception (const rtems_raw_except_connect_data* except)
+{
+ unsigned int level;
+
+ if (!ppc_vector_is_valid(except->exceptIndex)) {
+ printk("ppc_set_exception: vector %d is not valid\n",
+ except->exceptIndex);
+ return 0;
+ }
+ /*
+ * Check if default handler is actually connected. If not issue an error.
+ * You must first get the current handler via mpc60x_get_current_exception
+ * and then disconnect it using mpc60x_delete_exception.
+ * RATIONALE : to always have the same transition by forcing the user
+ * to get the previous handler before accepting to disconnect.
+ */
+
+ if (memcmp(ppc_get_vector_addr(except->exceptIndex),
+ (void*)default_raw_except_entry.hdl.raw_hdl,
+ default_raw_except_entry.hdl.raw_hdl_size)) {
+ printk("ppc_set_exception: raw vector not installed\n");
+ return 0;
+ }
+
+ _CPU_ISR_Disable(level);
+
+ raw_except_table [except->exceptIndex] = *except;
+ codemove((void*)ppc_get_vector_addr(except->exceptIndex),
+ except->hdl.raw_hdl,
+ except->hdl.raw_hdl_size,
+ PPC_CACHE_ALIGNMENT);
+ except->on(except);
+
+ _CPU_ISR_Enable(level);
+ return 1;
+}
+
+int ppc_get_current_exception (rtems_raw_except_connect_data* except)
+{
+ if (!ppc_vector_is_valid(except->exceptIndex)){
+ return 0;
+ }
+
+ *except = raw_except_table [except->exceptIndex];
+
+ return 1;
+}
+
+int ppc_delete_exception (const rtems_raw_except_connect_data* except)
+{
+ unsigned int level;
+
+ if (!ppc_vector_is_valid(except->exceptIndex)){
+ return 0;
+ }
+ /*
+ * Check if handler passed is actually connected. If not issue an error.
+ * You must first get the current handler via ppc_get_current_exception
+ * and then disconnect it using ppc_delete_exception.
+ * RATIONALE : to always have the same transition by forcing the user
+ * to get the previous handler before accepting to disconnect.
+ */
+ if (memcmp(ppc_get_vector_addr(except->exceptIndex),
+ (void*)except->hdl.raw_hdl,
+ except->hdl.raw_hdl_size)) {
+ return 0;
+ }
+ _CPU_ISR_Disable(level);
+
+ except->off(except);
+ codemove((void*)ppc_get_vector_addr(except->exceptIndex),
+ default_raw_except_entry.hdl.raw_hdl,
+ default_raw_except_entry.hdl.raw_hdl_size,
+ PPC_CACHE_ALIGNMENT);
+
+
+ raw_except_table[except->exceptIndex] = default_raw_except_entry;
+ raw_except_table[except->exceptIndex].exceptIndex = except->exceptIndex;
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+/*
+ * Exception global init.
+ */
+int ppc_init_exceptions (rtems_raw_except_global_settings* config)
+{
+ unsigned i;
+ unsigned int level;
+
+ /*
+ * store various accelerators
+ */
+ raw_except_table = config->rawExceptHdlTbl;
+ local_settings = config;
+ default_raw_except_entry = config->defaultRawEntry;
+
+ _CPU_ISR_Disable(level);
+
+ for (i=0; i <= LAST_VALID_EXC; i++) {
+ if (!ppc_vector_is_valid(i)){
+ continue;
+ }
+ codemove((void*)ppc_get_vector_addr(i),
+ raw_except_table[i].hdl.raw_hdl,
+ raw_except_table[i].hdl.raw_hdl_size,
+ PPC_CACHE_ALIGNMENT);
+ if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) {
+ raw_except_table[i].on(&raw_except_table[i]);
+ }
+ else {
+ raw_except_table[i].off(&raw_except_table[i]);
+ }
+ }
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+int ppc_get_exception_config (rtems_raw_except_global_settings** config)
+{
+ *config = local_settings;
+ return 1;
+}
diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.h b/c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.h
new file mode 100644
index 0000000000..1805484f8e
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.h
@@ -0,0 +1,324 @@
+/*
+ * raw_execption.h
+ *
+ * This file contains implementation of C function to
+ * Instantiate 60x ppc primary exception entries.
+ * More detailed information can be found on motorola
+ * site and more precisely in the following book :
+ *
+ * MPC750
+ * Risc Microporcessor User's Manual
+ * Mtorola REF : MPC750UM/AD 8/97
+ *
+ * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
+ * Canon Centre Recherche France.
+ *
+ * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
+ * to support 603, 603e, 604, 604e exceptions
+ *
+ * moved to "libcpu/powerpc/new-exceptions and consolidated
+ * by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+ * to be common for all PPCs with new excpetions
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _LIBCPU_RAW_EXCEPTION_H
+#define _LIBCPU_RAW_EXCEPTION_H
+
+#include <rtems/powerpc/powerpc.h>
+/*
+ * find out, whether we want to (re)enable the MMU in the assembly code
+ * FIXME: move this to a better location
+ */
+#if (defined(ppc403) || defined(ppc405))
+#define PPC_USE_MMU 0
+#else
+#define PPC_USE_MMU 1
+#endif
+
+/*
+ * Exception Vectors and offsets as defined in the MCP750 manual
+ * used by most PPCs
+ */
+
+#define ASM_RESET_VECTOR 0x01
+#define ASM_RESET_VECTOR_OFFSET (ASM_RESET_VECTOR << 8)
+
+#define ASM_MACH_VECTOR 0x02
+#define ASM_MACH_VECTOR_OFFSET (ASM_MACH_VECTOR << 8)
+
+#define ASM_PROT_VECTOR 0x03
+#define ASM_PROT_VECTOR_OFFSET (ASM_PROT_VECTOR << 8)
+
+#define ASM_ISI_VECTOR 0x04
+#define ASM_ISI_VECTOR_OFFSET (ASM_ISI_VECTOR << 8)
+
+#define ASM_EXT_VECTOR 0x05
+#define ASM_EXT_VECTOR_OFFSET (ASM_EXT_VECTOR << 8)
+
+#define ASM_ALIGN_VECTOR 0x06
+#define ASM_ALIGN_VECTOR_OFFSET (ASM_ALIGN_VECTOR << 8)
+
+#define ASM_PROG_VECTOR 0x07
+#define ASM_PROG_VECTOR_OFFSET (ASM_PROG_VECTOR << 8)
+
+#define ASM_FLOAT_VECTOR 0x08
+#define ASM_FLOAT_VECTOR_OFFSET (ASM_FLOAT_VECTOR << 8)
+
+#define ASM_DEC_VECTOR 0x09
+#define ASM_DEC_VECTOR_OFFSET (ASM_DEC_VECTOR << 8)
+
+/* Bummer: Altivec unavailable doesn't fit into this scheme... (0xf20).
+ * We'd like to avoid reserved vectors but OTOH we don't want to use
+ * just an available high number because tables (and copies) are of
+ * size LAST_VALID_EXC.
+ * So until there is a CPU that uses 0xA we'll just use that :-(
+ */
+#define ASM_VEC_VECTOR 0x0A
+#define ASM_VEC_VECTOR_OFFSET (0xf20)
+
+#define ASM_SYS_VECTOR 0x0C
+#define ASM_SYS_VECTOR_OFFSET (ASM_SYS_VECTOR << 8)
+
+#define ASM_TRACE_VECTOR 0x0D
+#define ASM_TRACE_VECTOR_OFFSET (ASM_TRACE_VECTOR << 8)
+
+#if defined(ppc405)
+ /*
+ * vectors for PPC405
+ */
+#define ASM_CRIT_VECTOR ASM_RESET_VECTOR
+#define ASM_CRIT_VECTOR_OFFSET (ASM_CRIT_VECTOR << 8)
+
+#define ASM_PIT_VECTOR 0x10
+#define ASM_PIT_VECTOR_OFFSET (ASM_PIT_VECTOR << 8)
+
+#define ASM_ITLBMISS_VECTOR 0x11
+#define ASM_ITLBMISS_VECTOR_OFFSET (ASM_ITLBMISS_VECTOR << 8)
+
+#define ASM_DTLBMISS_VECTOR 0x12
+#define ASM_DTLBMISS_VECTOR_OFFSET (ASM_DTLBMISS_VECTOR << 8)
+
+#define ASM_FIT_VECTOR 0x13
+#define ASM_FIT_VECTOR_OFFSET (0x1010)
+
+#define ASM_WDOG_VECTOR 0x14
+#define ASM_WDOG_VECTOR_OFFSET (0x1020)
+
+#define LAST_VALID_EXC ASM_WDOG_VECTOR
+
+/*
+ * bit mask of all exception vectors, that are handled
+ * as "critical" exsceptions (using SRR2/SRR3/rfci)
+ * this value will be evaluated in the default exception entry/exit
+ * code to determine, whether to use SRR0/SRR1/rfi or SRR2/SRR3/rfci
+ */
+#define ASM_VECTORS_CRITICAL \
+ (( 1 << (31-ASM_CRIT_VECTOR)) \
+ |(1 << (31-ASM_MACH_VECTOR)) \
+ |(1 << (31-ASM_WDOG_VECTOR)))
+
+#elif ( defined(mpc860) || defined(mpc821) )
+ /*
+ * vectors for MPC8xx
+ */
+
+/*
+ * FIXME: even more vector names might get used in common,
+ * but the names have diverged between different PPC families
+ */
+#define ASM_FLOATASSIST_VECTOR 0x0E
+#define ASM_FLOATASSIST_VECTOR_OFFSET (ASM_FLOATASSIST_VECTOR << 8)
+
+#define ASM_SOFTEMUL_VECTOR 0x10
+#define ASM_SOFTEMUL_VECTOR_OFFSET (ASM_SOFTEMUL_VECTOR << 8)
+
+#define ASM_ITLBMISS_VECTOR 0x11
+#define ASM_ITLBMISS_VECTOR_OFFSET (ASM_ITLBMISS_VECTOR << 8)
+
+#define ASM_DTLBMISS_VECTOR 0x12
+#define ASM_DTLBMISS_VECTOR_OFFSET (ASM_DTLBMISS_VECTOR << 8)
+
+#define ASM_ITLBERROR_VECTOR 0x13
+#define ASM_ITLBERROR_VECTOR_OFFSET (ASM_ITLBERROR_VECTOR << 8)
+
+#define ASM_DTLBERROR_VECTOR 0x14
+#define ASM_DTLBERROR_VECTOR_OFFSET (ASM_DTLBERROR_VECTOR << 8)
+
+#define ASM_DBREAK_VECTOR 0x1C
+#define ASM_DBREAK_VECTOR_OFFSET (ASM_DBREAK_VECTOR << 8)
+
+#define ASM_IBREAK_VECTOR 0x1D
+#define ASM_IBREAK_VECTOR_OFFSET (ASM_IBREAK_VECTOR << 8)
+
+#define ASM_PERIFBREAK_VECTOR 0x1E
+#define ASM_PERIFBREAK_VECTOR_OFFSET (ASM_PERIFBREAK_VECTOR << 8)
+
+#define ASM_DEVPORT_VECTOR 0x1F
+#define ASM_DEVPORT_VECTOR_OFFSET (ASM_DEVPORT_VECTOR_OFFSET << 8)
+
+#define LAST_VALID_EXC ASM_DEVPORT_VECTOR
+
+#elif (defined(mpc555) || defined(mpc505))
+ /*
+ * vectorx for MPC5xx
+ */
+#define ASM_FLOATASSIST_VECTOR 0x0E
+
+#define ASM_SOFTEMUL_VECTOR 0x10
+
+#define ASM_IPROT_VECTOR 0x13
+#define ASM_DPROT_VECTOR 0x14
+
+#define ASM_DBREAK_VECTOR 0x1C
+#define ASM_IBREAK_VECTOR 0x1D
+#define ASM_MEBREAK_VECTOR 0x1E
+#define ASM_NMEBREAK_VECTOR 0x1F
+
+#define LAST_VALID_EXC ASM_NMEBREAK_VECTOR
+
+#else /* 60x style cpu types */
+#define PPC_HAS_60X_VECTORS
+
+#define ASM_PERFMON_VECTOR 0x0F
+#define ASM_PERFMON_VECTOR_OFFSET (ASM_PERFMON_VECTOR << 8)
+
+#define ASM_IMISS_VECTOR 0x10
+
+#define ASM_DLMISS_VECTOR 0x11
+
+#define ASM_DSMISS_VECTOR 0x12
+
+#define ASM_ADDR_VECTOR 0x13
+#define ASM_ADDR_VECTOR_OFFSET (ASM_ADDR_VECTOR << 8)
+
+#define ASM_SYSMGMT_VECTOR 0x14
+#define ASM_SYSMGMT_VECTOR_OFFSET (ASM_SYSMGMT_VECTOR << 8)
+
+#define ASM_VEC_ASSIST_VECTOR 0x16
+#define ASM_VEC_ASSIST_VECTOR_OFFSET (ASM_VEC_ASSIST_VECTOR << 8)
+
+#define ASM_ITM_VECTOR 0x17
+#define ASM_ITM_VECTOR_OFFSET (ASM_ITM_VECTOR << 8)
+
+#define LAST_VALID_EXC ASM_ITM_VECTOR
+
+#endif
+
+ /*
+ * bits to be set in MSR in exception entry code
+ */
+#if ( PPC_HAS_RI) && ( PPC_USE_MMU)
+#define PPC_MSR_EXC_BITS (PPC_MSR_RI | PPC_MSR_DR | PPC_MSR_IR)
+#elif ( PPC_HAS_RI) && (!PPC_USE_MMU)
+#define PPC_MSR_EXC_BITS (PPC_MSR_RI)
+#elif (!PPC_HAS_RI) && ( PPC_USE_MMU)
+#define PPC_MSR_EXC_BITS ( PPC_MSR_DR | PPC_MSR_IR)
+#else
+#endif
+
+
+
+#ifndef ASM
+
+/*
+ * Type definition for raw exceptions.
+ */
+
+typedef unsigned char rtems_vector;
+struct __rtems_raw_except_connect_data__;
+typedef void (*rtems_raw_except_func) (void);
+typedef unsigned long rtems_raw_except_hdl_size;
+
+typedef struct {
+ rtems_vector vector;
+ rtems_raw_except_func raw_hdl;
+ rtems_raw_except_hdl_size raw_hdl_size;
+}rtems_raw_except_hdl;
+
+typedef void (*rtems_raw_except_enable) (const struct __rtems_raw_except_connect_data__*);
+typedef void (*rtems_raw_except_disable) (const struct __rtems_raw_except_connect_data__*);
+typedef int (*rtems_raw_except_is_enabled) (const struct __rtems_raw_except_connect_data__*);
+
+typedef struct __rtems_raw_except_connect_data__{
+ /*
+ * Exception vector (As defined in the manual)
+ */
+ rtems_vector exceptIndex;
+ /*
+ * Exception raw handler. See comment on handler properties below in function prototype.
+ */
+ rtems_raw_except_hdl hdl;
+ /*
+ * function for enabling raw exceptions. In order to be consistent
+ * with the fact that the raw connexion can defined in the
+ * libcpu library, this library should have no knowledge of
+ * board specific hardware to manage exceptions and thus the
+ * "on" routine must enable the except at processor level only.
+ *
+ */
+ rtems_raw_except_enable on;
+ /*
+ * function for disabling raw exceptions. In order to be consistent
+ * with the fact that the raw connexion can defined in the
+ * libcpu library, this library should have no knowledge of
+ * board specific hardware to manage exceptions and thus the
+ * "on" routine must disable the except both at device and PIC level.
+ *
+ */
+ rtems_raw_except_disable off;
+ /*
+ * function enabling to know what exception may currently occur
+ */
+ rtems_raw_except_is_enabled isOn;
+}rtems_raw_except_connect_data;
+
+typedef struct {
+ /*
+ * size of all the table fields (*Tbl) described below.
+ */
+ unsigned int exceptSize;
+ /*
+ * Default handler used when disconnecting exceptions.
+ */
+ rtems_raw_except_connect_data defaultRawEntry;
+ /*
+ * Table containing initials/current value.
+ */
+ rtems_raw_except_connect_data* rawExceptHdlTbl;
+}rtems_raw_except_global_settings;
+
+/*
+ * C callable function enabling to set up one raw idt entry
+ */
+extern int ppc_set_exception (const rtems_raw_except_connect_data*);
+
+/*
+ * C callable function enabling to get one current raw idt entry
+ */
+extern int ppc_get_current_exception (rtems_raw_except_connect_data*);
+
+/*
+ * C callable function enabling to remove one current raw idt entry
+ */
+extern int ppc_delete_exception (const rtems_raw_except_connect_data*);
+
+/*
+ * C callable function enabling to check if vector is valid
+ */
+extern int ppc_vector_is_valid(rtems_vector vector);
+
+/*
+ * Exception global init.
+ */
+extern int ppc_init_exceptions (rtems_raw_except_global_settings* config);
+extern int ppc_get_exception_config (rtems_raw_except_global_settings** config);
+
+# endif /* ASM */
+
+#endif
diff --git a/c/src/lib/libcpu/powerpc/ppc403/irq/ictrl.c b/c/src/lib/libcpu/powerpc/ppc403/irq/ictrl.c
new file mode 100644
index 0000000000..6a1f810cd0
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/ppc403/irq/ictrl.c
@@ -0,0 +1,292 @@
+/* ictrl.c
+ *
+ * This routine installs and handles external interrupt vectors for
+ * PowerPC 403 CPU built-in external interrupt controller
+ *
+ * Author: Thomas Doerfler <td@imd.m.isar.de>
+ *
+ * COPYRIGHT (c) 1998 by IMD, Puchheim, Germany
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of IMD not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * IMD makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Modifications for PPC405GP by Dennis Ehlin
+ *
+ */
+
+#include "ictrl.h"
+#include <rtems.h>
+#include <rtems/libio.h>
+
+#include <stdlib.h> /* for atexit() */
+
+/*
+ * ISR vector table to dispatch external interrupts
+ */
+
+rtems_isr_entry ictrl_vector_table[PPC_IRQ_EXT_MAX];
+
+/*
+ *
+ * some utilities to access the EXI* registers
+ *
+ */
+
+/*
+ * clear bits in EXISR that have a bit set in mask
+ */
+#if defined(ppc405)
+RTEMS_INLINE_ROUTINE void
+clr_exisr(uint32_t mask)
+{
+ asm volatile ("mtdcr 0xC0,%0"::"r" (mask));/*EXISR*/
+}
+
+/*
+ * get value of EXISR
+ */
+RTEMS_INLINE_ROUTINE uint32_t
+get_exisr(void)
+{
+ uint32_t val;
+
+ asm volatile ("mfdcr %0,0xC0":"=r" (val));/*EXISR*/
+ return val;
+}
+
+/*
+ * get value of EXIER
+ */
+RTEMS_INLINE_ROUTINE uint32_t
+get_exier(void)
+{
+ uint32_t val;
+ asm volatile ("mfdcr %0,0xC2":"=r" (val));/*EXIER*/
+ return val;
+}
+
+/*
+ * set value of EXIER
+ */
+RTEMS_INLINE_ROUTINE void
+set_exier(uint32_t val)
+{
+ asm volatile ("mtdcr 0xC2,%0"::"r" (val));/*EXIER*/
+}
+
+#else /* not ppc405 */
+
+RTEMS_INLINE_ROUTINE void
+clr_exisr(uint32_t mask)
+{
+ asm volatile ("mtdcr 0x40,%0"::"r" (mask));/*EXISR*/
+}
+
+/*
+ * get value of EXISR
+ */
+RTEMS_INLINE_ROUTINE uint32_t
+get_exisr(void)
+{
+ uint32_t val;
+
+ asm volatile ("mfdcr %0,0x40":"=r" (val));/*EXISR*/
+ return val;
+}
+
+/*
+ * get value of EXIER
+ */
+RTEMS_INLINE_ROUTINE uint32_t
+get_exier(void)
+{
+ uint32_t val;
+ asm volatile ("mfdcr %0,0x42":"=r" (val));/*EXIER*/
+ return val;
+}
+
+/*
+ * set value of EXIER
+ */
+RTEMS_INLINE_ROUTINE void
+set_exier(uint32_t val)
+{
+ asm volatile ("mtdcr 0x42,%0"::"r" (val));/*EXIER*/
+}
+#endif /* ppc405 */
+/*
+ * enable an external interrupt, make this interrupt consistent
+ */
+RTEMS_INLINE_ROUTINE void
+enable_ext_irq( uint32_t mask)
+{
+ uint32_t isrlvl;
+ _CPU_ISR_Disable(isrlvl);
+ set_exier(get_exier() | ((mask)&PPC_EXI_MASK));
+ _CPU_ISR_Enable(isrlvl);
+}
+
+/*
+ * disable an external interrupt, make this interrupt consistent
+ */
+RTEMS_INLINE_ROUTINE void
+disable_ext_irq( uint32_t mask)
+{
+ uint32_t isrlvl;
+ _CPU_ISR_Disable(isrlvl);
+ set_exier(get_exier() & ~(mask) & PPC_EXI_MASK);
+ _CPU_ISR_Enable(isrlvl);
+}
+
+/*
+ *
+ * this function is called, when a external interrupt is present and
+ * enabled but there is no handler installed. It will clear
+ * the corresponding enable bits and call the spurious handler
+ * present in the CPU Configuration Table, if any.
+ *
+ */
+void
+ictrl_spurious_handler(uint32_t spurious_mask,
+ CPU_Interrupt_frame *cpu_frame)
+{
+ int v;
+
+ for (v=0; v < PPC_IRQ_EXT_MAX; v++) {
+ if (VEC_TO_EXMSK(v) & spurious_mask) {
+ clr_exisr(VEC_TO_EXMSK(v));
+ disable_ext_irq(VEC_TO_EXMSK(v));
+#if 0
+ printf("spurious external interrupt: %d at pc 0x%x; disabling\n",
+ vector, cpu_frame->Interrupt.pcoqfront);
+#endif
+ if (rtems_cpu_configuration_get_spurious_handler()) {
+ rtems_cpu_configuration_get_spurious_handler()(v + PPC_IRQ_EXT_BASE,cpu_frame);
+ }
+ }
+ }
+}
+
+
+/*
+ * ISR Handler: this is called from the primary exception dispatcher
+ */
+
+void
+ictrl_isr(rtems_vector_number vector,CPU_Interrupt_frame *cpu_frame)
+{
+ uint32_t istat,
+ mask,
+ global_vec;
+ int exvec;
+ rtems_isr_entry handler;
+
+ istat = get_exisr() & get_exier() & PPC_EXI_MASK;
+
+ /* FIXME: this may be speeded up using cntlzw instruction */
+ for (exvec = 0;exvec < PPC_IRQ_EXT_MAX;exvec++) {
+ mask = VEC_TO_EXMSK(exvec);
+ if (0 != (istat & mask)) {
+ /*clr_exisr(mask); too early to ack*/
+ handler = ictrl_vector_table[exvec];
+ if (handler) {
+ istat &= ~mask;
+ global_vec = exvec + PPC_IRQ_EXT_BASE;
+ (handler)(global_vec);
+ }
+ clr_exisr(mask);/* now we can ack*/
+ }
+ }
+ if (istat != 0) { /* anything left? then we have a spurious interrupt */
+ ictrl_spurious_handler(istat,cpu_frame);
+ }
+}
+
+/*
+ *
+ * the following functions form the user interface
+ *
+ */
+
+/*
+ *
+ * install a user vector for one of the external interrupt sources
+ *
+ */
+rtems_status_code
+ictrl_set_vector(rtems_isr_entry new_handler,
+ uint32_t vector,
+ rtems_isr_entry *old_handler
+)
+{
+ /*
+ * We put the actual user ISR address in 'ictrl_vector_table'. This will
+ * be used by the _ictrl_isr so the user gets control.
+ */
+
+ /* check for valid vector range */
+ if ((vector >= PPC_IRQ_EXT_BASE) &&
+ (vector < PPC_IRQ_EXT_BASE + PPC_IRQ_EXT_MAX)) {
+ /* return old handler entry */
+ *old_handler = ictrl_vector_table[vector - PPC_IRQ_EXT_BASE];
+
+ if (new_handler != NULL) {
+ /* store handler function... */
+ ictrl_vector_table[vector - PPC_IRQ_EXT_BASE] = new_handler;
+ /* then enable it in EXIER register */
+ enable_ext_irq(VEC_TO_EXMSK(vector - PPC_IRQ_EXT_BASE));
+ }
+ else { /* new_handler == NULL */
+ /* then disable it in EXIER register */
+ disable_ext_irq(VEC_TO_EXMSK(vector - PPC_IRQ_EXT_BASE));
+ ictrl_vector_table[vector - PPC_IRQ_EXT_BASE] = NULL;
+ }
+ return RTEMS_SUCCESSFUL;
+ }
+ else {
+ return RTEMS_INVALID_NUMBER;
+ }
+}
+
+/*
+ * Called via atexit()
+ * deactivate the interrupt controller
+ */
+
+void
+ictrl_exit(void)
+{
+ /* mark them all unused */
+ disable_ext_irq(~0);
+ clr_exisr(~0);
+
+}
+
+/*
+ * activate the interrupt controller
+ */
+
+rtems_status_code
+ictrl_init(void)
+{
+ proc_ptr dummy;
+
+ /* mark them all unused */
+ disable_ext_irq(~0);
+ clr_exisr(~0);
+
+ /* install the external interrupt handler */
+ _CPU_ISR_install_vector(PPC_IRQ_EXTERNAL,
+ ictrl_isr,
+ &dummy);
+ atexit(ictrl_exit);
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/c/src/lib/libcpu/powerpc/ppc403/irq/ictrl.h b/c/src/lib/libcpu/powerpc/ppc403/irq/ictrl.h
new file mode 100644
index 0000000000..4370788108
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/ppc403/irq/ictrl.h
@@ -0,0 +1,95 @@
+/* ictrl.h
+ *
+ * This file contains definitions and declarations for the
+ * PowerPC 403 CPU built-in external interrupt controller
+ *
+ *
+ * Author: Thomas Doerfler <td@imd.m.isar.de>
+ *
+ * COPYRIGHT (c) 1998 by IMD, Puchheim, Germany
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of IMD not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * IMD makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Modifications for PPC405GP by Dennis Ehlin
+ *
+ */
+
+
+#ifndef _ICTRL_H
+#define _ICTRL_H
+
+#include <rtems.h>
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * definitions for second level IRQ handler support
+ * External Interrupts via EXTERNAL/EISR
+ */
+#define PPC_IRQ_EXT_BASE (PPC_IRQ_LAST+1)
+
+/* mask for external interrupt status in EXIER/EXISR register */
+/* note: critical interrupt is in these registers aswell */
+#ifndef ppc405
+#define PPC_EXI_MASK 0x0FFFFFFF
+#else /* ppc405 */
+#define PPC_EXI_MASK 0xFFFFFFFF
+#endif /* ppc405 */
+
+#ifndef ppc405
+#define PPC_IRQ_EXT_SPIR (PPC_IRQ_EXT_BASE+4)
+#define PPC_IRQ_EXT_SPIT (PPC_IRQ_EXT_BASE+5)
+#else /* ppc405 */
+#define PPC_IRQ_EXT_UART0 (PPC_IRQ_EXT_BASE+0)
+#define PPC_IRQ_EXT_UART1 (PPC_IRQ_EXT_BASE+1)
+#endif /* ppc405 */
+#define PPC_IRQ_EXT_JTAGR (PPC_IRQ_EXT_BASE+6)
+#define PPC_IRQ_EXT_JTAGT (PPC_IRQ_EXT_BASE+7)
+#define PPC_IRQ_EXT_DMA0 (PPC_IRQ_EXT_BASE+8)
+#define PPC_IRQ_EXT_DMA1 (PPC_IRQ_EXT_BASE+9)
+#define PPC_IRQ_EXT_DMA2 (PPC_IRQ_EXT_BASE+10)
+#define PPC_IRQ_EXT_DMA3 (PPC_IRQ_EXT_BASE+11)
+#define PPC_IRQ_EXT_0 (PPC_IRQ_EXT_BASE+27)
+#define PPC_IRQ_EXT_1 (PPC_IRQ_EXT_BASE+28)
+#define PPC_IRQ_EXT_2 (PPC_IRQ_EXT_BASE+29)
+#define PPC_IRQ_EXT_3 (PPC_IRQ_EXT_BASE+30)
+#define PPC_IRQ_EXT_4 (PPC_IRQ_EXT_BASE+31)
+
+#define PPC_IRQ_EXT_MAX (32)
+
+#define VEC_TO_EXMSK(v) (0x80000000 >> (v))
+
+/*
+ *
+ * install a user vector for one of the external interrupt sources
+ *
+ */
+rtems_status_code
+ictrl_set_vector(rtems_isr_entry new_handler,
+ uint32_t vector,
+ rtems_isr_entry *old_handler
+);
+/*
+ * activate the interrupt controller
+ */
+rtems_status_code
+ictrl_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ICTRL_H */
+/* end of include file */