Index: c/src/lib/libbsp/powerpc/gen405/opbintctrl/opbintctrl.c
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/opbintctrl/opbintctrl.c	(.../rtems/rtems-4.6.5)	(revision 0)
+++ c/src/lib/libbsp/powerpc/gen405/opbintctrl/opbintctrl.c	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -0,0 +1,178 @@
+/*  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 "opbintctrl.h"
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <stdlib.h>
+
+/*
+ *  ISR vector table to dispatch external interrupts
+ */
+rtems_isr_entry opb_intc_vector_table[OPB_INTC_IRQ_MAX];
+
+/* 
+ * Acknowledge/Clear a specific vector number 
+ */
+RTEMS_INLINE_ROUTINE void 
+awk_vector(unsigned32 vector) 
+{
+	*(unsigned32*)(OPB_INTC_BASE+OPB_INTC_IAR) = 1 << vector;
+} 
+
+/* 
+ * Enable a specific vector number 
+ * vector is a number counting from 0
+ */
+RTEMS_INLINE_ROUTINE void 
+enable_vector(unsigned32 vector) 
+{
+	*(unsigned32*)(OPB_INTC_BASE+OPB_INTC_IER) = 1 << vector;
+} 
+
+/* 
+ * Disable a specific vector number 
+ * vector is a number counting from 0
+ */
+RTEMS_INLINE_ROUTINE void 
+disable_vector(unsigned32 vector) 
+{
+	*(unsigned32*)(OPB_INTC_BASE+OPB_INTC_CIE) = 1 << vector;
+} 
+
+/* 
+ * 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(unsigned32 mask)
+{
+	*(unsigned32*)(OPB_INTC_BASE+OPB_INTC_IER) = mask;
+} 
+
+/* 
+ * Set ISR state.  Used to awknowledge a mask of vectors.
+ * If you only have to do one, use awk_vector.
+ */
+RTEMS_INLINE_ROUTINE void 
+set_isr(unsigned32 mask)
+{
+	*(unsigned32*)(OPB_INTC_BASE+OPB_INTC_ISR) = mask;
+} 
+
+/* 
+ * Get Highest Priority Pending Vector (aka read IVR)
+ */
+RTEMS_INLINE_ROUTINE unsigned32 
+get_vector() 
+{
+	volatile unsigned32 vector = *(unsigned32*)(OPB_INTC_BASE+OPB_INTC_IVR);
+	return vector;
+} 
+
+/* 
+ * Enable Hardware Interrupt Enable 
+ * This turns off support for software settable interrupts. 
+ */
+RTEMS_INLINE_ROUTINE void 
+enable_hie() 
+{
+	volatile unsigned32 value = *(unsigned32*)(OPB_INTC_BASE+OPB_INTC_MER);
+	value |= OPB_INTC_MER_HIE;
+	*(unsigned32*)(OPB_INTC_BASE+OPB_INTC_MER) = value;
+} 
+
+/* 
+ * Master IRQ (Dis)Enable
+ */
+RTEMS_INLINE_ROUTINE void 
+set_master_enable(unsigned32 value) 
+{
+	volatile unsigned32 v = *(unsigned32*)(OPB_INTC_BASE+OPB_INTC_MER);
+	v |= value ? OPB_INTC_MER_ME : 0;
+	*(unsigned32*)(OPB_INTC_BASE+OPB_INTC_MER) = v;
+} 
+
+/*
+ *  ISR Handler: this is called from the primary exception dispatcher
+ */
+ 
+void
+opb_intc_isr(rtems_vector_number vector,CPU_Interrupt_frame *cpu_frame)
+{
+	unsigned32 opb_vector;
+	rtems_isr_entry handler;
+
+	opb_vector = get_vector();
+	handler = opb_intc_vector_table[opb_vector];	
+	if(handler) {
+		(handler)(PPC_IRQ_EXTERNAL);	
+	} else {
+		/*printk("Spurious interrupt vector: %x\n", opb_vector);*/
+	}
+	awk_vector(opb_vector);
+}
+
+/*
+ * install a user vector for one of the external interrupt sources 
+ * vector is the number of the vector counting from 0.
+ */ 
+rtems_status_code
+opb_intc_set_vector(rtems_isr_entry new_handler, unsigned32 vector,
+	rtems_isr_entry *old_handler)
+{
+  /*
+   *  We put the actual user ISR address in 'opb_intc_vector_table'.  This will
+   *  be used by the _opb_intc_isr so the user gets control.
+   */
+
+	if(vector < OPB_INTC_IRQ_MAX) {
+		*old_handler = opb_intc_vector_table[vector];
+		if(new_handler) {
+			opb_intc_vector_table[vector] = new_handler;
+			enable_vector(vector);
+		} else {
+			disable_vector(vector);
+			opb_intc_vector_table[vector] = 0;
+		}
+		return RTEMS_SUCCESSFUL;
+	} 
+	return RTEMS_INVALID_NUMBER;
+}	
+
+/*
+ * activate the interrupt controller 
+ */
+rtems_status_code 
+opb_intc_init(void)
+{
+	proc_ptr dummy;
+	/* install the external interrupt handler */
+	_CPU_ISR_install_vector(PPC_IRQ_EXTERNAL, opb_intc_isr, &dummy);
+
+	/* Clear any currently set interrupts */
+	set_isr(0x0);
+	/* Disable all vectors */
+ 	set_ier(0x0);
+
+	/* Turn on normal hardware operation of interrupt controller */
+	enable_hie();
+	/* Enable master interrupt switch for the interrupt controller */
+	set_master_enable(1);
+
+	/* install exit handler to close opb_intc when program atexit called */
+	/* atexit(opb_intc_exit);*/
+
+	return RTEMS_SUCCESSFUL;
+}
+
Index: c/src/lib/libbsp/powerpc/gen405/opbintctrl/opbintctrl.h
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/opbintctrl/opbintctrl.h	(.../rtems/rtems-4.6.5)	(revision 0)
+++ c/src/lib/libbsp/powerpc/gen405/opbintctrl/opbintctrl.h	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -0,0 +1,66 @@
+/*  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>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Maximum number of IRQs.  Defined in vhdl model */
+#define OPB_INTC_IRQ_MAX	5
+
+/* Base Register address and register offsets */
+#define OPB_INTC_BASE		0x41200000
+/* 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
+
+/*
+ * install a user vector for one of the external interrupt sources 
+ */ 
+rtems_status_code opb_intc_set_vector(rtems_isr_entry new_handler,
+	unsigned32 vector, rtems_isr_entry *old_handler);
+/*
+ * activate the interrupt controller 
+ */
+rtems_status_code opb_intc_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*  _INCLUDE_OPBINTCTRL_H */
Index: c/src/lib/libbsp/powerpc/gen405/opbintctrl/Makefile.am
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/opbintctrl/Makefile.am	(.../rtems/rtems-4.6.5)	(revision 0)
+++ c/src/lib/libbsp/powerpc/gen405/opbintctrl/Makefile.am	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -0,0 +1,38 @@
+##
+## Makefile.am,v 1.8 2002/12/19 05:03:12 ralf Exp
+##
+
+
+PGM = $(ARCH)/opbintctrl.rel
+
+C_FILES = opbintctrl.c
+
+include_HEADERS = opbintctrl.h
+
+opb_intc_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
+
+include $(top_srcdir)/../../../../../../automake/compile.am
+include $(top_srcdir)/../../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+$(PGM): $(opb_intc_rel_OBJECTS)
+	$(make-rel)
+
+TMPINSTALL_FILES += $(PROJECT_INCLUDE) \
+	$(include_HEADERS:%=$(PROJECT_INCLUDE)/%) 
+
+$(PROJECT_INCLUDE):
+	$(mkinstalldirs) $@
+$(PROJECT_INCLUDE)/%.h: %.h
+	$(INSTALL_DATA) $< $@
+
+all-local: $(ARCH) $(opb_intc_rel_OBJECTS) $(PGM) $(TMPINSTALL_FILES)
+
+.PRECIOUS: $(PGM)
+
+EXTRA_DIST = opbintctrl.c opbintctrl.h
+
+include $(top_srcdir)/../../../../../../automake/local.am
Index: c/src/lib/libbsp/powerpc/gen405/bsp_specs
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/bsp_specs	(.../rtems/rtems-4.6.5)	(revision 1691)
+++ c/src/lib/libbsp/powerpc/gen405/bsp_specs	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -1,23 +1,20 @@
-%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)} %{!nostdlib: %{qrtems: ecrti%O%s --start-group \
+%{!qrtems: %(old_lib)} %{!nostdlib: %{qrtems: --start-group \
 %{!qrtems_debug: -lrtemsbsp -lrtemscpu} %{qrtems_debug: -lrtemsbsp_g -lrtemscpu_g} \
--lc -lgcc --end-group \
+-lc -lgcc --end-group  \
 %{!qnolinkcmds: -T linkcmds%s}}}
 
 *startfile:
-%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems: \
-%{!qrtems_debug: } \
-%{qrtems_debug: }}}
+%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems:  ecrti%O%s rtems_crti%O%s crtbegin.o%s }}
 
 *link:
 %{!qrtems: %(old_link)} %{qrtems: -dc -dp -u __vectors -u download_entry -N }
 
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
Index: c/src/lib/libbsp/powerpc/gen405/console/consolelite.c
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/console/consolelite.c	(.../rtems/rtems-4.6.5)	(revision 0)
+++ c/src/lib/libbsp/powerpc/gen405/console/consolelite.c	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -0,0 +1,287 @@
+/*
+ *  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 <opbintctrl.h>
+
+#define PORT 0x40600000
+#define RECV_REG 0
+#define TRAN_REG 4
+#define STAT_REG 8
+#define CTRL_REG 12
+
+#define POLL_DRIVEN
+
+/* Uncomment this to enable uart interrupts */
+/* #define INTERRUPT_DRIVEN */
+
+struct UartLiteState 
+{
+	unsigned32 iPrevWriteLen;	
+	void* iTty;
+};
+
+struct UartLiteState gUartLiteState;
+
+RTEMS_INLINE_ROUTINE unsigned32 uartLiteStatus()
+{
+  volatile unsigned32 s = *(unsigned32*)(PORT+STAT_REG);
+  return s;
+} 
+
+RTEMS_INLINE_ROUTINE unsigned32 uartLiteControl()
+{
+  volatile unsigned32 c = *(unsigned32*)(PORT+CTRL_REG);
+  return c;
+}
+
+RTEMS_INLINE_ROUTINE signed32 uartLiteRead()
+{
+  volatile signed32 c = *(unsigned32*)(PORT+RECV_REG);
+  return c;
+}
+
+RTEMS_INLINE_ROUTINE void uartLiteWrite(signed32 ch)
+{
+  *(unsigned32*)(PORT+TRAN_REG) = ch;
+}
+
+/* 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
+
+RTEMS_INLINE_ROUTINE void uartLiteEnableInterrupt()
+{
+	*(unsigned32*)(PORT+CTRL_REG) = uartLiteControl() | ENABLE_INTR;
+}
+
+RTEMS_INLINE_ROUTINE void uartLiteReset()
+{
+	if(uartLiteStatus() & INTR_ENABLED) {
+		*(unsigned32*)(PORT+CTRL_REG) = ENABLE_INTR | RST_RX_FIFO | RST_TX_FIFO;
+	}
+	else {
+		*(unsigned32*)(PORT+CTRL_REG) = RST_RX_FIFO | RST_TX_FIFO;
+	}
+}
+
+int uartLitePollWrite(int minor, const char* buf, int len)
+{
+	int i=0;
+	volatile unsigned int status = uartLiteStatus();
+	for(i=0; i<len; i++) {
+		while(status & TX_FIFO_FULL) {
+			status = uartLiteStatus();
+		}
+	uartLiteWrite(buf[i]); 
+	}	
+	return 0;
+}
+
+int uartLitePollRead(int minor)
+{
+	volatile unsigned int status = uartLiteStatus();
+	if(status & RX_FIFO_VALID_DATA)
+		return uartLiteRead();
+	else
+		return -1;
+}
+
+int uartLiteSetAttr(int minor, const struct termios *t)
+{
+	/* We just pretend that we support changing this.  In reality the xilinx
+	 * uartlite has a fixed baud, parity, hardware flow control etc etc. 
+	 * If you don't like this, don't use a uartlite and use a full 16550.
+	 */
+	return 0;
+}
+
+rtems_isr uartLiteIsr(rtems_vector_number v)
+{
+	if(uartLiteStatus() & STATUS_REG_ERROR_MASK) {
+		uartLiteReset();
+		return;
+	}
+	
+	if(uartLiteStatus() & RX_FIFO_VALID_DATA) {
+		char buf[RX_FIFO_SIZE];
+		unsigned32 i=0;
+		for(; uartLiteStatus() & RX_FIFO_VALID_DATA; i++) {
+			buf[i] = uartLiteRead();
+		} 
+		rtems_termios_enqueue_raw_characters(gUartLiteState.iTty, buf, i+1);
+	}
+
+	if(uartLiteStatus() & TX_FIFO_EMPTY) {
+		rtems_termios_dequeue_characters(gUartLiteState.iTty, gUartLiteState.iPrevWriteLen);
+	}
+}
+
+signed32 uartLiteInterruptWrite(signed32 minor, const char* buf, signed32 len)
+{
+	if(minor == 0) {
+		if(len > TX_FIFO_SIZE) {
+			len = TX_FIFO_SIZE;
+		}
+		unsigned32 i=0;
+		gUartLiteState.iPrevWriteLen = len;
+		for(; i < len; i++) {
+			uartLiteWrite(buf[i]);
+		}
+	}
+	return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code uartLiteInit()
+{
+	uartLiteEnableInterrupt();
+	uartLiteReset();
+
+#if defined INTERRUPT_DRIVEN
+	rtems_status_code sc;
+	rtems_isr_entry oldHandler;
+	sc = opb_intc_set_vector(uartLiteIsr, 4, &oldHandler);
+	return sc;
+#else
+  return RTEMS_SUCCESSFUL;
+#endif
+}
+
+rtems_device_driver console_initialize(rtems_device_major_number major,
+	rtems_device_minor_number minor, void* arg)
+{
+	rtems_status_code status;
+
+	rtems_termios_initialize();
+
+	/* Initialise the uartlite */
+	uartLiteInit();
+
+	status = rtems_io_register_name("/dev/console", major, 0);
+
+	if (status != RTEMS_SUCCESSFUL)
+		rtems_fatal_error_occurred (status);
+	return RTEMS_SUCCESSFUL;
+}
+
+#if defined INTERRUPT_DRIVEN
+static rtems_termios_callbacks gInterruptCallbacks = {
+	0,           /* firstOpen */
+	0,           /* lastClose */
+	0, 		   /* pollRead */
+	uartLiteInterruptWrite,   /* write */
+	uartLiteSetAttr,	/* uartLiteSetAttr */
+	0,			/* stopRemoteTx */
+	0,			/* startRemoteTx */
+	1				/* outputUsesInterrupts */
+};
+#elif defined POLL_DRIVEN
+static rtems_termios_callbacks gPollCallbacks = {
+	0,           /* firstOpen */
+	0,           /* lastClose */
+	uartLitePollRead,    /* uartLitePollRead */
+	uartLitePollWrite,   /* write */
+	uartLiteSetAttr,	/* uartLiteSetAttr */
+	0,	/* stopRemoteTx */
+	0,	/* startRemoteTx */
+	0	/* outputUsesInterrupts */
+};
+#endif
+
+rtems_device_driver console_open(rtems_device_major_number major,
+	rtems_device_minor_number minor, void* arg)
+{
+	rtems_status_code sc;
+	
+	/* Initialize members of UartLiteState */
+	gUartLiteState.iPrevWriteLen = 0;
+	rtems_libio_open_close_args_t* args = arg;
+
+#if defined INTERRUPT_DRIVEN
+	sc = rtems_termios_open (major, minor, arg, &gInterruptCallbacks);
+#elif defined POLL_DRIVEN
+	sc = rtems_termios_open (major, minor, arg, &gPollCallbacks);
+#else
+#error Must select one of INTERRUPT_DRIVE or POLL_DRIVEN
+#endif
+
+	gUartLiteState.iTty = args->iop->data1;
+
+	return sc;
+}
+
+rtems_device_driver console_close(rtems_device_major_number major,
+  rtems_device_minor_number minor, void* arg)
+{
+	return rtems_termios_close(arg);
+}
+
+rtems_device_driver console_read(rtems_device_major_number major,
+  rtems_device_minor_number minor, void* arg)
+{
+	return rtems_termios_read(arg);
+}
+
+rtems_device_driver console_write(rtems_device_major_number major,
+  rtems_device_minor_number minor, void* arg)
+{
+	return rtems_termios_write(arg);
+}
+
+rtems_device_driver console_control(rtems_device_major_number major,
+  rtems_device_minor_number minor, void* arg)
+{
+	rtems_libio_ioctl_args_t* args = arg;
+	if(args->command == RTEMS_IO_SET_ATTRIBUTES)
+		uartLiteSetAttr(minor, (struct termios*)args->buffer);
+
+	return rtems_termios_ioctl(arg);
+}
+
+#include <rtems/bspIo.h>
+
+void outputChar(char ch) 
+{
+	uartLitePollWrite(0, &ch, 1);
+}
+
+char inputChar()
+{
+	return uartLitePollRead(0);
+}
+
+BSP_output_char_function_type BSP_output_char = outputChar;
+BSP_polling_getchar_function_type BSP_poll_char = inputChar;
+
+
Index: c/src/lib/libbsp/powerpc/gen405/console/Makefile.am
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/console/Makefile.am	(.../rtems/rtems-4.6.5)	(revision 0)
+++ c/src/lib/libbsp/powerpc/gen405/console/Makefile.am	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -0,0 +1,28 @@
+##
+## Makefile.am,v 1.8 2002/12/19 05:03:12 ralf Exp
+##
+
+
+PGM = $(ARCH)/console.rel
+
+C_FILES = consolelite.c
+
+console_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
+
+include $(top_srcdir)/../../../../../../automake/compile.am
+include $(top_srcdir)/../../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+$(PGM): $(console_rel_OBJECTS)
+	$(make-rel)
+
+all-local: $(ARCH) $(console_rel_OBJECTS) $(PGM)
+
+.PRECIOUS: $(PGM)
+
+EXTRA_DIST = consolelite.c
+
+include $(top_srcdir)/../../../../../../automake/local.am
Index: c/src/lib/libbsp/powerpc/gen405/startup/bspstart.c
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/startup/bspstart.c	(.../rtems/rtems-4.6.5)	(revision 1691)
+++ c/src/lib/libbsp/powerpc/gen405/startup/bspstart.c	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -62,7 +62,7 @@
 #include <bsp.h>
 #include <rtems/libio.h>
 #include <rtems/libcsupport.h>
-#include <ictrl.h>
+#include <opbintctrl.h>
  
 /*
  *  The original table from the application and our copy of it with
@@ -96,7 +96,7 @@
 {
   rtems_status_code status;
   /* init the PPC405 external interrupt controller handler... */
-  status = ictrl_init();
+  status = opb_intc_init();
 }
 
 /*
@@ -181,7 +181,7 @@
   Cpu_table.postdriver_hook = bsp_postdriver_hook;
   Cpu_table.interrupt_stack_size = CONFIGURE_INTERRUPT_STACK_MEMORY;
 
-  Cpu_table.clicks_per_usec = 300; 
+  Cpu_table.clicks_per_usec = 100; 
   Cpu_table.serial_per_sec = 14625000; /* = (CPU Clock / UART Internal Clock Divisor) */
   Cpu_table.serial_external_clock = 0;
   Cpu_table.timer_internal_clock  = 1;
Index: c/src/lib/libbsp/powerpc/gen405/startup/linkcmds
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/startup/linkcmds	(.../rtems/rtems-4.6.5)	(revision 1691)
+++ c/src/lib/libbsp/powerpc/gen405/startup/linkcmds	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -17,8 +17,8 @@
  
 MEMORY
   {
-        RAM : ORIGIN = 0, LENGTH = 64M
-        FLASH : ORIGIN = 0xFFE00000, LENGTH = 16M
+        RAM : ORIGIN = 0, LENGTH = 32M
+        /*FLASH : ORIGIN = 0xFFE00000, LENGTH = 16M*/
   }
 SECTIONS
 {
@@ -69,7 +69,7 @@
 
      *(.lit)
      *(.shdata)
-     _init = .; __init = .; *(.init)
+     __init = .; *(.init)
      _fini = .; __fini = .; *(.fini)
      _endtext = ALIGN(0x10);
      text.end = .;
@@ -128,6 +128,7 @@
   .sbss2   	  : { *(.sbss2) *(.gnu.linkonce.sb2.*)	} >RAM
   PROVIDE (__SBSS2_END__ = .);
 
+  .jcr  : { KEEP (*(.jcr)) } > RAM
   __SBSS_START__ = .;
   .bss :
   {
Index: c/src/lib/libbsp/powerpc/gen405/configure.ac
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/configure.ac	(.../rtems/rtems-4.6.5)	(revision 1691)
+++ c/src/lib/libbsp/powerpc/gen405/configure.ac	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -18,7 +18,7 @@
 
 AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
 
-RTEMS_BSPOPTS_SET([PPC_USE_SPRG],[*],[1])
+RTEMS_BSPOPTS_SET([PPC_USE_SPRG],[*],[])
 RTEMS_BSPOPTS_HELP([PPC_USE_SPRG],
 [If defined, then the PowerPC specific code in RTEMS will use some
  of the special purpose registers to slightly optimize interrupt  
@@ -36,6 +36,10 @@
 dlentry/Makefile
 include/Makefile
 startup/Makefile
+console/Makefile
+opbintctrl/Makefile
+network/Makefile
+start/Makefile
 wrapup/Makefile])
 
 RTEMS_PPC_EXCEPTIONS([old])
Index: c/src/lib/libbsp/powerpc/gen405/include/bsp.h
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/include/bsp.h	(.../rtems/rtems-4.6.5)	(revision 1691)
+++ c/src/lib/libbsp/powerpc/gen405/include/bsp.h	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -98,7 +98,7 @@
 /* Constants */
 
 #define RAM_START 0
-#define RAM_END   0x00800000
+#define RAM_END   0x02000000
 
 
 /* miscellaneous stuff assumed to exist */
@@ -106,6 +106,12 @@
 extern rtems_configuration_table BSP_Configuration;     /* owned by BSP */
 extern rtems_cpu_table           Cpu_table;             /* owned by BSP */
 
+/* Network Defines */
+
+#define RTEMS_BSP_NETWORK_DRIVER_NAME "xilEmac0"
+extern signed32 xilEmacAttachWrapper(struct rtems_bsdnet_config*);
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH xilEmacAttachWrapper
+
 /*
  *  Device Driver Table Entries
  */
Index: c/src/lib/libbsp/powerpc/gen405/Makefile.am
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/Makefile.am	(.../rtems/rtems-4.6.5)	(revision 1691)
+++ c/src/lib/libbsp/powerpc/gen405/Makefile.am	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -6,7 +6,7 @@
 
 # wrapup is the one that actually builds and installs the library
 #  from the individual .rel files built in other directories
-SUBDIRS = include dlentry startup @exceptions@ wrapup
+SUBDIRS = include dlentry opbintctrl startup @exceptions@ console network start wrapup
 
 include $(top_srcdir)/../../bsp.am
 
Index: c/src/lib/libbsp/powerpc/gen405/network/Makefile.am
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/network/Makefile.am	(.../rtems/rtems-4.6.5)	(revision 0)
+++ c/src/lib/libbsp/powerpc/gen405/network/Makefile.am	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -0,0 +1,28 @@
+##
+## Makefile.am,v 1.8 2002/12/19 05:03:12 ralf Exp
+##
+
+
+PGM = $(ARCH)/network.rel
+
+C_FILES = network.c
+
+console_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
+
+include $(top_srcdir)/../../../../../../automake/compile.am
+include $(top_srcdir)/../../../../../../automake/lib.am
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+$(PGM): $(console_rel_OBJECTS)
+	$(make-rel)
+
+all-local: $(ARCH) $(console_rel_OBJECTS) $(PGM)
+
+.PRECIOUS: $(PGM)
+
+EXTRA_DIST = network.c
+
+include $(top_srcdir)/../../../../../../automake/local.am
Index: c/src/lib/libbsp/powerpc/gen405/network/network.c
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/network/network.c	(.../rtems/rtems-4.6.5)	(revision 0)
+++ c/src/lib/libbsp/powerpc/gen405/network/network.c	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -0,0 +1,47 @@
+/*
+ * BSP specific code for the Xilinx Open Processor Bus Ethernet Media
+ * Access Controller (OPB EMAC) version 1.02a
+ *
+ * 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 <libchip/xilemac.h>
+#include <opbintctrl.h>
+#include <stdio.h>
+
+struct XilEmac gXilEmac;
+
+rtems_isr xilEmacIsrWrapper(rtems_vector_number aVector)
+{
+  xilEmacIsr(aVector, &gXilEmac);
+}
+
+signed32 xilEmacAttachWrapper(struct rtems_bsdnet_ifconfig* aBsdConfig, signed32 aNotUsed )
+{
+  struct XilEmacConfig config;
+
+  config.iAddr = 0x40C00000;
+  config.iBroadcast = 1;
+  config.iMulticast = 1;
+
+  rtems_status_code sc = xilEmacAttach(aBsdConfig, &gXilEmac, &config);
+  /* Attach returns 1 for success! */
+  if(sc != 1) {
+    printf("Failed to attach xilinx ethermac driver\n");
+    return 0;
+  }
+  rtems_isr_entry oldHandler;
+  sc = opb_intc_set_vector(xilEmacIsrWrapper, 0, &oldHandler);
+  if(sc != RTEMS_SUCCESSFUL) {
+    printf("Could not set interrupt vector for ethernet\n");
+    /* Attach returns 0 for failure! */
+    return 0;
+  }
+}
+
Index: c/src/lib/libbsp/powerpc/gen405/start/Makefile.am
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/start/Makefile.am	(.../rtems/rtems-4.6.5)	(revision 0)
+++ c/src/lib/libbsp/powerpc/gen405/start/Makefile.am	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -0,0 +1,24 @@
+
+S_FILES = rtems_crti.S
+S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.$(OBJEXT))
+OBJS = $(S_O_FILES)
+
+include $(top_srcdir)/../../../../../../automake/compile.am
+include $(top_srcdir)/../../../../../../automake/lib.am
+
+bsplib_DATA = $(PROJECT_RELEASE)/lib/rtems_crti.$(OBJEXT)
+
+$(PROJECT_RELEASE)/lib/rtems_crti.$(OBJEXT): $(ARCH)/rtems_crti.$(OBJEXT)
+	$(INSTALL_DATA) $< $@
+
+TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/rtems_crti.$(OBJEXT)
+
+all-local: $(ARCH) $(OBJS) $(ARCH)/rtems_crti.$(OBJEXT) $(TMPINSTALL_FILES)
+
+$(OBJS): $(ARCH)
+
+.PRECIOUS: $(ARCH)/rtems_crti.$(OBJEXT)
+
+
+include $(top_srcdir)/../../../../../../automake/local.am
+
Index: c/src/lib/libbsp/powerpc/gen405/start/rtems_crti.S
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/start/rtems_crti.S	(.../rtems/rtems-4.6.5)	(revision 0)
+++ c/src/lib/libbsp/powerpc/gen405/start/rtems_crti.S	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -0,0 +1,33 @@
+/* rtems_crti.S */
+#include <asm.h>
+
+	/* terminate the __init() function and create
+	 * a new head '_init' for use by RTEMS to 
+	 * invoke C++ global constructors
+	 * NOTE: it is essential that this snippet
+	 * is hooked between ecrti and crtbegin
+	 * 
+	 * ecrti has the following .init section:
+	 * __init:
+	 *    stwu r1,-16(r1)
+	 *    mflr r0
+	 *    stw  r0,20(r1)
+	 *
+	 * The reason for this is that we want to call
+	 * __eabi() at an early stage but prevent __eabi()
+	 * from branching to __init (C++ exception init
+	 * and global CTORs). Hence we make __init a no-op
+	 * and create a new entry point:
+	 */
+	.section ".init","ax"
+	.align 2
+	lwz		r0,r20(r1)
+	mtlr	r0
+	addi	r1,r1,16
+	blr
+	.globl	_init
+	.type	_init,@function
+_init:
+	stwu	r1,-16(r1)
+	mflr	r0
+	stw		r0,20(r1)	
Index: c/src/lib/libbsp/powerpc/gen405/wrapup/Makefile.am
===================================================================
--- c/src/lib/libbsp/powerpc/gen405/wrapup/Makefile.am	(.../rtems/rtems-4.6.5)	(revision 1691)
+++ c/src/lib/libbsp/powerpc/gen405/wrapup/Makefile.am	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -2,9 +2,9 @@
 ## $Id: Makefile.am,v 1.7 2002/12/11 09:06:35 ralf Exp $
 ##
 
-BSP_PIECES = startup dlentry
+BSP_PIECES = startup console dlentry opbintctrl network
 # pieces to pick up out of libcpu/ppc
-CPU_PIECES = clock timer console tty_drv vectors ictrl
+CPU_PIECES = clock timer tty_drv vectors 
 
 # bummer; have to use $foreach since % pattern subst rules only replace 1x
 OBJS = $(foreach piece, $(BSP_PIECES), $(wildcard ../$(piece)/$(ARCH)/*.$(OBJEXT))) \
Index: c/src/libchip/network/xilemac.c
===================================================================
--- c/src/libchip/network/xilemac.c	(.../rtems/rtems-4.6.5)	(revision 0)
+++ c/src/libchip/network/xilemac.c	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -0,0 +1,743 @@
+/*
+ * Reusable portion (libchip) of the Xilinx Open Processor Bus Ethernet Media
+ * Access Controller (OPB EMAC) version 1.02a
+ *
+ * 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 <libchip/xilemac.h>
+#include <assert.h>
+#include <sys/sockio.h>
+#include <rtems/rtems_bsdnet.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include <net/if.h>
+/* Register Defines */
+
+/* IPIF Interrupt Service Regisers */
+#define DISR      0x0000 /*< Device Interrupt Status Register */
+#define DIPR      0x0004 /*< Device Interrupt Pending Register */
+#define DIER      0x0008 /*< Device Interrupt Enable Register */
+#define DIID      0x0018 /*< Device Interrupt ID Register */
+#define DGIE      0x001C /*< Device Global Interrupt Enable */
+#define IPISR     0x0020 /*< IP Interrupt Status Register */
+#define IPIER     0x0028 /*< IP Interrupt Enable Register */
+
+/* IPIF Software Reset/MIR Service Registers */
+#define DRST       0x0040 /*< Device Software Reset */
+#define DMIR       0x0040 /*< Module Ident Register */
+
+/* IPIF Read FIFO Service Registers */
+#define RFRST     0x2010 /*< Read Fifo Reset */
+#define RFMIR     0x2010 /*< Read Fifo Module ID Register */
+#define RFSR      0x2014 /*< Read Fifo Status Register */
+#define RFDR      0x2200 /*< Read Fifo Data Register */
+
+/* IPIF Write FIFO Service Registers */
+#define WFRST     0x2000 /*< Write Fifo Reset */
+#define WFMIR     0x2000 /*< Write Fifo Module ID Register */
+#define WFSR      0x2004 /*< Write Fifo Status Register */
+#define WFDR      0x2100 /*< Write Fifo Data Register */
+#define WFDRU     0x28FF /*< Write Fifo Upper Data Register */
+
+/* EMAC Core Registers */
+#define EMIR      0x1100 /*< EMAC Module ID Register */
+#define ECR       0x1104 /*< EMAC Control Register */
+#define IFGP      0x1108 /*< Interframe Gap Register */ 
+#define SAH       0x110C /*< Station Address High */
+#define SAL       0x1110 /*< Station Address Low */
+#define MGTCR     0x1114 /*< MII Management Control Register */
+#define MGTDR     0x1118 /*< MII Management Data Register */
+#define RPLR      0x111C /*< Receive Packet Length Register */
+#define TPLR      0x1120 /*< Transmit Packet Length Register */
+#define TSR       0x1124 /*< Transmit Status Register */
+#define RMFC      0x1128 /*< Receive Missed Frame Count */
+#define RCC       0x112C /*< Receive Collision Count */
+#define RFCSEC    0x1130 /*< Receive FCS Error Count */
+#define RAEC      0x1134 /*< Receive Alignment Error Count */ 
+#define TEDC      0x1138 /*< Transmit Excess Deferral Count */
+#define RSR       0x113C /*< Receive Status Register */
+#define CAMH      0x1140 /*< Receive CAM Entry High Register */
+#define CAML      0x1144 /*< Receive CAM Entry Low Register */
+
+/* Register Masks */
+
+/* RFSR */
+#define RFSR_OCCUPANCY_MASK   0x00FFFFFF /*< Read Fifo Status Occupancy Mask */
+
+/* WFSR */
+#define WFSR_VACANCY_MASK     0x00FFFFFF /*< Write Fifo Status Vacancy Mask */
+
+/* WFRST */
+#define WFRST_VALUE           0x0000000A /*< Value required to reset fifo */
+
+/* RFRST */
+#define RFRST_VALUE           0x0000000A /*< Value required to reset fifo */
+
+/* DRST */
+#define DRST_VALUE            0x0000000A /*< Value required to reset device */
+
+/* DGIE */
+#define DGIE_GIE_OFF          0x00000000 /*< Turn off master interrupt switch */
+#define DGIE_GIE_ON           0x80000000 /*< Turn on master interrupt switch */
+
+/* ECR */
+#define ECR_RSTTX             0x40000000 /*< Reset transmitter */
+#define ECR_ENTX              0x20000000 /*< Enable transmitter */
+#define ECR_RSTRX             0x10000000 /*< Reset receiver */
+#define ECR_ENRX              0x08000000 /*< Enable receiver */
+#define ECR_MA                0x00010000 /*< Enable Multicast Reception */
+
+/* DISR and DIER and DIPR (all have same offsets */
+
+#define DISR_TERR             0x00000001 /*< Transaction Error */
+#define DISR_IPIR             0x00000004 /*< IP (ie EMAC) interrupt request */
+#define DISR_RFDL             0x00000020 /*< Receive FIFO Deadlock */
+#define DISR_WFDL             0x00000040 /*< Xmit FIFO Deadloack */
+#define DISR_INTR_MASK        (DISR_IPIR)
+/*| DISR_RFDL \
+                              | DISR_WFDL)*/
+
+/* TSR */
+
+#define TSR_TXED              0x80000000 /*< Transmit Excess Deferral Error */
+#define TSR_PFIFOU            0x40000000 /*< Packet Fifo Underrun */
+#define TSR_TXLC              0x01000000 /*< Transmit Late Collision Error */
+
+/* IPISR and IPIER (they both have the same offsets */
+#define IPISR_TXCP             0x00000001 /*< Transmit Complete */
+#define IPISR_RXCP             0x00000002 /*< Receive Complete */
+#define IPISR_TERR             0x00000004 /*< Transmit Error */
+#define IPISR_RERR             0x00000008 /*< Receive Error */
+#define IPISR_TSFE             0x00000010 /*< Transmit Status Fifo Empty */
+#define IPISR_RLFE             0x00000020 /*< Receive Length Fifo Empty */
+#define IPISR_TLFF             0x00000040 /*< Transmit Length Fifo Full */
+#define IPISR_TSFO             0x00000200 /*< Transmit Status Fifo Overrun */
+#define IPISR_TSFU             0x00000400 /*< Transmit Status Fifo Underrun */
+#define IPISR_TLFO             0x00000800 /*< Transmit Length Fifo Overrun */
+#define IPISR_TLFU             0x00001000 /*< Transmit Length Fifo Underrun */
+#define IPISR_TPPR             0x00002000 /*< Transmit Pause Packet Received */
+#define IPISR_RDFO             0x00004000 /*< Receive Data Fifo Overrun */
+#define IPISR_RMFE             0x00008000 /*< Receive Missed Frame Error */
+#define IPISR_RCE              0x00010000 /*< Receive Collison Error */
+#define IPISR_RFCS             0x00020000 /*< Receive FCS Error Interrupt */
+#define IPISR_RLER             0x00040000 /*< Receive Length Field Error */
+#define IPISR_RSE              0x00080000 /*< Receive Short Error */
+#define IPISR_RLE              0x00100000 /*< Receive Long Frame Error */
+#define IPISR_RAE              0x00200000 /*< Receive Alignment Error */
+
+#define IPISR_INTR_RX_MASK  ( IPISR_RERR | \
+                              IPISR_RDFO | \
+                              IPISR_RMFE | \
+                              IPISR_RCE  | \
+                              IPISR_RFCS | \
+                              IPISR_RLER | \
+                              IPISR_RSE  | \
+                              IPISR_RLE  | \
+                              IPISR_RAE  | \
+                              IPISR_RXCP )
+
+#define IPISR_INTR_TX_MASK  ( IPISR_TSFO | \
+                              IPISR_TSFU | \
+                              IPISR_TLFO | \
+                              IPISR_TLFU | \
+                              IPISR_TPPR | \
+                              IPISR_TXCP )
+
+#define IPISR_INTR_MASK (IPISR_INTR_RX_MASK | IPISR_INTR_TX_MASK)
+
+#define INTERRUPT_EVENT RTEMS_EVENT_1
+#define START_TRANSMIT_EVENT RTEMS_EVENT_2
+
+/* Reading/Writing memory mapped i/o */
+#define IN32(aPtr) (*(volatile unsigned32 *)(aPtr))
+#define OUT32(aPtr, aValue) { (*(volatile unsigned32 *)(aPtr) = aValue);  }
+
+void xilEmacInit(void* aXilEmac);
+void xilEmacReset(struct XilEmac* aXilEmac);
+void xilEmacStop(struct XilEmac* aXilEmac);
+void xilEmacSend(struct ifnet* aIfnet);
+void xilEmacStart(struct XilEmac* aIfnet);
+void xilEmacMacAddress(struct XilEmac* aXilEmac, unsigned8* aBuf);
+void xilEmacSetMacAddress(struct XilEmac* aXilEmac,
+  unsigned8* aAddr);
+void xilEmacPrintStats(struct XilEmacStats* aStats);
+signed32 xilEmacIoctl(struct ifnet* aIfnet, signed32 aCommand, caddr_t aData);
+
+void xilEmacRxThread(void* aXilEmac);
+void xilEmacTxThread(void* aXilEmac);
+
+
+/* Read/Write Register Functions */
+void
+xilFifoRead(unsigned32 aBaseAddr, unsigned32* aBuf, unsigned32 aBytes)
+{
+  unsigned32 words = aBytes >> 2;
+  unsigned32 i;
+
+  for(i = 0; i < words; i++) {
+    aBuf[i] = IN32(aBaseAddr + RFDR);
+  }
+
+  /* If there was a non word sized read */
+  if(aBytes & 3) {
+    unsigned32 value;
+    unsigned8* byteBuf = (unsigned8*)aBuf;
+    value = IN32(aBaseAddr + RFDR);
+    unsigned32 bytes = words<<2;
+    switch(aBytes & 3) {
+      case 1:
+        byteBuf[bytes] = value >> 24;
+        break;
+      case 2:
+        byteBuf[bytes] = value >> 24;
+        byteBuf[bytes+1] = value >> 16 & 0xff;
+        break;
+      case 3:
+        byteBuf[bytes] = value >> 24;
+        byteBuf[bytes+1] = value >> 16 & 0xff;
+        byteBuf[bytes+2] = value >> 8 & 0xff;
+        break;
+    }
+  }
+}
+
+void
+xilFifoWrite(unsigned32 aBaseAddr, unsigned32* aBuf, unsigned32 aBytes)
+{
+
+  /* Ensure there's enough space in fifo */
+  volatile unsigned32 space = IN32(aBaseAddr + WFSR) & WFSR_VACANCY_MASK;
+  unsigned32 words = aBytes >> 2;
+
+  /* Fifo reports space in words, therefore we need to count all the words
+   * we'll write into, even if their partial */
+  if(aBytes & 3) {
+    words++;
+  }
+
+  /* If not enough space, spin until previous packet empties out */
+  if(space < words) {
+    /*printf("Tx Fifo waiting for space. Space: %x. Len: %x.\n",space, words);*/
+    while( (space = IN32(aBaseAddr + WFSR) & WFSR_VACANCY_MASK) < words );
+    /*printf("Space now available: Space: %x, Len: %x.\n",space, words);*/
+  }
+  
+  /* Bring words back to number of full words */ 
+  if(aBytes & 3) {
+    words--;
+  }
+  
+  /* Write out all full words in buffer */
+  unsigned32 i;
+  for(i = 0; i < words; i++) {
+    OUT32(aBaseAddr + WFDR, aBuf[i]);
+  }
+
+  /* If there's a non word multiple write output the remaining bytes */
+  if(aBytes & 3) {
+    unsigned32 value = 0;
+    unsigned8* ptr = (unsigned8*)&value;
+    unsigned8* byteBuf = (unsigned8*)aBuf;
+    unsigned32 lastByte = words << 2;
+    switch(aBytes & 3) {
+      case 1:
+        ptr[0] = byteBuf[lastByte];
+        break;
+      case 2:
+        ptr[0] = byteBuf[lastByte];
+        ptr[1] = byteBuf[lastByte+1];
+        break;
+      case 3:
+        ptr[0] = byteBuf[lastByte];
+        ptr[1] = byteBuf[lastByte+1];
+        ptr[2] = byteBuf[lastByte+2];
+        break;
+    }
+    OUT32(aBaseAddr + WFDR, value);
+  }
+}
+
+void xilEmacInit(void* aXilEmac)
+{
+  struct XilEmac* xilEmac = aXilEmac;
+
+  if(xilEmac->iRxThread == 0 && xilEmac->iTxThread == 0) {
+    xilEmac->iRxThread = rtems_bsdnet_newproc("xerx", 4096, xilEmacRxThread, 
+      xilEmac);
+    xilEmac->iTxThread = rtems_bsdnet_newproc("xetx", 4096, xilEmacTxThread, 
+      xilEmac);
+  }
+  
+  xilEmac->iArpcom.ac_if.if_flags |= IFF_RUNNING;
+}
+
+void xilEmacReset(struct XilEmac* aXilEmac)
+{
+  xilEmacStop(aXilEmac); 
+  xilEmacStart(aXilEmac);
+}
+
+void xilEmacStop(struct XilEmac* aXilEmac)
+{
+  /* Disable receiver and transmitter */
+  unsigned32 ecr = IN32(aXilEmac->iAddr + ECR);
+  ecr &= ~(ECR_ENTX | ECR_ENRX | ECR_MA);
+  OUT32(aXilEmac->iAddr + ECR, ecr);
+
+  /* Disable global interrupt enable */
+  OUT32(aXilEmac->iAddr + DGIE, DGIE_GIE_OFF);
+
+  aXilEmac->iStarted = 0;
+}
+
+void xilEmacStart(struct XilEmac* aXilEmac)
+{
+  if( !(aXilEmac->iStarted) ) {
+
+    /* Reset EMAC device */
+    OUT32(aXilEmac->iAddr + DRST, DRST_VALUE);
+    /* Reset Read and Write Fifos */
+    OUT32(aXilEmac->iAddr + RFRST, RFRST_VALUE);
+    OUT32(aXilEmac->iAddr + WFRST, WFRST_VALUE);
+
+    /* Set the hardware address, writing DRST, resets this */
+    xilEmacSetMacAddress(aXilEmac, aXilEmac->iArpcom.ac_enaddr);
+
+    /* Enable appropriate interrupts in the device interrupt enable register */
+    OUT32(aXilEmac->iAddr + DIER, DISR_INTR_MASK); 
+
+    /* Enable appropriate interrupts in the IP interrupt enable register */
+    OUT32(aXilEmac->iAddr + IPIER, IPISR_INTR_MASK);
+
+    /* Turn on global interrupt enable */
+    OUT32(aXilEmac->iAddr + DGIE, DGIE_GIE_ON);
+
+    /* Enable transmitter and receiver and enable multicast reception */
+    unsigned32 ecr = IN32(aXilEmac->iAddr + ECR);
+    ecr |= (ECR_ENTX | ECR_ENRX | ECR_MA);
+    /* Take Tx and Rx out of reset */
+    ecr &= ~(ECR_RSTTX | ECR_RSTRX);
+    OUT32(aXilEmac->iAddr + ECR, ecr);
+
+    /* Device is started */
+    aXilEmac->iStarted = 1;
+  }
+}
+
+void xilEmacMacAddress(struct XilEmac* aXilEmac, unsigned8* aBuf)
+{
+  unsigned32 macHi;
+  unsigned32 macLo;
+
+  macHi = IN32(aXilEmac->iAddr + SAH);
+  macLo = IN32(aXilEmac->iAddr + SAL);
+
+  aBuf[0] = (unsigned8)(macHi >> 8);
+  aBuf[1] = (unsigned8)(macHi);
+  aBuf[2] = (unsigned8)(macLo >> 24);
+  aBuf[3] = (unsigned8)(macLo >> 16);
+  aBuf[4] = (unsigned8)(macLo >> 8);
+  aBuf[5] = (unsigned8)(macLo);
+}
+
+void xilEmacSetMacAddress(struct XilEmac* aXilEmac, 
+  unsigned8* aAddr)
+{
+  /* You can't change the mac address while the card is in operation */
+  assert(aXilEmac->iStarted == 0);
+
+  /* Create and output high half word */
+  unsigned32 addr = (aAddr[0] << 8) | aAddr[1];
+  OUT32(aXilEmac->iAddr + SAH, addr);
+
+  /* Create and output low word */
+  addr = (aAddr[2] << 24) | (aAddr[3] << 16) |
+         (aAddr[4] << 8) | (aAddr[5]);
+  OUT32(aXilEmac->iAddr + SAL, addr);
+}
+
+void xilEmacPrintStats(struct XilEmacStats* aStats)
+{
+  printf("Interrupts: %u\n", aStats->iInterrupts);
+  printf("Rx Interrupts: %u", aStats->iRxInterrupts);
+  printf("Errors: %u", aStats->iRxError);
+  printf("Data Overrun: %u\n", aStats->iRxDataOverrun);
+  printf("Missed: %u", aStats->iRxMissed);
+  printf("Collision: %u", aStats->iRxCollision);
+  printf("Bad CRC: %u\n", aStats->iRxFcs);
+  printf("Bad Length Field: %u", aStats->iRxLengthField);
+  printf("Short: %u", aStats->iRxShort);
+  printf("Long: %u\n", aStats->iRxLong);
+  printf("Bad Alignment: %u\n", aStats->iRxAlignment);
+
+  printf("Tx Interrupts: %u", aStats->iTxInterrupts); 
+  printf("Status Overrun: %u", aStats->iTxStatusOverrun);
+  printf("Status Underrun: %u\n", aStats->iTxStatusUnderrun);
+  printf("Length Overrun: %u", aStats->iTxLengthOverrun);
+  printf("Length Underrun: %u", aStats->iTxLengthUnderrun);
+  printf("Pause Packet: %u\n", aStats->iTxPausePacket);
+  printf("Deferred: %u", aStats->iTxDeferred);
+  printf("Late Collision: %u", aStats->iTxLateCollision);
+  printf("Data Underrun: %u\n", aStats->iTxDataUnderrun);
+
+  printf("Transaction Bus Errors: %u\n", aStats->iTerr);
+  printf("Write Fifo Deadlocks: %u", aStats->iWfdl);
+  printf("Read Fifo Deadlocks: %u", aStats->iRfdl);
+}
+
+rtems_isr xilEmacIsr(rtems_vector_number aVector, struct XilEmac* aXilEmac)
+{
+  aXilEmac->iStats.iInterrupts++;
+
+  /* We received an interrupt, check which one */
+  volatile unsigned32 status = IN32(aXilEmac->iAddr + DIPR);
+  if(status & DISR_IPIR) {
+
+    /* Normal case, emac caused interrupt of general interrupt architecture  
+    * Figure out which one of the EMAC interrupts it was */
+    volatile unsigned32 ipisr = IN32(aXilEmac->iAddr + IPISR);
+
+    /* Clear the interrupts straight away.  This ensures latched interrupts
+     * are up to date with the actual state of the device.
+     */
+    OUT32(aXilEmac->iAddr + IPISR, ipisr);
+
+    /* Receive Complete ? 
+     * 1) inc counter, 2) disable interrupt, 3) notify rxThread
+     */
+    if(ipisr & IPISR_RXCP) {
+      aXilEmac->iStats.iRxInterrupts++; 
+
+      /* The Receive Complete (IPISR_RXCP) and Xmit Complete
+       * (IPISR_TXCP) interrupts are latached and only cleared by reading the
+       * fifo.  As we do this in a different thread, we need to disable the
+       * interrupt here, notify the thread, and ensure we renable the interrupt
+       * when that thread is done emptying the fifo.
+       */
+      volatile unsigned32 ier = IN32(aXilEmac->iAddr + IPIER);
+      ier &= ~IPISR_RXCP;
+      OUT32(aXilEmac->iAddr + IPIER, ier);
+
+      rtems_event_send(aXilEmac->iRxThread, INTERRUPT_EVENT);
+    } 
+    
+    /* Transmit Complete ?
+     * inc counter, check tsr, bump stats as appropriate 
+     */
+    if(ipisr & IPISR_TXCP) {
+      aXilEmac->iStats.iTxInterrupts++;
+      volatile unsigned32 tsr = IN32(aXilEmac->iAddr + TSR);
+      if(tsr & TSR_TXED) {
+        aXilEmac->iStats.iTxDeferred++; 
+      }
+      if(tsr & TSR_TXLC) {
+        aXilEmac->iStats.iTxLateCollision++;
+      }
+      if(tsr & TSR_PFIFOU) {
+        aXilEmac->iStats.iTxDataUnderrun++;
+      }
+      
+      /* Clear the interrupt.  This will actually clear the interrupt as we
+       * have read the TSR fifo and therefore removed the source of the
+       * interrupt 
+       */
+      OUT32(aXilEmac->iAddr + IPISR, IPISR_TXCP);
+    }
+    if(ipisr & IPISR_RAE) {
+      aXilEmac->iStats.iRxAlignment = IN32(aXilEmac->iAddr + RAEC);
+    }
+    if(ipisr & IPISR_RLE) {
+      aXilEmac->iStats.iRxLong++;
+    }
+    if(ipisr & IPISR_RSE) {
+      aXilEmac->iStats.iRxShort++;
+    }
+    if(ipisr & IPISR_RLFE) {
+      aXilEmac->iStats.iRxLengthField++;
+    }
+    if(ipisr & IPISR_RFCS) {
+      aXilEmac->iStats.iRxFcs = IN32(aXilEmac->iAddr + RFCSEC);
+    }
+    if(ipisr & IPISR_RCE) {
+      aXilEmac->iStats.iRxCollision = IN32(aXilEmac->iAddr + RCC);
+    }
+    if(ipisr & IPISR_RMFE) {
+      aXilEmac->iStats.iRxMissed = IN32(aXilEmac->iAddr + RMFC);
+    }
+    if(ipisr & IPISR_RDFO) {
+      aXilEmac->iStats.iRxDataOverrun++; 
+    }
+    if(ipisr & IPISR_RERR) {
+      aXilEmac->iStats.iRxError++;
+    }
+    if(ipisr & IPISR_TSFO) {
+      aXilEmac->iStats.iTxStatusOverrun++;
+    }
+    if(ipisr & IPISR_TSFU) {
+      aXilEmac->iStats.iTxStatusUnderrun++;
+    }
+    if(ipisr & IPISR_TLFO) {
+      aXilEmac->iStats.iTxLengthOverrun++;
+    }
+    if(ipisr & IPISR_TLFU) {
+      aXilEmac->iStats.iTxLengthUnderrun++;
+    }
+  } 
+  if(status & DISR_TERR) {
+    aXilEmac->iStats.iTerr++;
+  }
+  if(status & DISR_WFDL) {
+    aXilEmac->iStats.iWfdl++;
+  }
+  if(status & DISR_RFDL) {
+    aXilEmac->iStats.iRfdl++;
+  }
+}
+
+signed32 xilEmacAttach(struct rtems_bsdnet_ifconfig* aBsdConfig,
+  struct XilEmac* aXilEmac, struct XilEmacConfig* aConfig)
+{
+  struct ifnet* ifp;
+  signed32 mtu;
+  signed32 unit;
+  char* unitName;
+
+  unit = rtems_bsdnet_parse_driver_name(aBsdConfig, &unitName);
+  if(unit < 0 ) {
+    return 0;
+  }
+
+  ifp = &(aXilEmac->iArpcom.ac_if);
+  memset(aXilEmac, 0, sizeof(struct XilEmac));
+
+  if(aBsdConfig->hardware_address) {
+    memcpy(aXilEmac->iArpcom.ac_enaddr, aBsdConfig->hardware_address,
+      ETHER_ADDR_LEN);
+  } else {
+    printf("No hardware address given in rtems_bsdnet_ifconfig\n");
+    return 0;
+  }
+
+  aXilEmac->iConfig.iBroadcast = aConfig->iBroadcast;
+  aXilEmac->iConfig.iAddr = aConfig->iAddr;
+  aXilEmac->iConfig.iMulticast = aConfig->iMulticast;
+
+  /* This next one is just a shortcut copy of the previous */
+  aXilEmac->iAddr = aConfig->iAddr;
+
+  if(aBsdConfig->mtu) {
+    mtu = aBsdConfig->mtu;
+  } else {
+    mtu = ETHERMTU;
+  }
+
+  ifp->if_softc = aXilEmac;
+  ifp->if_unit = unit;
+  ifp->if_name = unitName;
+  ifp->if_mtu = mtu;
+  ifp->if_init = xilEmacInit;
+  ifp->if_ioctl = xilEmacIoctl;
+  ifp->if_start = xilEmacSend;
+  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);
+  
+  return 1;
+}
+
+signed32 xilEmacSetMulticastFilter(struct XilEmac* aXilEmac)
+{
+  return 0;
+}
+
+signed32 xilEmacIoctl(struct ifnet* aIfnet, signed32 aCommand, caddr_t aData)
+{
+  struct XilEmac* xilEmac = aIfnet->if_softc;
+  signed32 error = 0;
+  
+  switch(aCommand) {
+    case SIOCGIFADDR:
+    case SIOCSIFADDR:
+      ether_ioctl(aIfnet, aCommand, aData);
+      break;
+    case SIOCSIFFLAGS:
+      switch(aIfnet->if_flags & (IFF_UP | IFF_RUNNING)) {
+        case IFF_RUNNING:
+          xilEmacStop(xilEmac); 
+          break;
+        case IFF_UP:
+          xilEmacStart(xilEmac);
+          break;
+        case IFF_UP | IFF_RUNNING:
+          xilEmacReset(xilEmac);
+          break;
+        default:
+          assert(0);
+          break;
+      }
+      break;
+    case SIOCADDMULTI:
+    case SIOCDELMULTI: {
+        struct ifreq* ifr = (struct ifreq*) aData;
+        error = (aCommand == SIOCADDMULTI ?  
+            ether_addmulti(ifr, &(xilEmac->iArpcom)) : 
+            ether_delmulti(ifr, &(xilEmac->iArpcom)) );
+        /*ENETRESET indicates that driver should update its multicast filters */
+        if(error == ENETRESET) {
+            error = xilEmacSetMulticastFilter(xilEmac);
+        }
+        break;
+    }
+
+    case SIO_RTEMS_SHOW_STATS:
+      xilEmacPrintStats(&(xilEmac->iStats));
+      break;
+
+    default:
+      error = EINVAL;
+      break;
+  }
+  return error;
+}
+  
+void xilEmacSend(struct ifnet* aIfnet)
+{
+  struct XilEmac* xilEmac = aIfnet->if_softc;
+
+  rtems_event_send(xilEmac->iTxThread, START_TRANSMIT_EVENT);
+  aIfnet->if_flags |= IFF_OACTIVE;
+}
+
+unsigned8 gTxBuf[2048];
+
+void xilEmacSendPacket(struct XilEmac* aXilEmac, struct mbuf* aMbuf)
+{
+  struct mbuf* n = aMbuf;
+  unsigned32 len = 0;
+
+#ifdef DEBUG
+  printf("SendPacket\n");
+  printf("TXD: 0x%08x\n", (signed32) n->m_data);
+#endif
+  
+  for(;;) {
+#ifdef DEBUG
+    unsigned32 i = 0;
+    printf("MBUF: 0x%08x : ", (signed32) n->m_data);
+    for (i=0;i<n->m_len;i+=2) {
+      printf("%02x%02x ", mtod(n, unsigned8*)[i], mtod(n, unsigned8*)[i+1]); 
+    }
+    printf("\n");
+#endif
+
+    memcpy(gTxBuf+len, mtod(n, unsigned8*), n->m_len);
+    len += n->m_len; 
+
+    if( (n = n->m_next) == 0) {
+      break;
+    }
+  }
+  m_freem(aMbuf);
+  xilFifoWrite(aXilEmac->iAddr, (unsigned32*)gTxBuf, len);
+  /* Set the Transmit Packet Length Register which tells the xmit to start
+   * sending */
+  OUT32(aXilEmac->iAddr + TPLR, len);
+
+#ifdef DEBUG
+  memset(gTxBuf, 0, len);
+#endif
+}
+
+void xilEmacTxThread(void* aXilEmac)
+{
+  struct XilEmac* xilEmac = aXilEmac;
+  rtems_event_set events;
+  struct mbuf* m;
+
+  for(;;) {
+    /* Wait for a packet to send */
+    rtems_bsdnet_event_receive(START_TRANSMIT_EVENT, 
+      RTEMS_EVENT_ANY | RTEMS_WAIT,
+      RTEMS_NO_TIMEOUT,
+      &events);
+
+    /* Send packets till queue empty */
+    for(;;) {
+      IF_DEQUEUE(&(xilEmac->iArpcom.ac_if.if_snd), m);
+      if(!m) {
+        /* End of mbuf queue */
+        break;
+      }
+      xilEmacSendPacket(xilEmac, m);
+    } 
+    ifnet->if_flags &= ~IFF_OACTIVE;
+  }
+}
+
+void xilEmacRxThread(void* aXilEmac)
+{
+  struct XilEmac* xilEmac = aXilEmac;
+  rtems_event_set events;
+
+  for(;;) {
+    rtems_bsdnet_event_receive(INTERRUPT_EVENT, RTEMS_WAIT | RTEMS_EVENT_ANY,
+      RTEMS_NO_TIMEOUT, &events);
+
+    volatile unsigned32 status = IN32(xilEmac->iAddr + IPISR);
+
+    /* Receive Complete? */ 
+    if(status & IPISR_RXCP) {
+
+      /* Whilst there's still packets available (RXCP stays active as long as
+       * one length value has not been read from RPLR)  */
+      while( (status = IN32(xilEmac->iAddr + IPISR)) & IPISR_RXCP ) {
+
+        /* read length of received packet */
+        unsigned32 len = IN32(xilEmac->iAddr + RPLR);
+        
+        struct mbuf* m;
+        MGETHDR(m, M_WAIT, MT_DATA);
+        MCLGET(m, M_WAIT);
+        
+        struct ifnet* ifp = &(xilEmac->iArpcom.ac_if);
+        m->m_pkthdr.rcvif = ifp;
+
+        xilFifoRead(xilEmac->iAddr, mtod(m, unsigned32*), len);
+        m->m_len = len - sizeof(struct ether_header);
+        m->m_pkthdr.len = len - sizeof(struct ether_header);
+        struct ether_header* eh;
+        eh = mtod(m, struct ether_header*);
+        m->m_data += sizeof(struct ether_header);
+
+        ether_input(ifp, eh, m);
+
+        /* Try and turn off RXCP bit.  If there's still more packets, then this
+         * will reassert immediately.  If there's no more packets, this will
+         * turn it off.
+         */
+        OUT32(xilEmac->iAddr + IPISR, IPISR_RXCP);
+      }
+    }
+    else {
+      printf("unhandled status: %x\n", status);
+    }
+    /* Re-enable receive complete interrupt */
+    OUT32(xilEmac->iAddr + IPIER, IPISR_RXCP);
+  }
+}
+
Index: c/src/libchip/network/xilemac.h
===================================================================
--- c/src/libchip/network/xilemac.h	(.../rtems/rtems-4.6.5)	(revision 0)
+++ c/src/libchip/network/xilemac.h	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -0,0 +1,82 @@
+/*
+ * Reusable portion (libchip) of the Xilinx Open Processor Bus Ethernet Media
+ * Access Controller (OPB EMAC) version 1.02a
+ *
+ * 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.
+ *
+ */
+
+#ifndef _XILINX_EMAC_
+#define _XILINX_EMAC_
+
+
+#include <rtems.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+/* This doesn't get defined automatically for header files.  It is needed
+ * for ether_ioctl to be visible in the freebsd networking stack. */
+#define KERNEL
+#include <sys/mbuf.h>
+
+#include <net/if.h>
+#include <netinet/if_ether.h>
+#include <netinet/in.h>
+
+struct XilEmacStats {
+  unsigned32 iInterrupts;
+
+  unsigned32 iRxInterrupts;
+  unsigned32 iRxError;
+  unsigned32 iRxDataOverrun; 
+  unsigned32 iRxMissed;
+  unsigned32 iRxCollision;
+  unsigned32 iRxFcs;
+  unsigned32 iRxLengthField;
+  unsigned32 iRxShort;
+  unsigned32 iRxLong;
+  unsigned32 iRxAlignment;
+
+  unsigned32 iTxInterrupts;
+  unsigned32 iTxStatusOverrun;
+  unsigned32 iTxStatusUnderrun;
+  unsigned32 iTxLengthOverrun;
+  unsigned32 iTxLengthUnderrun;
+  unsigned32 iTxPausePacket;
+
+  unsigned32 iTxDeferred;
+  unsigned32 iTxLateCollision;
+  unsigned32 iTxDataUnderrun; 
+
+  unsigned32 iTerr;
+  unsigned32 iWfdl;
+  unsigned32 iRfdl;
+};
+
+struct XilEmacConfig {
+  unsigned32 iAddr;
+  unsigned8 iBroadcast;
+  unsigned8 iMulticast;
+};
+
+struct XilEmac {
+  struct arpcom iArpcom;
+  struct XilEmacConfig iConfig;
+  struct XilEmacStats iStats;
+  unsigned32 iStarted;
+  unsigned32 iAddr; 
+  
+  rtems_id iRxThread;
+  rtems_id iTxThread;
+};
+
+rtems_isr xilEmacIsr(rtems_vector_number aVector, struct XilEmac* aXilEmac);
+signed32 xilEmacAttach(struct rtems_bsdnet_ifconfig* aBsdConfig, 
+  struct XilEmac* aXilEmac, struct XilEmacConfig* aConfig);
+
+#endif /* _XILINX_EMAC_*/
Index: c/src/libchip/network/README.xilemac
===================================================================
--- c/src/libchip/network/README.xilemac	(.../rtems/rtems-4.6.5)	(revision 0)
+++ c/src/libchip/network/README.xilemac	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -0,0 +1,22 @@
+Driver for xilinx opb ethernet MAC - README
+-------------------------------------------
+
+This is a driver for the xilinx opb ethernet mac 1.02a
+
+The vhdl ip core was compiled with the default settings plus the following
+overrides:
+
+C_DMA_PRESENT 3
+C_IPIF_RDFIFO_DEPTH 32768
+C_IPIF_WRFIFO_DEPTH 32768
+C_OPB_CLK_PERIOD_PS 10000
+
+Although DMA is present in the ip core described above, this version of the
+driver does not utilise it and functions through coping to and from the tx and
+rx fifos.
+
+For an example of how to connect this driver into a bsp see:
+c/src/lib/libbsp/powerpc/gen405/include/bsp.h and
+c/src/lib/libbsp/powerpc/gen405/network/network.c
+
+
Index: c/src/libchip/network/Makefile.am
===================================================================
--- c/src/libchip/network/Makefile.am	(.../rtems/rtems-4.6.5)	(revision 1691)
+++ c/src/libchip/network/Makefile.am	(.../volkano/rtems/rtems-src)	(revision 1691)
@@ -9,11 +9,11 @@
 LIB = $(ARCH)/$(LIBNAME).a
 
 C_FILES = cs8900.c dec21140.c i82586.c sonic.c if_fxp.c elnk.c open_eth.c \
-          smc91111.c 
+          smc91111.c xilemac.c
 OBJS = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
 
 include_libchip_HEADERS = cs8900.h i82586var.h if_fxpvar.h sonic.h if_media.h \
-    mii.h open_eth.h smc91111.h smc91111exp.h
+    mii.h open_eth.h smc91111.h smc91111exp.h xilemac.h
 
 include $(top_srcdir)/../../../automake/compile.am
 include $(top_srcdir)/../../../automake/lib.am
@@ -51,6 +51,6 @@
 EXTRA_DIST = README README.cs8900 README.dec21140 README.i82586 \
     README.open_eth README.sonic cs8900.c cs8900.c.bsp dec21140.c \
     i82586.c if_fxp.c open_eth.c sonic.c \
-    smc91111.c 
+    smc91111.c xilemac.c
 
 include $(top_srcdir)/../../../automake/local.am

