diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig
new file mode 100644
index 0000000..4ab904f
--- /dev/null
+++ b/arch/nios2/Kconfig
@@ -0,0 +1,199 @@
+#
+# Nios2 port by Wind River Systems Inc trough:
+#   fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+#
+
+menu "NiosII Configuration"
+
+choice
+	prompt "NiosII FPGA configuration"
+
+config NIOS2_DEFAULT_MMU
+	bool "MMU_DEFAULT"
+	help
+	  The default mmu config for the v17 release
+
+config NIOS2_MAXIMUM_MMU
+	bool "MAXIMUM_MMU"
+	help
+	  The maximum mmu config for the v17 release
+
+config NIOS2_CUSTOM_FPGA
+	bool "CUSTOM_FPGA"
+	help
+	  Adapt the kernel to custom FPGA configuration. You will
+          need to generate a header file for your desgin using the
+	  "sopc-create-header-files" scripts provided by Altera.
+	  The file "include/asm-nios2/custom_fpga.h" will be used.
+
+endchoice
+
+config NIOS2_HW_MUL_SUPPORT
+       bool "HW mul support"
+       default y
+       help
+	Enables the -mhw-mul compiler flag.
+
+config NIOS2_HW_MULX_SUPPORT
+       bool "HW mulx support"
+       default n
+       help
+	Enables the -mhw-mulx compiler flag.
+
+config NIOS2_HW_DIV_SUPPORT
+       bool "HW div support"
+       default n
+       help
+	Enables the -mhw-div compiler flag.
+
+config NIOS2_UIMAGE_FLASHADDR
+       hex "Offset address for uImage.flash"
+       default 0x1C80000
+       help
+       	  uImage.flash is simply an srec of the uImage with an
+          offset. Suitable for use with the nios2-flash-programmer
+          tool.
+
+config PASS_CMDLINE
+	bool "Passed kernel command line from u-boot"
+	default n
+	help
+	  Use bootargs env variable from u-boot for kernel command line.
+	  will override "Default kernel command string".
+          Say N if you are unsure.
+
+config BOOT_LINK_OFFSET
+	hex "Link address offset for booting"
+	default "0x00500000"
+	help
+	  This option allows you to set the link address offset of the zImage.
+	  This can be useful if you are on a board which has a small amount of
+	  memory.
+
+config AVALON_DMA
+	bool "Support for DMA controller with Avalon interface"
+	default y
+	help
+	  Support the Altera DMA controller with Avalon interface, so drivers
+	  for DMA-able devices can use this interface.
+
+config GENERIC_GPIO
+	bool "GPIO interface"
+	default n
+	help
+    	  The custom gpio core, openip/gpio, uses fewer LEs and runs faster
+    	  than the Altera PIO. The spinlock is no longer needed.
+
+config PIO_DEVICES
+       tristate "Enable NiosII PIO driver"
+       default y
+       help
+
+config PIO_LED
+       bool "Enable NiosII PIO led driver"
+       depends on PIO_DEVICES
+       default y
+       help
+         Enable the example PIO led driver (which just
+         displays a timer value on the 8 leds)
+
+source "arch/nios2/drivers/Kconfig"
+
+endmenu
+
+config NIOS2
+	bool
+	default y
+	# Horrible source of confusion.  Die, die, die ...
+	select EMBEDDED
+
+config MMU
+       bool
+       default y
+
+
+config RWSEM_GENERIC_SPINLOCK
+	bool
+	default y
+
+#
+# FIXME: Should UID16 really be set ?
+#
+config UID16
+       bool
+       default y
+
+config GENERIC_CSUM
+	def_bool y
+
+config GENERIC_FIND_NEXT_BIT
+	bool
+	default y
+
+config GENERIC_HWEIGHT
+	bool
+	default y
+
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
+config GENERIC_TIME
+	bool
+	default y
+
+config GENERIC_HARDIRQS
+	def_bool y
+
+config GENERIC_IRQ_PROBE
+	def_bool y
+
+config NO_IOPORT
+	def_bool y
+
+config ZONE_DMA
+       bool
+       default y
+
+config EARLY_PRINTK
+       bool
+       default y
+
+config BINFMT_ELF
+       bool
+       default y
+
+# FIXME: really !
+config NOT_COHERENT_CACHE
+       bool
+       default n
+
+config HZ
+       int
+       default 100
+
+config TRACE_IRQFLAGS_SUPPORT
+       bool
+       default n
+
+source "mm/Kconfig"
+
+source "kernel/Kconfig.preempt"
+
+source "init/Kconfig"
+
+source "kernel/Kconfig.freezer"
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/nios2/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
diff --git a/arch/nios2/Kconfig.debug b/arch/nios2/Kconfig.debug
new file mode 100644
index 0000000..72d5c19
--- /dev/null
+++ b/arch/nios2/Kconfig.debug
@@ -0,0 +1,98 @@
+menu "Kernel hacking"
+
+config TRACE_IRQFLAGS_SUPPORT
+	bool
+	default y
+
+source "lib/Kconfig.debug"
+
+config CROSSCOMPILE
+	bool "Are you using a crosscompiler"
+	help
+	  Say Y here if you are compiling the kernel on a different
+	  architecture than the one it is intended to run on.  This is just a
+	  convenience option which will select the appropriate value for
+	  the CROSS_COMPILE make variable which otherwise has to be passed on
+	  the command line from mips-linux-, mipsel-linux-, mips64-linux- and
+	  mips64el-linux- as appropriate for a particular kernel configuration.
+	  You will have to pass the value for CROSS_COMPILE manually if the
+	  name prefix for your tools is different.
+
+config CMDLINE
+	string "Default kernel command string"
+	default ""
+	help
+	  On some platforms, there is currently no way for the boot loader to
+	  pass arguments to the kernel. For these platforms, you can supply
+	  some command-line options at build time by entering them here.  In
+	  other cases you can specify kernel args so that you don't have
+	  to set them up in board prom initialization routines.
+
+config DEBUG_STACK_USAGE
+	bool "Enable stack utilization instrumentation"
+	depends on DEBUG_KERNEL
+	help
+	  Enables the display of the minimum amount of free stack which each
+	  task has ever had available in the sysrq-T and sysrq-P debug output.
+
+	  This option will slow down process creation somewhat.
+
+config CONFIG_SMTC_IDLE_HOOK_DEBUG
+	bool "Enable additional debug checks before going into CPU idle loop"
+	depends on DEBUG_KERNEL && MIPS_MT_SMTC
+	help
+	  This option enables Enable additional debug checks before going into
+	  CPU idle loop.  For details on these checks, see
+	  arch/mips/kernel/smtc.c.  This debugging option result in significant
+	  overhead so should be disabled in production kernels.
+
+config KGDB
+	bool "Remote GDB kernel debugging"
+	depends on DEBUG_KERNEL && SYS_SUPPORTS_KGDB
+	select DEBUG_INFO
+	help
+	  If you say Y here, it will be possible to remotely debug the MIPS
+	  kernel using gdb. This enlarges your kernel image disk size by
+	  several megabytes and requires a machine with more than 16 MB,
+	  better 32 MB RAM to avoid excessive linking time. This is only
+	  useful for kernel hackers. If unsure, say N.
+
+config SYS_SUPPORTS_KGDB
+	bool
+
+config GDB_CONSOLE
+	bool "Console output to GDB"
+	depends on KGDB
+	help
+	  If you are using GDB for remote debugging over a serial port and
+	  would like kernel messages to be formatted into GDB $O packets so
+	  that GDB prints them as program output, say 'Y'.
+
+config SB1XXX_CORELIS
+	bool "Corelis Debugger"
+	depends on SIBYTE_SB1xxx_SOC
+	select DEBUG_INFO
+	help
+	  Select compile flags that produce code that can be processed by the
+	  Corelis mksym utility and UDB Emulator.
+
+config RUNTIME_DEBUG
+	bool "Enable run-time debugging"
+	depends on DEBUG_KERNEL
+	help
+	  If you say Y here, some debugging macros will do run-time checking.
+	  If you say N here, those macros will mostly turn to no-ops.  See
+	  include/asm-mips/debug.h for debuging macros.
+	  If unsure, say N.
+
+config MIPS_UNCACHED
+	bool "Run uncached"
+	depends on DEBUG_KERNEL && !SMP && !SGI_IP27
+	help
+	  If you say Y here there kernel will disable all CPU caches.  This will
+	  reduce the system's performance dramatically but can help finding
+	  otherwise hard to track bugs.  It can also useful if you're doing
+	  hardware debugging with a logic analyzer and need to see all traffic
+	  on the bus.
+
+endmenu
diff --git a/arch/nios2/Makefile b/arch/nios2/Makefile
new file mode 100644
index 0000000..f46245b
--- /dev/null
+++ b/arch/nios2/Makefile
@@ -0,0 +1,63 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1994, 95, 96, 2003 by Wind River Systems
+# Written by Fredrik Markstrom
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" cleaning up for this architecture.
+#
+#
+# Nios2 port by Wind River Systems Inc trough:
+#   fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+#
+
+cflags-y :=
+LDFLAGS		:=
+LDFLAGS_vmlinux	:=
+
+KBUILD_AFLAGS += $(cflags-y)
+KBUILD_CFLAGS += -pipe -D__linux__ -D__ELF__ $(cflags-y)
+KBUILD_CFLAGS += $(if $(CONFIG_NIOS2_HW_MUL_SUPPORT),-mhw-mul,-mno-hw-mul)
+KBUILD_CFLAGS += $(if $(CONFIG_NIOS2_HW_MULX_SUPPORT),-mhw-mulx,-mno-hw-mulx)
+KBUILD_CFLAGS += $(if $(CONFIG_NIOS2_HW_DIV_SUPPORT),-mhw-div,-mno-hw-div)
+
+KBUILD_CFLAGS += -fno-optimize-sibling-calls
+KBUILD_CFLAGS += -DNO_TEXT_SECTIONS
+KBUILD_CFLAGS += -fno-builtin
+KBUILD_CFLAGS += -G 0
+
+LDFLAGS += $(if $(CONFIG_NIOS2_HW_MUL_OFF),-mno-hw-mul)
+LDFLAGS += -mnios2elf
+
+head-y		:= arch/nios2/kernel/head.o
+libs-y		+= arch/nios2/lib/
+core-y		+= arch/nios2/kernel/ arch/nios2/mm/
+
+archclean:
+	$(Q)$(MAKE) $(clean)=$(boot)
+
+INSTALL_PATH ?= /tftpboot
+boot := arch/$(ARCH)/boot
+BOOT_TARGETS = vmImage zImage
+PHONY += $(BOOT_TARGETS) install
+KBUILD_IMAGE := $(boot)/vmImage
+
+all: vmImage
+
+$(BOOT_TARGETS): vmlinux
+	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+install:
+	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
+
+define archhelp
+  echo  '* vmImage         - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage)'
+  echo  '  install         - Install kernel using'
+  echo  '                     (your) ~/bin/$(CROSS_COMPILE)installkernel or'
+  echo  '                     (distribution) PATH: $(CROSS_COMPILE)installkernel or'
+  echo  '                     install to $$(INSTALL_PATH)'
+endef
diff --git a/arch/nios2/boot/Makefile b/arch/nios2/boot/Makefile
new file mode 100644
index 0000000..e5ec93b
--- /dev/null
+++ b/arch/nios2/boot/Makefile
@@ -0,0 +1,41 @@
+#
+# arch/nios2/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+
+MKIMAGE := $(srctree)/scripts/mkuboot.sh
+
+targets := vmImage
+extra-y += vmlinux.bin vmlinux.gz
+subdir- := compressed
+
+quiet_cmd_uimage = UIMAGE  $@
+      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \
+                   -C gzip -n 'Linux-$(KERNELRELEASE)' \
+                   -a $(shell $(NM) vmlinux | awk '$$NF == "_stext" {print $$1}') \
+                   -e $(shell $(NM) vmlinux | awk '$$NF == "_start" {print $$1}') \
+                   -d $< $@
+
+OBJCOPYFLAGS_vmlinux.bin := -O binary
+$(obj)/vmlinux.bin: vmlinux FORCE
+	$(call if_changed,objcopy)
+
+$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,gzip)
+
+$(obj)/vmImage: $(obj)/vmlinux.gz
+	$(call if_changed,uimage)
+	@$(kecho) 'Kernel: $@ is ready'
+
+$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
+	$(call if_changed,objcopy)
+	@$(kecho) 'Kernel: $@ is ready'
+
+$(obj)/compressed/vmlinux: $(obj)/vmlinux.gz FORCE
+	$(Q)$(MAKE) $(build)=$(obj)/compressed $@
+
+install:
+	sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
diff --git a/arch/nios2/boot/compressed/Makefile b/arch/nios2/boot/compressed/Makefile
new file mode 100644
index 0000000..c5413ef
--- /dev/null
+++ b/arch/nios2/boot/compressed/Makefile
@@ -0,0 +1,22 @@
+#
+# linux/arch/sh/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+targets		:= vmlinux head.o misc.o \
+		   piggy.o vmlinux.lds
+EXTRA_AFLAGS	:=
+
+OBJECTS = $(obj)/head.o $(obj)/misc.o
+
+LDFLAGS_vmlinux := -T
+
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(obj)/piggy.o FORCE
+	$(call if_changed,ld)
+	@:
+
+LDFLAGS_piggy.o := -r --format binary --oformat elf32-littlenios2 -T
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/../vmlinux.gz FORCE
+	$(call if_changed,ld)
diff --git a/arch/nios2/boot/compressed/console.c b/arch/nios2/boot/compressed/console.c
new file mode 100644
index 0000000..ae8b7af
--- /dev/null
+++ b/arch/nios2/boot/compressed/console.c
@@ -0,0 +1,136 @@
+#include <asm/nios.h>
+#include <asm/io.h>
+
+static void *my_ioremap(unsigned long physaddr)
+{
+	return (void *)(physaddr | IO_REGION_BASE);
+}
+
+#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE)
+
+#define ALTERA_JTAGUART_SIZE                      8
+#define ALTERA_JTAGUART_DATA_REG                  0
+#define ALTERA_JTAGUART_CONTROL_REG               4
+#define ALTERA_JTAGUART_CONTROL_AC_MSK            (0x00000400)
+#define ALTERA_JTAGUART_CONTROL_WSPACE_MSK        (0xFFFF0000)
+static unsigned uartbase;
+
+#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
+static void jtag_putc(int ch)
+{
+	if (readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) &
+	    ALTERA_JTAGUART_CONTROL_WSPACE_MSK)
+		writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG);
+}
+#else
+static void jtag_putc(int ch)
+{
+	while ((readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) &
+		ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) ;
+	writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG);
+}
+#endif
+
+static int putchar(int ch)
+{
+	jtag_putc(ch);
+	return ch;
+}
+
+static void console_init(void)
+{
+	uartbase = (unsigned long)my_ioremap(JTAG_UART_BASE);
+	writel(ALTERA_JTAGUART_CONTROL_AC_MSK,
+	       uartbase + ALTERA_JTAGUART_CONTROL_REG);
+}
+
+#elif defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE)
+
+#define ALTERA_UART_SIZE                  32
+#define ALTERA_UART_TXDATA_REG            4
+#define ALTERA_UART_STATUS_REG            8
+#define ALTERA_UART_DIVISOR_REG           16
+#define ALTERA_UART_STATUS_TRDY_MSK       (0x40)
+static unsigned uartbase;
+
+static void uart_putc(int ch)
+{
+	int i;
+
+	for (i = 0; (i < 0x10000); i++) {
+		if (readw(uartbase + ALTERA_UART_STATUS_REG) &
+		    ALTERA_UART_STATUS_TRDY_MSK)
+			break;
+	}
+	writeb(ch, uartbase + ALTERA_UART_TXDATA_REG);
+}
+
+static int putchar(int ch)
+{
+	uart_putc(ch);
+	if (ch == '\n')
+		uart_putc('\r');
+	return ch;
+}
+
+static void console_init(void)
+{
+	unsigned int baud, baudclk;
+
+	uartbase = (unsigned long)my_ioremap((unsigned long)UART0_BASE);
+	baud = CONFIG_SERIAL_ALTERA_UART_BAUDRATE;
+	baudclk = UART0_FREQ / baud;
+	writew(baudclk, uartbase + ALTERA_UART_DIVISOR_REG);
+}
+
+#else
+
+static int putchar(int ch)
+{
+	return ch;
+}
+
+static void console_init(void)
+{
+}
+
+#endif
+
+static int puts(const char *s)
+{
+	while (*s)
+		putchar(*s++);
+	return 0;
+}
+
+#define TOP_NIBBLE (sizeof(int) * 8 - 4)
+static int putx(unsigned x)
+{
+	int i;
+	int k;
+
+	putchar(' ');
+	for (i = (2 * sizeof(unsigned)); i > 0; i--) {
+		k = (x >> TOP_NIBBLE) & 0x000f;
+		if (k < 10)
+			k += '0';
+		else
+			k += 'a' - 10;
+
+		putchar(k);
+
+		x <<= 4;
+	}
+	return 0;
+}
+
+static void dump(unsigned a, int len)
+{
+	unsigned *p = (void *)a;
+	int i;
+	for (i = 0; i < len; i++) {
+		putx(*p++);
+		if ((i % 4) == 3)
+			putchar('\n');
+	}
+}
diff --git a/arch/nios2/boot/compressed/head.S b/arch/nios2/boot/compressed/head.S
new file mode 100644
index 0000000..f1c1943
--- /dev/null
+++ b/arch/nios2/boot/compressed/head.S
@@ -0,0 +1,108 @@
+/*
+ *  linux/arch/nios2/boot/compressed/head.S
+ *
+ *  This code can be loaded anywhere, eg FLASH ROM as reset vector,
+ *  as long as output does not overlap it.
+ */
+
+#include <asm/asm-offsets.h>
+#include <asm/asm-macros.h>
+
+	.text
+	.set noat
+	.global _start
+_start:
+	wrctl	status, r0		/* disable interrupt */
+	/* invalidate all instruction cache */
+	movia	r1, NIOS2_ICACHE_SIZE
+	movui	r2, NIOS2_ICACHE_LINE_SIZE
+1:	initi	r1
+	sub	r1, r1, r2
+	bgt	r1, r0, 1b
+	/* invalidate all data cache */
+	movia	r1, NIOS2_DCACHE_SIZE
+	movui	r2, NIOS2_DCACHE_LINE_SIZE
+1:	initd	0(r1)
+	sub	r1, r1, r2
+	bgt	r1, r0, 1b
+
+	nextpc	r1			/* Find out where we are */
+chkadr:
+	movia	r2, chkadr
+	beq	r1, r2, finish_move	/* We are running in correct address, done */
+	/* move code, r1: src, r2: dest, r3: last dest */
+	addi	r1, r1, (_start - chkadr)	/* Source */
+	movia	r2, _start		/* Destination */
+	movia	r3, __bss_start		/* End of copy */
+1:	ldw	r8, 0(r1)		/* load a word from [r1] */
+	stw	r8, 0(r2)		/* stort a word to dest [r2] */
+	addi	r1, r1, 4		/* inc the src addr */
+	addi	r2, r2, 4		/* inc the dest addr */
+	blt	r2, r3, 1b
+	/* flush the data cache after moving */
+	movia	r1, NIOS2_DCACHE_SIZE
+	movui	r2, NIOS2_DCACHE_LINE_SIZE
+1:	flushd	0(r1)
+	sub	r1, r1, r2
+	bgt	r1, r0, 1b
+	movia	r1, finish_move
+	jmp	r1			/* jmp to linked address */
+
+finish_move:
+	/* zero out the .bss segment (uninitialized common data) */
+	movia	r2, __bss_start		/* presume nothing is between */
+	movia	r1, _end		/* the .bss and _end. */
+1: 	stb	r0, 0(r2)
+	addi	r2, r2, 1
+	bne	r1, r2, 1b
+	/*
+	 * set up the stack pointer, some where higher than _end.
+	 * The stack space must be greater than 32K for decompress.
+	 */
+	movia	sp, 0x10000
+	add	sp, sp, r1
+	/* save args passed from u-boot, maybe */
+	addi	sp, sp, -16
+	stw	r4, 0(sp)
+	stw	r5, 4(sp)
+	stw	r6, 8(sp)
+	stw	r7, 12(sp)
+	/* decompress the kernel */
+	call	decompress_kernel
+	/* pass saved args to kernel */
+	ldw	r4, 0(sp)
+	ldw	r5, 4(sp)
+	ldw	r6, 8(sp)
+	ldw	r7, 12(sp)
+
+	/* flush all data cache after decompressing */
+	movia	r1, NIOS2_DCACHE_SIZE
+	movui	r2, NIOS2_DCACHE_LINE_SIZE
+1:	flushd	0(r1)
+	sub	r1, r1, r2
+	bgt	r1, r0, 1b
+	/* flush all instruction cache */
+	movia	r1, NIOS2_ICACHE_SIZE
+	movui	r2, NIOS2_ICACHE_LINE_SIZE
+1:	flushi	r1
+	sub	r1, r1, r2
+	bgt	r1, r0, 1b
+	flushp
+	/* jump to start real kernel */
+	movia	r1, (LINUX_SDRAM_START | KERNEL_REGION_BASE_ASM)
+	jmp	r1
+
+	.balign 512
+fake_headers_as_bzImage:
+	.short	0
+	.ascii	"HdrS"
+	.short	0x0202
+	.short	0
+	.short	0
+	.byte	0x00, 0x10
+	.short	0
+	.byte	0
+	.byte	1
+	.byte	0x00, 0x80
+	.long	0
+	.long	0
diff --git a/arch/nios2/boot/compressed/misc.c b/arch/nios2/boot/compressed/misc.c
new file mode 100644
index 0000000..c036d02
--- /dev/null
+++ b/arch/nios2/boot/compressed/misc.c
@@ -0,0 +1,178 @@
+/*
+ * arch/nios2/boot/compressed/misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for SH by Stuart Menefy, Aug 1999
+ *
+ * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
+ */
+
+#include <linux/string.h>
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n)     memset ((s), 0, (n))
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define WSIZE 0x8000		/* Window size must be at least 32k, */
+				/* and a power of two */
+
+static uch *inbuf;	     /* input buffer */
+static uch window[WSIZE];    /* Sliding window buffer */
+
+static unsigned insize = 0;  /* valid bytes in inbuf */
+static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
+static unsigned outcnt = 0;  /* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
+#define RESERVED     0xC0 /* bit 6,7:   reserved */
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) {if(!(cond)) error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+static int  fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+
+extern char input_data[];
+extern int input_len;
+
+static long bytes_out = 0;
+static uch *output_data;
+static unsigned long output_ptr = 0;
+
+#include "console.c"
+
+static void error(char *m);
+
+int puts(const char *);
+
+extern int _end;
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#define HEAP_SIZE             0x10000
+
+#include "../../../../lib/inflate.c"
+
+void* memset(void* s, int c, size_t n)
+{
+	int i;
+	char *ss = (char*)s;
+
+	for (i=0;i<n;i++) ss[i] = c;
+	return s;
+}
+
+void* memcpy(void* __dest, __const void* __src,
+			    size_t __n)
+{
+	int i;
+	char *d = (char *)__dest, *s = (char *)__src;
+
+	for (i=0;i<__n;i++) d[i] = s[i];
+	return __dest;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf(void)
+{
+	if (insize != 0) {
+		error("ran out of input data");
+	}
+
+	inbuf = input_data;
+	insize = input_len;
+	inptr = 1;
+	return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window(void)
+{
+    ulg c = crc;         /* temporary variable */
+    unsigned n;
+    uch *in, *out, ch;
+    in = window;
+    out = &output_data[output_ptr];
+    for (n = 0; n < outcnt; n++) {
+	    ch = *out++ = *in++;
+	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+    }
+    crc = c;
+    bytes_out += (ulg)outcnt;
+    output_ptr += (ulg)outcnt;
+    outcnt = 0;
+}
+
+static void error(char *x)
+{
+	puts("\nERROR\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	while(1);	/* Halt */
+}
+
+void decompress_kernel(void)
+{
+  output_data = (void *)(DDR2_TOP_BASE | KERNEL_REGION_BASE);
+  output_ptr = 0;
+  free_mem_ptr = (unsigned long)&_end;
+  free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
+  console_init();
+  makecrc();
+  puts("Uncompressing Linux... ");
+  gunzip();
+  puts("Ok, booting the kernel.\n");
+#if 0
+  puts("start at ");
+  putx(DDR2_TOP_BASE | KERNEL_REGION_BASE);
+  putchar('\n');
+  dump(DDR2_TOP_BASE | KERNEL_REGION_BASE, 64);
+  putchar('\n');
+#endif
+}
diff --git a/arch/nios2/boot/compressed/vmlinux.lds.S b/arch/nios2/boot/compressed/vmlinux.lds.S
new file mode 100644
index 0000000..a4373d5
--- /dev/null
+++ b/arch/nios2/boot/compressed/vmlinux.lds.S
@@ -0,0 +1,34 @@
+#include <asm-generic/vmlinux.lds.h>
+#include <asm/nios.h>
+
+OUTPUT_FORMAT("elf32-littlenios2", "elf32-littlenios2", "elf32-littlenios2")
+
+OUTPUT_ARCH(nios)
+ENTRY(_start)	/* Defined in head.S */
+
+SECTIONS
+{
+  . = (DDR2_TOP_BASE + CONFIG_BOOT_LINK_OFFSET) | KERNEL_REGION_BASE;
+
+  _text = .;
+  .text : { *(.text) } = 0
+  .rodata : { *(.rodata) *(.rodata.*) }
+  _etext = .;
+
+  . = ALIGN(32 / 8);
+  .data : { *(.data) }
+  . = ALIGN(32 / 8);
+  _got = .;
+  .got  : { *(.got) _egot = .; *(.got.*) }
+  _edata  =  .;
+
+  . = ALIGN(32 / 8);
+  __bss_start = .;
+  .bss : { *(.bss) *(.sbss) }
+  . = ALIGN(32 / 8);
+  _ebss = .;
+  end = . ;
+  _end = . ;
+
+  got_len = (_egot - _got);
+}
diff --git a/arch/nios2/boot/compressed/vmlinux.scr b/arch/nios2/boot/compressed/vmlinux.scr
new file mode 100644
index 0000000..33a57d9
--- /dev/null
+++ b/arch/nios2/boot/compressed/vmlinux.scr
@@ -0,0 +1,10 @@
+SECTIONS
+{
+  .data : { 
+	input_len = .;
+	LONG(input_data_end - input_data) input_data = .; 
+	*(.data) 
+	. = ALIGN(4); 
+	input_data_end = .; 
+	}
+}
diff --git a/arch/nios2/defconfig.initrd b/arch/nios2/defconfig.initrd
new file mode 100644
index 0000000..219a8dc
--- /dev/null
+++ b/arch/nios2/defconfig.initrd
@@ -0,0 +1,617 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21
+# Thu Dec 11 17:20:43 2008
+#
+
+#
+# NiosII Configuration
+#
+CONFIG_NIOS2_DEFAULT_MMU=y
+# CONFIG_NIOS2_MAXIMUM_MMU is not set
+# CONFIG_NIOS2_CUSTOM_FPGA is not set
+CONFIG_NIOS2_HW_MUL_SUPPORT=y
+# CONFIG_NIOS2_HW_MULX_SUPPORT is not set
+# CONFIG_NIOS2_HW_DIV_SUPPORT is not set
+CONFIG_NIOS2_UIMAGE_FLASHADDR=0x1C80000
+CONFIG_NIOS2=y
+CONFIG_MMU=y
+CONFIG_PIO_DEVICES=m
+CONFIG_PIO_LED=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_PASS_CMDLINE=y
+CONFIG_UID16=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_NOT_COHERENT_CACHE is not set
+CONFIG_HZ=100
+# CONFIG_TRACE_IRQFLAGS_SUPPORT is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="../rootfs"
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_SHMEM is not set
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+# CONFIG_NETDEVICES is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_ALTERA_JTAGUART=y
+CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE=y
+CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS=y
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CROSSCOMPILE is not set
+CONFIG_CMDLINE="lpj=415744 console=ttyJ0 ro rdinit=/init0"
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/nios2/defconfig.nfsroot b/arch/nios2/defconfig.nfsroot
new file mode 100644
index 0000000..e4d4714
--- /dev/null
+++ b/arch/nios2/defconfig.nfsroot
@@ -0,0 +1,770 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21
+# Fri Feb 13 14:22:53 2009
+#
+
+#
+# NiosII Configuration
+#
+CONFIG_NIOS2_DEFAULT_MMU=y
+# CONFIG_NIOS2_MAXIMUM_MMU is not set
+# CONFIG_NIOS2_CUSTOM_FPGA is not set
+CONFIG_NIOS2_HW_MUL_SUPPORT=y
+# CONFIG_NIOS2_HW_MULX_SUPPORT is not set
+# CONFIG_NIOS2_HW_DIV_SUPPORT is not set
+CONFIG_NIOS2_UIMAGE_FLASHADDR=0x1C80000
+CONFIG_NIOS2=y
+CONFIG_PIO_DEVICES=m
+CONFIG_PIO_LED=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_PASS_CMDLINE=y
+CONFIG_UID16=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_NOT_COHERENT_CACHE is not set
+CONFIG_HZ=100
+# CONFIG_TRACE_IRQFLAGS_SUPPORT is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_SHMEM is not set
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_MARVELL_TX_DELAY=y
+CONFIG_MARVELL_RX_DELAY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+CONFIG_ALT_TSE=y
+CONFIG_DECS_MEMORY_SELECT=y
+CONFIG_DECS_MEMORY_BASE=0x08002000
+# CONFIG_PHY_IRQ_PRESENCE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_ALTERA_JTAGUART=y
+CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE=y
+CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS=y
+CONFIG_SERIAL_ALTERA_UART=y
+CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4
+CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200
+CONFIG_SERIAL_ALTERA_UART_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT3_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_DIRECTIO=y
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CROSSCOMPILE is not set
+CONFIG_CMDLINE="lpj=415744 noinitrd root=/dev/nfs rw nfsroot=192.168.0.12:/srv/nios2 ip=dhcp console=ttyJ0 init=/init0"
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/nios2/drivers/Kconfig b/arch/nios2/drivers/Kconfig
new file mode 100644
index 0000000..74b5c53
--- /dev/null
+++ b/arch/nios2/drivers/Kconfig
@@ -0,0 +1,15 @@
+# Platfrom drivers configuration
+
+menu "Additional NiosII Device Drivers"
+
+source "arch/nios2/drivers/pci/Kconfig"
+
+config ALTERA_REMOTE_UPDATE
+	bool "Remote update support"
+	depends on NIOS2
+	default N
+	help
+	  This driver provides support for automatic reconfiguration of a 
+	  CycloneIII FPGA (Possibly others too).
+
+endmenu
diff --git a/arch/nios2/drivers/Makefile b/arch/nios2/drivers/Makefile
new file mode 100644
index 0000000..9893bd4
--- /dev/null
+++ b/arch/nios2/drivers/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the Linux nios2-specific device drivers.
+#
+
+obj-$(CONFIG_PCI)		+= pci/
+obj-$(CONFIG_ALTERA_REMOTE_UPDATE)	+= altremote.o
diff --git a/arch/nios2/drivers/altremote.c b/arch/nios2/drivers/altremote.c
new file mode 100644
index 0000000..872b5c2
--- /dev/null
+++ b/arch/nios2/drivers/altremote.c
@@ -0,0 +1,383 @@
+/*
+ *  Altera remote update driver
+ *
+ *  (c) Copyright 2008 Walter Goossens <waltergoossens@home.nl>
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/watchdog.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#define REG_MSM_STATE     0x00
+#define REG_CDONE_CHECK   0x04
+#define REG_WDOG_COUNTER  0x08
+#define REG_WDOG_ENABLE   0x0C
+#define REG_BOOT_ADDR     0x10
+#define REG_INT_OSC       0x18
+#define REG_CFG_SOURCE    0x1C
+#define REG_GPR           0x80
+#define CFG_CURR          0x00
+#define CFG_PREV1         0x20
+#define CFG_PREV2         0x40
+
+#define CFG_SOURCE_USER     0x01
+#define CFG_SOURCE_WDOG     0x02
+#define CFG_SOURCE_NSTATUS  0x04
+#define CFG_SOURCE_CRC      0x08
+#define CFG_SOURCE_NCONFIG  0x10
+#define CFG_SOURCE_ALL      0x1F
+
+#define PET_WDOG            0x02
+
+static int altremote_wdt_pet(void);
+static ssize_t altremote_wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
+static int altremote_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+static int altremote_wdt_open(struct inode *inode, struct file *file);
+static int altremote_wdt_release(struct inode *inode, struct file *file);
+
+struct altremote_data {
+  void __iomem *base;
+  struct resource *res;
+  int initsteps;
+};
+
+static struct altremote_data altremote = {
+  .base = NULL,
+  .res = NULL,
+  .initsteps = 0,
+};
+
+static const struct file_operations altremote_wdt_fops = {
+  .owner    = THIS_MODULE,
+  .llseek   = no_llseek,
+  .write    = altremote_wdt_write,
+  .ioctl    = altremote_wdt_ioctl,
+  .open     = altremote_wdt_open,
+  .release  = altremote_wdt_release,
+};
+
+static struct miscdevice altremote_wdt_miscdev = {
+  .minor  = WATCHDOG_MINOR,
+  .name = "watchdog",
+  .fops = &altremote_wdt_fops,
+};
+
+
+
+static unsigned long wdt_is_open;
+static unsigned long wdt_timeout = 0;
+/**
+ *  altremote_wdt_pet
+ *
+ *  Reload counter one with the watchdog heartbeat.
+ */
+static int altremote_wdt_pet(void) {
+  iowrite32(PET_WDOG, altremote.base + REG_GPR);
+  iowrite32(0, altremote.base + REG_GPR);
+  return 0;
+}
+
+/**
+ *  altremote_wdt_write:
+ *  @file: file handle to the watchdog
+ *  @buf: buffer to write (unused as data does not matter here
+ *  @count: count of bytes
+ *  @ppos: pointer to the position to write. No seeks allowed
+ *
+ *  A write to a watchdog device is defined as a keepalive signal. Any
+ *  write of data will do, as we we don't define content meaning.
+ */
+static ssize_t altremote_wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) {
+  if(count) {
+    altremote_wdt_pet();
+  }
+  return count;
+}
+
+/**
+ *  altremote_wdt_ioctl:
+ *  @inode: inode of the device
+ *  @file: file handle to the device
+ *  @cmd: watchdog command
+ *  @arg: argument pointer
+ *
+ *  The watchdog API defines a common set of functions for all watchdogs
+ *  according to their available features. We only actually usefully support
+ *  querying capabilities and current status.
+ */
+static int altremote_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) {
+  void __user *argp = (void __user *)arg;
+
+  static struct watchdog_info ident = {
+    .options =  WDIOF_KEEPALIVEPING,
+    .firmware_version = 1,
+    .identity = "altremote_wdt",
+  };
+
+  switch(cmd) {
+    case WDIOC_GETSUPPORT:
+      return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
+    case WDIOC_KEEPALIVE:
+      altremote_wdt_pet();
+      return 0;
+    default:
+      return -ENOIOCTLCMD;
+  }
+}
+
+/**
+ *  altremote_wdt_open:
+ *  @inode: inode of device
+ *  @file: file handle to device
+ *
+ *  The watchdog device has been opened. The watchdog device is single
+ *  open and on opening we load the counters. 
+ *  The timeout depends on the value you selected in SOPC-builder.
+ */
+static int altremote_wdt_open(struct inode *inode, struct file *file) {
+  if(test_and_set_bit(0, &wdt_is_open))
+    return -EBUSY;
+  return nonseekable_open(inode, file);
+}
+
+/**
+ *  altremote_wdt_release:
+ *  @inode: inode to board
+ *  @file: file handle to board
+ *
+ */
+static int altremote_wdt_release(struct inode *inode, struct file *file) {
+  clear_bit(0, &wdt_is_open);
+  printk(KERN_CRIT "altremote: WDT device closed unexpectedly.  WDT will (can) not stop!\n");
+  altremote_wdt_pet();
+  return 0;
+}
+
+/* following are the sysfs callback functions */
+static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf)
+{
+  int num = 0;
+  u32 reg = ioread32(altremote.base + (CFG_PREV1 | REG_CFG_SOURCE));
+  
+  num = sprintf(buf, "Reconfigured by: ");
+  switch(reg)
+  {
+    case CFG_SOURCE_USER: {
+      num += sprintf(buf + num, "user request\n");
+    } break;
+    case CFG_SOURCE_WDOG: {
+      num += sprintf(buf + num, "user watchdog timeout\n");
+    } break;
+    case CFG_SOURCE_NSTATUS: {
+      num += sprintf(buf + num, "nSTATUS assertion\n");
+    } break;
+    case CFG_SOURCE_CRC: {
+      num += sprintf(buf + num, "CRC Error in application\n");
+    } break;
+    case CFG_SOURCE_NCONFIG: {
+      num += sprintf(buf + num, "external configuration request (nCONFIG)\n");
+    } break;
+    default: {
+      num += sprintf(buf + num,"Unknown source 0x%X\n",reg);
+    }
+  }
+  num += sprintf(buf + num,"Configured from 0x%06X\n",ioread32(altremote.base  + REG_BOOT_ADDR));
+  if(ioread32(altremote.base + REG_WDOG_ENABLE))
+  {
+    num += sprintf(buf + num, "Watchdog running\n");
+  } else {
+    num += sprintf(buf + num, "Watchdog NOT running\n");
+  }
+  return num;
+}
+
+static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
+
+static ssize_t set_config_addr(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+  unsigned long val = simple_strtoul(buf, NULL, 16);
+  dev_printk(KERN_INFO, dev, "We'll try to reboot to 0x%lX (0x%lX)\n",val,val>>3);
+  iowrite32(val>>3, altremote.base + REG_BOOT_ADDR);
+  return count;
+}
+
+static DEVICE_ATTR(config_addr, S_IWUSR, NULL, set_config_addr);
+
+static ssize_t reconfig(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+  dev_printk(KERN_WARNING, dev, "Warning! We'll reboot!\n");
+  //Enable internal osc.
+  iowrite32(0x00, altremote.base + REG_WDOG_ENABLE);
+  if(wdt_timeout>0)
+  {
+    iowrite32(wdt_timeout, altremote.base + REG_WDOG_COUNTER);
+    iowrite32(0x01, altremote.base + REG_WDOG_ENABLE);
+  }
+  iowrite32(0x01, altremote.base + REG_INT_OSC);
+  iowrite32(0x01, altremote.base + REG_CDONE_CHECK);
+  iowrite32(CFG_SOURCE_ALL, altremote.base + REG_CFG_SOURCE);
+  iowrite32(0x01, altremote.base + REG_GPR);
+  return count;
+}
+
+static DEVICE_ATTR(reconfig, S_IWUSR, NULL, reconfig);
+
+static ssize_t show_watchdog(struct device *dev, struct device_attribute *attr, char *buf)
+{
+  if(altremote.initsteps>=4)
+  {
+    return sprintf(buf, "%u\n", ioread32(altremote.base + REG_WDOG_COUNTER));
+  } else {
+    return sprintf(buf, "%lu\n", wdt_timeout);
+  }
+}
+
+static ssize_t set_watchdog(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+  if(altremote.initsteps>=4)
+  {
+    altremote_wdt_pet();
+  } else {
+    wdt_timeout = simple_strtoul(buf, NULL, 10);
+  }
+  return count;
+}
+
+static DEVICE_ATTR(watchdog, S_IWUSR | S_IRUGO, show_watchdog, set_watchdog);
+
+static int altremote_remove(struct platform_device* pdev)
+{
+  if(altremote.initsteps>=4)
+  {
+    misc_deregister(&altremote_wdt_miscdev);
+  }
+  if(altremote.initsteps>=3)
+  {
+    iounmap(altremote.base);
+  }
+  if(altremote.initsteps>=2)
+  {
+    release_mem_region(altremote.res->start, resource_size(altremote.res));
+  }
+  altremote.initsteps = 0;
+  return 0;
+}
+
+static int __devinit altremote_probe(struct platform_device *pdev)
+{
+  u32 status;
+  int ret;
+
+  if(altremote.initsteps != 0)
+  {
+    //We only allow ONE instance!!
+    return -ENODEV;
+  }
+  altremote.res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+  if (!altremote.res)
+    return -ENODEV;
+
+  altremote.initsteps++;
+  if (!request_mem_region(altremote.res->start, resource_size(altremote.res), pdev->name)) {
+    dev_err(&pdev->dev, "Memory region busy\n");
+    altremote_remove(pdev);
+    return -EBUSY;
+  }
+  altremote.initsteps++;
+  altremote.base = ioremap(altremote.res->start, resource_size(altremote.res));
+  if (!altremote.base) {
+    dev_err(&pdev->dev, "Unable to map registers\n");
+    ret = -EIO;
+    goto err_out;
+  }
+  altremote.initsteps++;
+
+  ret = device_create_file(&pdev->dev, &dev_attr_status);
+  if (ret)
+    goto err_out_sysfs;
+
+  ret = device_create_file(&pdev->dev, &dev_attr_reconfig);
+  if (ret)
+    goto err_out_sysfs;
+
+  status = ioread32(altremote.base + REG_MSM_STATE);
+  switch(status)
+  {
+    case 0: {
+      dev_info(&pdev->dev, "Found altremote block in Factory Mode\n");
+      ret = device_create_file(&pdev->dev, &dev_attr_config_addr);
+      if (ret)
+        goto err_out_sysfs;
+
+      ret = device_create_file(&pdev->dev, &dev_attr_watchdog);
+      if (ret)
+        goto err_out_sysfs;
+    } break;
+    case 1: {
+      dev_printk(KERN_INFO, &pdev->dev, "Found altremote block in Application Mode\n");
+    } break;
+    case 3: {
+      dev_printk(KERN_INFO, &pdev->dev, "Found altremote block in Application Mode with Watchdog enabled\n");
+      ret = misc_register(&altremote_wdt_miscdev);
+      if (ret) {
+        printk(KERN_ERR "altremote_wdt: cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret);
+        goto err_out;
+      }
+      ret = device_create_file(&pdev->dev, &dev_attr_watchdog);
+      if (ret)
+        goto err_out_wdt;
+      altremote.initsteps++;
+    } break;
+    default: {
+      dev_info(&pdev->dev, "Found altremote block unknwon state 0x%X\n", status);
+    }
+  }
+  return 0;
+
+err_out_wdt:
+  misc_deregister(&altremote_wdt_miscdev);
+err_out_sysfs:
+  device_remove_file(&pdev->dev, &dev_attr_config_addr);
+  device_remove_file(&pdev->dev, &dev_attr_reconfig);
+  device_remove_file(&pdev->dev, &dev_attr_status);
+  iounmap(altremote.base);
+err_out:
+  release_mem_region(altremote.res->start, resource_size(altremote.res));
+  altremote_remove(pdev);
+  return ret;
+}
+
+static struct platform_driver altremote_driver = {
+  .probe  = altremote_probe,
+  .remove = __devexit_p(altremote_remove),
+  .driver = {
+    .owner = THIS_MODULE,
+    .name = "altremote",
+  },
+};
+
+static int __init altremote_init(void)
+{
+  return platform_driver_register(&altremote_driver);
+}
+
+static void __exit altremote_exit(void)
+{
+  platform_driver_unregister(&altremote_driver);
+}
+
+module_init(altremote_init);
+module_exit(altremote_exit);
+
+MODULE_AUTHOR("Walter Goossens <waltergoossens@home.nl>");
+MODULE_DESCRIPTION("Altera Remote Update Driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/nios2/drivers/pci/Kconfig b/arch/nios2/drivers/pci/Kconfig
new file mode 100644
index 0000000..6c3b175
--- /dev/null
+++ b/arch/nios2/drivers/pci/Kconfig
@@ -0,0 +1,4 @@
+config PCI_ALTPCI
+	bool "Altera PCI host bridge"
+	select PCI
+	default n
diff --git a/arch/nios2/drivers/pci/Makefile b/arch/nios2/drivers/pci/Makefile
new file mode 100644
index 0000000..b027e1e
--- /dev/null
+++ b/arch/nios2/drivers/pci/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the PCI specific kernel interface routines under Linux.
+#
+
+obj-y += pci.o
+obj-$(CONFIG_PCI_ALTPCI) += altpci.o setup-irq.o pci-auto.o
diff --git a/arch/nios2/drivers/pci/altpci.c b/arch/nios2/drivers/pci/altpci.c
new file mode 100644
index 0000000..b509ca4
--- /dev/null
+++ b/arch/nios2/drivers/pci/altpci.c
@@ -0,0 +1,204 @@
+/* arch/sh/kernel/pci.c
+ * $Id: altpci.c,v 1.1 2006-07-05 06:23:17 gerg Exp $
+ *
+ * Copyright (c) 2002 M. R. Brown  <mrbrown@linux-sh.org>
+ * 
+ * 
+ * These functions are collected here to reduce duplication of common
+ * code amongst the many platform-specific PCI support code files.
+ * 
+ * These routines require the following board-specific routines:
+ * void pcibios_fixup_irqs();
+ *
+ * See include/asm-sh/pci.h for more information.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+/*
+ * Direct access to PCI hardware...
+ */
+#define pcicfg_space (na_pci_compiler_0_PCI_Bus_Access)  // avalon space
+#define pciio  (pcicfg_space+0x100000)    // pci io device base in avalon space
+#define pcimm  (pcicfg_space+0x200000)    // pci mem device base in avalon space
+  // idsel of ad11=dev0,ad12=dev1  , using type 0 config request
+#define pcicfg(dev,fun,reg) (pcicfg_space | ((dev)<<11) | ((fun)<<8) | (reg))    // cfg space
+
+// FIX ME for your board, dram device for external pci masters access
+static int __init alt_pci_init(void)
+{
+  unsigned dev,fun;
+  // setup dram bar
+  dev=0; fun=0;
+  outl(nasys_program_mem,pcicfg(dev,fun,0x10));  // mem space
+  outw(0x0006,pcicfg(dev,fun,0x04));   // enable master, mem space
+  return 0;
+}
+
+subsys_initcall(alt_pci_init);
+
+#define PCICFG(bus, devfn, where)  (pcicfg_space | (bus->number << 16) | (devfn << 8) | (where & ~3))
+#define ALT_PCI_IO_BASE	        (pciio)
+#define ALT_PCI_IO_SIZE	        0x100000
+#define ALT_PCI_MEMORY_BASE	(pcimm)	
+#define ALT_PCI_MEM_SIZE	0x100000
+
+/*
+ * Functions for accessing PCI configuration space with type 1 accesses
+ */
+
+// FIX ME for your board, number of pci bus, and number of devices
+static inline int pci_range_ck(struct pci_bus *bus, unsigned int devfn)
+{
+  if (bus->number > 0 || PCI_SLOT(devfn) == 0 || PCI_SLOT(devfn) > 2)
+		return -1;
+
+	return 0;
+}
+
+static int alt_pci_read(struct pci_bus *bus, unsigned int devfn,
+			   int where, int size, u32 *val)
+{
+	u32 data;
+
+	if (pci_range_ck(bus, devfn))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	// local_irq_save(flags);
+	data = inl(PCICFG(bus, devfn, where));
+	// local_irq_restore(flags);
+
+	switch (size) {
+	case 1:
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+		break;
+	case 2:
+		*val = (data >> ((where & 2) << 3)) & 0xffff;
+		break;
+	case 4:
+		*val = data;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/* 
+ * we'll do a read,
+ * mask,write operation.
+ * We'll allow an odd byte offset, though it should be illegal.
+ */ 
+static int alt_pci_write(struct pci_bus *bus, unsigned int devfn,
+			    int where, int size, u32 val)
+{
+	int shift;
+	u32 data;
+
+	if (pci_range_ck(bus, devfn))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	// local_irq_save(flags);
+	data = inl(PCICFG(bus, devfn, where));
+	// local_irq_restore(flags);
+
+	switch (size) {
+	case 1:
+		shift = (where & 3) << 3;
+		data &= ~(0xff << shift);
+		data |= ((val & 0xff) << shift);
+		break;
+	case 2:
+		shift = (where & 2) << 3;
+		data &= ~(0xffff << shift);
+		data |= ((val & 0xffff) << shift);
+		break;
+	case 4:
+		data = val;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	outl(data, PCICFG(bus, devfn, where));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops alt_pci_ops = {
+	.read 		= alt_pci_read,
+	.write		= alt_pci_write,
+};
+
+static struct resource alt_io_resource = {
+	.name   = "ALTPCI IO",
+	.start  = ALT_PCI_IO_BASE,
+	.end    = ALT_PCI_IO_BASE + ALT_PCI_IO_SIZE - 1,
+	.flags  = IORESOURCE_IO
+};
+
+static struct resource alt_mem_resource = {
+	.name   = "ALTPCI mem",
+	.start  = ALT_PCI_MEMORY_BASE,
+	.end    = ALT_PCI_MEMORY_BASE + ALT_PCI_MEM_SIZE - 1,
+	.flags  = IORESOURCE_MEM
+};
+
+extern struct pci_ops alt_pci_ops;
+
+struct pci_channel board_pci_channels[] = {
+	{ &alt_pci_ops, &alt_io_resource, &alt_mem_resource, 0, 0xff },
+	{ NULL, NULL, NULL, 0, 0 },
+};
+
+char *pcibios_setup(char *option)
+{
+	/* Nothing for us to handle. */
+	return(option);
+}
+
+void pcibios_fixup_bus(struct pci_bus *b)
+{
+}
+
+/* 
+ * 	IRQ functions 
+ */
+static u8 __init altpci_no_swizzle(struct pci_dev *dev, u8 *pin)
+{
+	/* no swizzling */
+	return PCI_SLOT(dev->devfn);
+}
+
+// FIX ME for your board, nios2 irqn mapping
+int __init pcibios_map_platform_irq(u8 slot, u8 pin)
+{
+  int irq = na_irqn_0_irq + ((slot-1)*4) + (pin-1);
+  // printk("map slot %d pin %d irq %d\n",slot,pin,irq);
+  return irq;
+}
+
+static int altpci_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int irq = -1;
+
+	/* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
+	irq = pcibios_map_platform_irq(slot,pin);
+	if( irq < 0 ) {
+	  // printk("PCI: Error mapping IRQ on device %s\n", pci_name(dev));
+	  return irq;
+	}
+
+	// printk("Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
+
+	return irq;
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+	pci_fixup_irqs(altpci_no_swizzle, altpci_pci_lookup_irq);
+}
+
diff --git a/arch/nios2/drivers/pci/pci-auto.c b/arch/nios2/drivers/pci/pci-auto.c
new file mode 100644
index 0000000..e1cdfdc
--- /dev/null
+++ b/arch/nios2/drivers/pci/pci-auto.c
@@ -0,0 +1,559 @@
+/*
+ * PCI autoconfiguration library
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2000, 2001 MontaVista Software Inc.
+ * Copyright 2001 Bradley D. LaRonde <brad@ltc.com>
+ * Copyright 2003 Paul Mundt <lethal@linux-sh.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/*
+ * Modified for MIPS by Jun Sun, jsun@mvista.com
+ *
+ * . Simplify the interface between pci_auto and the rest: a single function.
+ * . Assign resources from low address to upper address.
+ * . change most int to u32.
+ *
+ * Further modified to include it as mips generic code, ppopov@mvista.com.
+ *
+ * 2001-10-26  Bradley D. LaRonde <brad@ltc.com>
+ * - Add a top_bus argument to the "early config" functions so that
+ *   they can set a fake parent bus pointer to convince the underlying
+ *   pci ops to use type 1 configuration for sub busses.
+ * - Set bridge base and limit registers correctly.
+ * - Align io and memory base properly before and after bridge setup.
+ * - Don't fall through to pci_setup_bars for bridge.
+ * - Reformat the debug output to look more like lspci's output.
+ *
+ * Cloned for SuperH by M. R. Brown, mrbrown@0xd6.org
+ *
+ * 2003-08-05  Paul Mundt <lethal@linux-sh.org>
+ * - Don't update the BAR values on systems that already have valid addresses
+ *   and don't want these updated for whatever reason, by way of a new config
+ *   option check. However, we still read in the old BAR values so that they
+ *   can still be reported through the debug output.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#undef	DEBUG
+#define	DEBUG       // you can remove debug message here
+
+#ifdef 	DEBUG
+#define	DBG(x...)	printk(x)
+#else
+#define	DBG(x...)	
+#endif
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+static struct pci_dev *fake_pci_dev(struct pci_channel *hose,
+	int top_bus, int busnr, int devfn)
+{
+	static struct pci_dev dev;
+	static struct pci_bus bus;
+
+	dev.bus = &bus;
+	dev.sysdata = hose;
+	dev.devfn = devfn;
+	bus.number = busnr;
+	bus.ops = hose->pci_ops;
+
+	if(busnr != top_bus)
+		/* Fake a parent bus structure. */
+		bus.parent = &bus;
+	else
+		bus.parent = NULL;
+
+	return &dev;
+}
+
+#define EARLY_PCI_OP(rw, size, type)					\
+int early_##rw##_config_##size(struct pci_channel *hose,		\
+	int top_bus, int bus, int devfn, int offset, type value)	\
+{									\
+	return pci_##rw##_config_##size(				\
+		fake_pci_dev(hose, top_bus, bus, devfn),		\
+		offset, value);						\
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
+static struct resource *io_resource_inuse;
+static struct resource *mem_resource_inuse;
+
+static u32 pciauto_lower_iospc;
+static u32 pciauto_upper_iospc;
+
+static u32 pciauto_lower_memspc;
+static u32 pciauto_upper_memspc;
+
+static void __init 
+pciauto_setup_bars(struct pci_channel *hose,
+		   int top_bus,
+		   int current_bus,
+		   int pci_devfn,
+		   int bar_limit)
+{
+	u32 bar_response, bar_size, bar_value;
+	u32 bar, addr_mask, bar_nr = 0;
+	u32 * upper_limit;
+	u32 * lower_limit;
+	int found_mem64 = 0;
+
+	for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) {
+#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
+		u32 bar_addr;
+
+		/* Read the old BAR value */
+		early_read_config_dword(hose, top_bus,
+					current_bus,
+					pci_devfn,
+					bar,
+					&bar_addr);
+#endif
+
+		/* Tickle the BAR and get the response */
+		early_write_config_dword(hose, top_bus,
+					 current_bus,
+					 pci_devfn,
+					 bar,
+					 0xffffffff);
+
+		early_read_config_dword(hose, top_bus,
+					current_bus,
+					pci_devfn,
+					bar,
+					&bar_response);
+
+#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
+		/* 
+		 * Write the old BAR value back out, only update the BAR
+		 * if we implicitly want resources to be updated, which
+		 * is done by the generic code further down. -- PFM.
+		 */
+		early_write_config_dword(hose, top_bus,
+					 current_bus,
+					 pci_devfn,
+					 bar,
+					 bar_addr);
+#endif
+
+		/* If BAR is not implemented go to the next BAR */
+		if (!bar_response)
+			continue;
+
+		/*
+		 * Workaround for a BAR that doesn't use its upper word,
+		 * like the ALi 1535D+ PCI DC-97 Controller Modem (M5457).
+		 * bdl <brad@ltc.com>
+		 */
+		if (!(bar_response & 0xffff0000))
+			bar_response |= 0xffff0000;
+
+retry:
+		/* Check the BAR type and set our address mask */
+		if (bar_response & PCI_BASE_ADDRESS_SPACE) {
+			addr_mask = PCI_BASE_ADDRESS_IO_MASK;
+			upper_limit = &pciauto_upper_iospc;
+			lower_limit = &pciauto_lower_iospc;
+			DBG("        I/O");
+		} else {
+			if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			    PCI_BASE_ADDRESS_MEM_TYPE_64)
+				found_mem64 = 1;
+
+			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
+			upper_limit = &pciauto_upper_memspc;
+			lower_limit = &pciauto_lower_memspc;
+			DBG("        Mem");
+		}
+
+
+		/* Calculate requested size */
+		bar_size = ~(bar_response & addr_mask) + 1;
+
+		/* Allocate a base address */
+		bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size;
+
+		if ((bar_value + bar_size) > *upper_limit) {
+			if (bar_response & PCI_BASE_ADDRESS_SPACE) {
+				if (io_resource_inuse->child) {
+					io_resource_inuse = 
+						io_resource_inuse->child;
+					pciauto_lower_iospc = 
+						io_resource_inuse->start;
+					pciauto_upper_iospc = 
+						io_resource_inuse->end + 1;
+					goto retry;
+				}
+
+			} else {
+				if (mem_resource_inuse->child) {
+					mem_resource_inuse = 
+						mem_resource_inuse->child;
+					pciauto_lower_memspc = 
+						mem_resource_inuse->start;
+					pciauto_upper_memspc = 
+						mem_resource_inuse->end + 1;
+					goto retry;
+				}
+			}
+			DBG(" unavailable -- skipping, value %x size %x\n",
+					bar_value, bar_size);
+			continue;
+		}
+
+#if 1
+		/* Write it out and update our limit */
+		early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+					 bar, bar_value);
+#endif
+
+		*lower_limit = bar_value + bar_size;
+
+		/*
+		 * If we are a 64-bit decoder then increment to the
+		 * upper 32 bits of the bar and force it to locate
+		 * in the lower 4GB of memory.
+		 */ 
+		if (found_mem64) {
+			bar += 4;
+			early_write_config_dword(hose, top_bus,
+						 current_bus,
+						 pci_devfn,
+						 bar,
+						 0x00000000);
+		}
+
+		DBG(" at 0x%.8x [size=0x%x]\n", bar_value, bar_size);
+
+		bar_nr++;
+	}
+
+}
+
+static void __init
+pciauto_prescan_setup_bridge(struct pci_channel *hose,
+			     int top_bus,
+			     int current_bus,
+			     int pci_devfn,
+			     int sub_bus)
+{
+	/* Configure bus number registers */
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+	                        PCI_PRIMARY_BUS, current_bus);
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+				PCI_SECONDARY_BUS, sub_bus + 1);
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+				PCI_SUBORDINATE_BUS, 0xff);
+
+	/* Align memory and I/O to 1MB and 4KB boundaries. */
+	pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1))
+		& ~(0x100000 - 1);
+	pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1))
+		& ~(0x1000 - 1);
+
+	/* Set base (lower limit) of address range behind bridge. */
+	early_write_config_word(hose, top_bus, current_bus, pci_devfn,
+		PCI_MEMORY_BASE, pciauto_lower_memspc >> 16);
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+		PCI_IO_BASE, (pciauto_lower_iospc & 0x0000f000) >> 8);
+	early_write_config_word(hose, top_bus, current_bus, pci_devfn,
+		PCI_IO_BASE_UPPER16, pciauto_lower_iospc >> 16);
+
+	/* We don't support prefetchable memory for now, so disable */
+	early_write_config_word(hose, top_bus, current_bus, pci_devfn,
+				PCI_PREF_MEMORY_BASE, 0);
+	early_write_config_word(hose, top_bus, current_bus, pci_devfn,
+				PCI_PREF_MEMORY_LIMIT, 0);
+}
+
+static void __init
+pciauto_postscan_setup_bridge(struct pci_channel *hose,
+			      int top_bus,
+			      int current_bus,
+			      int pci_devfn,
+			      int sub_bus)
+{
+	u32 temp;
+
+	/*
+	 * [jsun] we always bump up baselines a little, so that if there
+	 * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
+	 * spaces.
+	 */
+	pciauto_lower_memspc += 1;
+	pciauto_lower_iospc += 1;
+
+	/* Configure bus number registers */
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+				PCI_SUBORDINATE_BUS, sub_bus);
+
+	/* Set upper limit of address range behind bridge. */
+	early_write_config_word(hose, top_bus, current_bus, pci_devfn,
+		PCI_MEMORY_LIMIT, pciauto_lower_memspc >> 16);
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+		PCI_IO_LIMIT, (pciauto_lower_iospc & 0x0000f000) >> 8);
+	early_write_config_word(hose, top_bus, current_bus, pci_devfn,
+		PCI_IO_LIMIT_UPPER16, pciauto_lower_iospc >> 16);
+
+	/* Align memory and I/O to 1MB and 4KB boundaries. */
+	pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1))
+		& ~(0x100000 - 1);
+	pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1))
+		& ~(0x1000 - 1);
+
+	/* Enable memory and I/O accesses, enable bus master */
+	early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
+		PCI_COMMAND, &temp);
+	early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+		PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY
+		| PCI_COMMAND_MASTER);
+}
+
+static void __init
+pciauto_prescan_setup_cardbus_bridge(struct pci_channel *hose,
+			int top_bus,
+			int current_bus,
+			int pci_devfn,
+			int sub_bus)
+{
+	/* Configure bus number registers */
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+				PCI_PRIMARY_BUS, current_bus);
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+				PCI_SECONDARY_BUS, sub_bus + 1);
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+				PCI_SUBORDINATE_BUS, 0xff);
+
+	/* Align memory and I/O to 4KB and 4 byte boundaries. */
+	pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
+		& ~(0x1000 - 1);
+	pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
+		& ~(0x4 - 1);
+
+	early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+		PCI_CB_MEMORY_BASE_0, pciauto_lower_memspc);
+	early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+		PCI_CB_IO_BASE_0, pciauto_lower_iospc);
+}
+
+static void __init
+pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose,
+			int top_bus,
+			int current_bus,
+			int pci_devfn,
+			int sub_bus)
+{
+	u32 temp;
+
+#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
+	/*
+	 * [jsun] we always bump up baselines a little, so that if there
+	 * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
+	 * spaces.
+	 */
+	pciauto_lower_memspc += 1;
+	pciauto_lower_iospc += 1;
+#endif
+
+	/*
+	 * Configure subordinate bus number.  The PCI subsystem
+	 * bus scan will renumber buses (reserving three additional
+	 * for this PCI<->CardBus bridge for the case where a CardBus
+	 * adapter contains a P2P or CB2CB bridge.
+	 */
+
+	early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+				PCI_SUBORDINATE_BUS, sub_bus);
+
+	/*
+	 * Reserve an additional 4MB for mem space and 16KB for
+	 * I/O space.  This should cover any additional space
+	 * requirement of unusual CardBus devices with
+	 * additional bridges that can consume more address space.
+	 *
+	 * Although pcmcia-cs currently will reprogram bridge
+	 * windows, the goal is to add an option to leave them
+	 * alone and use the bridge window ranges as the regions
+	 * that are searched for free resources upon hot-insertion
+	 * of a device.  This will allow a PCI<->CardBus bridge
+	 * configured by this routine to happily live behind a
+	 * P2P bridge in a system.
+	 */
+#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
+	pciauto_lower_memspc += 0x00400000;
+	pciauto_lower_iospc += 0x00004000;
+#endif
+
+	/* Align memory and I/O to 4KB and 4 byte boundaries. */
+	pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
+		& ~(0x1000 - 1);
+	pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
+		& ~(0x4 - 1);
+	/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+	early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+		PCI_CB_MEMORY_LIMIT_0, pciauto_lower_memspc - 1);
+	early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+		PCI_CB_IO_LIMIT_0, pciauto_lower_iospc - 1);
+
+	/* Enable memory and I/O accesses, enable bus master */
+	early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
+		PCI_COMMAND, &temp);
+	early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+		PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+		PCI_COMMAND_MASTER);
+}
+
+#define	PCIAUTO_IDE_MODE_MASK		0x05
+
+static int __init
+pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
+{
+	int sub_bus;
+	u32 pci_devfn, pci_class, cmdstat, found_multi=0;
+	unsigned short vid, did;
+	unsigned char header_type;
+	int devfn_start = 0;
+	int devfn_stop = 0xff;
+
+	sub_bus = current_bus;
+	
+	if (hose->first_devfn)
+		devfn_start = hose->first_devfn;
+	if (hose->last_devfn)
+		devfn_stop = hose->last_devfn;
+	
+	for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
+
+		if (PCI_FUNC(pci_devfn) && !found_multi)
+			continue;
+
+		early_read_config_word(hose, top_bus, current_bus, pci_devfn,
+				       PCI_VENDOR_ID, &vid);
+
+		if (vid == 0xffff) continue;
+
+		early_read_config_byte(hose, top_bus, current_bus, pci_devfn,
+				       PCI_HEADER_TYPE, &header_type);
+
+		if (!PCI_FUNC(pci_devfn))
+			found_multi = header_type & 0x80;
+
+		early_read_config_word(hose, top_bus, current_bus, pci_devfn,
+				       PCI_DEVICE_ID, &did);
+
+		early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
+					PCI_CLASS_REVISION, &pci_class);
+
+		if ((pci_class & 0xff000000)==0) continue;   // devices before pci 2.0
+
+		DBG("%.2x:%.2x.%x Class %.4x: %.4x:%.4x",
+			current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn),
+			pci_class >> 16, vid, did);
+		if (pci_class & 0xff)
+			DBG(" (rev %.2x)", pci_class & 0xff);
+		DBG("\n");
+
+		if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) {
+			DBG("        Bridge: primary=%.2x, secondary=%.2x\n",
+				current_bus, sub_bus + 1);
+#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
+			pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_1);
+#endif
+			pciauto_prescan_setup_bridge(hose, top_bus, current_bus,
+						     pci_devfn, sub_bus);
+			DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
+				sub_bus + 1,
+				pciauto_lower_iospc, pciauto_lower_memspc);
+			sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
+			DBG("Back to bus %.2x\n", current_bus);
+			pciauto_postscan_setup_bridge(hose, top_bus, current_bus,
+							pci_devfn, sub_bus);
+			continue;
+		} else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) {
+			DBG("  CARDBUS  Bridge: primary=%.2x, secondary=%.2x\n",
+				current_bus, sub_bus + 1);
+			DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn));
+			/* Place CardBus Socket/ExCA registers */
+			pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0);
+ 
+			pciauto_prescan_setup_cardbus_bridge(hose, top_bus,
+					current_bus, pci_devfn, sub_bus);
+ 
+			DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
+				sub_bus + 1,
+				pciauto_lower_iospc, pciauto_lower_memspc);
+			sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
+			DBG("Back to bus %.2x, sub_bus is %x\n", current_bus, sub_bus);
+			pciauto_postscan_setup_cardbus_bridge(hose, top_bus,
+					current_bus, pci_devfn, sub_bus);
+			continue;
+		} else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
+
+			unsigned char prg_iface;
+
+			early_read_config_byte(hose, top_bus, current_bus,
+				pci_devfn, PCI_CLASS_PROG, &prg_iface);
+			if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
+				DBG("Skipping legacy mode IDE controller\n");
+				continue;
+			}
+		}
+
+		/*
+		 * Found a peripheral, enable some standard
+		 * settings
+		 */
+		early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
+					PCI_COMMAND, &cmdstat);
+		early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
+					 PCI_COMMAND, cmdstat | PCI_COMMAND_IO |
+					 PCI_COMMAND_MEMORY |
+					 PCI_COMMAND_MASTER);
+#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
+		early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
+					PCI_LATENCY_TIMER, 0x80);
+#endif
+
+		/* Allocate PCI I/O and/or memory space */
+		pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5);
+	}
+	return sub_bus;
+}
+
+int __init
+pciauto_assign_resources(int busno, struct pci_channel *hose)
+{
+	/* setup resource limits */
+	io_resource_inuse = hose->io_resource;
+	mem_resource_inuse = hose->mem_resource;
+
+	pciauto_lower_iospc = io_resource_inuse->start;
+	pciauto_upper_iospc = io_resource_inuse->end + 1;
+	pciauto_lower_memspc = mem_resource_inuse->start;
+	pciauto_upper_memspc = mem_resource_inuse->end + 1;
+	DBG("Autoconfig PCI channel 0x%p\n", hose);
+	DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n",
+		busno, pciauto_lower_iospc, pciauto_upper_iospc, 
+		pciauto_lower_memspc, pciauto_upper_memspc);
+
+	return pciauto_bus_scan(hose, busno, busno);
+}
diff --git a/arch/nios2/drivers/pci/pci.c b/arch/nios2/drivers/pci/pci.c
new file mode 100644
index 0000000..1c1c547
--- /dev/null
+++ b/arch/nios2/drivers/pci/pci.c
@@ -0,0 +1,151 @@
+/* arch/sh/kernel/pci.c
+ * $Id: pci.c,v 1.4 2007-11-22 04:57:40 gerg Exp $
+ *
+ * Copyright (c) 2002 M. R. Brown  <mrbrown@linux-sh.org>
+ * 
+ * 
+ * These functions are collected here to reduce duplication of common
+ * code amongst the many platform-specific PCI support code files.
+ * 
+ * These routines require the following board-specific routines:
+ * void pcibios_fixup_irqs();
+ *
+ * See include/asm-sh/pci.h for more information.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+static int __init pcibios_init(void)
+{
+	struct pci_channel *p;
+	struct pci_bus *bus;
+	int busno;
+
+#if 1
+	/* assign resources */
+	busno = 0;
+	for (p = board_pci_channels; p->pci_ops != NULL; p++) {
+		busno = pciauto_assign_resources(busno, p) + 1;
+	}
+#endif
+
+	/* scan the buses */
+	busno = 0;
+	for (p= board_pci_channels; p->pci_ops != NULL; p++) {
+		bus = pci_scan_bus(busno, p->pci_ops, p);
+		busno = bus->subordinate+1;
+	}
+
+	/* board-specific fixups */
+	pcibios_fixup_irqs();
+
+	return 0;
+}
+
+subsys_initcall(pcibios_init);
+
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4*resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= IORESOURCE_ROM_ENABLE;
+		new |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
+	
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+		       "%s/%d (%08x != %08x)\n", pci_name(dev), resource,
+		       new, check);
+	}
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ */
+void pcibios_align_resource(void *data, struct resource *res,
+			    resource_size_t size, resource_size_t align)
+{
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		if (start & 0x300) {
+			start = (start + 0x3ff) & ~0x3ff;
+			res->start = start;
+		}
+	}
+}
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for(idx=0; idx<6; idx++) {
+		if (!(mask & (1 << idx)))
+			continue;
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because "
+			       "of resource collisions\n", pci_name(dev));
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (dev->resource[PCI_ROM_RESOURCE].start)
+		cmd |= PCI_COMMAND_MEMORY;
+	if (cmd != old_cmd) {
+		printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n",
+		       pci_name(dev), old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+/*
+ *  If we set up a device for bus mastering, we need to check and set
+ *  the latency timer as it may not be properly set.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
diff --git a/arch/nios2/drivers/pci/setup-irq.c b/arch/nios2/drivers/pci/setup-irq.c
new file mode 100644
index 0000000..0fa8f98
--- /dev/null
+++ b/arch/nios2/drivers/pci/setup-irq.c
@@ -0,0 +1 @@
+#include "../../../../drivers/pci/setup-irq.c"
diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild
new file mode 100644
index 0000000..a31e9f7
--- /dev/null
+++ b/arch/nios2/include/asm/Kbuild
@@ -0,0 +1,3 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += traps.h ucontext.h
diff --git a/arch/nios2/include/asm/addrspace.h b/arch/nios2/include/asm/addrspace.h
new file mode 100644
index 0000000..2a905a1
--- /dev/null
+++ b/arch/nios2/include/asm/addrspace.h
@@ -0,0 +1,15 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 99 Ralf Baechle
+ * Copyright (C) 2000, 2002  Maciej W. Rozycki
+ * Copyright (C) 1990, 1999 by Silicon Graphics, Inc.
+ */
+#ifndef _ASM_NIOS2_ADDRSPACE_H
+#define _ASM_NIOS2_ADDRSPACE_H
+
+#include <asm/spaces.h>
+
+#endif /* _ASM_NIOS2_ADDRSPACE_H */
diff --git a/arch/nios2/include/asm/asm-macros.h b/arch/nios2/include/asm/asm-macros.h
new file mode 100644
index 0000000..9dda7cd
--- /dev/null
+++ b/arch/nios2/include/asm/asm-macros.h
@@ -0,0 +1,331 @@
+/*
+ * Macro used to simplify coding multi-line assembler.
+ * Some of the bit test macro can simplify down to one line
+ * depending on the mask value.
+ *
+ * Copyright (C) 2004 Microtronix Datacom Ltd.
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * ANDs reg2 with mask and places the result in reg1.
+ *
+ * You cannnot use the same register for reg1 & reg2.
+ */
+
+.macro ANDI32	reg1,reg2,mask
+ .if \mask & 0xffff
+  .if \mask & 0xffff0000
+	movhi	\reg1,%hi(\mask)
+	movui	\reg1,%lo(\mask)
+	and	\reg1,\reg1,\reg2
+  .else
+	andi	\reg1,\reg2,%lo(\mask)
+  .endif
+ .else
+	andhi	\reg1,\reg2,%hi(\mask)
+ .endif
+.endm
+
+/*
+ * ORs reg2 with mask and places the result in reg1.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro ORI32	reg1,reg2,mask
+ .if \mask & 0xffff
+  .if \mask & 0xffff0000
+	orhi	\reg1,\reg2,%hi(\mask)
+	ori	\reg1,\reg2,%lo(\mask)
+  .else
+	ori	\reg1,\reg2,%lo(\mask)
+  .endif
+ .else
+	orhi	\reg1,\reg2,%hi(\mask)
+ .endif
+.endm
+
+/*
+ * XORs reg2 with mask and places the result in reg1.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro XORI32	reg1,reg2,mask
+ .if \mask & 0xffff
+  .if \mask & 0xffff0000
+	xorhi	\reg1,\reg2,%hi(\mask)
+	xori	\reg1,\reg1,%lo(\mask)
+  .else
+	xori	\reg1,\reg2,%lo(\mask)
+  .endif
+ .else
+	xorhi	\reg1,\reg2,%hi(\mask)
+ .endif
+.endm
+
+/*
+ * This is a support macro for BTBZ & BTBNZ.  It checks
+ * the bit to make sure it is valid 32 value.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro BT	reg1,reg2,bit
+.if \bit > 31
+ .err 
+.else
+ .if \bit < 16
+	andi	\reg1,\reg2,(1 << \bit)
+ .else
+	andhi	\reg1,\reg2,(1 << (\bit - 16))
+ .endif
+.endif
+.endm
+
+/*
+ * Tests the bit in reg2 and branches to label if the
+ * bit is zero.  The result of the bit test is stored in reg1.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTBZ	reg1,reg2,bit,label
+	BT	\reg1,\reg2,\bit
+	beq	\reg1,r0,\label
+.endm
+
+/*
+ * Tests the bit in reg2 and branches to label if the
+ * bit is non-zero.  The result of the bit test is stored in reg1.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTBNZ	reg1,reg2,bit,label
+	BT	\reg1,\reg2,\bit
+	bne	\reg1,r0,\label
+.endm
+
+/*
+ * Tests the bit in reg2 and then compliments the bit in reg2.
+ * The result of the bit test is stored in reg1.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTC	reg1,reg2,bit
+.if \bit > 31
+ .err 
+.else
+ .if \bit < 16
+	andi	\reg1,\reg2,(1 << \bit)
+	xori	\reg2,\reg2,(1 << \bit)
+ .else
+	andhi	\reg1,\reg2,(1 << (\bit - 16))
+	xorhi	\reg2,\reg2,(1 << (\bit - 16))
+ .endif
+.endif
+.endm
+
+/*
+ * Tests the bit in reg2 and then sets the bit in reg2.
+ * The result of the bit test is stored in reg1.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTS	reg1,reg2,bit
+.if \bit > 31
+ .err 
+.else
+ .if \bit < 16
+	andi	\reg1,\reg2,(1 << \bit)
+	ori	\reg2,\reg2,(1 << \bit)
+ .else
+	andhi	\reg1,\reg2,(1 << (\bit - 16))
+	orhi	\reg2,\reg2,(1 << (\bit - 16))
+ .endif
+.endif
+.endm
+
+/*
+ * Tests the bit in reg2 and then resets the bit in reg2.
+ * The result of the bit test is stored in reg1.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTR	reg1,reg2,bit
+.if \bit > 31
+ .err 
+.else
+ .if \bit < 16
+	andi	\reg1,\reg2,(1 << \bit)
+	andi	\reg2,\reg2,%lo(~(1 << \bit))
+ .else
+	andhi	\reg1,\reg2,(1 << (\bit - 16))
+	andhi	\reg2,\reg2,%lo(~(1 << (\bit - 16)))
+ .endif
+.endif
+.endm
+
+/*
+ * Tests the bit in reg2 and then compliments the bit in reg2.
+ * The result of the bit test is stored in reg1.  If the 
+ * original bit was zero it branches to label.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTCBZ	reg1,reg2,bit,label
+	BTC	\reg1,\reg2,\bit
+	beq	\reg1,r0,\label
+.endm
+
+/*
+ * Tests the bit in reg2 and then compliments the bit in reg2.
+ * The result of the bit test is stored in reg1.  If the 
+ * original bit was non-zero it branches to label.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTCBNZ	reg1,reg2,bit,label
+	BTC	\reg1,\reg2,\bit
+	bne	\reg1,r0,\label
+.endm
+
+/*
+ * Tests the bit in reg2 and then sets the bit in reg2.
+ * The result of the bit test is stored in reg1.  If the 
+ * original bit was zero it branches to label.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTSBZ	reg1,reg2,bit,label
+	BTS	\reg1,\reg2,\bit
+	beq	\reg1,r0,\label
+.endm
+
+/*
+ * Tests the bit in reg2 and then sets the bit in reg2.
+ * The result of the bit test is stored in reg1.  If the 
+ * original bit was non-zero it branches to label.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTSBNZ	reg1,reg2,bit,label
+	BTS	\reg1,\reg2,\bit
+	bne	\reg1,r0,\label
+.endm
+
+/*
+ * Tests the bit in reg2 and then resets the bit in reg2.
+ * The result of the bit test is stored in reg1.  If the 
+ * original bit was zero it branches to label.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTRBZ	reg1,reg2,bit,label
+	BTR	\reg1,\reg2,\bit
+	bne	\reg1,r0,\label
+.endm
+
+/*
+ * Tests the bit in reg2 and then resets the bit in reg2.
+ * The result of the bit test is stored in reg1.  If the 
+ * original bit was non-zero it branches to label.
+ *
+ * It is NOT safe to use the same register for reg1 & reg2.
+ */
+
+.macro BTRBNZ	reg1,reg2,bit,label
+	BTR	\reg1,\reg2,\bit
+	bne	\reg1,r0,\label
+.endm
+
+/*
+ * Tests the bits in mask against reg2 stores the result in reg1.
+ * If the all the bits in the mask are zero it branches to label.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro TSTBZ	reg1,reg2,mask,label
+	ANDI32	\reg1,\reg2,\mask
+	beq	\reg1,r0,\label
+.endm
+
+/*
+ * Tests the bits in mask against reg2 stores the result in reg1.
+ * If the any of the bits in the mask are 1 it branches to label.
+ *
+ * It is safe to use the same register for reg1 & reg2.
+ */
+
+.macro TSTBNZ	reg1,reg2,mask,label
+	ANDI32	\reg1,\reg2,\mask
+	bne	\reg1,r0,\label
+.endm
+
+/*
+ * Pushes reg onto the stack.
+ */
+
+.macro PUSH	reg
+	addi	sp,sp,-4
+	stw	\reg,0(sp)
+.endm
+
+/*
+ * Pops the top of the stack into reg.
+ */
+
+.macro POP	reg
+	ldw	\reg,0(sp)
+	addi	sp,sp,4
+.endm
+
+/*
+ * Clears reg
+ */
+
+.macro CLR	reg
+	  mov	\reg,r0
+.endm
+
+/*
+ * The preprocessor macro does not work for
+ * the nios2 compiler. Undefine ENTRY and define
+ * a real assembler macro.
+ */
+#undef ENTRY
+#define ENTRY(name) ASM_ENTRY name
+
+.macro ASM_ENTRY name
+.globl \name
+__ALIGN
+  \name:
+.endm
diff --git a/arch/nios2/include/asm/asm-offsets.h b/arch/nios2/include/asm/asm-offsets.h
new file mode 100644
index 0000000..b6e7567
--- /dev/null
+++ b/arch/nios2/include/asm/asm-offsets.h
@@ -0,0 +1,97 @@
+#ifndef __ASM_OFFSETS_H__
+#define __ASM_OFFSETS_H__
+/*
+ * DO NOT MODIFY.
+ *
+ * This file was generated by Kbuild
+ *
+ */
+
+#define TASK_STATE 0 /* offsetof(struct task_struct, state)	#  */
+#define TASK_FLAGS 12 /* offsetof(struct task_struct, flags)	#  */
+#define TASK_PTRACE 16 /* offsetof(struct task_struct, ptrace)	#  */
+#define TASK_BLOCKED 460 /* offsetof(struct task_struct, blocked)	#  */
+#define TASK_THREAD 424 /* offsetof(struct task_struct, thread)	#  */
+#define TASK_MM 128 /* offsetof(struct task_struct, mm)	#  */
+#define TASK_ACTIVE_MM 132 /* offsetof(struct task_struct, active_mm)	#  */
+#define STAT_IRQ 64 /* offsetof(struct kernel_stat, irqs)	#  */
+#define CPUSTAT_SOFTIRQ_PENDING 0 /* offsetof(irq_cpustat_t, __softirq_pending)	#  */
+#define IRQ_HANDLER 0 /* offsetof(struct irq_hand, handler)	#  */
+#define IRQ_FLAGS 4 /* offsetof(struct irq_hand, flags)	#  */
+#define IRQ_DEV_ID 8 /* offsetof(struct irq_hand, dev_id)	#  */
+#define IRQ_DEVNAME 12 /* offsetof(struct irq_hand, devname)	#  */
+#define THREAD_KSP 4 /* offsetof(struct thread_struct, ksp)	#  */
+#define THREAD_KPSR 8 /* offsetof(struct thread_struct, kpsr)	#  */
+#define THREAD_FLAGS 12 /* offsetof(struct thread_struct, flags)	#  */
+#define PT_ORIG_R2 60 /* offsetof(struct pt_regs, orig_r2)	#  */
+#define PT_ORIG_R7 88 /* offsetof(struct pt_regs, orig_r7)	#  */
+#define PT_R1 32 /* offsetof(struct pt_regs, r1)	#  */
+#define PT_R2 36 /* offsetof(struct pt_regs, r2)	#  */
+#define PT_R3 40 /* offsetof(struct pt_regs, r3)	#  */
+#define PT_R4 44 /* offsetof(struct pt_regs, r4)	#  */
+#define PT_R5 48 /* offsetof(struct pt_regs, r5)	#  */
+#define PT_R6 52 /* offsetof(struct pt_regs, r6)	#  */
+#define PT_R7 56 /* offsetof(struct pt_regs, r7)	#  */
+#define PT_R8 0 /* offsetof(struct pt_regs, r8)	#  */
+#define PT_R9 4 /* offsetof(struct pt_regs, r9)	#  */
+#define PT_R10 8 /* offsetof(struct pt_regs, r10)	#  */
+#define PT_R11 12 /* offsetof(struct pt_regs, r11)	#  */
+#define PT_R12 16 /* offsetof(struct pt_regs, r12)	#  */
+#define PT_R13 20 /* offsetof(struct pt_regs, r13)	#  */
+#define PT_R14 24 /* offsetof(struct pt_regs, r14)	#  */
+#define PT_R15 28 /* offsetof(struct pt_regs, r15)	#  */
+#define PT_EA 84 /* offsetof(struct pt_regs, ea)	#  */
+#define PT_RA 64 /* offsetof(struct pt_regs, ra)	#  */
+#define PT_FP 68 /* offsetof(struct pt_regs, fp)	#  */
+#define PT_SP 72 /* offsetof(struct pt_regs, sp)	#  */
+#define PT_GP 76 /* offsetof(struct pt_regs, gp)	#  */
+#define PT_ESTATUS 80 /* offsetof(struct pt_regs, estatus)	#  */
+#define PT_REGS_SIZE 92 /* sizeof(struct pt_regs)	#  */
+#define SW_R16 0 /* offsetof(struct switch_stack, r16)	#  */
+#define SW_R17 4 /* offsetof(struct switch_stack, r17)	#  */
+#define SW_R18 8 /* offsetof(struct switch_stack, r18)	#  */
+#define SW_R19 12 /* offsetof(struct switch_stack, r19)	#  */
+#define SW_R20 16 /* offsetof(struct switch_stack, r20)	#  */
+#define SW_R21 20 /* offsetof(struct switch_stack, r21)	#  */
+#define SW_R22 24 /* offsetof(struct switch_stack, r22)	#  */
+#define SW_R23 28 /* offsetof(struct switch_stack, r23)	#  */
+#define SW_FP 32 /* offsetof(struct switch_stack, fp)	#  */
+#define SW_GP 36 /* offsetof(struct switch_stack, gp)	#  */
+#define SW_RA 40 /* offsetof(struct switch_stack, ra)	#  */
+#define SWITCH_STACK_SIZE 44 /* sizeof(struct switch_stack)	#  */
+#define ESTATUS_EU_ASM 2 /* ESTATUS_EU	#  */
+#define NIOS2_STATUS_PIE_MSK_ASM 1 /* NIOS2_STATUS_PIE_MSK	#  */
+#define NIOS2_STATUS_PIE_OFST_ASM 0 /* NIOS2_STATUS_PIE_OFST	#  */
+#define NIOS2_STATUS_U_MSK_ASM 2 /* NIOS2_STATUS_U_MSK	#  */
+#define NIOS2_STATUS_U_OFST_ASM 1 /* NIOS2_STATUS_U_OFST	#  */
+#define STAT_IRQ 64 /* offsetof(struct kernel_stat, irqs)	#  */
+#define TI_TASK 0 /* offsetof(struct thread_info, task)	#  */
+#define TI_EXECDOMAIN 4 /* offsetof(struct thread_info, exec_domain)	#  */
+#define TI_FLAGS 8 /* offsetof(struct thread_info, flags)	#  */
+#define TI_CPU 12 /* offsetof(struct thread_info, cpu)	#  */
+#define TI_PREEMPT_COUNT 16 /* offsetof(struct thread_info, preempt_count)	#  */
+#define PREEMPT_ACTIVE_ASM 268435456 /* PREEMPT_ACTIVE	#  */
+#define THREAD_SIZE_ASM 4096 /* THREAD_SIZE	#  */
+#define TIF_SYSCALL_TRACE_ASM 31 /* TIF_SYSCALL_TRACE	#  */
+#define TIF_NOTIFY_RESUME_ASM 1 /* TIF_NOTIFY_RESUME	#  */
+#define TIF_SIGPENDING_ASM 2 /* TIF_SIGPENDING	#  */
+#define TIF_NEED_RESCHED_ASM 3 /* TIF_NEED_RESCHED	#  */
+#define TIF_POLLING_NRFLAG_ASM 17 /* TIF_POLLING_NRFLAG	#  */
+#define _TIF_SYSCALL_TRACE_ASM -2147483648 /* _TIF_SYSCALL_TRACE	#  */
+#define _TIF_NOTIFY_RESUME_ASM 2 /* _TIF_NOTIFY_RESUME	#  */
+#define _TIF_SIGPENDING_ASM 4 /* _TIF_SIGPENDING	#  */
+#define _TIF_NEED_RESCHED_ASM 8 /* _TIF_NEED_RESCHED	#  */
+#define _TIF_POLLING_NRFLAG_ASM 131072 /* _TIF_POLLING_NRFLAG	#  */
+#define _TIF_WORK_MASK_ASM 65487 /* _TIF_WORK_MASK	#  */
+#define STAT_TLB_FAST_HANDLER 36 /* offsetof(struct tlb_stat, tlb_fast_handler)	#  */
+#define LINUX_SDRAM_START 268435456 /* DDR2_TOP_BASE	#  */
+#define LINUX_SDRAM_END 402653184 /* DDR2_TOP_BASE+DDR2_TOP_SPAN	#  */
+#define NIOS2_ICACHE_SIZE 32768 /* ICACHE_SIZE	#  */
+#define NIOS2_ICACHE_LINE_SIZE 32 /* ICACHE_LINE_SIZE	#  */
+#define NIOS2_DCACHE_SIZE 32768 /* DCACHE_SIZE	#  */
+#define NIOS2_DCACHE_LINE_SIZE 32 /* DCACHE_LINE_SIZE	#  */
+#define KERNEL_REGION_BASE_ASM -1073741824 /* KERNEL_REGION_BASE	#  */
+#define CPU_EXCEPT_VIRT_ADDRESS_ASM -805306336 /* EXCEPTION_ADDR	#  */
+#define CPU_FAST_TLB_MISS_EXCEPTION_VIRT_ADDR_ASM -939527168 /* FAST_TLB_MISS_EXCEPTION_ADDR	#  */
+
+#endif
diff --git a/arch/nios2/include/asm/atomic.h b/arch/nios2/include/asm/atomic.h
new file mode 100644
index 0000000..f0cc1f8
--- /dev/null
+++ b/arch/nios2/include/asm/atomic.h
@@ -0,0 +1 @@
+#include <asm-generic/atomic.h>
diff --git a/arch/nios2/include/asm/auxvec.h b/arch/nios2/include/asm/auxvec.h
new file mode 100644
index 0000000..41fa68b
--- /dev/null
+++ b/arch/nios2/include/asm/auxvec.h
@@ -0,0 +1 @@
+#include <asm-generic/auxvec.h>
diff --git a/arch/nios2/include/asm/bitops.h b/arch/nios2/include/asm/bitops.h
new file mode 100644
index 0000000..a72468f
--- /dev/null
+++ b/arch/nios2/include/asm/bitops.h
@@ -0,0 +1 @@
+#include <asm-generic/bitops.h>
diff --git a/arch/nios2/include/asm/bitsperlong.h b/arch/nios2/include/asm/bitsperlong.h
new file mode 100644
index 0000000..6dc0bb0
--- /dev/null
+++ b/arch/nios2/include/asm/bitsperlong.h
@@ -0,0 +1 @@
+#include <asm-generic/bitsperlong.h>
diff --git a/arch/nios2/include/asm/bug.h b/arch/nios2/include/asm/bug.h
new file mode 100644
index 0000000..b12fd89
--- /dev/null
+++ b/arch/nios2/include/asm/bug.h
@@ -0,0 +1 @@
+#include <asm-generic/bug.h>
diff --git a/arch/nios2/include/asm/bugs.h b/arch/nios2/include/asm/bugs.h
new file mode 100644
index 0000000..61791e1
--- /dev/null
+++ b/arch/nios2/include/asm/bugs.h
@@ -0,0 +1 @@
+#include <asm-generic/bugs.h>
diff --git a/arch/nios2/include/asm/byteorder.h b/arch/nios2/include/asm/byteorder.h
new file mode 100644
index 0000000..9558416
--- /dev/null
+++ b/arch/nios2/include/asm/byteorder.h
@@ -0,0 +1 @@
+#include <linux/byteorder/little_endian.h>
diff --git a/arch/nios2/include/asm/cache.h b/arch/nios2/include/asm/cache.h
new file mode 100644
index 0000000..88c6151
--- /dev/null
+++ b/arch/nios2/include/asm/cache.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2004 Microtronix Datacom Ltd.
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef _ASM_NIOS2_CACHE_H
+#define _ASM_NIOS2_CACHE_H
+
+#include <asm/nios.h>
+
+/* bytes per L1 cache line */
+#define        L1_CACHE_BYTES	ICACHE_LINE_SIZE 	/* 32, this need to be at least 1 */
+#define L1_CACHE_ALIGN(x)	(((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
+#define L1_CACHE_SHIFT	ICACHE_LINE_SIZE_LOG2
+
+
+#define __cacheline_aligned
+#define ____cacheline_aligned
+
+#define SMP_CACHE_SHIFT		L1_CACHE_SHIFT
+#define SMP_CACHE_BYTES		L1_CACHE_BYTES
+
+#endif
diff --git a/arch/nios2/include/asm/cachectl.h b/arch/nios2/include/asm/cachectl.h
new file mode 100644
index 0000000..4729667
--- /dev/null
+++ b/arch/nios2/include/asm/cachectl.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2004 Microtronix Datacom Ltd.
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _ASM_NIOS2_CACHECTL_H
+#define _ASM_NIOS2_CACHECTL_H
+
+/* Definitions for the cacheflush system call.  */
+
+#define FLUSH_SCOPE_LINE    1	/* Flush a cache line */
+#define FLUSH_SCOPE_PAGE    2	/* Flush a page */
+#define FLUSH_SCOPE_ALL     3	/* Flush the whole cache -- superuser only */
+
+#define FLUSH_CACHE_DATA    1	/* Writeback and flush data cache */
+#define FLUSH_CACHE_INSN    2	/* Flush instruction cache */
+#define FLUSH_CACHE_BOTH    3	/* Flush both caches */
+
+#endif /* _ASM_NIOS2_CACHECTL_H */
diff --git a/arch/nios2/include/asm/cacheflush.h b/arch/nios2/include/asm/cacheflush.h
new file mode 100644
index 0000000..b685169
--- /dev/null
+++ b/arch/nios2/include/asm/cacheflush.h
@@ -0,0 +1,56 @@
+#ifndef _ASM_NIOS2_CACHEFLUSH_H
+#define _ASM_NIOS2_CACHEFLUSH_H
+
+/*
+ * Ported from m68knommu.
+ *
+ * (C) Copyright 2003, Microtronix Datacom Ltd.
+ * (C) Copyright 2000-2002, Greg Ungerer <gerg@snapgear.com>
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/mm.h>
+#include <asm/page.h>
+
+extern void flush_cache_all(void);
+extern void flush_cache_dup_mm(struct mm_struct *mm);
+extern void flush_cache_mm(struct mm_struct *mm);
+extern void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn);
+extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+extern void flush_dcache_page(struct page* page);
+extern void flush_dcache_range(unsigned long start, unsigned long end);
+extern void flush_icache_page(struct vm_area_struct *vma, struct page* page);
+extern void flush_icache_range(unsigned long start,unsigned long end);
+extern void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
+                               unsigned long user_vaddr,
+                               void *dst, void *src, int len);
+
+extern void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+                              unsigned long user_vaddr,
+                              void *dst, void *src, int len);
+
+
+#define flush_cache_vmap(start, end) flush_dcache_range(start, end)
+#define flush_cache_vunmap(start, end) flush_dcache_range(start, end)
+
+#define flush_dcache_mmap_lock(mapping)         do { } while(0)
+#define flush_dcache_mmap_unlock(mapping)       do { } while(0)
+
+
+#endif /* _ASM_NIOS2_CACHEFLUSH_H */
diff --git a/arch/nios2/include/asm/checksum.h b/arch/nios2/include/asm/checksum.h
new file mode 100644
index 0000000..adbb5e6
--- /dev/null
+++ b/arch/nios2/include/asm/checksum.h
@@ -0,0 +1 @@
+#include <asm-generic/checksum.h>
diff --git a/arch/nios2/include/asm/cprefix.h b/arch/nios2/include/asm/cprefix.h
new file mode 100644
index 0000000..dc722b8
--- /dev/null
+++ b/arch/nios2/include/asm/cprefix.h
@@ -0,0 +1,38 @@
+/* cprefix.h:  This file is included by assembly source which needs
+ *             to know what the c-label prefixes are. The newer versions
+ *	       of cpp that come with gcc predefine such things to help
+ *	       us out. The reason this stuff is needed is to make
+ *	       solaris compiles of the kernel work.
+ *
+ * Copyright (C) 2004 Microtronix Datacom Ltd.
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef _ASM_NIOS2_CPREFIX_H
+#define _ASM_NIOS2_CPREFIX_H
+
+#define C_LABEL_PREFIX
+
+#define CONCAT(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a##b
+
+#define C_LABEL(name) CONCAT(C_LABEL_PREFIX, name)
+
+#endif /* !(_ASM_NIOS2_CPREFIX_H) */
diff --git a/arch/nios2/include/asm/cputime.h b/arch/nios2/include/asm/cputime.h
new file mode 100644
index 0000000..6d68ad7
--- /dev/null
+++ b/arch/nios2/include/asm/cputime.h
@@ -0,0 +1 @@
+#include <asm-generic/cputime.h>
diff --git a/arch/nios2/include/asm/current.h b/arch/nios2/include/asm/current.h
new file mode 100644
index 0000000..4c51401
--- /dev/null
+++ b/arch/nios2/include/asm/current.h
@@ -0,0 +1 @@
+#include <asm-generic/current.h>
diff --git a/arch/nios2/include/asm/custom_fpga.h b/arch/nios2/include/asm/custom_fpga.h
new file mode 100644
index 0000000..5a1fb6c
--- /dev/null
+++ b/arch/nios2/include/asm/custom_fpga.h
@@ -0,0 +1,625 @@
+#ifndef _ALTERA_CPU_H_
+#define _ALTERA_CPU_H_
+
+/*
+ * This file was automatically generated by the swinfo2header utility.
+ *
+ * Created from SOPC Builder system 'cycloneIII_embedded_evaluation_kit_web_server_sopc' in
+ * file './cycloneIII_embedded_evaluation_kit_web_server_sopc.sopcinfo'.
+ */
+
+/*
+ * This file contains macros for module 'cpu' and devices
+ * connected to the following masters:
+ *   instruction_master
+ *   tightly_coupled_instruction_master_0
+ *   data_master
+ *   tightly_coupled_data_master_0
+ *
+ * Do not #include this header file and another header file created for a
+ * different module or master group at the same time.
+ * Doing so may result in duplicate #defines.
+ * Instead, use the system header file which has #defines with unique names.
+ */
+
+/*
+ * Macros for module 'cpu', class 'altera_nios2'.
+ * The macros have no prefix.
+ */
+#define CPU_IMPLEMENTATION "fast"
+#define CPU_FREQ 100000000u
+#define ICACHE_LINE_SIZE 32
+#define ICACHE_LINE_SIZE_LOG2 5
+#define ICACHE_SIZE 4096
+#define DCACHE_LINE_SIZE 32
+#define DCACHE_LINE_SIZE_LOG2 5
+#define DCACHE_SIZE 2048
+#define INITDA_SUPPORTED 
+#define FLUSHDA_SUPPORTED 
+#define HAS_JMPI_INSTRUCTION 
+#define MMU_PRESENT 
+#define KERNEL_REGION_BASE 0xc0000000
+#define IO_REGION_BASE 0xe0000000
+#define KERNEL_MMU_REGION_BASE 0x80000000
+#define USER_REGION_BASE 0x0
+#define PROCESS_ID_NUM_BITS 10
+#define TLB_NUM_WAYS 16
+#define TLB_NUM_WAYS_LOG2 4
+#define TLB_PTR_SZ 8
+#define TLB_NUM_ENTRIES 256
+#define FAST_TLB_MISS_EXCEPTION_ADDR 0xc6000800
+#define EXCEPTION_ADDR 0xc5000020
+#define RESET_ADDR 0xc4000000
+#define BREAK_ADDR 0xc6000020
+#define HAS_DEBUG_STUB 
+#define HAS_DEBUG_CORE 1
+#define HAS_ILLEGAL_INSTRUCTION_EXCEPTION 
+#define HAS_ILLEGAL_MEMORY_ACCESS_EXCEPTION 
+#define HAS_EXTRA_EXCEPTION_INFO 
+#define CPU_ID_SIZE 1
+#define CPU_ID_VALUE 0x0
+#define HARDWARE_DIVIDE_PRESENT 0
+#define HARDWARE_MULTIPLY_PRESENT 1
+#define HARDWARE_MULX_PRESENT 0
+#define INST_ADDR_WIDTH 27
+#define DATA_ADDR_WIDTH 28
+
+/*
+ * Macros for device 'ddr_sdram', class 'altmemddr'
+ * The macros are prefixed with 'DDR_SDRAM_'.
+ * The prefix is the slave descriptor.
+ */
+#define DDR_SDRAM_COMPONENT_TYPE altmemddr
+#define DDR_SDRAM_COMPONENT_NAME ddr_sdram
+#define DDR_SDRAM_BASE 0x0
+#define DDR_SDRAM_SPAN 33554432u
+
+/*
+ * Macros for device 'lcd_sgdma', class 'altera_avalon_sgdma'
+ * The macros are prefixed with 'LCD_SGDMA_'.
+ * The prefix is the slave descriptor.
+ */
+#define LCD_SGDMA_COMPONENT_TYPE altera_avalon_sgdma
+#define LCD_SGDMA_COMPONENT_NAME lcd_sgdma
+#define LCD_SGDMA_BASE 0x2000000
+#define LCD_SGDMA_SPAN 1024u
+#define LCD_SGDMA_IRQ 2
+#define LCD_SGDMA_READ_BLOCK_DATA_WIDTH 64
+#define LCD_SGDMA_WRITE_BLOCK_DATA_WIDTH 64
+#define LCD_SGDMA_STREAM_DATA_WIDTH 64
+#define LCD_SGDMA_ADDRESS_WIDTH 32
+#define LCD_SGDMA_HAS_READ_BLOCK 1
+#define LCD_SGDMA_HAS_WRITE_BLOCK 0
+#define LCD_SGDMA_READ_BURSTCOUNT_WIDTH 4
+#define LCD_SGDMA_WRITE_BURSTCOUNT_WIDTH 4
+#define LCD_SGDMA_BURST_TRANSFER 0
+#define LCD_SGDMA_ALWAYS_DO_MAX_BURST 1
+#define LCD_SGDMA_DESCRIPTOR_READ_BURST 0
+#define LCD_SGDMA_UNALIGNED_TRANSFER 0
+#define LCD_SGDMA_CONTROL_SLAVE_DATA_WIDTH 32
+#define LCD_SGDMA_CONTROL_SLAVE_ADDRESS_WIDTH 8
+#define LCD_SGDMA_DESC_DATA_WIDTH 32
+#define LCD_SGDMA_CHAIN_WRITEBACK_DATA_WIDTH 32
+#define LCD_SGDMA_STATUS_TOKEN_DATA_WIDTH 24
+#define LCD_SGDMA_BYTES_TO_TRANSFER_DATA_WIDTH 16
+#define LCD_SGDMA_BURST_DATA_WIDTH 8
+#define LCD_SGDMA_CONTROL_DATA_WIDTH 8
+#define LCD_SGDMA_ATLANTIC_CHANNEL_DATA_WIDTH 4
+#define LCD_SGDMA_COMMAND_FIFO_DATA_WIDTH 104
+#define LCD_SGDMA_SYMBOLS_PER_BEAT 8
+#define LCD_SGDMA_IN_ERROR_WIDTH 0
+#define LCD_SGDMA_OUT_ERROR_WIDTH 0
+
+/*
+ * Macros for device 'ddr_sdram', class 'altmemddr'
+ * Path to the device is from the master group 'lcd_sgdma_m_read'.
+ * The macros are prefixed with 'LCD_SGDMA_M_READ_DDR_SDRAM_'.
+ * The prefix is the master group descriptor and the slave descriptor.
+ */
+#define LCD_SGDMA_M_READ_DDR_SDRAM_COMPONENT_TYPE altmemddr
+#define LCD_SGDMA_M_READ_DDR_SDRAM_COMPONENT_NAME ddr_sdram
+#define LCD_SGDMA_M_READ_DDR_SDRAM_BASE 0x0
+#define LCD_SGDMA_M_READ_DDR_SDRAM_SPAN 33554432u
+
+/*
+ * Macros for device 'ext_flash', class 'altera_avalon_cfi_flash'
+ * The macros are prefixed with 'EXT_FLASH_'.
+ * The prefix is the slave descriptor.
+ */
+#define EXT_FLASH_COMPONENT_TYPE altera_avalon_cfi_flash
+#define EXT_FLASH_COMPONENT_NAME ext_flash
+#define EXT_FLASH_BASE 0x4000000
+#define EXT_FLASH_SPAN 16777216u
+#define EXT_FLASH_SETUP_VALUE 25
+#define EXT_FLASH_WAIT_VALUE 70
+#define EXT_FLASH_HOLD_VALUE 20
+#define EXT_FLASH_TIMING_UNITS "ns"
+#define EXT_FLASH_SIZE 16777216u
+
+/*
+ * Macros for device 'ssram', class 'altera_avalon_cy7c1380_ssram'
+ * The macros are prefixed with 'SSRAM_'.
+ * The prefix is the slave descriptor.
+ */
+#define SSRAM_COMPONENT_TYPE altera_avalon_cy7c1380_ssram
+#define SSRAM_COMPONENT_NAME ssram
+#define SSRAM_BASE 0x5000000
+#define SSRAM_SPAN 1048576u
+#define SSRAM_SRAM_MEMORY_SIZE 1
+#define SSRAM_SRAM_MEMORY_UNITS 1048576
+#define SSRAM_SSRAM_DATA_WIDTH 32
+#define SSRAM_SSRAM_READ_LATENCY 2
+
+/*
+ * Macros for device 'onchip_memory2_0', class 'altera_avalon_onchip_memory2'
+ * The macros are prefixed with 'ONCHIP_MEMORY2_0_'.
+ * The prefix is the slave descriptor.
+ */
+#define ONCHIP_MEMORY2_0_COMPONENT_TYPE altera_avalon_onchip_memory2
+#define ONCHIP_MEMORY2_0_COMPONENT_NAME onchip_memory2_0
+#define ONCHIP_MEMORY2_0_BASE 0x6000800
+#define ONCHIP_MEMORY2_0_SPAN 1024u
+#define ONCHIP_MEMORY2_0_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0
+#define ONCHIP_MEMORY2_0_INIT_CONTENTS_FILE "onchip_memory2_0"
+#define ONCHIP_MEMORY2_0_NON_DEFAULT_INIT_FILE_ENABLED 0
+#define ONCHIP_MEMORY2_0_GUI_RAM_BLOCK_TYPE "Automatic"
+#define ONCHIP_MEMORY2_0_WRITABLE 1
+#define ONCHIP_MEMORY2_0_DUAL_PORT 1
+#define ONCHIP_MEMORY2_0_SIZE_VALUE 1024u
+#define ONCHIP_MEMORY2_0_SIZE_MULTIPLE 1
+#define ONCHIP_MEMORY2_0_CONTENTS_INFO ""
+#define ONCHIP_MEMORY2_0_RAM_BLOCK_TYPE "Auto"
+#define ONCHIP_MEMORY2_0_INIT_MEM_CONTENT 1
+#define ONCHIP_MEMORY2_0_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0
+#define ONCHIP_MEMORY2_0_INSTANCE_ID "NONE"
+#define ONCHIP_MEMORY2_0_READ_DURING_WRITE_MODE "DONT_CARE"
+
+/*
+ * Macros for device 'mmc_spi', class 'altera_avalon_spi'
+ * The macros are prefixed with 'MMC_SPI_'.
+ * The prefix is the slave descriptor.
+ */
+#define MMC_SPI_COMPONENT_TYPE altera_avalon_spi
+#define MMC_SPI_COMPONENT_NAME mmc_spi
+#define MMC_SPI_BASE 0x8000000
+#define MMC_SPI_SPAN 256u
+#define MMC_SPI_IRQ 3
+#define MMC_SPI_DATABITS 8
+#define MMC_SPI_DATAWIDTH 16
+#define MMC_SPI_TARGETCLOCK 20000000u
+#define MMC_SPI_CLOCKUNITS "Hz"
+#define MMC_SPI_CLOCKMULT 1
+#define MMC_SPI_NUMSLAVES 1
+#define MMC_SPI_ISMASTER 1
+#define MMC_SPI_CLOCKPOLARITY 0
+#define MMC_SPI_CLOCKPHASE 0
+#define MMC_SPI_LSBFIRST 0
+#define MMC_SPI_EXTRADELAY 0
+#define MMC_SPI_TARGETSSDELAY "0.0"
+#define MMC_SPI_DELAYUNITS "ns"
+#define MMC_SPI_DELAYMULT "1.0E-9"
+#define MMC_SPI_PREFIX "spi_"
+
+/*
+ * Macros for device 'sys_clk_timer', class 'altera_avalon_timer'
+ * The macros are prefixed with 'SYS_CLK_TIMER_'.
+ * The prefix is the slave descriptor.
+ */
+#define SYS_CLK_TIMER_COMPONENT_TYPE altera_avalon_timer
+#define SYS_CLK_TIMER_COMPONENT_NAME sys_clk_timer
+#define SYS_CLK_TIMER_BASE 0x8000100
+#define SYS_CLK_TIMER_SPAN 256u
+#define SYS_CLK_TIMER_IRQ 8
+#define SYS_CLK_TIMER_ALWAYS_RUN 0
+#define SYS_CLK_TIMER_FIXED_PERIOD 0
+#define SYS_CLK_TIMER_SNAPSHOT 1
+#define SYS_CLK_TIMER_PERIOD 10.0
+#define SYS_CLK_TIMER_PERIOD_UNITS "ms"
+#define SYS_CLK_TIMER_RESET_OUTPUT 0
+#define SYS_CLK_TIMER_TIMEOUT_PULSE_OUTPUT 0
+#define SYS_CLK_TIMER_FREQ 60000000u
+#define SYS_CLK_TIMER_LOAD_VALUE 599999ULL
+#define SYS_CLK_TIMER_COUNTER_SIZE 32
+#define SYS_CLK_TIMER_MULT 0.0010
+#define SYS_CLK_TIMER_TICKS_PER_SEC 100u
+
+/*
+ * Macros for device 'sysid', class 'altera_avalon_sysid'
+ * The macros are prefixed with 'SYSID_'.
+ * The prefix is the slave descriptor.
+ */
+#define SYSID_COMPONENT_TYPE altera_avalon_sysid
+#define SYSID_COMPONENT_NAME sysid
+#define SYSID_BASE 0x8000200
+#define SYSID_SPAN 64u
+#define SYSID_ID 324290607u
+#define SYSID_TIMESTAMP 1245382019u
+
+/*
+ * Macros for device 'ps2_0', class 'altera_up_avalon_ps2_classic'
+ * The macros are prefixed with 'PS2_0_'.
+ * The prefix is the slave descriptor.
+ */
+#define PS2_0_COMPONENT_TYPE altera_up_avalon_ps2_classic
+#define PS2_0_COMPONENT_NAME ps2_0
+#define PS2_0_BASE 0x8000240
+#define PS2_0_SPAN 8u
+#define PS2_0_IRQ 1
+
+/*
+ * Macros for device 'gpio_0', class 'gpio'
+ * The macros are prefixed with 'GPIO_0_'.
+ * The prefix is the slave descriptor.
+ */
+#define GPIO_0_COMPONENT_TYPE gpio
+#define GPIO_0_COMPONENT_NAME gpio_0
+#define GPIO_0_BASE 0x8000300
+#define GPIO_0_SPAN 256u
+
+/*
+ * Macros for device 'uart', class 'altera_avalon_uart'
+ * The macros are prefixed with 'UART_'.
+ * The prefix is the slave descriptor.
+ */
+#define UART_COMPONENT_TYPE altera_avalon_uart
+#define UART_COMPONENT_NAME uart
+#define UART_BASE 0x8000400
+#define UART_SPAN 256u
+#define UART_IRQ 5
+#define UART_BAUD 115200
+#define UART_DATA_BITS 8
+#define UART_FIXED_BAUD 1
+#define UART_PARITY 'N'
+#define UART_STOP_BITS 1
+#define UART_SYNC_REG_DEPTH 2
+#define UART_USE_CTS_RTS 0
+#define UART_USE_EOP_REGISTER 0
+#define UART_SIM_TRUE_BAUD 0
+#define UART_SIM_CHAR_STREAM ""
+#define UART_FREQ 60000000u
+
+/*
+ * Macros for device 'jtag_uart', class 'altera_avalon_jtag_uart'
+ * The macros are prefixed with 'JTAG_UART_'.
+ * The prefix is the slave descriptor.
+ */
+#define JTAG_UART_COMPONENT_TYPE altera_avalon_jtag_uart
+#define JTAG_UART_COMPONENT_NAME jtag_uart
+#define JTAG_UART_BASE 0x8002000
+#define JTAG_UART_SPAN 64u
+#define JTAG_UART_IRQ 10
+#define JTAG_UART_WRITE_DEPTH 8
+#define JTAG_UART_READ_DEPTH 8
+#define JTAG_UART_WRITE_THRESHOLD 4
+#define JTAG_UART_READ_THRESHOLD 4
+
+/*
+ * Macros for device 'button_pio', class 'altera_avalon_pio'
+ * The macros are prefixed with 'BUTTON_PIO_'.
+ * The prefix is the slave descriptor.
+ */
+#define BUTTON_PIO_COMPONENT_TYPE altera_avalon_pio
+#define BUTTON_PIO_COMPONENT_NAME button_pio
+#define BUTTON_PIO_BASE 0x8004000
+#define BUTTON_PIO_SPAN 128u
+#define BUTTON_PIO_IRQ 12
+#define BUTTON_PIO_DO_TEST_BENCH_WIRING 1
+#define BUTTON_PIO_DRIVEN_SIM_VALUE 0xf
+#define BUTTON_PIO_HAS_TRI 0
+#define BUTTON_PIO_HAS_OUT 0
+#define BUTTON_PIO_HAS_IN 1
+#define BUTTON_PIO_CAPTURE 1
+#define BUTTON_PIO_BIT_CLEARING_EDGE_REGISTER 0
+#define BUTTON_PIO_BIT_MODIFYING_OUTPUT_REGISTER 0
+#define BUTTON_PIO_DATA_WIDTH 4
+#define BUTTON_PIO_RESET_VALUE 0x0
+#define BUTTON_PIO_EDGE_TYPE "RISING"
+#define BUTTON_PIO_IRQ_TYPE "EDGE"
+#define BUTTON_PIO_FREQ 60000000u
+
+/*
+ * Macros for device 'touch_panel_pen_irq_n', class 'altera_avalon_pio'
+ * The macros are prefixed with 'TOUCH_PANEL_PEN_IRQ_N_'.
+ * The prefix is the slave descriptor.
+ */
+#define TOUCH_PANEL_PEN_IRQ_N_COMPONENT_TYPE altera_avalon_pio
+#define TOUCH_PANEL_PEN_IRQ_N_COMPONENT_NAME touch_panel_pen_irq_n
+#define TOUCH_PANEL_PEN_IRQ_N_BASE 0x8010000
+#define TOUCH_PANEL_PEN_IRQ_N_SPAN 128u
+#define TOUCH_PANEL_PEN_IRQ_N_IRQ 14
+#define TOUCH_PANEL_PEN_IRQ_N_DO_TEST_BENCH_WIRING 0
+#define TOUCH_PANEL_PEN_IRQ_N_DRIVEN_SIM_VALUE 0x0
+#define TOUCH_PANEL_PEN_IRQ_N_HAS_TRI 0
+#define TOUCH_PANEL_PEN_IRQ_N_HAS_OUT 0
+#define TOUCH_PANEL_PEN_IRQ_N_HAS_IN 1
+#define TOUCH_PANEL_PEN_IRQ_N_CAPTURE 1
+#define TOUCH_PANEL_PEN_IRQ_N_BIT_CLEARING_EDGE_REGISTER 0
+#define TOUCH_PANEL_PEN_IRQ_N_BIT_MODIFYING_OUTPUT_REGISTER 0
+#define TOUCH_PANEL_PEN_IRQ_N_DATA_WIDTH 1
+#define TOUCH_PANEL_PEN_IRQ_N_RESET_VALUE 0x0
+#define TOUCH_PANEL_PEN_IRQ_N_EDGE_TYPE "FALLING"
+#define TOUCH_PANEL_PEN_IRQ_N_IRQ_TYPE "EDGE"
+#define TOUCH_PANEL_PEN_IRQ_N_FREQ 60000000u
+
+/*
+ * Macros for device 'touch_panel_spi', class 'altera_avalon_spi'
+ * The macros are prefixed with 'TOUCH_PANEL_SPI_'.
+ * The prefix is the slave descriptor.
+ */
+#define TOUCH_PANEL_SPI_COMPONENT_TYPE altera_avalon_spi
+#define TOUCH_PANEL_SPI_COMPONENT_NAME touch_panel_spi
+#define TOUCH_PANEL_SPI_BASE 0x8011000
+#define TOUCH_PANEL_SPI_SPAN 256u
+#define TOUCH_PANEL_SPI_IRQ 16
+#define TOUCH_PANEL_SPI_DATABITS 8
+#define TOUCH_PANEL_SPI_DATAWIDTH 16
+#define TOUCH_PANEL_SPI_TARGETCLOCK 32000u
+#define TOUCH_PANEL_SPI_CLOCKUNITS "Hz"
+#define TOUCH_PANEL_SPI_CLOCKMULT 1
+#define TOUCH_PANEL_SPI_NUMSLAVES 1
+#define TOUCH_PANEL_SPI_ISMASTER 1
+#define TOUCH_PANEL_SPI_CLOCKPOLARITY 0
+#define TOUCH_PANEL_SPI_CLOCKPHASE 0
+#define TOUCH_PANEL_SPI_LSBFIRST 0
+#define TOUCH_PANEL_SPI_EXTRADELAY 0
+#define TOUCH_PANEL_SPI_TARGETSSDELAY "0.0"
+#define TOUCH_PANEL_SPI_DELAYUNITS "ns"
+#define TOUCH_PANEL_SPI_DELAYMULT "1.0E-9"
+#define TOUCH_PANEL_SPI_PREFIX "spi_"
+
+/*
+ * Macros for device 'performance_counter', class 'altera_avalon_performance_counter'
+ * The macros are prefixed with 'PERFORMANCE_COUNTER_'.
+ * The prefix is the slave descriptor.
+ */
+#define PERFORMANCE_COUNTER_COMPONENT_TYPE altera_avalon_performance_counter
+#define PERFORMANCE_COUNTER_COMPONENT_NAME performance_counter
+#define PERFORMANCE_COUNTER_BASE 0x8020000
+#define PERFORMANCE_COUNTER_SPAN 256u
+#define PERFORMANCE_COUNTER_HOW_MANY_SECTIONS 1
+
+/*
+ * Macros for device 'pll', class 'altera_avalon_pll'
+ * The macros are prefixed with 'PLL_'.
+ * The prefix is the slave descriptor.
+ */
+#define PLL_COMPONENT_TYPE altera_avalon_pll
+#define PLL_COMPONENT_NAME pll
+#define PLL_BASE 0x8200000
+#define PLL_SPAN 256u
+#define PLL_ARESET "None"
+#define PLL_PFDENA "None"
+#define PLL_LOCKED "None"
+#define PLL_PLLENA "None"
+#define PLL_SCANCLK "None"
+#define PLL_SCANDATA "None"
+#define PLL_SCANREAD "None"
+#define PLL_SCANWRITE "None"
+#define PLL_SCANCLKENA "None"
+#define PLL_SCANACLR "None"
+#define PLL_SCANDATAOUT "None"
+#define PLL_SCANDONE "None"
+#define PLL_CONFIGUPDATE "None"
+#define PLL_PHASECOUNTERSELECT "None"
+#define PLL_PHASEDONE "None"
+#define PLL_PHASEUPDOWN "None"
+#define PLL_PHASESTEP "None"
+
+/*
+ * Macros for device 'remote_update', class 'altera_avalon_remote_update_cycloneiii'
+ * The macros are prefixed with 'REMOTE_UPDATE_'.
+ * The prefix is the slave descriptor.
+ */
+#define REMOTE_UPDATE_COMPONENT_TYPE altera_avalon_remote_update_cycloneiii
+#define REMOTE_UPDATE_COMPONENT_NAME remote_update
+#define REMOTE_UPDATE_BASE 0x8610000
+#define REMOTE_UPDATE_SPAN 2048u
+
+/*
+ * Macros for device 'sgdma_rx', class 'altera_avalon_sgdma'
+ * The macros are prefixed with 'SGDMA_RX_'.
+ * The prefix is the slave descriptor.
+ */
+#define SGDMA_RX_COMPONENT_TYPE altera_avalon_sgdma
+#define SGDMA_RX_COMPONENT_NAME sgdma_rx
+#define SGDMA_RX_BASE 0x8702000
+#define SGDMA_RX_SPAN 1024u
+#define SGDMA_RX_IRQ 4
+#define SGDMA_RX_READ_BLOCK_DATA_WIDTH 32
+#define SGDMA_RX_WRITE_BLOCK_DATA_WIDTH 32
+#define SGDMA_RX_STREAM_DATA_WIDTH 32
+#define SGDMA_RX_ADDRESS_WIDTH 32
+#define SGDMA_RX_HAS_READ_BLOCK 0
+#define SGDMA_RX_HAS_WRITE_BLOCK 1
+#define SGDMA_RX_READ_BURSTCOUNT_WIDTH 4
+#define SGDMA_RX_WRITE_BURSTCOUNT_WIDTH 4
+#define SGDMA_RX_BURST_TRANSFER 0
+#define SGDMA_RX_ALWAYS_DO_MAX_BURST 1
+#define SGDMA_RX_DESCRIPTOR_READ_BURST 0
+#define SGDMA_RX_UNALIGNED_TRANSFER 0
+#define SGDMA_RX_CONTROL_SLAVE_DATA_WIDTH 32
+#define SGDMA_RX_CONTROL_SLAVE_ADDRESS_WIDTH 8
+#define SGDMA_RX_DESC_DATA_WIDTH 32
+#define SGDMA_RX_CHAIN_WRITEBACK_DATA_WIDTH 32
+#define SGDMA_RX_STATUS_TOKEN_DATA_WIDTH 24
+#define SGDMA_RX_BYTES_TO_TRANSFER_DATA_WIDTH 16
+#define SGDMA_RX_BURST_DATA_WIDTH 8
+#define SGDMA_RX_CONTROL_DATA_WIDTH 8
+#define SGDMA_RX_ATLANTIC_CHANNEL_DATA_WIDTH 4
+#define SGDMA_RX_COMMAND_FIFO_DATA_WIDTH 104
+#define SGDMA_RX_SYMBOLS_PER_BEAT 4
+#define SGDMA_RX_IN_ERROR_WIDTH 6
+#define SGDMA_RX_OUT_ERROR_WIDTH 0
+
+/*
+ * Macros for device 'ddr_sdram', class 'altmemddr'
+ * Path to the device is from the master group 'sgdma_rx_m_write'.
+ * The macros are prefixed with 'SGDMA_RX_M_WRITE_DDR_SDRAM_'.
+ * The prefix is the master group descriptor and the slave descriptor.
+ */
+#define SGDMA_RX_M_WRITE_DDR_SDRAM_COMPONENT_TYPE altmemddr
+#define SGDMA_RX_M_WRITE_DDR_SDRAM_COMPONENT_NAME ddr_sdram
+#define SGDMA_RX_M_WRITE_DDR_SDRAM_BASE 0x0
+#define SGDMA_RX_M_WRITE_DDR_SDRAM_SPAN 33554432u
+
+/*
+ * Macros for device 'ext_flash', class 'altera_avalon_cfi_flash'
+ * Path to the device is from the master group 'sgdma_rx_m_write'.
+ * The macros are prefixed with 'SGDMA_RX_M_WRITE_EXT_FLASH_'.
+ * The prefix is the master group descriptor and the slave descriptor.
+ */
+#define SGDMA_RX_M_WRITE_EXT_FLASH_COMPONENT_TYPE altera_avalon_cfi_flash
+#define SGDMA_RX_M_WRITE_EXT_FLASH_COMPONENT_NAME ext_flash
+#define SGDMA_RX_M_WRITE_EXT_FLASH_BASE 0x4000000
+#define SGDMA_RX_M_WRITE_EXT_FLASH_SPAN 16777216u
+#define SGDMA_RX_M_WRITE_EXT_FLASH_SETUP_VALUE 25
+#define SGDMA_RX_M_WRITE_EXT_FLASH_WAIT_VALUE 70
+#define SGDMA_RX_M_WRITE_EXT_FLASH_HOLD_VALUE 20
+#define SGDMA_RX_M_WRITE_EXT_FLASH_TIMING_UNITS "ns"
+#define SGDMA_RX_M_WRITE_EXT_FLASH_SIZE 16777216u
+
+/*
+ * Macros for device 'ssram', class 'altera_avalon_cy7c1380_ssram'
+ * Path to the device is from the master group 'sgdma_rx_m_write'.
+ * The macros are prefixed with 'SGDMA_RX_M_WRITE_SSRAM_'.
+ * The prefix is the master group descriptor and the slave descriptor.
+ */
+#define SGDMA_RX_M_WRITE_SSRAM_COMPONENT_TYPE altera_avalon_cy7c1380_ssram
+#define SGDMA_RX_M_WRITE_SSRAM_COMPONENT_NAME ssram
+#define SGDMA_RX_M_WRITE_SSRAM_BASE 0x5000000
+#define SGDMA_RX_M_WRITE_SSRAM_SPAN 1048576u
+#define SGDMA_RX_M_WRITE_SSRAM_SRAM_MEMORY_SIZE 1
+#define SGDMA_RX_M_WRITE_SSRAM_SRAM_MEMORY_UNITS 1048576
+#define SGDMA_RX_M_WRITE_SSRAM_SSRAM_DATA_WIDTH 32
+#define SGDMA_RX_M_WRITE_SSRAM_SSRAM_READ_LATENCY 2
+
+/*
+ * Macros for device 'sgdma_tx', class 'altera_avalon_sgdma'
+ * The macros are prefixed with 'SGDMA_TX_'.
+ * The prefix is the slave descriptor.
+ */
+#define SGDMA_TX_COMPONENT_TYPE altera_avalon_sgdma
+#define SGDMA_TX_COMPONENT_NAME sgdma_tx
+#define SGDMA_TX_BASE 0x8702400
+#define SGDMA_TX_SPAN 1024u
+#define SGDMA_TX_IRQ 6
+#define SGDMA_TX_READ_BLOCK_DATA_WIDTH 32
+#define SGDMA_TX_WRITE_BLOCK_DATA_WIDTH 32
+#define SGDMA_TX_STREAM_DATA_WIDTH 32
+#define SGDMA_TX_ADDRESS_WIDTH 32
+#define SGDMA_TX_HAS_READ_BLOCK 1
+#define SGDMA_TX_HAS_WRITE_BLOCK 0
+#define SGDMA_TX_READ_BURSTCOUNT_WIDTH 4
+#define SGDMA_TX_WRITE_BURSTCOUNT_WIDTH 4
+#define SGDMA_TX_BURST_TRANSFER 0
+#define SGDMA_TX_ALWAYS_DO_MAX_BURST 1
+#define SGDMA_TX_DESCRIPTOR_READ_BURST 0
+#define SGDMA_TX_UNALIGNED_TRANSFER 0
+#define SGDMA_TX_CONTROL_SLAVE_DATA_WIDTH 32
+#define SGDMA_TX_CONTROL_SLAVE_ADDRESS_WIDTH 8
+#define SGDMA_TX_DESC_DATA_WIDTH 32
+#define SGDMA_TX_CHAIN_WRITEBACK_DATA_WIDTH 32
+#define SGDMA_TX_STATUS_TOKEN_DATA_WIDTH 24
+#define SGDMA_TX_BYTES_TO_TRANSFER_DATA_WIDTH 16
+#define SGDMA_TX_BURST_DATA_WIDTH 8
+#define SGDMA_TX_CONTROL_DATA_WIDTH 8
+#define SGDMA_TX_ATLANTIC_CHANNEL_DATA_WIDTH 4
+#define SGDMA_TX_COMMAND_FIFO_DATA_WIDTH 104
+#define SGDMA_TX_SYMBOLS_PER_BEAT 4
+#define SGDMA_TX_IN_ERROR_WIDTH 0
+#define SGDMA_TX_OUT_ERROR_WIDTH 1
+
+/*
+ * Macros for device 'ddr_sdram', class 'altmemddr'
+ * Path to the device is from the master group 'sgdma_tx_m_read'.
+ * The macros are prefixed with 'SGDMA_TX_M_READ_DDR_SDRAM_'.
+ * The prefix is the master group descriptor and the slave descriptor.
+ */
+#define SGDMA_TX_M_READ_DDR_SDRAM_COMPONENT_TYPE altmemddr
+#define SGDMA_TX_M_READ_DDR_SDRAM_COMPONENT_NAME ddr_sdram
+#define SGDMA_TX_M_READ_DDR_SDRAM_BASE 0x0
+#define SGDMA_TX_M_READ_DDR_SDRAM_SPAN 33554432u
+
+/*
+ * Macros for device 'ext_flash', class 'altera_avalon_cfi_flash'
+ * Path to the device is from the master group 'sgdma_tx_m_read'.
+ * The macros are prefixed with 'SGDMA_TX_M_READ_EXT_FLASH_'.
+ * The prefix is the master group descriptor and the slave descriptor.
+ */
+#define SGDMA_TX_M_READ_EXT_FLASH_COMPONENT_TYPE altera_avalon_cfi_flash
+#define SGDMA_TX_M_READ_EXT_FLASH_COMPONENT_NAME ext_flash
+#define SGDMA_TX_M_READ_EXT_FLASH_BASE 0x4000000
+#define SGDMA_TX_M_READ_EXT_FLASH_SPAN 16777216u
+#define SGDMA_TX_M_READ_EXT_FLASH_SETUP_VALUE 25
+#define SGDMA_TX_M_READ_EXT_FLASH_WAIT_VALUE 70
+#define SGDMA_TX_M_READ_EXT_FLASH_HOLD_VALUE 20
+#define SGDMA_TX_M_READ_EXT_FLASH_TIMING_UNITS "ns"
+#define SGDMA_TX_M_READ_EXT_FLASH_SIZE 16777216u
+
+/*
+ * Macros for device 'ssram', class 'altera_avalon_cy7c1380_ssram'
+ * Path to the device is from the master group 'sgdma_tx_m_read'.
+ * The macros are prefixed with 'SGDMA_TX_M_READ_SSRAM_'.
+ * The prefix is the master group descriptor and the slave descriptor.
+ */
+#define SGDMA_TX_M_READ_SSRAM_COMPONENT_TYPE altera_avalon_cy7c1380_ssram
+#define SGDMA_TX_M_READ_SSRAM_COMPONENT_NAME ssram
+#define SGDMA_TX_M_READ_SSRAM_BASE 0x5000000
+#define SGDMA_TX_M_READ_SSRAM_SPAN 1048576u
+#define SGDMA_TX_M_READ_SSRAM_SRAM_MEMORY_SIZE 1
+#define SGDMA_TX_M_READ_SSRAM_SRAM_MEMORY_UNITS 1048576
+#define SGDMA_TX_M_READ_SSRAM_SSRAM_DATA_WIDTH 32
+#define SGDMA_TX_M_READ_SSRAM_SSRAM_READ_LATENCY 2
+
+/*
+ * Macros for device 'tse_mac', class 'triple_speed_ethernet'
+ * The macros are prefixed with 'TSE_MAC_'.
+ * The prefix is the slave descriptor.
+ */
+#define TSE_MAC_COMPONENT_TYPE triple_speed_ethernet
+#define TSE_MAC_COMPONENT_NAME tse_mac
+#define TSE_MAC_BASE 0x8702800
+#define TSE_MAC_SPAN 1024u
+#define TSE_MAC_TRANSMIT "sgdma_tx"
+#define TSE_MAC_RECEIVE "sgdma_rx"
+#define TSE_MAC_TRANSMIT_FIFO_DEPTH 512
+#define TSE_MAC_RECEIVE_FIFO_DEPTH 512
+#define TSE_MAC_FIFO_WIDTH 32
+#define TSE_MAC_ENABLE_MACLITE 0
+#define TSE_MAC_MACLITE_GIGE 0
+#define TSE_MAC_USE_MDIO 1
+#define TSE_MAC_NUMBER_OF_CHANNEL 1
+#define TSE_MAC_NUMBER_OF_MAC_MDIO_SHARED 1
+#define TSE_MAC_IS_MULTICHANNEL_MAC 0
+#define TSE_MAC_MDIO_SHARED 0
+#define TSE_MAC_REGISTER_SHARED 0
+#define TSE_MAC_PCS 0
+#define TSE_MAC_PCS_SGMII 0
+#define TSE_MAC_PCS_ID 0u
+
+/*
+ * Macros for device 'descriptor_memory', class 'altera_avalon_onchip_memory2'
+ * The macros are prefixed with 'DESCRIPTOR_MEMORY_'.
+ * The prefix is the slave descriptor.
+ */
+#define DESCRIPTOR_MEMORY_COMPONENT_TYPE altera_avalon_onchip_memory2
+#define DESCRIPTOR_MEMORY_COMPONENT_NAME descriptor_memory
+#define DESCRIPTOR_MEMORY_BASE 0xb000000
+#define DESCRIPTOR_MEMORY_SPAN 4096u
+#define DESCRIPTOR_MEMORY_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0
+#define DESCRIPTOR_MEMORY_INIT_CONTENTS_FILE "descriptor_memory"
+#define DESCRIPTOR_MEMORY_NON_DEFAULT_INIT_FILE_ENABLED 0
+#define DESCRIPTOR_MEMORY_GUI_RAM_BLOCK_TYPE "Automatic"
+#define DESCRIPTOR_MEMORY_WRITABLE 1
+#define DESCRIPTOR_MEMORY_DUAL_PORT 0
+#define DESCRIPTOR_MEMORY_SIZE_VALUE 4096u
+#define DESCRIPTOR_MEMORY_SIZE_MULTIPLE 1
+#define DESCRIPTOR_MEMORY_CONTENTS_INFO ""
+#define DESCRIPTOR_MEMORY_RAM_BLOCK_TYPE "Auto"
+#define DESCRIPTOR_MEMORY_INIT_MEM_CONTENT 1
+#define DESCRIPTOR_MEMORY_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0
+#define DESCRIPTOR_MEMORY_INSTANCE_ID "NONE"
+#define DESCRIPTOR_MEMORY_READ_DURING_WRITE_MODE "DONT_CARE"
+
+
+#endif /* _ALTERA_CPU_H_ */
diff --git a/arch/nios2/include/asm/default_mmu.h b/arch/nios2/include/asm/default_mmu.h
new file mode 100644
index 0000000..adf963a
--- /dev/null
+++ b/arch/nios2/include/asm/default_mmu.h
@@ -0,0 +1,371 @@
+#ifndef _ALTERA_LINUX_CPU_H_
+#define _ALTERA_LINUX_CPU_H_
+
+/* Note, this file was manually edited after generation
+ * since the multiple inclusion proctetion macro above collides with
+ * include/linux/cpu.h
+ */
+
+/*
+ * This file was automatically generated by the swinfo2header utility.
+ *
+ * Created from SOPC Builder system 'nios2_linux_3c120_125mhz_sys_sopc' in
+ * file 'default//nios2_linux_3c120_125mhz_sys_sopc.sopcinfo'.
+ */
+
+/*
+ * This file contains macros for module 'linux_cpu' and devices
+ * connected to the following masters:
+ *   instruction_master
+ *   tightly_coupled_instruction_master_0
+ *   data_master
+ *   tightly_coupled_data_master_0
+ *
+ * Do not #include this header file and another header file created for a
+ * different module or master group at the same time.
+ * Doing so may result in duplicate #defines.
+ * Instead, use the system header file which has #defines with unique names.
+ */
+
+/*
+ * Macros for module 'linux_cpu', class 'altera_nios2'.
+ * The macros have no prefix.
+ */
+#define CPU_IMPLEMENTATION "fast"
+#define ICACHE_LINE_SIZE 32
+#define ICACHE_LINE_SIZE_LOG2 5
+#define ICACHE_SIZE 32768
+#define DCACHE_LINE_SIZE 32
+#define DCACHE_LINE_SIZE_LOG2 5
+#define DCACHE_SIZE 32768
+#define INITDA_SUPPORTED 
+#define FLUSHDA_SUPPORTED 
+#define HAS_JMPI_INSTRUCTION 
+#define MMU_PRESENT 
+#define KERNEL_REGION_BASE 0xc0000000
+#define IO_REGION_BASE 0xe0000000
+#define KERNEL_MMU_REGION_BASE 0x80000000
+#define USER_REGION_BASE 0x0
+#define PROCESS_ID_NUM_BITS 8
+#define TLB_NUM_WAYS 16
+#define TLB_PTR_SZ 7
+#define TLB_NUM_ENTRIES 128
+#define FAST_TLB_MISS_EXCEPTION_ADDR 0xc7fff400
+#define EXCEPTION_ADDR 0xd0000020
+#define RESET_ADDR 0xc2800000
+#define BREAK_ADDR 0xc7fff820
+#define HAS_DEBUG_STUB 
+#define HAS_DEBUG_CORE 1
+#define HAS_ILLEGAL_INSTRUCTION_EXCEPTION 
+#define HAS_ILLEGAL_MEMORY_ACCESS_EXCEPTION 
+#define HAS_EXTRA_EXCEPTION_INFO 
+#define CPU_ID_SIZE 1
+#define CPU_ID_VALUE 0x0
+#define HARDWARE_DIVIDE_PRESENT 1
+#define HARDWARE_MULTIPLY_PRESENT 1
+#define HARDWARE_MULX_PRESENT 0
+#define INST_ADDR_WIDTH 29
+#define DATA_ADDR_WIDTH 29
+
+/*
+ * Macros for device 'cfi_flash_64m', class 'altera_avalon_cfi_flash'
+ * The macros are prefixed with 'CFI_FLASH_64M_'.
+ * The prefix is the slave descriptor.
+ */
+#define CFI_FLASH_64M_BASE 0x0
+#define CFI_FLASH_64M_SPAN 67108864u
+#define CFI_FLASH_64M_SETUP_VALUE 75
+#define CFI_FLASH_64M_WAIT_VALUE 35
+#define CFI_FLASH_64M_HOLD_VALUE 1
+#define CFI_FLASH_64M_TIMING_UNITS "ns"
+#define CFI_FLASH_64M_SIZE 67108864u
+
+/*
+ * Macros for device 'fast_tlb_miss_ram_1k', class 'altera_avalon_onchip_memory2'
+ * The macros are prefixed with 'FAST_TLB_MISS_RAM_1K_'.
+ * The prefix is the slave descriptor.
+ */
+#define FAST_TLB_MISS_RAM_1K_BASE 0x7fff400
+#define FAST_TLB_MISS_RAM_1K_SPAN 1024u
+#define FAST_TLB_MISS_RAM_1K_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0
+#define FAST_TLB_MISS_RAM_1K_INIT_CONTENTS_FILE "fast_tlb_miss_ram_1k"
+#define FAST_TLB_MISS_RAM_1K_NON_DEFAULT_INIT_FILE_ENABLED 0
+#define FAST_TLB_MISS_RAM_1K_GUI_RAM_BLOCK_TYPE "Automatic"
+#define FAST_TLB_MISS_RAM_1K_WRITABLE 1
+#define FAST_TLB_MISS_RAM_1K_DUAL_PORT 1
+#define FAST_TLB_MISS_RAM_1K_SIZE_VALUE 1024u
+#define FAST_TLB_MISS_RAM_1K_SIZE_MULTIPLE 1
+#define FAST_TLB_MISS_RAM_1K_CONTENTS_INFO ""
+#define FAST_TLB_MISS_RAM_1K_RAM_BLOCK_TYPE "Auto"
+#define FAST_TLB_MISS_RAM_1K_INIT_MEM_CONTENT 1
+#define FAST_TLB_MISS_RAM_1K_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0
+#define FAST_TLB_MISS_RAM_1K_INSTANCE_ID "NONE"
+#define FAST_TLB_MISS_RAM_1K_READ_DURING_WRITE_MODE "DONT_CARE"
+
+/*
+ * Macros for device 'descriptor_memory', class 'altera_avalon_onchip_memory2'
+ * The macros are prefixed with 'DESCRIPTOR_MEMORY_'.
+ * The prefix is the slave descriptor.
+ */
+#define DESCRIPTOR_MEMORY_BASE 0x8002000
+#define DESCRIPTOR_MEMORY_SPAN 8192u
+#define DESCRIPTOR_MEMORY_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0
+#define DESCRIPTOR_MEMORY_INIT_CONTENTS_FILE "descriptor_memory"
+#define DESCRIPTOR_MEMORY_NON_DEFAULT_INIT_FILE_ENABLED 0
+#define DESCRIPTOR_MEMORY_GUI_RAM_BLOCK_TYPE "Automatic"
+#define DESCRIPTOR_MEMORY_WRITABLE 1
+#define DESCRIPTOR_MEMORY_DUAL_PORT 0
+#define DESCRIPTOR_MEMORY_SIZE_VALUE 8192u
+#define DESCRIPTOR_MEMORY_SIZE_MULTIPLE 1
+#define DESCRIPTOR_MEMORY_CONTENTS_INFO ""
+#define DESCRIPTOR_MEMORY_RAM_BLOCK_TYPE "Auto"
+#define DESCRIPTOR_MEMORY_INIT_MEM_CONTENT 1
+#define DESCRIPTOR_MEMORY_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0
+#define DESCRIPTOR_MEMORY_INSTANCE_ID "NONE"
+#define DESCRIPTOR_MEMORY_READ_DURING_WRITE_MODE "DONT_CARE"
+
+/*
+ * Macros for device 'tse_mac', class 'triple_speed_ethernet'
+ * The macros are prefixed with 'TSE_MAC_'.
+ * The prefix is the slave descriptor.
+ */
+#define TSE_MAC_BASE 0x8004000
+#define TSE_MAC_SPAN 1024u
+#define TSE_MAC_TRANSMIT "sgdma_tx"
+#define TSE_MAC_RECEIVE "sgdma_rx"
+#define TSE_MAC_TRANSMIT_FIFO_DEPTH 2048
+#define TSE_MAC_RECEIVE_FIFO_DEPTH 2048
+#define TSE_MAC_FIFO_WIDTH 32
+#define TSE_MAC_ENABLE_MACLITE 0
+#define TSE_MAC_MACLITE_GIGE 0
+#define TSE_MAC_USE_MDIO 1
+#define TSE_MAC_NUMBER_OF_CHANNEL 0
+#define TSE_MAC_NUMBER_OF_MAC_MDIO_SHARED 0
+#define TSE_MAC_IS_MULTICHANNEL_MAC 0
+#define TSE_MAC_MDIO_SHARED 0
+#define TSE_MAC_REGISTER_SHARED 0
+#define TSE_MAC_PCS 0
+#define TSE_MAC_PCS_SGMII 0
+#define TSE_MAC_PCS_ID 0u
+
+/*
+ * Macros for device 'sgdma_rx', class 'altera_avalon_sgdma'
+ * The macros are prefixed with 'SGDMA_RX_'.
+ * The prefix is the slave descriptor.
+ */
+#define SGDMA_RX_BASE 0x8004400
+#define SGDMA_RX_SPAN 1024u
+#define SGDMA_RX_IRQ 2
+#define SGDMA_RX_READ_BLOCK_DATA_WIDTH 32
+#define SGDMA_RX_WRITE_BLOCK_DATA_WIDTH 32
+#define SGDMA_RX_STREAM_DATA_WIDTH 32
+#define SGDMA_RX_ADDRESS_WIDTH 32
+#define SGDMA_RX_HAS_READ_BLOCK 0
+#define SGDMA_RX_HAS_WRITE_BLOCK 1
+#define SGDMA_RX_READ_BURSTCOUNT_WIDTH 4
+#define SGDMA_RX_WRITE_BURSTCOUNT_WIDTH 4
+#define SGDMA_RX_BURST_TRANSFER 0
+#define SGDMA_RX_ALWAYS_DO_MAX_BURST 1
+#define SGDMA_RX_DESCRIPTOR_READ_BURST 0
+#define SGDMA_RX_UNALIGNED_TRANSFER 0
+#define SGDMA_RX_CONTROL_SLAVE_DATA_WIDTH 32
+#define SGDMA_RX_CONTROL_SLAVE_ADDRESS_WIDTH 8
+#define SGDMA_RX_DESC_DATA_WIDTH 32
+#define SGDMA_RX_CHAIN_WRITEBACK_DATA_WIDTH 32
+#define SGDMA_RX_STATUS_TOKEN_DATA_WIDTH 24
+#define SGDMA_RX_BYTES_TO_TRANSFER_DATA_WIDTH 16
+#define SGDMA_RX_BURST_DATA_WIDTH 8
+#define SGDMA_RX_CONTROL_DATA_WIDTH 8
+#define SGDMA_RX_ATLANTIC_CHANNEL_DATA_WIDTH 4
+#define SGDMA_RX_COMMAND_FIFO_DATA_WIDTH 104
+#define SGDMA_RX_SYMBOLS_PER_BEAT 4
+#define SGDMA_RX_IN_ERROR_WIDTH 6
+#define SGDMA_RX_OUT_ERROR_WIDTH 0
+
+/*
+ * Macros for device 'ddr2_lo_latency_128m', class 'altmemddr2'
+ * Path to the device is from the master group 'sgdma_rx_m_write'.
+ * The macros are prefixed with 'SGDMA_RX_M_WRITE_DDR2_LO_LATENCY_128M_'.
+ * The prefix is the master group descriptor and the slave descriptor.
+ */
+#define SGDMA_RX_M_WRITE_DDR2_LO_LATENCY_128M_BASE 0x10000000
+#define SGDMA_RX_M_WRITE_DDR2_LO_LATENCY_128M_SPAN 134217728u
+
+/*
+ * Macros for device 'sgdma_tx', class 'altera_avalon_sgdma'
+ * The macros are prefixed with 'SGDMA_TX_'.
+ * The prefix is the slave descriptor.
+ */
+#define SGDMA_TX_BASE 0x8004800
+#define SGDMA_TX_SPAN 1024u
+#define SGDMA_TX_IRQ 3
+#define SGDMA_TX_READ_BLOCK_DATA_WIDTH 32
+#define SGDMA_TX_WRITE_BLOCK_DATA_WIDTH 32
+#define SGDMA_TX_STREAM_DATA_WIDTH 32
+#define SGDMA_TX_ADDRESS_WIDTH 32
+#define SGDMA_TX_HAS_READ_BLOCK 1
+#define SGDMA_TX_HAS_WRITE_BLOCK 0
+#define SGDMA_TX_READ_BURSTCOUNT_WIDTH 4
+#define SGDMA_TX_WRITE_BURSTCOUNT_WIDTH 4
+#define SGDMA_TX_BURST_TRANSFER 0
+#define SGDMA_TX_ALWAYS_DO_MAX_BURST 1
+#define SGDMA_TX_DESCRIPTOR_READ_BURST 0
+#define SGDMA_TX_UNALIGNED_TRANSFER 0
+#define SGDMA_TX_CONTROL_SLAVE_DATA_WIDTH 32
+#define SGDMA_TX_CONTROL_SLAVE_ADDRESS_WIDTH 8
+#define SGDMA_TX_DESC_DATA_WIDTH 32
+#define SGDMA_TX_CHAIN_WRITEBACK_DATA_WIDTH 32
+#define SGDMA_TX_STATUS_TOKEN_DATA_WIDTH 24
+#define SGDMA_TX_BYTES_TO_TRANSFER_DATA_WIDTH 16
+#define SGDMA_TX_BURST_DATA_WIDTH 8
+#define SGDMA_TX_CONTROL_DATA_WIDTH 8
+#define SGDMA_TX_ATLANTIC_CHANNEL_DATA_WIDTH 4
+#define SGDMA_TX_COMMAND_FIFO_DATA_WIDTH 104
+#define SGDMA_TX_SYMBOLS_PER_BEAT 4
+#define SGDMA_TX_IN_ERROR_WIDTH 0
+#define SGDMA_TX_OUT_ERROR_WIDTH 1
+
+/*
+ * Macros for device 'ddr2_lo_latency_128m', class 'altmemddr2'
+ * Path to the device is from the master group 'sgdma_tx_m_read'.
+ * The macros are prefixed with 'SGDMA_TX_M_READ_DDR2_LO_LATENCY_128M_'.
+ * The prefix is the master group descriptor and the slave descriptor.
+ */
+#define SGDMA_TX_M_READ_DDR2_LO_LATENCY_128M_BASE 0x10000000
+#define SGDMA_TX_M_READ_DDR2_LO_LATENCY_128M_SPAN 134217728u
+
+/*
+ * Macros for device 'uart', class 'altera_avalon_uart'
+ * The macros are prefixed with 'UART_'.
+ * The prefix is the slave descriptor.
+ */
+#define UART_BASE 0x8004c80
+#define UART_SPAN 32u
+#define UART_IRQ 10
+#define UART_BAUD 115200
+#define UART_DATA_BITS 8
+#define UART_FIXED_BAUD 0
+#define UART_PARITY 'N'
+#define UART_STOP_BITS 1
+#define UART_USE_CTS_RTS 0
+#define UART_USE_EOP_REGISTER 0
+#define UART_SIM_TRUE_BAUD 0
+#define UART_SIM_CHAR_STREAM ""
+#define UART_FREQ 62500000u
+
+/*
+ * Macros for device 'user_led_pio_8out', class 'altera_avalon_pio'
+ * The macros are prefixed with 'USER_LED_PIO_8OUT_'.
+ * The prefix is the slave descriptor.
+ */
+#define USER_LED_PIO_8OUT_BASE 0x8004cc0
+#define USER_LED_PIO_8OUT_SPAN 16u
+#define USER_LED_PIO_8OUT_DO_TEST_BENCH_WIRING 0
+#define USER_LED_PIO_8OUT_DRIVEN_SIM_VALUE 0x0
+#define USER_LED_PIO_8OUT_HAS_TRI 0
+#define USER_LED_PIO_8OUT_HAS_OUT 1
+#define USER_LED_PIO_8OUT_HAS_IN 0
+#define USER_LED_PIO_8OUT_CAPTURE 0
+#define USER_LED_PIO_8OUT_BIT_CLEARING_EDGE_REGISTER 0
+#define USER_LED_PIO_8OUT_DATA_WIDTH 8
+#define USER_LED_PIO_8OUT_RESET_VALUE 0xff
+#define USER_LED_PIO_8OUT_EDGE_TYPE "NONE"
+#define USER_LED_PIO_8OUT_IRQ_TYPE "NONE"
+#define USER_LED_PIO_8OUT_FREQ 62500000u
+
+/*
+ * Macros for device 'user_dipsw_pio_8in', class 'altera_avalon_pio'
+ * The macros are prefixed with 'USER_DIPSW_PIO_8IN_'.
+ * The prefix is the slave descriptor.
+ */
+#define USER_DIPSW_PIO_8IN_BASE 0x8004ce0
+#define USER_DIPSW_PIO_8IN_SPAN 16u
+#define USER_DIPSW_PIO_8IN_IRQ 8
+#define USER_DIPSW_PIO_8IN_DO_TEST_BENCH_WIRING 0
+#define USER_DIPSW_PIO_8IN_DRIVEN_SIM_VALUE 0x0
+#define USER_DIPSW_PIO_8IN_HAS_TRI 0
+#define USER_DIPSW_PIO_8IN_HAS_OUT 0
+#define USER_DIPSW_PIO_8IN_HAS_IN 1
+#define USER_DIPSW_PIO_8IN_CAPTURE 1
+#define USER_DIPSW_PIO_8IN_BIT_CLEARING_EDGE_REGISTER 1
+#define USER_DIPSW_PIO_8IN_DATA_WIDTH 8
+#define USER_DIPSW_PIO_8IN_RESET_VALUE 0x0
+#define USER_DIPSW_PIO_8IN_EDGE_TYPE "ANY"
+#define USER_DIPSW_PIO_8IN_IRQ_TYPE "EDGE"
+#define USER_DIPSW_PIO_8IN_FREQ 62500000u
+
+/*
+ * Macros for device 'user_pb_pio_4in', class 'altera_avalon_pio'
+ * The macros are prefixed with 'USER_PB_PIO_4IN_'.
+ * The prefix is the slave descriptor.
+ */
+#define USER_PB_PIO_4IN_BASE 0x8004d00
+#define USER_PB_PIO_4IN_SPAN 16u
+#define USER_PB_PIO_4IN_IRQ 9
+#define USER_PB_PIO_4IN_DO_TEST_BENCH_WIRING 0
+#define USER_PB_PIO_4IN_DRIVEN_SIM_VALUE 0x0
+#define USER_PB_PIO_4IN_HAS_TRI 0
+#define USER_PB_PIO_4IN_HAS_OUT 0
+#define USER_PB_PIO_4IN_HAS_IN 1
+#define USER_PB_PIO_4IN_CAPTURE 1
+#define USER_PB_PIO_4IN_BIT_CLEARING_EDGE_REGISTER 1
+#define USER_PB_PIO_4IN_DATA_WIDTH 4
+#define USER_PB_PIO_4IN_RESET_VALUE 0x0
+#define USER_PB_PIO_4IN_EDGE_TYPE "ANY"
+#define USER_PB_PIO_4IN_IRQ_TYPE "EDGE"
+#define USER_PB_PIO_4IN_FREQ 62500000u
+
+/*
+ * Macros for device 'sysid', class 'altera_avalon_sysid'
+ * The macros are prefixed with 'SYSID_'.
+ * The prefix is the slave descriptor.
+ */
+#define SYSID_BASE 0x8004d40
+#define SYSID_SPAN 8u
+#define SYSID_ID 1174346794u
+#define SYSID_TIMESTAMP 1233287581u
+
+/*
+ * Macros for device 'jtag_uart', class 'altera_avalon_jtag_uart'
+ * The macros are prefixed with 'JTAG_UART_'.
+ * The prefix is the slave descriptor.
+ */
+#define JTAG_UART_BASE 0x8004d50
+#define JTAG_UART_SPAN 8u
+#define JTAG_UART_IRQ 1
+#define JTAG_UART_WRITE_DEPTH 64
+#define JTAG_UART_READ_DEPTH 64
+#define JTAG_UART_WRITE_THRESHOLD 8
+#define JTAG_UART_READ_THRESHOLD 8
+
+/*
+ * Macros for device 'linux_timer_1ms', class 'altera_avalon_timer'
+ * The macros are prefixed with 'LINUX_TIMER_1MS_'.
+ * The prefix is the slave descriptor.
+ */
+#define LINUX_TIMER_1MS_BASE 0x8400000
+#define LINUX_TIMER_1MS_SPAN 32u
+#define LINUX_TIMER_1MS_IRQ 11
+#define LINUX_TIMER_1MS_ALWAYS_RUN 0
+#define LINUX_TIMER_1MS_FIXED_PERIOD 0
+#define LINUX_TIMER_1MS_SNAPSHOT 1
+#define LINUX_TIMER_1MS_PERIOD 1
+#define LINUX_TIMER_1MS_PERIOD_UNITS "ms"
+#define LINUX_TIMER_1MS_RESET_OUTPUT 0
+#define LINUX_TIMER_1MS_TIMEOUT_PULSE_OUTPUT 0
+#define LINUX_TIMER_1MS_FREQ 125000000u
+#define LINUX_TIMER_1MS_LOAD_VALUE 124999ULL
+#define LINUX_TIMER_1MS_COUNTER_SIZE 32
+#define LINUX_TIMER_1MS_MULT 0.0010
+#define LINUX_TIMER_1MS_TICKS_PER_SEC 1000u
+
+/*
+ * Macros for device 'ddr2_lo_latency_128m', class 'altmemddr2'
+ * The macros are prefixed with 'DDR2_LO_LATENCY_128M_'.
+ * The prefix is the slave descriptor.
+ */
+#define DDR2_LO_LATENCY_128M_BASE 0x10000000
+#define DDR2_LO_LATENCY_128M_SPAN 134217728u
+
+
+#endif /* _ALTERA_LINUX_CPU_H_ */
diff --git a/arch/nios2/include/asm/delay.h b/arch/nios2/include/asm/delay.h
new file mode 100644
index 0000000..d2b5586
--- /dev/null
+++ b/arch/nios2/include/asm/delay.h
@@ -0,0 +1,99 @@
+#ifndef _ASM_NIOS2_DELAY_H
+#define _ASM_NIOS2_DELAY_H
+
+/*--------------------------------------------------------------------
+ *
+ * include/asm-nios2/delay.h
+ *
+ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al
+ *
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Jan/20/2004      dgt     NiosII
+ *
+ ---------------------------------------------------------------------*/
+
+
+#include <asm/param.h>
+
+extern __inline__ void __delay(unsigned long loops)
+{
+	int dummy;
+
+	__asm__ __volatile__(
+        "1:  \n\t"
+        "    beq    %0,zero,2f\n\t"
+        "    addi   %0, %0, -1\n\t" 
+        "    br     1b\n\t" 
+        "2:  \n\t" 
+
+        :  "=r" (dummy)                     /* Need output for optimizer */
+
+        :  "0" (loops)                      /* %0  Input                */
+        );
+}
+
+/*
+ * Note that 19 * 226 == 4294 ==~ 2^32 / 10^6, so
+ * loops = (4294 * usecs * loops_per_jiffy * HZ) / 2^32.
+ *
+ * The mul instruction gives us loops = (a * b) / 2^32.
+ * We choose a = usecs * 19 * HZ and b = loops_per_jiffy * 226
+ * because this lets us support a wide range of HZ and
+ * loops_per_jiffy values without either a or b overflowing 2^32.
+ * Thus we need usecs * HZ <= (2^32 - 1) / 19 = 226050910 and
+ * loops_per_jiffy <= (2^32 - 1) / 226 = 19004280
+ * (which corresponds to ~3800 bogomips at HZ = 100).
+ *  -- paulus
+ */
+#define __MAX_UDELAY	(226050910UL/HZ)	/* maximum udelay argument */
+#define __MAX_NDELAY	(4294967295UL/HZ)	/* maximum ndelay argument */
+
+extern unsigned long loops_per_jiffy;
+
+extern __inline__ void __udelay(unsigned int x)
+{
+	unsigned int loops;
+	/* Note, if this is compiled with -mhw-mulx it will produce a "mulxuu"
+	 * (at least in toolchain 145) so there is no need for inline
+	 * assembly here anymore, which might in turn be emulated if unsupported
+	 * by the design.
+	 */
+	loops = (unsigned int)((((unsigned long long)(x) * (unsigned long long)(loops_per_jiffy * 226))) >> 32);
+	__delay(loops);
+}
+
+extern __inline__ void __ndelay(unsigned int x)
+{
+	unsigned int loops;
+	/* see comment above
+	 */
+	loops = (unsigned int)((((unsigned long long)(x) * (unsigned long long)(loops_per_jiffy * 5))) >> 32);
+	__delay(loops);
+}
+
+extern void __bad_udelay(void);		/* deliberately undefined */
+extern void __bad_ndelay(void);		/* deliberately undefined */
+
+#define udelay(n) (__builtin_constant_p(n)? \
+	((n) > __MAX_UDELAY? __bad_udelay(): __udelay((n) * (19 * HZ))) : \
+	__udelay((n) * (19 * HZ)))
+
+#define ndelay(n) (__builtin_constant_p(n)? \
+	((n) > __MAX_NDELAY? __bad_ndelay(): __ndelay((n) * HZ)) : \
+	__ndelay((n) * HZ))
+
+#define muldiv(a, b, c)    (((a)*(b))/(c))
+
+#endif /* defined(_NIOS_DELAY_H) */
diff --git a/arch/nios2/include/asm/device.h b/arch/nios2/include/asm/device.h
new file mode 100644
index 0000000..dc11a45
--- /dev/null
+++ b/arch/nios2/include/asm/device.h
@@ -0,0 +1,2 @@
+#include <asm-generic/device.h>
+
diff --git a/arch/nios2/include/asm/div64.h b/arch/nios2/include/asm/div64.h
new file mode 100644
index 0000000..6cd978c
--- /dev/null
+++ b/arch/nios2/include/asm/div64.h
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff --git a/arch/nios2/include/asm/dma-mapping.h b/arch/nios2/include/asm/dma-mapping.h
new file mode 100644
index 0000000..dc196c6
--- /dev/null
+++ b/arch/nios2/include/asm/dma-mapping.h
@@ -0,0 +1,79 @@
+#ifndef _ASM_NIOS2_DMA_MAPPING_H
+#define _ASM_NIOS2_DMA_MAPPING_H
+
+#include <asm/scatterlist.h>
+#include <asm/cache.h>
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+			   dma_addr_t *dma_handle, gfp_t flag);
+
+void dma_free_noncoherent(struct device *dev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle);
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+			   dma_addr_t *dma_handle, gfp_t flag);
+
+void dma_free_coherent(struct device *dev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle);
+
+extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+	enum dma_data_direction direction);
+extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
+	size_t size, enum dma_data_direction direction);
+extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	enum dma_data_direction direction);
+extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
+	unsigned long offset, size_t size, enum dma_data_direction direction);
+extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
+	size_t size, enum dma_data_direction direction);
+extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+	int nhwentries, enum dma_data_direction direction);
+extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction);
+extern void dma_sync_single_for_device(struct device *dev,
+	dma_addr_t dma_handle, size_t size, enum dma_data_direction direction);
+extern void dma_sync_single_range_for_cpu(struct device *dev,
+	dma_addr_t dma_handle, unsigned long offset, size_t size,
+	enum dma_data_direction direction);
+extern void dma_sync_single_range_for_device(struct device *dev,
+	dma_addr_t dma_handle, unsigned long offset, size_t size,
+	enum dma_data_direction direction);
+extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+	int nelems, enum dma_data_direction direction);
+extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+	int nelems, enum dma_data_direction direction);
+extern int dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
+extern int dma_supported(struct device *dev, u64 mask);
+
+static inline int
+dma_set_mask(struct device *dev, u64 mask)
+{
+	if(!dev->dma_mask || !dma_supported(dev, mask))
+		return -EIO;
+
+	*dev->dma_mask = mask;
+
+	return 0;
+}
+
+static inline int
+dma_get_cache_alignment(void)
+{
+	/* XXX Largest on any MIPS */
+	return 128;
+}
+
+extern int dma_is_consistent(dma_addr_t dma_addr);
+
+extern void dma_cache_sync(void *vaddr, size_t size,
+	       enum dma_data_direction direction);
+
+// #define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
+// 
+// extern int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
+// 	dma_addr_t device_addr, size_t size, int flags);
+// extern void dma_release_declared_memory(struct device *dev);
+// extern void * dma_mark_declared_memory_occupied(struct device *dev,
+// 	dma_addr_t device_addr, size_t size);
+
+#endif /* _ASM_NIOS2_DMA_MAPPING_H */
diff --git a/arch/nios2/include/asm/dma.h b/arch/nios2/include/asm/dma.h
new file mode 100644
index 0000000..7ce20d9
--- /dev/null
+++ b/arch/nios2/include/asm/dma.h
@@ -0,0 +1 @@
+#include <asm-generic/dma.h>
diff --git a/arch/nios2/include/asm/elf.h b/arch/nios2/include/asm/elf.h
new file mode 100644
index 0000000..6b55a23
--- /dev/null
+++ b/arch/nios2/include/asm/elf.h
@@ -0,0 +1,119 @@
+#ifndef _ASM_NIOS2_ELF_H
+#define _ASM_NIOS2_ELF_H
+
+#define R_NIOS2_NONE		0
+#define R_NIOS2_S16		1
+#define R_NIOS2_U16		2
+#define R_NIOS2_PCREL16		3
+#define R_NIOS2_CALL26		4
+#define R_NIOS2_IMM5		5
+#define R_NIOS2_CACHE_OPX 	6
+#define R_NIOS2_IMM6		7
+#define R_NIOS2_IMM8		8
+#define R_NIOS2_HI16		9
+#define R_NIOS2_LO16		10
+#define R_NIOS2_HIADJ16 	11
+#define R_NIOS2_BFD_RELOC_32	12
+#define R_NIOS2_BFD_RELOC_16	13
+#define R_NIOS2_BFD_RELOC_8	14
+#define R_NIOS2_GPREL		15
+#define R_NIOS2_GNU_VTINHERIT 	16
+#define R_NIOS2_GNU_VTENTRY  	17
+#define R_NIOS2_UJMP		18
+#define R_NIOS2_CJMP		19
+#define R_NIOS2_CALLR		20
+#define R_NIOS2_ALIGN		21
+/* Keep this the last entry.  */
+#define R_NIOS2_NUM		22
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef unsigned long elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_ALTERA_NIOS2)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2LSB
+#define ELF_ARCH	EM_ALTERA_NIOS2
+
+#define ELF_PLAT_INIT(_r, load_addr)
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	4096
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE         0xD0000000UL
+
+/* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
+   now struct_user_regs, they are different) */
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)				\
+	/* Bleech. */							\
+	pr_reg[0]  = regs->r8;						\
+	pr_reg[1]  = regs->r9;						\
+	pr_reg[2]  = regs->r10;						\
+	pr_reg[3]  = regs->r11;						\
+	pr_reg[4]  = regs->r12;						\
+	pr_reg[5]  = regs->r13;						\
+	pr_reg[6]  = regs->r14;						\
+	pr_reg[7]  = regs->r15;						\
+	pr_reg[8]  = regs->r1;						\
+	pr_reg[9]  = regs->r2;						\
+	pr_reg[10] = regs->r3;						\
+	pr_reg[11] = regs->r4;						\
+	pr_reg[12] = regs->r5;						\
+	pr_reg[13] = regs->r6;						\
+	pr_reg[14] = regs->r7;						\
+	pr_reg[15] = regs->orig_r2;					\
+	pr_reg[16] = regs->ra;						\
+	pr_reg[17] = regs->fp;						\
+	pr_reg[18] = regs->sp;						\
+	pr_reg[19] = regs->gp;						\
+	pr_reg[20] = regs->estatus;					\
+	pr_reg[21] = regs->ea;						\
+	pr_reg[22] = regs->orig_r7;					\
+	{								\
+	  struct switch_stack *sw = ((struct switch_stack *)regs) - 1;	\
+	  pr_reg[23] = sw->r16;						\
+	  pr_reg[24] = sw->r17;						\
+	  pr_reg[25] = sw->r18;						\
+	  pr_reg[26] = sw->r19;						\
+	  pr_reg[27] = sw->r20;						\
+	  pr_reg[28] = sw->r21;						\
+	  pr_reg[29] = sw->r22;						\
+	  pr_reg[30] = sw->r23;						\
+	  pr_reg[31] = sw->fp;						\
+	  pr_reg[32] = sw->gp;						\
+	  pr_reg[33] = sw->ra;						\
+	}
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.  */
+
+#define ELF_PLATFORM  (NULL)
+
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
+
+#endif
diff --git a/arch/nios2/include/asm/emergency-restart.h b/arch/nios2/include/asm/emergency-restart.h
new file mode 100644
index 0000000..3711bd9
--- /dev/null
+++ b/arch/nios2/include/asm/emergency-restart.h
@@ -0,0 +1 @@
+#include <asm-generic/emergency-restart.h>
diff --git a/arch/nios2/include/asm/entry.h b/arch/nios2/include/asm/entry.h
new file mode 100644
index 0000000..eb977a9
--- /dev/null
+++ b/arch/nios2/include/asm/entry.h
@@ -0,0 +1,179 @@
+/*
+ * Hacked from m68knommu port.
+ *
+ *  Copyright(C) 2004 Microtronix Datacom Ltd.
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _ASM_NIOS2_ENTRY_H
+#define _ASM_NIOS2_ENTRY_H
+
+#ifdef __ASSEMBLY__
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/asm-offsets.h>
+
+/*
+ * Stack layout in 'ret_from_exception':
+ *
+ * This allows access to the syscall arguments in registers r4-r8
+ *
+ *	 0(sp) - r8
+ *	 4(sp) - r9
+ *	 8(sp) - r10
+ *	 C(sp) - r11
+ *	10(sp) - r12
+ *	14(sp) - r13
+ *	18(sp) - r14
+ *	1C(sp) - r15
+ *	20(sp) - r1
+ *	24(sp) - r2
+ *	28(sp) - r3
+ *	2C(sp) - r4
+ *	30(sp) - r5
+ *	34(sp) - r6
+ *	38(sp) - r7
+ *	3C(sp) - orig_r2
+ *	40(sp) - ra
+ *	44(sp) - fp
+ *	48(sp) - sp
+ *	4C(sp) - gp
+ *	50(sp) - estatus
+ *	58(sp) - ea
+ *
+ */
+
+/* process bits for task_struct.flags */
+PF_TRACESYS_OFF = 3
+PF_TRACESYS_BIT = 5
+PF_PTRACED_OFF = 3
+PF_PTRACED_BIT = 4
+PF_DTRACE_OFF = 1
+PF_DTRACE_BIT = 5
+
+LENOSYS = 38
+
+/*
+ * This defines the normal kernel pt-regs layout.
+ *
+ */
+
+/*
+ * Standard Nios2 interrupt entry and exit macros.
+ * Must be called with interrupts disabled.
+ */
+.macro SAVE_ALL
+	rdctl	r24,estatus
+	andi	r24,r24,NIOS2_STATUS_U_MSK_ASM
+	beq	r24,r0,1f		// In supervisor mode, already on kernel stack
+
+	movia	r24,_current_thread	// Switch to current kernel stack
+	ldw	r24,0(r24)		//  using the thread_info
+	addi	r24,r24,THREAD_SIZE_ASM-PT_REGS_SIZE
+	stw	sp,PT_SP(r24)		// Save user stack before changing
+	mov	sp,r24
+	br	2f
+
+1:	mov	r24,sp
+	addi	sp,sp,-PT_REGS_SIZE	// Backup the kernel stack pointer
+	stw	r24,PT_SP(sp)
+2:	stw	r1,PT_R1(sp)
+	stw	r2,PT_R2(sp)
+	stw	r3,PT_R3(sp)
+	stw	r4,PT_R4(sp)
+	stw	r5,PT_R5(sp)
+	stw	r6,PT_R6(sp)
+	stw	r7,PT_R7(sp)
+	stw	r8,PT_R8(sp)
+	stw	r9,PT_R9(sp)
+	stw	r10,PT_R10(sp)
+	stw	r11,PT_R11(sp)
+	stw	r12,PT_R12(sp)
+	stw	r13,PT_R13(sp)
+	stw	r14,PT_R14(sp)
+	stw	r15,PT_R15(sp)
+	stw	r2,PT_ORIG_R2(sp)
+	stw	r7,PT_ORIG_R7(sp)
+	stw	ra,PT_RA(sp)
+	stw	fp,PT_FP(sp)
+	stw	gp,PT_GP(sp)
+	rdctl	r24,estatus
+	stw	r24,PT_ESTATUS(sp)
+	stw	ea,PT_EA(sp)
+.endm
+
+.macro RESTORE_ALL
+ 	ldw	r1,PT_R1(sp)		// Restore registers
+	ldw	r2,PT_R2(sp)
+	ldw	r3,PT_R3(sp)
+	ldw	r4,PT_R4(sp)
+	ldw	r5,PT_R5(sp)
+	ldw	r6,PT_R6(sp)
+	ldw	r7,PT_R7(sp)
+	ldw	r8,PT_R8(sp)
+	ldw	r9,PT_R9(sp)
+	ldw	r10,PT_R10(sp)
+	ldw	r11,PT_R11(sp)
+	ldw	r12,PT_R12(sp)
+	ldw	r13,PT_R13(sp)
+	ldw	r14,PT_R14(sp)
+	ldw	r15,PT_R15(sp)
+	ldw	ra,PT_RA(sp)
+	ldw	fp,PT_FP(sp)
+	ldw	gp,PT_GP(sp)
+	ldw	r24,PT_ESTATUS(sp)
+	wrctl	estatus,r24
+	ldw	ea,PT_EA(sp)
+	ldw	sp,PT_SP(sp)		// Restore sp last
+.endm
+
+.macro	SAVE_SWITCH_STACK
+	addi	sp,sp,-SWITCH_STACK_SIZE
+	stw	r16,SW_R16(sp)
+	stw	r17,SW_R17(sp)
+	stw	r18,SW_R18(sp)
+	stw	r19,SW_R19(sp)
+	stw	r20,SW_R20(sp)
+	stw	r21,SW_R21(sp)
+	stw	r22,SW_R22(sp)
+	stw	r23,SW_R23(sp)
+	stw	fp,SW_FP(sp)
+	stw	gp,SW_GP(sp)
+	stw	ra,SW_RA(sp)
+.endm
+
+.macro	RESTORE_SWITCH_STACK
+	ldw	r16,SW_R16(sp)
+	ldw	r17,SW_R17(sp)
+	ldw	r18,SW_R18(sp)
+	ldw	r19,SW_R19(sp)
+	ldw	r20,SW_R20(sp)
+	ldw	r21,SW_R21(sp)
+	ldw	r22,SW_R22(sp)
+	ldw	r23,SW_R23(sp)
+	ldw	fp,SW_FP(sp)
+	ldw	gp,SW_GP(sp)
+	ldw	ra,SW_RA(sp)
+	addi	sp,sp,SWITCH_STACK_SIZE
+.endm
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_NIOS2_ENTRY_H */
diff --git a/arch/nios2/include/asm/errno.h b/arch/nios2/include/asm/errno.h
new file mode 100644
index 0000000..4c82b50
--- /dev/null
+++ b/arch/nios2/include/asm/errno.h
@@ -0,0 +1 @@
+#include <asm-generic/errno.h>
diff --git a/arch/nios2/include/asm/fb.h b/arch/nios2/include/asm/fb.h
new file mode 100644
index 0000000..3a4988e
--- /dev/null
+++ b/arch/nios2/include/asm/fb.h
@@ -0,0 +1 @@
+#include <asm-generic/fb.h>
diff --git a/arch/nios2/include/asm/fcntl.h b/arch/nios2/include/asm/fcntl.h
new file mode 100644
index 0000000..0b3912c
--- /dev/null
+++ b/arch/nios2/include/asm/fcntl.h
@@ -0,0 +1,11 @@
+#ifndef _ASM_NIOS2_FCNTL_H
+#define _ASM_NIOS2_FCNTL_H
+
+#define O_DIRECTORY	040000	/* must be a directory */
+#define O_NOFOLLOW	0100000	/* don't follow links */
+#define O_DIRECT	0200000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE	0400000
+
+#include <asm-generic/fcntl.h>
+
+#endif /* _ASM_NIOS2_FCNTL_H */
diff --git a/arch/nios2/include/asm/fixmap.h b/arch/nios2/include/asm/fixmap.h
new file mode 100644
index 0000000..bdcfdca
--- /dev/null
+++ b/arch/nios2/include/asm/fixmap.h
@@ -0,0 +1,120 @@
+/*
+ * fixmap.h: compile-time virtual memory allocation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 Ingo Molnar
+ *
+ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
+ */
+
+#ifndef _ASM_NIOS2_FIXMAP_H
+#define _ASM_NIOS2_FIXMAP_H
+
+#include <asm/page.h>
+#ifdef CONFIG_HIGHMEM
+#include <linux/threads.h>
+#include <asm/kmap_types.h>
+#endif
+
+/*
+ * Here we define all the compile-time 'special' virtual
+ * addresses. The point is to have a constant address at
+ * compile time, but to set the physical address only
+ * in the boot process. We allocate these special  addresses
+ * from the end of virtual memory (0xfffff000) backwards.
+ * Also this lets us do fail-safe vmalloc(), we
+ * can guarantee that these special addresses and
+ * vmalloc()-ed addresses never overlap.
+ *
+ * these 'compile-time allocated' memory buffers are
+ * fixed-size 4k pages. (or larger if used with an increment
+ * highger than 1) use fixmap_set(idx,phys) to associate
+ * physical memory with fixmap indices.
+ *
+ * TLB entries of such buffers will not be flushed across
+ * task switches.
+ */
+
+/*
+ * on UP currently we will have no trace of the fixmap mechanizm,
+ * no page table allocations, etc. This might change in the
+ * future, say framebuffers for the console driver(s) could be
+ * fix-mapped?
+ */
+enum fixed_addresses {
+#define FIX_N_COLOURS 8
+	FIX_CMAP_BEGIN,
+	FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS,
+#ifdef CONFIG_HIGHMEM
+	/* reserved pte's for temporary kernel mappings */
+	FIX_KMAP_BEGIN = FIX_CMAP_END + 1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+#endif
+	__end_of_fixed_addresses
+};
+
+extern void __set_fixmap (enum fixed_addresses idx,
+					unsigned long phys, pgprot_t flags);
+
+#define set_fixmap(idx, phys) \
+		__set_fixmap(idx, phys, PAGE_KERNEL)
+/*
+ * Some hardware wants to get fixmapped without caching.
+ */
+#define set_fixmap_nocache(idx, phys) \
+		__set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
+/*
+ * used by vmalloc.c.
+ *
+ * Leave one empty page between vmalloc'ed areas and
+ * the start of the fixmap, and leave one page empty
+ * at the top of mem..
+ */
+#define FIXADDR_TOP	((unsigned long)(long)(int)0xfffe0000)
+#define FIXADDR_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
+
+#define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
+#define __virt_to_fix(x)	((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+
+extern void __this_fixmap_does_not_exist(void);
+
+/*
+ * 'index to address' translation. If anyone tries to use the idx
+ * directly without tranlation, we catch the bug with a NULL-deference
+ * kernel oops. Illegal ranges of incoming indices are caught too.
+ */
+static inline unsigned long fix_to_virt(const unsigned int idx)
+{
+	/*
+	 * this branch gets completely eliminated after inlining,
+	 * except when someone tries to use fixaddr indices in an
+	 * illegal way. (such as mixing up address types or using
+	 * out-of-range indices).
+	 *
+	 * If it doesn't get removed, the linker will complain
+	 * loudly with a reasonably clear error message..
+	 */
+	if (idx >= __end_of_fixed_addresses)
+		__this_fixmap_does_not_exist();
+
+        return __fix_to_virt(idx);
+}
+
+static inline unsigned long virt_to_fix(const unsigned long vaddr)
+{
+	BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
+	return __virt_to_fix(vaddr);
+}
+
+/*
+ * Called from pgtable_init()
+ */
+extern void fixrange_init(unsigned long start, unsigned long end,
+        pgd_t *pgd_base);
+
+
+#endif
diff --git a/arch/nios2/include/asm/flat.h b/arch/nios2/include/asm/flat.h
new file mode 100644
index 0000000..526e1cc
--- /dev/null
+++ b/arch/nios2/include/asm/flat.h
@@ -0,0 +1,129 @@
+/*
+ * include/asm-nios2/flat.h -- uClinux bFLT relocations
+ *
+ *  Copyright (C) 2004,05  Microtronix Datacom Ltd
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Wentao Xu <wentao@microtronix.com>
+ */
+
+#ifndef _ASM_NIOS2_FLAT_H__
+#define _ASM_NIOS2_FLAT_H__
+
+#define	flat_reloc_valid(reloc, size)	((reloc) <= (size + 0x8000))
+
+/* The stack is 64-bit aligned for Nios II, so (sp - 1) shall
+ * be 64-bit aligned, where -1 is for argc
+ */
+#define	flat_stack_align(sp)		(sp = (unsigned long *)(((unsigned long)sp - 1) & (-8)))
+
+/* The uClibc port for Nios II expects the argc is followed by argv and envp */
+#define	flat_argvp_envp_on_stack()	1
+
+#define	flat_old_ram_flag(flags)	(flags)
+
+/* We store the type of relocation in the top 4 bits of the `relval.' */
+
+/* Convert a relocation entry into an address.  */
+static inline unsigned long
+flat_get_relocate_addr (unsigned long relval)
+{
+	return relval & 0x0fffffff; /* Mask out top 4-bits */
+}
+
+#define FLAT_NIOS2_RELOC_TYPE(relval) ((relval) >> 28)
+
+#define FLAT_NIOS2_R_32			0 /* Normal 32-bit reloc */
+#define FLAT_NIOS2_R_HI_LO		1 /* High 16-bits + low 16-bits field */
+#define FLAT_NIOS2_R_HIADJ_LO	2 /* High 16-bits adjust + low 16-bits field */
+#define FLAT_NIOS2_R_CALL26		4 /* Call imm26 */
+
+#define flat_set_persistent(relval, p)	0
+
+/* Extract the address to be relocated from the symbol reference at rp;
+ * relval is the raw relocation-table entry from which RP is derived.
+ * rp shall always be 32-bit aligned
+ */
+static inline unsigned long flat_get_addr_from_rp (unsigned long *rp,
+						   unsigned long relval,
+						   unsigned long flags,
+						   unsigned long *persistent)
+{
+	switch (FLAT_NIOS2_RELOC_TYPE(relval))
+	{
+	case FLAT_NIOS2_R_32:
+		/* Simple 32-bit address. The loader expect it in bigger endian */
+		return htonl(*rp);
+
+	case FLAT_NIOS2_R_HI_LO:
+		/* get the two 16-bit immediate value from instructions, then
+		 * construct a 32-bit value. Again the loader expect bigger endian
+		 */
+		return htonl ((((rp[0] >> 6) & 0xFFFF) << 16 ) | 
+					  ((rp[1] >> 6) & 0xFFFF));
+
+	case FLAT_NIOS2_R_HIADJ_LO:
+		{
+		/* get the two 16-bit immediate value from instructions, then
+		 * construct a 32-bit value. Again the loader expect bigger endian
+		 */
+		 unsigned int low, high;
+		 high = (rp[0] >> 6) & 0xFFFF;
+		 low  = (rp[1] >> 6) & 0xFFFF;
+		 
+		 if ((low >> 15) & 1) high--;
+		 
+		 return htonl ((high << 16 ) | low );
+		}
+	case FLAT_NIOS2_R_CALL26:
+		/* the 26-bit immediate value is actually 28-bit */
+		return htonl(((*rp) >> 6) << 2);
+
+	default:
+		return ~0;	/* bogus value */
+	}
+}
+
+/* Insert the address addr into the symbol reference at rp;
+ * relval is the raw relocation-table entry from which rp is derived.
+ * rp shall always be 32-bit aligned
+ */
+static inline void flat_put_addr_at_rp (unsigned long *rp, unsigned long addr,
+					unsigned long relval)
+{
+	unsigned long exist_val;
+	switch (FLAT_NIOS2_RELOC_TYPE (relval)) {
+	case FLAT_NIOS2_R_32:
+		/* Simple 32-bit address.  */
+		*rp = addr;
+		break;
+
+	case FLAT_NIOS2_R_HI_LO:
+		exist_val = rp[0];
+		rp[0] = ((((exist_val >> 22) << 16) | (addr >> 16)) << 6) | (exist_val & 0x3F);
+		exist_val = rp[1];
+		rp[1] = ((((exist_val >> 22) << 16) | (addr & 0xFFFF)) << 6) | (exist_val & 0x3F);
+		break;
+
+	case FLAT_NIOS2_R_HIADJ_LO:
+		{
+		unsigned int high = (addr >> 16);
+		if ((addr >> 15) & 1) 
+			high = (high + 1) & 0xFFFF;
+		exist_val = rp[0];
+		rp[0] = ((((exist_val >> 22) << 16) | high) << 6) | (exist_val & 0x3F);
+		exist_val = rp[1];
+		rp[1] = ((((exist_val >> 22) << 16) | (addr & 0xFFFF)) << 6) | (exist_val & 0x3F);
+		break;
+		}
+	case FLAT_NIOS2_R_CALL26:
+		/* the opcode of CALL is 0, so just store the value */
+		*rp = ((addr >> 2) << 6);
+		break;
+	}
+}
+
+#endif /* _ASM_NIOS2_FLAT_H__ */
diff --git a/arch/nios2/include/asm/ftrace.h b/arch/nios2/include/asm/ftrace.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/arch/nios2/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/nios2/include/asm/futex.h b/arch/nios2/include/asm/futex.h
new file mode 100644
index 0000000..0b74582
--- /dev/null
+++ b/arch/nios2/include/asm/futex.h
@@ -0,0 +1 @@
+#include <asm-generic/futex.h>
diff --git a/arch/nios2/include/asm/gpio.h b/arch/nios2/include/asm/gpio.h
new file mode 100644
index 0000000..4c701d0
--- /dev/null
+++ b/arch/nios2/include/asm/gpio.h
@@ -0,0 +1,80 @@
+#ifndef _ASM_NIOS2_GPIO_H_
+#define _ASM_NIOS2_GPIO_H_ 1
+
+#include <asm/io.h>
+extern resource_size_t nios2_gpio_mapbase;
+
+#define AVALON_GPIO_PORT(p) (nios2_gpio_mapbase + ((p) << 2))
+
+static inline int gpio_is_valid(int number)
+{
+	return 1;
+}
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+	return 0;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+}
+
+static inline int gpio_direction_input(unsigned gpio)
+{
+	writel(1, AVALON_GPIO_PORT(gpio));
+	return 0;
+}
+
+static inline int gpio_direction_output(unsigned gpio, int value)
+{
+	writel(value?3:2, AVALON_GPIO_PORT(gpio));
+	return 0;
+}
+
+static inline int gpio_get_value(unsigned gpio)
+{
+	return readl(AVALON_GPIO_PORT(gpio));
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+	writel(value?3:2, AVALON_GPIO_PORT(gpio));
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+	return 0;
+}
+
+static inline int gpio_get_value_cansleep(unsigned gpio)
+{
+	return gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value_cansleep(unsigned gpio, int value)
+{
+	gpio_set_value(gpio, value);
+}
+
+static inline int gpio_export(unsigned gpio, bool direction_may_change)
+{
+	return 0;
+}
+
+static inline void gpio_unexport(unsigned gpio)
+{
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+	return -EINVAL;
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+	return -EINVAL;
+}
+
+#undef AVALON_GPIO_PORT
+#endif /* _ASM_NIOS2_GPIO_H_ */
diff --git a/arch/nios2/include/asm/hardirq.h b/arch/nios2/include/asm/hardirq.h
new file mode 100644
index 0000000..fb3c05a
--- /dev/null
+++ b/arch/nios2/include/asm/hardirq.h
@@ -0,0 +1 @@
+#include <asm-generic/hardirq.h>
diff --git a/arch/nios2/include/asm/hw_irq.h b/arch/nios2/include/asm/hw_irq.h
new file mode 100644
index 0000000..1f5ef7d
--- /dev/null
+++ b/arch/nios2/include/asm/hw_irq.h
@@ -0,0 +1 @@
+#include <asm-generic/hw_irq.h>
diff --git a/arch/nios2/include/asm/io.h b/arch/nios2/include/asm/io.h
new file mode 100644
index 0000000..e9b99f1
--- /dev/null
+++ b/arch/nios2/include/asm/io.h
@@ -0,0 +1,243 @@
+#ifndef __NIOS2_IO_H__
+#define __NIOS2_IO_H__
+
+#include <asm/system.h>
+#include <asm/pgtable-bits.h>
+
+#define readb(addr) \
+    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define readw(addr) \
+    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
+#define readl(addr) \
+    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
+
+#define readb_relaxed(addr) readb(addr)
+#define readw_relaxed(addr) readw(addr)
+#define readl_relaxed(addr) readl(addr)
+
+#define writeb(b, addr) (void)((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b, addr) (void)((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b, addr) (void)((*(volatile unsigned int *) (addr)) = (b))
+
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+
+#ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE
+#define __IO_USE_DUFFS
+#endif
+
+#ifdef __IO_USE_DUFFS
+
+/* Use "Duff's Device" to unroll the loops. */
+#define __IO_OUT_LOOP(a, b, l)				\
+	do {						\
+		if (l > 0) {				\
+			int _n = (l + 7) / 8;		\
+			switch (l % 8) {		\
+			case 0: do {	*a = *b++;	\
+			case 7:		*a = *b++;	\
+			case 6:		*a = *b++;	\
+			case 5:		*a = *b++;	\
+			case 4:		*a = *b++;	\
+			case 3:		*a = *b++;	\
+			case 2:		*a = *b++;	\
+			case 1:		*a = *b++;	\
+				} while (--_n > 0);	\
+			}				\
+		}					\
+	} while (0)
+
+#define __IO_IN_LOOP(a, b, l)				\
+	do {						\
+		if (l > 0) {				\
+			int _n = (l + 7) / 8;		\
+			switch (l % 8) {		\
+			case 0: do {	*b++ = *a;	\
+			case 7:		*b++ = *a;	\
+			case 6:		*b++ = *a;	\
+			case 5:		*b++ = *a;	\
+			case 4:		*b++ = *a;	\
+			case 3:		*b++ = *a;	\
+			case 2:		*b++ = *a;	\
+			case 1:		*b++ = *a;	\
+				} while (--_n > 0);	\
+			}				\
+		}					\
+	} while (0)
+
+#else
+
+/* Use simple loops. */
+#define __IO_OUT_LOOP(a, b, l)				\
+	do {						\
+		while (l--) 				\
+			*a = *b++;			\
+	} while (0)
+
+#define __IO_IN_LOOP(a, b, l)				\
+	do {						\
+		while (l--)				\
+			*b++ = *a;			\
+	} while (0)
+
+#endif
+
+
+static inline void io_outsb(void __iomem *addr, void *buf, int len)
+{
+	volatile unsigned char *ap = (volatile unsigned char *)addr;
+	unsigned char *bp = (unsigned char *)buf;
+	__IO_OUT_LOOP(ap, bp, len);
+}
+
+static inline void io_outsw(void __iomem *addr, void *buf, int len)
+{
+	volatile unsigned short *ap = (volatile unsigned short *)addr;
+	unsigned short *bp = (unsigned short *)buf;
+	__IO_OUT_LOOP(ap, bp, len);
+}
+
+static inline void io_outsl(void __iomem *addr, void *buf, int len)
+{
+	volatile unsigned int *ap = (volatile unsigned int *)addr;
+	unsigned int *bp = (unsigned int *)buf;
+	__IO_OUT_LOOP(ap, bp, len);
+}
+
+static inline void io_insb(void __iomem *addr, void *buf, int len)
+{
+	volatile unsigned char *ap = (volatile unsigned char *)addr;
+	unsigned char *bp = (unsigned char *)buf;
+	__IO_IN_LOOP(ap, bp, len);
+}
+
+static inline void io_insw(void __iomem *addr, void *buf, int len)
+{
+	volatile unsigned short *ap = (volatile unsigned short *)addr;
+	unsigned short *bp = (unsigned short *)buf;
+	__IO_IN_LOOP(ap, bp, len);
+}
+
+static inline void io_insl(void __iomem *addr, void *buf, int len)
+{
+	volatile unsigned int *ap = (volatile unsigned int *)addr;
+	unsigned int *bp = (unsigned int *)buf;
+	__IO_IN_LOOP(ap, bp, len);
+}
+
+#undef __IO_OUT_LOOP
+#undef __IO_IN_LOOP
+#undef __IO_USE_DUFFS
+
+#define mmiowb()
+
+/*
+ *	make the short names macros so specific devices
+ *	can override them as required
+ */
+
+#define memset_io(a, b, c)	memset((void *)(a), (b), (c))
+#define memcpy_fromio(a, b, c)	memcpy((a), (void *)(b), (c))
+#define memcpy_toio(a, b, c)	memcpy((void *)(a), (b), (c))
+
+#define inb(addr)    readb(addr)
+#define inw(addr)    readw(addr)
+#define inl(addr)    readl(addr)
+#define outb(x, addr) ((void) writeb(x, addr))
+#define outw(x, addr) ((void) writew(x, addr))
+#define outl(x, addr) ((void) writel(x, addr))
+
+#define inb_p(addr)    inb(addr)
+#define inw_p(addr)    inw(addr)
+#define inl_p(addr)    inl(addr)
+#define outb_p(x, addr) outb(x, addr)
+#define outw_p(x, addr) outw(x, addr)
+#define outl_p(x, addr) outl(x, addr)
+
+#define outsb(a, b, l) io_outsb(a, b, l)
+#define outsw(a, b, l) io_outsw(a, b, l)
+#define outsl(a, b, l) io_outsl(a, b, l)
+
+#define insb(a, b, l) io_insb(a, b, l)
+#define insw(a, b, l) io_insw(a, b, l)
+#define insl(a, b, l) io_insl(a, b, l)
+
+#define ioread8_rep(a,d,c)	insb(a,d,c)
+#define ioread16_rep(a,d,c)	insw(a,d,c)
+#define ioread32_rep(a,d,c)	insl(a,d,c)
+#define iowrite8_rep(a,s,c)	outsb(a,s,c)
+#define iowrite16_rep(a,s,c)	outsw(a,s,c)
+#define iowrite32_rep(a,s,c)	outsl(a,s,c)
+
+#define ioread8(X)			readb(X)
+#define ioread16(X)			readw(X)
+#define ioread32(X)			readl(X)
+#define iowrite8(val,X)			writeb(val,X)
+#define iowrite16(val,X)		writew(val,X)
+#define iowrite32(val,X)		writel(val,X)
+
+
+extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
+extern void __iounmap(void *addr);
+
+extern inline void *ioremap(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, 0);
+}
+extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, 0);
+}
+extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, 0);
+}
+extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, _PAGE_CACHED);
+}
+
+extern inline void iounmap(void *addr) {
+   __iounmap(addr);
+}
+
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* Pages to physical address... */
+#define page_to_phys(page)      virt_to_phys(page_to_virt(page))
+#define page_to_bus(page)       page_to_virt(page)
+
+#define phys_to_virt(vaddr)	((void *) ((unsigned long)vaddr + PAGE_OFFSET - PHYS_OFFSET))
+#define virt_to_phys(vaddr)	((unsigned long) ((unsigned long)vaddr - PAGE_OFFSET + PHYS_OFFSET))
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+#define ioport_map(port, nr)	ioremap(port, nr)
+#define ioport_unmap(port)	iounmap(port)
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p)	__va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p)	p
+
+/* Macros used for smc91x.c driver */
+#define readsb(p, d, l)		insb(p, d, l)
+#define readsw(p, d, l)		insw(p, d, l)
+#define readsl(p, d, l)		insl(p, d, l)
+#define writesb(p, d, l)	outsb(p, d, l)
+#define writesw(p, d, l)	outsw(p, d, l)
+#define writesl(p, d, l)	outsl(p, d, l)
+
+#endif /* __NIOS2_IO_H__ */
diff --git a/arch/nios2/include/asm/ioctl.h b/arch/nios2/include/asm/ioctl.h
new file mode 100644
index 0000000..b279fe0
--- /dev/null
+++ b/arch/nios2/include/asm/ioctl.h
@@ -0,0 +1 @@
+#include <asm-generic/ioctl.h>
diff --git a/arch/nios2/include/asm/ioctls.h b/arch/nios2/include/asm/ioctls.h
new file mode 100644
index 0000000..89e0475
--- /dev/null
+++ b/arch/nios2/include/asm/ioctls.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_NIOS2_IOCTLS_H
+#define _ASM_NIOS2_IOCTLS_H
+
+#define FIOQSIZE	0x545E
+#include <asm-generic/ioctls.h>
+
+#endif
diff --git a/arch/nios2/include/asm/ipcbuf.h b/arch/nios2/include/asm/ipcbuf.h
new file mode 100644
index 0000000..84c7e51
--- /dev/null
+++ b/arch/nios2/include/asm/ipcbuf.h
@@ -0,0 +1 @@
+#include <asm-generic/ipcbuf.h>
diff --git a/arch/nios2/include/asm/irq.h b/arch/nios2/include/asm/irq.h
new file mode 100644
index 0000000..8824b2b
--- /dev/null
+++ b/arch/nios2/include/asm/irq.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_NIOS2_IRQ_H
+#define _ASM_NIOS2_IRQ_H
+
+#define SYS_IRQS	32
+#define NR_IRQS		SYS_IRQS
+
+#include <asm-generic/irq.h>
+
+#endif
diff --git a/arch/nios2/include/asm/irq_regs.h b/arch/nios2/include/asm/irq_regs.h
new file mode 100644
index 0000000..3dd9c0b
--- /dev/null
+++ b/arch/nios2/include/asm/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/arch/nios2/include/asm/kdebug.h b/arch/nios2/include/asm/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/arch/nios2/include/asm/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/arch/nios2/include/asm/kmap_types.h b/arch/nios2/include/asm/kmap_types.h
new file mode 100644
index 0000000..3575c64
--- /dev/null
+++ b/arch/nios2/include/asm/kmap_types.h
@@ -0,0 +1 @@
+#include <asm-generic/kmap_types.h>
diff --git a/arch/nios2/include/asm/linkage.h b/arch/nios2/include/asm/linkage.h
new file mode 100644
index 0000000..b9bbc66
--- /dev/null
+++ b/arch/nios2/include/asm/linkage.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_NIOS2_LINKAGE_H
+#define _ASM_NIOS2_LINKAGE_H
+
+#define __ALIGN .align 4
+#define __ALIGN_STR ".align 4"
+
+#endif
diff --git a/arch/nios2/include/asm/local.h b/arch/nios2/include/asm/local.h
new file mode 100644
index 0000000..c11c530
--- /dev/null
+++ b/arch/nios2/include/asm/local.h
@@ -0,0 +1 @@
+#include <asm-generic/local.h>
diff --git a/arch/nios2/include/asm/maximum_mmu.h b/arch/nios2/include/asm/maximum_mmu.h
new file mode 100644
index 0000000..c4eff5a
--- /dev/null
+++ b/arch/nios2/include/asm/maximum_mmu.h
@@ -0,0 +1,371 @@
+#ifndef _ALTERA_LINUX_CPU_H_
+#define _ALTERA_LINUX_CPU_H_
+
+/* Note, this file was manually edited after generation
+ * since the multiple inclusion proctetion macro above collides with
+ * include/linux/cpu.h
+ */
+
+/*
+ * This file was automatically generated by the swinfo2header utility.
+ *
+ * Created from SOPC Builder system 'nios2_linux_3c120_125mhz_sys_sopc' in
+ * file 'maximum//nios2_linux_3c120_125mhz_sys_sopc.sopcinfo'.
+ */
+
+/*
+ * This file contains macros for module 'linux_cpu' and devices
+ * connected to the following masters:
+ *   instruction_master
+ *   tightly_coupled_instruction_master_0
+ *   data_master
+ *   tightly_coupled_data_master_0
+ *
+ * Do not #include this header file and another header file created for a
+ * different module or master group at the same time.
+ * Doing so may result in duplicate #defines.
+ * Instead, use the system header file which has #defines with unique names.
+ */
+
+/*
+ * Macros for module 'linux_cpu', class 'altera_nios2'.
+ * The macros have no prefix.
+ */
+#define CPU_IMPLEMENTATION "fast"
+#define ICACHE_LINE_SIZE 32
+#define ICACHE_LINE_SIZE_LOG2 5
+#define ICACHE_SIZE 32768
+#define DCACHE_LINE_SIZE 32
+#define DCACHE_LINE_SIZE_LOG2 5
+#define DCACHE_SIZE 32768
+#define INITDA_SUPPORTED 
+#define FLUSHDA_SUPPORTED 
+#define HAS_JMPI_INSTRUCTION 
+#define MMU_PRESENT 
+#define KERNEL_REGION_BASE 0xc0000000
+#define IO_REGION_BASE 0xe0000000
+#define KERNEL_MMU_REGION_BASE 0x80000000
+#define USER_REGION_BASE 0x0
+#define PROCESS_ID_NUM_BITS 14
+#define TLB_NUM_WAYS 16
+#define TLB_PTR_SZ 10
+#define TLB_NUM_ENTRIES 1024
+#define FAST_TLB_MISS_EXCEPTION_ADDR 0xc7fff400
+#define EXCEPTION_ADDR 0xd0000020
+#define RESET_ADDR 0xc2800000
+#define BREAK_ADDR 0xc7fff820
+#define HAS_DEBUG_STUB 
+#define HAS_DEBUG_CORE 1
+#define HAS_ILLEGAL_INSTRUCTION_EXCEPTION 
+#define HAS_ILLEGAL_MEMORY_ACCESS_EXCEPTION 
+#define HAS_EXTRA_EXCEPTION_INFO 
+#define CPU_ID_SIZE 1
+#define CPU_ID_VALUE 0x0
+#define HARDWARE_DIVIDE_PRESENT 1
+#define HARDWARE_MULTIPLY_PRESENT 1
+#define HARDWARE_MULX_PRESENT 0
+#define INST_ADDR_WIDTH 29
+#define DATA_ADDR_WIDTH 29
+
+/*
+ * Macros for device 'cfi_flash_64m', class 'altera_avalon_cfi_flash'
+ * The macros are prefixed with 'CFI_FLASH_64M_'.
+ * The prefix is the slave descriptor.
+ */
+#define CFI_FLASH_64M_BASE 0x0
+#define CFI_FLASH_64M_SPAN 67108864u
+#define CFI_FLASH_64M_SETUP_VALUE 75
+#define CFI_FLASH_64M_WAIT_VALUE 35
+#define CFI_FLASH_64M_HOLD_VALUE 1
+#define CFI_FLASH_64M_TIMING_UNITS "ns"
+#define CFI_FLASH_64M_SIZE 67108864u
+
+/*
+ * Macros for device 'fast_tlb_miss_ram_1k', class 'altera_avalon_onchip_memory2'
+ * The macros are prefixed with 'FAST_TLB_MISS_RAM_1K_'.
+ * The prefix is the slave descriptor.
+ */
+#define FAST_TLB_MISS_RAM_1K_BASE 0x7fff400
+#define FAST_TLB_MISS_RAM_1K_SPAN 1024u
+#define FAST_TLB_MISS_RAM_1K_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0
+#define FAST_TLB_MISS_RAM_1K_INIT_CONTENTS_FILE "fast_tlb_miss_ram_1k"
+#define FAST_TLB_MISS_RAM_1K_NON_DEFAULT_INIT_FILE_ENABLED 0
+#define FAST_TLB_MISS_RAM_1K_GUI_RAM_BLOCK_TYPE "Automatic"
+#define FAST_TLB_MISS_RAM_1K_WRITABLE 1
+#define FAST_TLB_MISS_RAM_1K_DUAL_PORT 1
+#define FAST_TLB_MISS_RAM_1K_SIZE_VALUE 1024u
+#define FAST_TLB_MISS_RAM_1K_SIZE_MULTIPLE 1
+#define FAST_TLB_MISS_RAM_1K_CONTENTS_INFO ""
+#define FAST_TLB_MISS_RAM_1K_RAM_BLOCK_TYPE "Auto"
+#define FAST_TLB_MISS_RAM_1K_INIT_MEM_CONTENT 1
+#define FAST_TLB_MISS_RAM_1K_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0
+#define FAST_TLB_MISS_RAM_1K_INSTANCE_ID "NONE"
+#define FAST_TLB_MISS_RAM_1K_READ_DURING_WRITE_MODE "DONT_CARE"
+
+/*
+ * Macros for device 'descriptor_memory', class 'altera_avalon_onchip_memory2'
+ * The macros are prefixed with 'DESCRIPTOR_MEMORY_'.
+ * The prefix is the slave descriptor.
+ */
+#define DESCRIPTOR_MEMORY_BASE 0x8002000
+#define DESCRIPTOR_MEMORY_SPAN 8192u
+#define DESCRIPTOR_MEMORY_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0
+#define DESCRIPTOR_MEMORY_INIT_CONTENTS_FILE "descriptor_memory"
+#define DESCRIPTOR_MEMORY_NON_DEFAULT_INIT_FILE_ENABLED 0
+#define DESCRIPTOR_MEMORY_GUI_RAM_BLOCK_TYPE "Automatic"
+#define DESCRIPTOR_MEMORY_WRITABLE 1
+#define DESCRIPTOR_MEMORY_DUAL_PORT 0
+#define DESCRIPTOR_MEMORY_SIZE_VALUE 8192u
+#define DESCRIPTOR_MEMORY_SIZE_MULTIPLE 1
+#define DESCRIPTOR_MEMORY_CONTENTS_INFO ""
+#define DESCRIPTOR_MEMORY_RAM_BLOCK_TYPE "Auto"
+#define DESCRIPTOR_MEMORY_INIT_MEM_CONTENT 1
+#define DESCRIPTOR_MEMORY_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0
+#define DESCRIPTOR_MEMORY_INSTANCE_ID "NONE"
+#define DESCRIPTOR_MEMORY_READ_DURING_WRITE_MODE "DONT_CARE"
+
+/*
+ * Macros for device 'tse_mac', class 'triple_speed_ethernet'
+ * The macros are prefixed with 'TSE_MAC_'.
+ * The prefix is the slave descriptor.
+ */
+#define TSE_MAC_BASE 0x8004000
+#define TSE_MAC_SPAN 1024u
+#define TSE_MAC_TRANSMIT "sgdma_tx"
+#define TSE_MAC_RECEIVE "sgdma_rx"
+#define TSE_MAC_TRANSMIT_FIFO_DEPTH 2048
+#define TSE_MAC_RECEIVE_FIFO_DEPTH 2048
+#define TSE_MAC_FIFO_WIDTH 32
+#define TSE_MAC_ENABLE_MACLITE 0
+#define TSE_MAC_MACLITE_GIGE 0
+#define TSE_MAC_USE_MDIO 1
+#define TSE_MAC_NUMBER_OF_CHANNEL 0
+#define TSE_MAC_NUMBER_OF_MAC_MDIO_SHARED 0
+#define TSE_MAC_IS_MULTICHANNEL_MAC 0
+#define TSE_MAC_MDIO_SHARED 0
+#define TSE_MAC_REGISTER_SHARED 0
+#define TSE_MAC_PCS 0
+#define TSE_MAC_PCS_SGMII 0
+#define TSE_MAC_PCS_ID 0u
+
+/*
+ * Macros for device 'sgdma_rx', class 'altera_avalon_sgdma'
+ * The macros are prefixed with 'SGDMA_RX_'.
+ * The prefix is the slave descriptor.
+ */
+#define SGDMA_RX_BASE 0x8004400
+#define SGDMA_RX_SPAN 1024u
+#define SGDMA_RX_IRQ 2
+#define SGDMA_RX_READ_BLOCK_DATA_WIDTH 32
+#define SGDMA_RX_WRITE_BLOCK_DATA_WIDTH 32
+#define SGDMA_RX_STREAM_DATA_WIDTH 32
+#define SGDMA_RX_ADDRESS_WIDTH 32
+#define SGDMA_RX_HAS_READ_BLOCK 0
+#define SGDMA_RX_HAS_WRITE_BLOCK 1
+#define SGDMA_RX_READ_BURSTCOUNT_WIDTH 4
+#define SGDMA_RX_WRITE_BURSTCOUNT_WIDTH 4
+#define SGDMA_RX_BURST_TRANSFER 0
+#define SGDMA_RX_ALWAYS_DO_MAX_BURST 1
+#define SGDMA_RX_DESCRIPTOR_READ_BURST 0
+#define SGDMA_RX_UNALIGNED_TRANSFER 0
+#define SGDMA_RX_CONTROL_SLAVE_DATA_WIDTH 32
+#define SGDMA_RX_CONTROL_SLAVE_ADDRESS_WIDTH 8
+#define SGDMA_RX_DESC_DATA_WIDTH 32
+#define SGDMA_RX_CHAIN_WRITEBACK_DATA_WIDTH 32
+#define SGDMA_RX_STATUS_TOKEN_DATA_WIDTH 24
+#define SGDMA_RX_BYTES_TO_TRANSFER_DATA_WIDTH 16
+#define SGDMA_RX_BURST_DATA_WIDTH 8
+#define SGDMA_RX_CONTROL_DATA_WIDTH 8
+#define SGDMA_RX_ATLANTIC_CHANNEL_DATA_WIDTH 4
+#define SGDMA_RX_COMMAND_FIFO_DATA_WIDTH 104
+#define SGDMA_RX_SYMBOLS_PER_BEAT 4
+#define SGDMA_RX_IN_ERROR_WIDTH 6
+#define SGDMA_RX_OUT_ERROR_WIDTH 0
+
+/*
+ * Macros for device 'ddr2_lo_latency_128m', class 'altmemddr2'
+ * Path to the device is from the master group 'sgdma_rx_m_write'.
+ * The macros are prefixed with 'SGDMA_RX_M_WRITE_DDR2_LO_LATENCY_128M_'.
+ * The prefix is the master group descriptor and the slave descriptor.
+ */
+#define SGDMA_RX_M_WRITE_DDR2_LO_LATENCY_128M_BASE 0x10000000
+#define SGDMA_RX_M_WRITE_DDR2_LO_LATENCY_128M_SPAN 134217728u
+
+/*
+ * Macros for device 'sgdma_tx', class 'altera_avalon_sgdma'
+ * The macros are prefixed with 'SGDMA_TX_'.
+ * The prefix is the slave descriptor.
+ */
+#define SGDMA_TX_BASE 0x8004800
+#define SGDMA_TX_SPAN 1024u
+#define SGDMA_TX_IRQ 3
+#define SGDMA_TX_READ_BLOCK_DATA_WIDTH 32
+#define SGDMA_TX_WRITE_BLOCK_DATA_WIDTH 32
+#define SGDMA_TX_STREAM_DATA_WIDTH 32
+#define SGDMA_TX_ADDRESS_WIDTH 32
+#define SGDMA_TX_HAS_READ_BLOCK 1
+#define SGDMA_TX_HAS_WRITE_BLOCK 0
+#define SGDMA_TX_READ_BURSTCOUNT_WIDTH 4
+#define SGDMA_TX_WRITE_BURSTCOUNT_WIDTH 4
+#define SGDMA_TX_BURST_TRANSFER 0
+#define SGDMA_TX_ALWAYS_DO_MAX_BURST 1
+#define SGDMA_TX_DESCRIPTOR_READ_BURST 0
+#define SGDMA_TX_UNALIGNED_TRANSFER 0
+#define SGDMA_TX_CONTROL_SLAVE_DATA_WIDTH 32
+#define SGDMA_TX_CONTROL_SLAVE_ADDRESS_WIDTH 8
+#define SGDMA_TX_DESC_DATA_WIDTH 32
+#define SGDMA_TX_CHAIN_WRITEBACK_DATA_WIDTH 32
+#define SGDMA_TX_STATUS_TOKEN_DATA_WIDTH 24
+#define SGDMA_TX_BYTES_TO_TRANSFER_DATA_WIDTH 16
+#define SGDMA_TX_BURST_DATA_WIDTH 8
+#define SGDMA_TX_CONTROL_DATA_WIDTH 8
+#define SGDMA_TX_ATLANTIC_CHANNEL_DATA_WIDTH 4
+#define SGDMA_TX_COMMAND_FIFO_DATA_WIDTH 104
+#define SGDMA_TX_SYMBOLS_PER_BEAT 4
+#define SGDMA_TX_IN_ERROR_WIDTH 0
+#define SGDMA_TX_OUT_ERROR_WIDTH 1
+
+/*
+ * Macros for device 'ddr2_lo_latency_128m', class 'altmemddr2'
+ * Path to the device is from the master group 'sgdma_tx_m_read'.
+ * The macros are prefixed with 'SGDMA_TX_M_READ_DDR2_LO_LATENCY_128M_'.
+ * The prefix is the master group descriptor and the slave descriptor.
+ */
+#define SGDMA_TX_M_READ_DDR2_LO_LATENCY_128M_BASE 0x10000000
+#define SGDMA_TX_M_READ_DDR2_LO_LATENCY_128M_SPAN 134217728u
+
+/*
+ * Macros for device 'uart', class 'altera_avalon_uart'
+ * The macros are prefixed with 'UART_'.
+ * The prefix is the slave descriptor.
+ */
+#define UART_BASE 0x8004c80
+#define UART_SPAN 32u
+#define UART_IRQ 10
+#define UART_BAUD 115200
+#define UART_DATA_BITS 8
+#define UART_FIXED_BAUD 0
+#define UART_PARITY 'N'
+#define UART_STOP_BITS 1
+#define UART_USE_CTS_RTS 0
+#define UART_USE_EOP_REGISTER 0
+#define UART_SIM_TRUE_BAUD 0
+#define UART_SIM_CHAR_STREAM ""
+#define UART_FREQ 62500000u
+
+/*
+ * Macros for device 'user_led_pio_8out', class 'altera_avalon_pio'
+ * The macros are prefixed with 'USER_LED_PIO_8OUT_'.
+ * The prefix is the slave descriptor.
+ */
+#define USER_LED_PIO_8OUT_BASE 0x8004cc0
+#define USER_LED_PIO_8OUT_SPAN 16u
+#define USER_LED_PIO_8OUT_DO_TEST_BENCH_WIRING 0
+#define USER_LED_PIO_8OUT_DRIVEN_SIM_VALUE 0x0
+#define USER_LED_PIO_8OUT_HAS_TRI 0
+#define USER_LED_PIO_8OUT_HAS_OUT 1
+#define USER_LED_PIO_8OUT_HAS_IN 0
+#define USER_LED_PIO_8OUT_CAPTURE 0
+#define USER_LED_PIO_8OUT_BIT_CLEARING_EDGE_REGISTER 0
+#define USER_LED_PIO_8OUT_DATA_WIDTH 8
+#define USER_LED_PIO_8OUT_RESET_VALUE 0xff
+#define USER_LED_PIO_8OUT_EDGE_TYPE "NONE"
+#define USER_LED_PIO_8OUT_IRQ_TYPE "NONE"
+#define USER_LED_PIO_8OUT_FREQ 62500000u
+
+/*
+ * Macros for device 'user_dipsw_pio_8in', class 'altera_avalon_pio'
+ * The macros are prefixed with 'USER_DIPSW_PIO_8IN_'.
+ * The prefix is the slave descriptor.
+ */
+#define USER_DIPSW_PIO_8IN_BASE 0x8004ce0
+#define USER_DIPSW_PIO_8IN_SPAN 16u
+#define USER_DIPSW_PIO_8IN_IRQ 8
+#define USER_DIPSW_PIO_8IN_DO_TEST_BENCH_WIRING 0
+#define USER_DIPSW_PIO_8IN_DRIVEN_SIM_VALUE 0x0
+#define USER_DIPSW_PIO_8IN_HAS_TRI 0
+#define USER_DIPSW_PIO_8IN_HAS_OUT 0
+#define USER_DIPSW_PIO_8IN_HAS_IN 1
+#define USER_DIPSW_PIO_8IN_CAPTURE 1
+#define USER_DIPSW_PIO_8IN_BIT_CLEARING_EDGE_REGISTER 1
+#define USER_DIPSW_PIO_8IN_DATA_WIDTH 8
+#define USER_DIPSW_PIO_8IN_RESET_VALUE 0x0
+#define USER_DIPSW_PIO_8IN_EDGE_TYPE "ANY"
+#define USER_DIPSW_PIO_8IN_IRQ_TYPE "EDGE"
+#define USER_DIPSW_PIO_8IN_FREQ 62500000u
+
+/*
+ * Macros for device 'user_pb_pio_4in', class 'altera_avalon_pio'
+ * The macros are prefixed with 'USER_PB_PIO_4IN_'.
+ * The prefix is the slave descriptor.
+ */
+#define USER_PB_PIO_4IN_BASE 0x8004d00
+#define USER_PB_PIO_4IN_SPAN 16u
+#define USER_PB_PIO_4IN_IRQ 9
+#define USER_PB_PIO_4IN_DO_TEST_BENCH_WIRING 0
+#define USER_PB_PIO_4IN_DRIVEN_SIM_VALUE 0x0
+#define USER_PB_PIO_4IN_HAS_TRI 0
+#define USER_PB_PIO_4IN_HAS_OUT 0
+#define USER_PB_PIO_4IN_HAS_IN 1
+#define USER_PB_PIO_4IN_CAPTURE 1
+#define USER_PB_PIO_4IN_BIT_CLEARING_EDGE_REGISTER 1
+#define USER_PB_PIO_4IN_DATA_WIDTH 4
+#define USER_PB_PIO_4IN_RESET_VALUE 0x0
+#define USER_PB_PIO_4IN_EDGE_TYPE "ANY"
+#define USER_PB_PIO_4IN_IRQ_TYPE "EDGE"
+#define USER_PB_PIO_4IN_FREQ 62500000u
+
+/*
+ * Macros for device 'sysid', class 'altera_avalon_sysid'
+ * The macros are prefixed with 'SYSID_'.
+ * The prefix is the slave descriptor.
+ */
+#define SYSID_BASE 0x8004d40
+#define SYSID_SPAN 8u
+#define SYSID_ID 284355090u
+#define SYSID_TIMESTAMP 1233268417u
+
+/*
+ * Macros for device 'jtag_uart', class 'altera_avalon_jtag_uart'
+ * The macros are prefixed with 'JTAG_UART_'.
+ * The prefix is the slave descriptor.
+ */
+#define JTAG_UART_BASE 0x8004d50
+#define JTAG_UART_SPAN 8u
+#define JTAG_UART_IRQ 1
+#define JTAG_UART_WRITE_DEPTH 64
+#define JTAG_UART_READ_DEPTH 64
+#define JTAG_UART_WRITE_THRESHOLD 8
+#define JTAG_UART_READ_THRESHOLD 8
+
+/*
+ * Macros for device 'linux_timer_1ms', class 'altera_avalon_timer'
+ * The macros are prefixed with 'LINUX_TIMER_1MS_'.
+ * The prefix is the slave descriptor.
+ */
+#define LINUX_TIMER_1MS_BASE 0x8400000
+#define LINUX_TIMER_1MS_SPAN 32u
+#define LINUX_TIMER_1MS_IRQ 11
+#define LINUX_TIMER_1MS_ALWAYS_RUN 0
+#define LINUX_TIMER_1MS_FIXED_PERIOD 0
+#define LINUX_TIMER_1MS_SNAPSHOT 1
+#define LINUX_TIMER_1MS_PERIOD 1
+#define LINUX_TIMER_1MS_PERIOD_UNITS "ms"
+#define LINUX_TIMER_1MS_RESET_OUTPUT 0
+#define LINUX_TIMER_1MS_TIMEOUT_PULSE_OUTPUT 0
+#define LINUX_TIMER_1MS_FREQ 125000000u
+#define LINUX_TIMER_1MS_LOAD_VALUE 124999ULL
+#define LINUX_TIMER_1MS_COUNTER_SIZE 32
+#define LINUX_TIMER_1MS_MULT 0.0010
+#define LINUX_TIMER_1MS_TICKS_PER_SEC 1000u
+
+/*
+ * Macros for device 'ddr2_lo_latency_128m', class 'altmemddr2'
+ * The macros are prefixed with 'DDR2_LO_LATENCY_128M_'.
+ * The prefix is the slave descriptor.
+ */
+#define DDR2_LO_LATENCY_128M_BASE 0x10000000
+#define DDR2_LO_LATENCY_128M_SPAN 134217728u
+
+
+#endif /* _ALTERA_LINUX_CPU_H_ */
diff --git a/arch/nios2/include/asm/mman.h b/arch/nios2/include/asm/mman.h
new file mode 100644
index 0000000..8eebf89
--- /dev/null
+++ b/arch/nios2/include/asm/mman.h
@@ -0,0 +1 @@
+#include <asm-generic/mman.h>
diff --git a/arch/nios2/include/asm/mmu.h b/arch/nios2/include/asm/mmu.h
new file mode 100644
index 0000000..888018b
--- /dev/null
+++ b/arch/nios2/include/asm/mmu.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * Taken from the m68knommu.
+ * 
+ * Copyright (C) 2004, Microtronix Datacom Ltd.
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _ASM_NIOS2_MMU_H
+#define _ASM_NIOS2_MMU_H
+
+typedef unsigned long mm_context_t[NR_CPUS];
+
+#endif /* _ASM_NIOS2_MMU_H */
diff --git a/arch/nios2/include/asm/mmu_context.h b/arch/nios2/include/asm/mmu_context.h
new file mode 100644
index 0000000..083710d
--- /dev/null
+++ b/arch/nios2/include/asm/mmu_context.h
@@ -0,0 +1,59 @@
+/*
+ * Switch a MMU context.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_NIOS2_MMU_CONTEXT_H
+#define _ASM_NIOS2_MMU_CONTEXT_H
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm-generic/mm_hooks.h>
+
+/* ivho: leaving old MIPS comment
+ * For the fast tlb miss handlers, we keep a per cpu array of pointers
+ * to the current pgd for each processor. Also, the proc. id is stuffed
+ * into the context register.
+ */
+extern unsigned long pgd_current[];
+
+void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk);
+
+/* ivho: leaving old MIPS comment
+ * Initialize the context related info for a new mm_struct
+ * instance.
+ */
+int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+
+/* Normal, classic MIPS get_new_mmu_context */
+void get_new_mmu_context(struct mm_struct *mm, unsigned long cpu);
+
+/* ivho: leaving old MIPS comment
+ * Destroy context related info for an mm_struct that is about
+ * to be put to rest.
+ */
+void destroy_context(struct mm_struct *mm);
+
+void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+	       struct task_struct *tsk);
+
+
+void deactivate_mm(struct task_struct *tsk, struct mm_struct *mm);
+
+
+/* ivho: leaving old MIPS comment
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+void activate_mm(struct mm_struct *prev, struct mm_struct *next);
+
+
+#endif /* _ASM_NIOS2_MMU_CONTEXT_H */
diff --git a/arch/nios2/include/asm/module.h b/arch/nios2/include/asm/module.h
new file mode 100644
index 0000000..1e4b79f
--- /dev/null
+++ b/arch/nios2/include/asm/module.h
@@ -0,0 +1 @@
+#include <asm-generic/module.h>
diff --git a/arch/nios2/include/asm/msgbuf.h b/arch/nios2/include/asm/msgbuf.h
new file mode 100644
index 0000000..809134c
--- /dev/null
+++ b/arch/nios2/include/asm/msgbuf.h
@@ -0,0 +1 @@
+#include <asm-generic/msgbuf.h>
diff --git a/arch/nios2/include/asm/mutex.h b/arch/nios2/include/asm/mutex.h
new file mode 100644
index 0000000..ff6101a
--- /dev/null
+++ b/arch/nios2/include/asm/mutex.h
@@ -0,0 +1 @@
+#include <asm-generic/mutex-dec.h>
diff --git a/arch/nios2/include/asm/nios.h b/arch/nios2/include/asm/nios.h
new file mode 100644
index 0000000..7bc3c38
--- /dev/null
+++ b/arch/nios2/include/asm/nios.h
@@ -0,0 +1,125 @@
+#ifndef _ASM_NIOS2_H__
+#define _ASM_NIOS2_H__
+
+#if defined(CONFIG_NIOS2_DEFAULT_MMU)
+#include <asm/default_mmu.h>
+#elif defined(CONFIG_NIOS2_MAXIMUM_MMU)
+#include <asm/maximum_mmu.h>
+#elif defined(CONFIG_NIOS2_CUSTOM_FPGA)
+#include <asm/custom_fpga.h>
+#else
+#error "No FPGA configuration selected
+#endif
+
+/* Fake CPU frequency if not defined by the design header file */
+#ifndef CPU_FREQ
+# define CPU_FREQ	0
+#endif
+
+/* Added compability mode with macro names from "old" design...
+ * FIXME: we should really fix drivers instead. but this makes it
+ * easier to switch between old and new design...
+ */
+
+#ifdef LINUX_TIMER_1MS_FREQ
+
+#define CONFIG_ALTERA_CYCLONE_III
+#define DDR2_TOP_BASE DDR2_LO_LATENCY_128M_BASE
+#define DDR2_TOP_SPAN DDR2_LO_LATENCY_128M_SPAN
+
+#define EXT_FLASH_BASE CFI_FLASH_64M_BASE
+#define EXT_FLASH_SPAN CFI_FLASH_64M_SPAN
+
+#define TIMER_1MS_FREQ LINUX_TIMER_1MS_FREQ
+#define TIMER_1MS_BASE LINUX_TIMER_1MS_BASE
+#define TIMER_1MS_SPAN LINUX_TIMER_1MS_SPAN
+#define TIMER_1MS_IRQ LINUX_TIMER_1MS_IRQ
+
+#endif
+
+/* 2C35 dev board */
+#ifdef TIMER_0_FREQ
+
+#define CONFIG_ALTERA_CYCLONE_II
+#define DDR2_TOP_BASE SDRAM_0_BASE
+#define DDR2_TOP_SPAN SDRAM_0_SPAN
+
+#define TIMER_1MS_FREQ TIMER_0_FREQ
+#define TIMER_1MS_BASE TIMER_0_BASE
+#define TIMER_1MS_SPAN TIMER_0_SPAN
+#define TIMER_1MS_IRQ TIMER_0_IRQ
+
+#define UART_BASE UART_0_BASE
+#define UART_SPAN UART_0_SPAN
+#define UART_IRQ UART_0_IRQ
+#define UART_FREQ UART_0_FREQ
+
+#define JTAG_UART_BASE JTAG_UART_0_BASE
+#define JTAG_UART_SPAN JTAG_UART_0_SPAN
+#define JTAG_UART_IRQ JTAG_UART_0_IRQ
+
+#endif
+
+/* NEEK dev board */
+#ifdef SYS_CLK_TIMER_BASE
+
+#define CONFIG_ALTERA_NEEK_C3
+#define DDR2_TOP_BASE DDR_SDRAM_BASE
+#define DDR2_TOP_SPAN DDR_SDRAM_SPAN
+
+#define TIMER_1MS_FREQ SYS_CLK_TIMER_FREQ
+#define TIMER_1MS_BASE SYS_CLK_TIMER_BASE
+#define TIMER_1MS_SPAN SYS_CLK_TIMER_SPAN
+#define TIMER_1MS_IRQ SYS_CLK_TIMER_IRQ
+
+#endif
+
+/* Nios II Constants */
+#define NIOS2_STATUS_PIE_MSK  0x1
+#define NIOS2_STATUS_PIE_OFST 0
+#define NIOS2_STATUS_U_MSK    0x2
+#define NIOS2_STATUS_U_OFST   1
+
+
+#define RDCTL(r) __builtin_rdctl(r)
+#define WRCTL(r,v) __builtin_wrctl(r,v)
+
+#define CTL_STATUS    0
+#define CTL_ESTATUS   1
+#define CTL_BSTATUS   2
+#define CTL_IENABLE   3
+#define CTL_IPENDING  4
+#define CTL_CPUID     5
+#define CTL_RSV1      6
+#define CTL_EXCEPTION 7
+#define CTL_PTEADDR   8
+#define CTL_TLBACC    9
+#define CTL_TLBMISC   10
+#define CTL_RSV2      11
+#define CTL_BADADDR   12
+#define CTL_CONFIG    13
+#define CTL_MPUBASE   14
+#define CTL_MPUACC    15 
+#define CTL_SIM    6
+
+
+#define EXC_RESET               0       /* System reset         */
+#define EXC_CPU_RESET           1       /* CPU reset            */
+#define EXC_EXTERNAL_INTERRUPT  2       /* Interrupt            */
+#define EXC_TRAP                3       /* Trap instruction     */
+#define EXC_UNIMPLEMTED_INSN    4       /* Unimplemented instruction */
+#define EXC_ILLEGAL_INSN        5       /* Illegal instruction     */
+#define EXC_DATA_UNALIGNED      6       /* Misaligned data access   */
+#define EXC_CODE_UNALIGNED      7       /* Misaligned destination address   */
+#define EXC_DIVISION_ERROR      8       /* Division error  */
+#define EXC_SUPERV_INSN_ACCESS  9       /* Supervisor only instr. access       */
+#define EXC_UNUSED              10      /* Unused     */
+#define EXC_SUPERV_DATA_ACCESS  11      /* Supervisor only data address       */
+#define EXC_TLB_DOUBLEFAULT     12      /* TLB double fault.       */
+#define EXC_X_PROTECTION_FAULT  13      /* TLB permission violation (x) */
+#define EXC_R_PROTECTION_FAULT  14      /* TLB permission violation (r) */
+#define EXC_W_PROT_FAULT        15      /* TLB permission violation (w) */
+#define EXC_MPU_REGION_VIOLATION 16     /* MPU region violation */
+
+#endif
+
diff --git a/arch/nios2/include/asm/page.h b/arch/nios2/include/asm/page.h
new file mode 100644
index 0000000..c94b593
--- /dev/null
+++ b/arch/nios2/include/asm/page.h
@@ -0,0 +1,128 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999, 2000, 03 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_NIOS2_PAGE_H
+#define _ASM_NIOS2_PAGE_H
+
+
+#include <asm/spaces.h>
+
+/*
+ * PAGE_SHIFT determines the page size
+ */
+#define PAGE_SHIFT	12
+#define PAGE_SIZE	4096
+#define PAGE_MASK	(~(PAGE_SIZE - 1))
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This gives the physical RAM offset.
+ */
+#define PHYS_OFFSET		DDR2_TOP_BASE
+
+/*
+ * It's normally defined only for FLATMEM config but it's
+ * used in our early mem init code for all memory models.
+ * So always define it.
+ */
+#define ARCH_PFN_OFFSET		PFN_UP(PHYS_OFFSET)
+
+#include <linux/pfn.h>
+#include <asm/io.h>
+
+static inline void clear_page(void * page) {
+  memset(page, 0, PAGE_SIZE);
+}
+extern void copy_page(void * to, void * from);
+
+extern unsigned long shm_align_mask;
+
+static inline unsigned long pages_do_alias(unsigned long addr1,
+	unsigned long addr2)
+{
+	return (addr1 ^ addr2) & shm_align_mask;
+}
+
+struct page;
+
+extern void clear_user_page(void *addr, unsigned long vaddr, struct page *page);
+
+extern void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+			   struct page *to);
+struct vm_area_struct;
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+#define pte_val(x)	((x).pte)
+#define __pte(x)	((pte_t) { (x) } )
+
+
+/*
+ * Finall the top of the hierarchy, the pgd
+ */
+typedef struct { unsigned long pgd; } pgd_t;
+#define pgd_val(x)	((x).pgd)
+#define __pgd(x)	((pgd_t) { (x) } )
+
+/*
+ * Manipulate page protection bits
+ */
+typedef struct { unsigned long pgprot; } pgprot_t;
+#define pgprot_val(x)	((x).pgprot)
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+typedef struct page *pgtable_t;
+
+/*
+ * On R4000-style MMUs where a TLB entry is mapping a adjacent even / odd
+ * pair of pages we only have a single global bit per pair of pages.  When
+ * writing to the TLB make sure we always have the bit set for both pages
+ * or none.  This macro is used to access the `buddy' of the pte we're just
+ * working on.
+ */
+#define ptep_buddy(x)	((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * __pa()/__va() should be used only during mem init.
+ */
+#define __pa_page_offset(x)	PAGE_OFFSET
+#define __pa_symbol(x)	__pa(RELOC_HIDE((unsigned long)(x),0))
+#define __pa(x)		((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET)
+#define __va(x)		((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET))
+
+#define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
+
+#define pfn_valid(pfn)		((pfn) >= ARCH_PFN_OFFSET && (pfn) < (max_mapnr + ARCH_PFN_OFFSET))
+
+#define virt_to_page(kaddr)	pfn_to_page(PFN_DOWN(virt_to_phys(kaddr)))
+#define virt_addr_valid(kaddr)	pfn_valid(PFN_DOWN(virt_to_phys(kaddr)))
+
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#define UNCAC_ADDR(addr) ((void *)((unsigned)(addr) | IO_REGION_BASE))
+#define CAC_ADDR(addr) ((void *)((unsigned)(addr) & ~IO_REGION_BASE | KERNEL_REGION_BASE))
+
+#define page_to_virt(page)	((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
+
+#if 0
+#ifdef CONFIG_LIMITED_DMA
+#define WANT_PAGE_VIRTUAL
+#endif
+#define WANT_PAGE_VIRTUAL
+#endif
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/getorder.h>
+
+#endif /* _ASM_NIOS2_PAGE_H */
diff --git a/arch/nios2/include/asm/param.h b/arch/nios2/include/asm/param.h
new file mode 100644
index 0000000..965d454
--- /dev/null
+++ b/arch/nios2/include/asm/param.h
@@ -0,0 +1 @@
+#include <asm-generic/param.h>
diff --git a/arch/nios2/include/asm/pci.h b/arch/nios2/include/asm/pci.h
new file mode 100644
index 0000000..449bb9e
--- /dev/null
+++ b/arch/nios2/include/asm/pci.h
@@ -0,0 +1,112 @@
+#ifndef _ASM_NIOS2_PCI_H
+#define _ASM_NIOS2_PCI_H
+
+#ifdef __KERNEL__
+
+#include <linux/dma-mapping.h>
+
+/* Can be used to override the logic in pci_scan_bus for skipping
+   already-configured bus numbers - to be used for buggy BIOSes
+   or architectures with incomplete PCI setup by the loader */
+
+#define pcibios_assign_all_busses()	1
+#define pcibios_scan_all_fns(a, b)	0
+
+/*
+ * A board can define one or more PCI channels that represent built-in (or
+ * external) PCI controllers.
+ */
+struct pci_channel {
+	struct pci_ops *pci_ops;
+	struct resource *io_resource;
+	struct resource *mem_resource;
+	int first_devfn;
+	int last_devfn;
+};
+
+/*
+ * Each board initializes this array and terminates it with a NULL entry.
+ */
+extern struct pci_channel board_pci_channels[];
+
+#define PCIBIOS_MIN_IO		board_pci_channels->io_resource->start
+#define PCIBIOS_MIN_MEM		board_pci_channels->mem_resource->start
+
+struct pci_dev;
+
+extern void pcibios_set_master(struct pci_dev *dev);
+
+static inline void pcibios_penalize_isa_irq(int irq, int active)
+{
+	/* We don't do dynamic PCI IRQ allocation */
+}
+
+/* Dynamic DMA mapping stuff.
+ * SuperH has everything mapped statically like x86.
+ */
+
+/* The PCI address space does equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS	(1)
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include <asm/io.h>
+
+/* pci_unmap_{single,page} being a nop depends upon the
+ * configuration.
+ */
+#ifdef CONFIG_SH_PCIDMA_NONCOHERENT
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	\
+	dma_addr_t ADDR_NAME;
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)		\
+	__u32 LEN_NAME;
+#define pci_unmap_addr(PTR, ADDR_NAME)			\
+	((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)		\
+	(((PTR)->ADDR_NAME) = (VAL))
+#define pci_unmap_len(PTR, LEN_NAME)			\
+	((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)		\
+	(((PTR)->LEN_NAME) = (VAL))
+#else
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME)		(0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)	do { } while (0)
+#define pci_unmap_len(PTR, LEN_NAME)		(0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	do { } while (0)
+#endif
+
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
+/* Board-specific fixup routines. */
+extern void pcibios_fixup(void);
+extern void pcibios_fixup_irqs(void);
+
+#ifdef CONFIG_PCI_AUTO
+extern int pciauto_assign_resources(int busno, struct pci_channel *hose);
+#endif
+
+#endif /* __KERNEL__ */
+
+/* generic pci stuff */
+#include <asm-generic/pci.h>
+
+/* generic DMA-mapping stuff */
+#include <asm-generic/pci-dma-compat.h>
+
+#endif /* _ASM_NIOS2_PCI_H */
+
diff --git a/arch/nios2/include/asm/percpu.h b/arch/nios2/include/asm/percpu.h
new file mode 100644
index 0000000..06a959d
--- /dev/null
+++ b/arch/nios2/include/asm/percpu.h
@@ -0,0 +1 @@
+#include <asm-generic/percpu.h>
diff --git a/arch/nios2/include/asm/pgalloc.h b/arch/nios2/include/asm/pgalloc.h
new file mode 100644
index 0000000..ae93048
--- /dev/null
+++ b/arch/nios2/include/asm/pgalloc.h
@@ -0,0 +1,107 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 2001, 2003 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_NIOS2_PGALLOC_H
+#define _ASM_NIOS2_PGALLOC_H
+
+#include <linux/highmem.h>
+#include <linux/mm.h>
+
+static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
+	pte_t *pte)
+{
+	set_pmd(pmd, __pmd((unsigned long)pte));
+}
+
+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
+	pgtable_t pte)
+{
+	set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
+}
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+/*
+ * Initialize a new pmd table with invalid pointers.
+ */
+extern void pmd_init(unsigned long page, unsigned long pagetable);
+
+/*
+ * Initialize a new pgd / pmd table with invalid pointers.
+ */
+extern void pgd_init(unsigned long page);
+
+pgd_t *pgd_alloc(struct mm_struct *mm); // ivho: moved imple to pgalloc.c
+
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+	free_pages((unsigned long)pgd, PGD_ORDER);
+}
+
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+	unsigned long address)
+{
+	pte_t *pte;
+
+	pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, PTE_ORDER);
+
+	return pte;
+}
+
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
+	unsigned long address)
+{
+	struct page *pte;
+
+	pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER);
+	if (pte) {
+		pgtable_page_ctor(pte);
+      /* FIXME: This is only here for the iss, to avoid alias at address 0
+       */
+#if 1
+		clear_highpage(pte);
+#else
+      pte_t *p = kmap_atomic(pte, KM_USER0);
+      int i;
+
+      for(i = 0; i < 1024; i++) {
+         pte_val(p[i]) = i & 0xf;
+      }
+      kunmap_atomic(p, KM_USER0);
+#endif
+   }
+
+	return pte;
+}
+
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+	free_pages((unsigned long)pte, PTE_ORDER);
+}
+
+static inline void pte_free(struct mm_struct *mm, struct page *pte)
+{
+	pgtable_page_dtor(pte);
+	__free_pages(pte, PTE_ORDER);
+}
+
+#define __pte_free_tlb(tlb,pte,addr)			\
+do {							\
+	pgtable_page_dtor(pte);				\
+	tlb_remove_page((tlb),(pte));			\
+} while (0)
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+
+#define check_pgt_cache()	do { } while (0)
+
+extern void pagetable_init(void);
+
+#endif /* _ASM_NIOS2_PGALLOC_H */
diff --git a/arch/nios2/include/asm/pgtable-bits.h b/arch/nios2/include/asm/pgtable-bits.h
new file mode 100644
index 0000000..0e04c38
--- /dev/null
+++ b/arch/nios2/include/asm/pgtable-bits.h
@@ -0,0 +1,38 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 2002 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
+ * Copyright (C) 2002  Maciej W. Rozycki
+ */
+#ifndef _ASM_NIOS2_PGTABLE_BITS_H
+#define _ASM_NIOS2_PGTABLE_BITS_H
+
+/* These are actual HW defined protection bits (unshifted) in TLBACC
+ */
+#define _PAGE_GLOBAL                (1<<0)
+#define _PAGE_EXEC                  (1<<1)
+#define _PAGE_WRITE                 (1<<2)
+#define _PAGE_READ                  (1<<3)
+#define _PAGE_CACHED                (1<<4)
+
+/* TLBACC also has 7 IGNORE bits to use for SW defined attributes
+ */
+#define _PAGE_PRESENT               (1<<5)
+#define _PAGE_ACCESSED              (1<<6)  
+#define _PAGE_MODIFIED              (1<<7)  
+#define _PAGE_FILE                  (1<<8)  
+#define _PAGE_VALID                 (1<<9)
+#define _PAGE_OLD                   (1<<10)
+
+#if 1
+/* ivho: lets not turn on caches right now...
+ */
+#define PAGE_CACHABLE_DEFAULT	_PAGE_CACHED
+#else
+#define PAGE_CACHABLE_DEFAULT	0
+#endif
+
+#endif /* _ASM_NIOS2_PGTABLE_BITS_H */
diff --git a/arch/nios2/include/asm/pgtable.h b/arch/nios2/include/asm/pgtable.h
new file mode 100644
index 0000000..5f523ea
--- /dev/null
+++ b/arch/nios2/include/asm/pgtable.h
@@ -0,0 +1,222 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * pgd = Page Global Directory
+ * pud = Page Upped Directory
+ * pmd = Page Middle Directory
+ * pte = Page Table Entry
+ *
+ * Copyright (C) 2003 Ralf Baechle
+ */
+#ifndef _ASM_NIOS2_PGTABLE_H
+#define _ASM_NIOS2_PGTABLE_H
+
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/addrspace.h>
+
+#include <asm/pgtable-bits.h>
+#include <asm-generic/pgtable-nopmd.h>
+
+#define FIRST_USER_ADDRESS	0
+#define VMALLOC_START	KERNEL_MMU_REGION_BASE
+#define VMALLOC_END	   (KERNEL_REGION_BASE-1)
+
+struct mm_struct;
+
+/* Helper macro
+ */ 
+#define MKP(x,w,r) __pgprot(_PAGE_PRESENT|PAGE_CACHABLE_DEFAULT|\
+			    ((x)?_PAGE_EXEC:0)|			 \
+			    ((r)?_PAGE_READ:0)|			 \
+			    ((w)?_PAGE_WRITE:0))
+/*
+ * These are the macros that generic kernel code needs 
+ * (to populate protection_map[])
+ */
+
+/* Remove W bit on private pages for COW support
+ */	    
+#define __P000	MKP(0,0,0)
+#define __P001	MKP(0,0,1)
+#define __P010	MKP(0,0,0) /*COW*/
+#define __P011	MKP(0,0,1) /*COW*/
+#define __P100	MKP(1,0,0) 
+#define __P101	MKP(1,0,1)
+#define __P110	MKP(1,0,0) /*COW*/
+#define __P111	MKP(1,0,1) /*COW*/
+
+/* Shared pages can have exact HW mapping
+ */ 
+#define __S000	MKP(0,0,0)
+#define __S001	MKP(0,0,1)
+#define __S010	MKP(0,1,0) 
+#define __S011	MKP(0,1,1)
+#define __S100	MKP(1,0,0)
+#define __S101	MKP(1,0,1)
+#define __S110	MKP(1,1,0)
+#define __S111	MKP(1,1,1)
+
+/* Used all over the kernel
+ */
+#define PAGE_KERNEL __pgprot(_PAGE_PRESENT|PAGE_CACHABLE_DEFAULT|_PAGE_READ|_PAGE_WRITE|_PAGE_EXEC|_PAGE_GLOBAL)
+
+/* ivho:PAGE_COPY only used by read_zero_pagealigned() in mem.c
+ */
+#define PAGE_COPY MKP(0,0,1)
+
+
+#define PGD_ORDER	0
+#define PUD_ORDER	aieeee_attempt_to_allocate_pud
+#define PMD_ORDER	1
+#define PTE_ORDER	0
+
+#define PTRS_PER_PGD	((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t))
+#define PTRS_PER_PTE	((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
+
+#define USER_PTRS_PER_PGD	(KERNEL_MMU_REGION_BASE/PGDIR_SIZE)
+
+#define PGDIR_SHIFT	22
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
+
+/* ivho: ?
+ */ 
+#define PTE_FILE_MAX_BITS       28
+
+/* ivho: is vaddr always "unsigned long"? 
+ */
+struct page * ZERO_PAGE(unsigned long vaddr);
+
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
+
+/*
+ * (pmds are folded into puds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+void set_pmd(pmd_t *pmdptr, pmd_t pmdval);
+
+extern void paging_init(void);
+
+/* to find an entry in a pagetable-directory */
+//#define pgd_offset(mm,addr)	((mm)->pgd + pgd_index(addr))
+//ivho: checkme type of addr
+pgd_t *pgd_offset(struct mm_struct *, unsigned long addr);
+
+void pgtable_cache_init(void);
+
+/* ivho: set back to "static inline" when correct in pgtable.c
+ */
+int pte_write(pte_t pte);
+int pte_dirty(pte_t pte);
+int pte_young(pte_t pte);
+int pte_file(pte_t pte);
+static inline int pte_special(pte_t pte)	{ return 0; }
+
+#include <linux/swap.h>
+swp_entry_t   __pte_to_swp_entry(pte_t pte);
+pte_t         __swp_entry_to_pte(swp_entry_t swp);
+unsigned long __swp_type(swp_entry_t);
+pgoff_t       __swp_offset(swp_entry_t);
+swp_entry_t   __swp_entry(unsigned long, pgoff_t offset);
+
+int pte_none(pte_t pte);
+int pte_present(pte_t pte);
+
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+pte_t pte_wrprotect(pte_t pte);
+pte_t pte_mkclean(pte_t pte);
+pte_t pte_mkold(pte_t pte);
+pte_t pte_mkwrite(pte_t pte);
+pte_t pte_mkdirty(pte_t pte);
+static inline pte_t pte_mkspecial(pte_t pte)	{ return pte; }
+
+pte_t pte_mkyoung(pte_t pte);
+pte_t pte_modify(pte_t pte, pgprot_t newprot);
+
+int   pmd_present(pmd_t pmd);
+void  pmd_clear(pmd_t *pmdp);
+
+/*
+ * Certain architectures need to do special things when pte's
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+void set_pte(pte_t *ptep, pte_t pteval);
+void set_pte_at(struct mm_struct *mm, unsigned long addr,pte_t *ptep, pte_t pteval);
+
+//int pmd_none2 (pmd_t *pmd);
+int pmd_none(pmd_t pmd);
+int pmd_bad(pmd_t pmd);
+
+
+void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+pte_t mk_pte(struct page *page, pgprot_t pgprot);
+
+void update_mmu_cache(struct vm_area_struct *vma,
+				    unsigned long address, pte_t pte);
+
+void pte_unmap(pte_t *pte);
+void pte_unmap_nested(pte_t *pte);
+
+pte_t pgoff_to_pte(pgoff_t off);
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+#define pmd_phys(pmd)		virt_to_phys((void *)pmd_val(pmd))
+#define pmd_page(pmd)		(pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
+#define pmd_page_vaddr(pmd)	pmd_val(pmd)
+
+//#define pud_none(pud) 0
+//#define pmd_offset(pmd,off) 0
+
+unsigned long pte_pfn(pte_t pte);
+pte_t * pte_offset_map(pmd_t *dir, unsigned long address);
+pte_t * pte_offset_map_nested(pmd_t *dir, unsigned long address);
+
+/* to find an entry in a kernel page-table-directory */
+pgd_t * pgd_offset_k(unsigned long address);
+
+/* Get the address to the PTE for a vaddr in specfic directory 
+ */
+pte_t * pte_offset_kernel(pmd_t * dir, unsigned long address);
+
+void pgd_ERROR(pgd_t e);
+
+
+pte_t pfn_pte(unsigned long  pfn, pgprot_t prot);
+
+pgoff_t pte_to_pgoff(pte_t pte);
+struct page * pte_page(pte_t pte);
+
+int kern_addr_valid(unsigned long addr);
+
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)	\
+	remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+/*
+ * We provide our own get_unmapped area to cope with the virtual aliasing
+ * constraints placed on us by the cache architecture.
+ */
+
+#define HAVE_ARCH_UNMAPPED_AREA
+
+#include <asm-generic/pgtable.h>
+
+#endif /* _ASM_NIOS2_PGTABLE_H */
diff --git a/arch/nios2/include/asm/pio_struct.h b/arch/nios2/include/asm/pio_struct.h
new file mode 100644
index 0000000..a0506cd
--- /dev/null
+++ b/arch/nios2/include/asm/pio_struct.h
@@ -0,0 +1,16 @@
+#ifndef _PIO_STRUCT_H_
+#define _PIO_STRUCT_H_
+// PIO Peripheral
+
+// PIO Registers
+typedef volatile struct
+	{
+	int np_piodata;          // read/write, up to 32 bits
+	int np_piodirection;     // write/readable, up to 32 bits, 1->output bit
+	int np_piointerruptmask; // write/readable, up to 32 bits, 1->enable interrupt
+	int np_pioedgecapture;   // read, up to 32 bits, cleared by any write
+	} np_pio;
+
+// PIO Routines
+void nr_pio_showhex(int value); // shows low byte on pio named na_seven_seg_pio
+#endif
diff --git a/arch/nios2/include/asm/poll.h b/arch/nios2/include/asm/poll.h
new file mode 100644
index 0000000..587cb21
--- /dev/null
+++ b/arch/nios2/include/asm/poll.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_NIOS2_POLL_H
+#define _ASM_NIOS2_POLL_H
+
+#define POLLWRNORM	POLLOUT
+#define POLLWRBAND	256
+
+#include <asm-generic/poll.h>
+
+#endif
diff --git a/arch/nios2/include/asm/posix_types.h b/arch/nios2/include/asm/posix_types.h
new file mode 100644
index 0000000..6516f98
--- /dev/null
+++ b/arch/nios2/include/asm/posix_types.h
@@ -0,0 +1,27 @@
+#ifndef _ASM_NIOS2_POSIX_TYPES_H
+#define _ASM_NIOS2_POSIX_TYPES_H
+
+typedef unsigned short __kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
+typedef unsigned short __kernel_nlink_t;
+#define __kernel_nlink_t __kernel_nlink_t
+
+typedef unsigned int __kernel_ipc_pid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
+typedef unsigned long __kernel_size_t;
+typedef long __kernel_ssize_t;
+typedef int __kernel_ptrdiff_t;
+#define __kernel_size_t __kernel_size_t
+
+typedef unsigned short __kernel_old_uid_t;
+typedef unsigned short __kernel_old_gid_t;
+#define __kernel_old_uid_t __kernel_old_uid_t
+
+typedef unsigned short __kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
+
+#include <asm-generic/posix_types.h>
+
+#endif
diff --git a/arch/nios2/include/asm/processor.h b/arch/nios2/include/asm/processor.h
new file mode 100644
index 0000000..cb32b17
--- /dev/null
+++ b/arch/nios2/include/asm/processor.h
@@ -0,0 +1,134 @@
+/*--------------------------------------------------------------------
+ *
+ * include/asm-nios2/processor.h
+ *
+ * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2001  Ken Hill (khill@microtronix.com)    
+ *                     Vic Phillips (vic@microtronix.com)
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * hacked from:
+ *      include/asm-sparc/processor.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Jan/20/2004		dgt	    NiosII
+ * Nov/02/2003      dgt     Fix task_size
+ *
+ ---------------------------------------------------------------------*/
+
+#ifndef _ASM_NIOS2_PROCESSOR_H
+#define _ASM_NIOS2_PROCESSOR_H
+
+#define NIOS2_FLAG_KTHREAD	0x00000001	/* task is a kernel thread */
+#define NIOS2_FLAG_COPROC	0x00000002	/* Thread used coprocess */
+#define NIOS2_FLAG_DEBUG	0x00000004	/* task is being debugged */
+
+#define NIOS2_OP_NOP 0x1883a
+#define NIOS2_OP_BREAK	0x3da03a
+
+#ifdef __KERNEL__
+
+#define STACK_TOP	TASK_SIZE
+#define STACK_TOP_MAX	STACK_TOP
+
+#endif
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/string.h>
+
+#include <asm/ptrace.h>
+#include <asm/signal.h>
+#include <asm/segment.h>
+#include <asm/system.h> /* for get_hi_limit */
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/*
+ * The nios has no problems with write protection
+ */
+#define wp_works_ok 1
+#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
+
+/* Whee, this is STACK_TOP and the lowest kernel address too... */
+#define KERNBASE        0xc0000000UL /* First address the kernel will 
+                                      * eventually be 
+                                      */
+#define TASK_SIZE	0x7fff0000UL
+#define MAX_USER_ADDR	  0xc0000000UL
+#define MMAP_SEARCH_START 0x40000000UL
+#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
+
+/* The Nios processor specific thread struct. */
+struct thread_struct {
+	struct pt_regs *kregs;
+
+	/* Context switch saved kernel state. */
+	unsigned long ksp;
+	unsigned long kpsr;
+
+	/* Flags are defined below
+    */
+	unsigned long flags;
+};
+
+#define INIT_MMAP \
+   { &init_mm, (0), (0), __pgprot(0x0) , VM_READ | VM_WRITE | VM_EXEC }
+
+#define INIT_THREAD {                        \
+      .kregs	= 0,                          \
+      .ksp		= 0,                          \
+      .kpsr		= 0,                          \
+      .flags	= NIOS2_FLAG_KTHREAD,         \
+}
+
+struct task_struct;
+/* Free all resources held by a thread. */
+extern void release_thread(struct task_struct *);
+
+extern unsigned long thread_saved_pc(struct task_struct *t);
+
+extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp);
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk)	do { } while (0)
+
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+#define THREAD_START_SP (THREAD_SIZE - sizeof(struct pt_regs))
+#define task_pt_regs(p) \
+	((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
+
+unsigned long get_wchan(struct task_struct *p);
+
+/* Used by procfs
+ */
+#define KSTK_EIP(tsk)  ((tsk)->thread.kregs->ea)
+#define KSTK_ESP(tsk)  ((tsk)->thread.kregs->sp)
+
+#define cpu_relax()    do { } while (0)
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_NIOS2_PROCESSOR_H */
diff --git a/arch/nios2/include/asm/ptrace.h b/arch/nios2/include/asm/ptrace.h
new file mode 100644
index 0000000..60b90dd
--- /dev/null
+++ b/arch/nios2/include/asm/ptrace.h
@@ -0,0 +1,152 @@
+/*
+ * Taken from the m68k port.
+ *
+ * Copyright (C) 2004, Microtronix Datacom Ltd.
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef _ASM_NIOS2_PTRACE_H
+#define _ASM_NIOS2_PTRACE_H
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Register numbers used by 'ptrace' system call interface.
+ */
+
+/* GP registers */
+#define PTR_R0		0
+#define PTR_R1		1
+#define PTR_R2		2
+#define PTR_R3		3
+#define PTR_R4		4
+#define PTR_R5		5
+#define PTR_R6		6
+#define PTR_R7		7
+#define PTR_R8		8
+#define PTR_R9		9
+#define PTR_R10		10
+#define PTR_R11		11
+#define PTR_R12		12
+#define PTR_R13		13
+#define PTR_R14		14
+#define PTR_R15		15
+#define PTR_R16		16
+#define PTR_R17		17
+#define PTR_R18		18
+#define PTR_R19		19
+#define PTR_R20		20
+#define PTR_R21		21
+#define PTR_R22		22
+#define PTR_R23		23
+#define PTR_R24		24
+#define PTR_R25		25
+#define PTR_GP		26
+#define PTR_SP		27
+#define PTR_FP		28
+#define PTR_EA		29
+#define PTR_BA		30
+#define PTR_RA		31
+/* Control registers */
+#define PTR_PC    	32
+#define PTR_STATUS	33
+#define PTR_ESTATUS	34
+#define PTR_BSTATUS	35
+#define PTR_IENABLE	36
+#define PTR_IPENDING	37
+#define PTR_CPUID	38
+#define PTR_CTL6	39
+#define PTR_CTL7	40
+#define PTR_PTEADDR	41
+#define PTR_TLBACC	42
+#define PTR_TLBMISC	43
+
+/* Text/data offsets, needed by gdbserver */
+#define PT_TEXT_ADDR	44*4
+#define PT_TEXT_END_ADDR 45*4
+#define PT_DATA_ADDR	46*4
+
+/* this struct defines the way the registers are stored on the
+   stack during a system call. 
+
+   There is a fake_regs in setup.c that has to match pt_regs.*/
+
+struct pt_regs {
+	unsigned long  r8;		/* r8-r15 Caller-saved GP registers */
+	unsigned long  r9;
+	unsigned long  r10;
+	unsigned long  r11;
+	unsigned long  r12;
+	unsigned long  r13;
+	unsigned long  r14;
+	unsigned long  r15;
+	unsigned long  r1;		/* Assembler temporary */
+	unsigned long  r2;		/* Retval LS 32bits */
+	unsigned long  r3;		/* Retval MS 32bits */
+	unsigned long  r4;		/* r4-r7 Register arguments */
+	unsigned long  r5;
+	unsigned long  r6;
+	unsigned long  r7;
+	unsigned long  orig_r2;		/* Copy of r2 ?? */
+	unsigned long  ra;		/* Return address */
+	unsigned long  fp;		/* Frame pointer */
+	unsigned long  sp;		/* Stack pointer */
+	unsigned long  gp;		/* Global pointer */
+	unsigned long  estatus;
+	unsigned long  ea;		/* Exception return address (pc) */
+   unsigned long  orig_r7;
+};
+
+/*
+ * This is the extended stack used by signal handlers and the context
+ * switcher: it's pushed after the normal "struct pt_regs".
+ */
+struct switch_stack {
+	unsigned long  r16;		/* r16-r23 Callee-saved GP registers */
+	unsigned long  r17;
+	unsigned long  r18;
+	unsigned long  r19;
+	unsigned long  r20;
+	unsigned long  r21;
+	unsigned long  r22;
+	unsigned long  r23;
+	unsigned long  fp;
+	unsigned long  gp;
+	unsigned long  ra;
+};
+
+#ifdef __KERNEL__
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+
+/* 
+ */
+/* Supervisor mode  
+ */
+#define ESTATUS_EU  (0x00000002)
+
+#define user_mode(regs) (((regs)->estatus & ESTATUS_EU))
+#define instruction_pointer(regs) ((regs)->ra)
+#define profile_pc(regs) instruction_pointer(regs)
+extern void show_regs(struct pt_regs *);
+
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_NIOS2_PTRACE_H */
diff --git a/arch/nios2/include/asm/resource.h b/arch/nios2/include/asm/resource.h
new file mode 100644
index 0000000..04bc4db
--- /dev/null
+++ b/arch/nios2/include/asm/resource.h
@@ -0,0 +1 @@
+#include <asm-generic/resource.h>
diff --git a/arch/nios2/include/asm/scatterlist.h b/arch/nios2/include/asm/scatterlist.h
new file mode 100644
index 0000000..019145d
--- /dev/null
+++ b/arch/nios2/include/asm/scatterlist.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_NIOS2_SCATTERLIST_H
+#define _ASM_NIOS2_SCATTERLIST_H
+
+#define ISA_DMA_THRESHOLD (0xffffffff)
+#include <asm-generic/scatterlist.h>
+
+#endif
diff --git a/arch/nios2/include/asm/sections.h b/arch/nios2/include/asm/sections.h
new file mode 100644
index 0000000..2b8c516
--- /dev/null
+++ b/arch/nios2/include/asm/sections.h
@@ -0,0 +1 @@
+#include <asm-generic/sections.h>
diff --git a/arch/nios2/include/asm/segment.h b/arch/nios2/include/asm/segment.h
new file mode 100644
index 0000000..50d94fb
--- /dev/null
+++ b/arch/nios2/include/asm/segment.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_NIOS2_SEGMENT_H
+#define _ASM_NIOS2_SEGMENT_H
+
+/* Only here because we have some old header files that expect it.. */
+
+#endif /* _ASM_NIOS2_SEGMENT_H */
diff --git a/arch/nios2/include/asm/sembuf.h b/arch/nios2/include/asm/sembuf.h
new file mode 100644
index 0000000..7673b83
--- /dev/null
+++ b/arch/nios2/include/asm/sembuf.h
@@ -0,0 +1 @@
+#include <asm-generic/sembuf.h>
diff --git a/arch/nios2/include/asm/setup.h b/arch/nios2/include/asm/setup.h
new file mode 100644
index 0000000..552df83
--- /dev/null
+++ b/arch/nios2/include/asm/setup.h
@@ -0,0 +1 @@
+#include <asm-generic/setup.h>
diff --git a/arch/nios2/include/asm/shmbuf.h b/arch/nios2/include/asm/shmbuf.h
new file mode 100644
index 0000000..83c05fc
--- /dev/null
+++ b/arch/nios2/include/asm/shmbuf.h
@@ -0,0 +1 @@
+#include <asm-generic/shmbuf.h>
diff --git a/arch/nios2/include/asm/shmparam.h b/arch/nios2/include/asm/shmparam.h
new file mode 100644
index 0000000..93f30de
--- /dev/null
+++ b/arch/nios2/include/asm/shmparam.h
@@ -0,0 +1 @@
+#include <asm-generic/shmparam.h>
diff --git a/arch/nios2/include/asm/sigcontext.h b/arch/nios2/include/asm/sigcontext.h
new file mode 100644
index 0000000..4ebbf10
--- /dev/null
+++ b/arch/nios2/include/asm/sigcontext.h
@@ -0,0 +1,35 @@
+/*
+ * Taken from the m68knommu.
+ *
+ * Copyright (C) 2004, Microtronix Datacom Ltd.
+ * 
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _ASM_NIOS2_SIGCONTEXT_H
+#define _ASM_NIOS2_SIGCONTEXT_H
+
+#include <asm/ptrace.h>
+
+struct sigcontext {
+	struct pt_regs regs;
+	unsigned long  sc_mask; 	/* old sigmask */
+};
+
+#endif
diff --git a/arch/nios2/include/asm/siginfo.h b/arch/nios2/include/asm/siginfo.h
new file mode 100644
index 0000000..0815d29
--- /dev/null
+++ b/arch/nios2/include/asm/siginfo.h
@@ -0,0 +1 @@
+#include <asm-generic/siginfo.h>
diff --git a/arch/nios2/include/asm/signal.h b/arch/nios2/include/asm/signal.h
new file mode 100644
index 0000000..da712e0
--- /dev/null
+++ b/arch/nios2/include/asm/signal.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2004, Microtronix Datacom Ltd.
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _ASM_NIOS2_SIGNAL_H
+#define _ASM_NIOS2_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	_NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#include <asm-generic/signal-defs.h>
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_NIOS2_SIGNAL_H */
diff --git a/arch/nios2/include/asm/smp.h b/arch/nios2/include/asm/smp.h
new file mode 100644
index 0000000..a1100a0
--- /dev/null
+++ b/arch/nios2/include/asm/smp.h
@@ -0,0 +1,32 @@
+#ifndef _ASM_NIOS2_SMP_H
+#define _ASM_NIOS2_SMP_H
+
+/*--------------------------------------------------------------------
+ *
+ * include/asm-nios2/smp.h
+ *
+ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al
+ *
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Jan/20/2004		dgt	    NiosII
+ *
+ ---------------------------------------------------------------------*/
+
+
+#ifdef CONFIG_SMP
+#error SMP not supported
+#endif
+
+#endif
diff --git a/arch/nios2/include/asm/socket.h b/arch/nios2/include/asm/socket.h
new file mode 100644
index 0000000..6b71384
--- /dev/null
+++ b/arch/nios2/include/asm/socket.h
@@ -0,0 +1 @@
+#include <asm-generic/socket.h>
diff --git a/arch/nios2/include/asm/sockios.h b/arch/nios2/include/asm/sockios.h
new file mode 100644
index 0000000..def6d47
--- /dev/null
+++ b/arch/nios2/include/asm/sockios.h
@@ -0,0 +1 @@
+#include <asm-generic/sockios.h>
diff --git a/arch/nios2/include/asm/spaces.h b/arch/nios2/include/asm/spaces.h
new file mode 100644
index 0000000..4fe797b
--- /dev/null
+++ b/arch/nios2/include/asm/spaces.h
@@ -0,0 +1,28 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle
+ * Copyright (C) 2000, 2002  Maciej W. Rozycki
+ * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_NIOS2_GENERIC_SPACES_H
+#define _ASM_NIOS2_GENERIC_SPACES_H
+
+#include <asm/nios.h>
+
+/*
+ * This handles the memory map.
+ * We handle pages at KSEG0 for kernels with 32 bit address space.
+ */
+#define PAGE_OFFSET		(KERNEL_REGION_BASE + DDR2_TOP_BASE)
+
+/*
+ * Memory above this physical address will be considered highmem.
+ */
+#ifndef HIGHMEM_START
+#define HIGHMEM_START		0x20000000UL
+#endif
+
+#endif /* _ASM_NIOS2_GENERIC_SPACES_H */
diff --git a/arch/nios2/include/asm/spinlock.h b/arch/nios2/include/asm/spinlock.h
new file mode 100644
index 0000000..a4b8f9a
--- /dev/null
+++ b/arch/nios2/include/asm/spinlock.h
@@ -0,0 +1 @@
+#include <asm-generic/spinlock.h>
diff --git a/arch/nios2/include/asm/stat.h b/arch/nios2/include/asm/stat.h
new file mode 100644
index 0000000..73b0991
--- /dev/null
+++ b/arch/nios2/include/asm/stat.h
@@ -0,0 +1,100 @@
+#ifndef _ASM_NIOS2_STAT_H
+#define _ASM_NIOS2_STAT_H
+
+/*--------------------------------------------------------------------
+ *
+ * include/asm-nios2/stat.h
+ *
+ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al
+ *
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Jan/20/2004		dgt	    NiosII
+ *
+ ---------------------------------------------------------------------*/
+
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+struct stat {
+	unsigned short st_dev;
+	unsigned short __pad1;
+	unsigned long st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned short __pad2;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  __unused1;
+	unsigned long  st_mtime;
+	unsigned long  __unused2;
+	unsigned long  st_ctime;
+	unsigned long  __unused3;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned long long	st_dev;
+	unsigned char	__pad1[4];
+
+#define STAT64_HAS_BROKEN_ST_INO	1
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char	__pad3[4];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+	unsigned long long st_blocks;	/* Number 512-byte blocks allocated. */
+
+	unsigned long	st_atime;
+	unsigned long	st_atime_nsec;
+
+	unsigned long	st_mtime;
+	unsigned long	st_mtime_nsec;
+
+	unsigned long	st_ctime;
+	unsigned long	st_ctime_nsec;
+
+	unsigned long long	st_ino;
+};
+
+#endif
diff --git a/arch/nios2/include/asm/statfs.h b/arch/nios2/include/asm/statfs.h
new file mode 100644
index 0000000..0b91fe1
--- /dev/null
+++ b/arch/nios2/include/asm/statfs.h
@@ -0,0 +1 @@
+#include <asm-generic/statfs.h>
diff --git a/arch/nios2/include/asm/string.h b/arch/nios2/include/asm/string.h
new file mode 100644
index 0000000..525d050
--- /dev/null
+++ b/arch/nios2/include/asm/string.h
@@ -0,0 +1,45 @@
+#ifndef _ASM_NIOS2_STRING_H__
+#define _ASM_NIOS2_STRING_H__
+
+/*--------------------------------------------------------------------
+ *
+ * include/asm-nios2/string.h
+ *
+ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Jan/20/2004		dgt	    NiosII
+ *
+ ---------------------------------------------------------------------*/
+
+
+#ifdef __KERNEL__ /* only set these up for kernel code */
+
+#define __HAVE_ARCH_MEMMOVE
+void * memmove(void * d, const void * s, size_t count);
+#define __HAVE_ARCH_MEMCPY
+extern void * memcpy(void *d, const void *s, size_t count);
+#define __HAVE_ARCH_MEMSET
+extern void * memset(void * s,int c,size_t count);
+
+#if 0
+#define __HAVE_ARCH_BCOPY
+#define __HAVE_ARCH_STRLEN
+#endif
+
+#endif /* KERNEL */
+
+#endif /* !(_ASM_NIOS2_STRING_H__) */
diff --git a/arch/nios2/include/asm/swab.h b/arch/nios2/include/asm/swab.h
new file mode 100644
index 0000000..7847e56
--- /dev/null
+++ b/arch/nios2/include/asm/swab.h
@@ -0,0 +1 @@
+#include <asm-generic/swab.h>
diff --git a/arch/nios2/include/asm/system.h b/arch/nios2/include/asm/system.h
new file mode 100644
index 0000000..e97a4fa
--- /dev/null
+++ b/arch/nios2/include/asm/system.h
@@ -0,0 +1,155 @@
+/*
+ * Taken from the m68k.
+ *
+ * Copyright (C) 2004, Microtronix Datacom Ltd.
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef _ASM_NIOS2_SYSTQEM_H
+#define _ASM_NIOS2_SYSTQEM_H
+
+#include <linux/linkage.h>
+#include <linux/compiler.h>
+#include <asm/segment.h>
+#include <asm/entry.h>
+#include <asm/nios.h>
+#include <linux/string.h>
+#include <asm/addrspace.h>
+
+/*
+ * switch_to(n) should switch tasks to task ptr, first checking that
+ * ptr isn't the current task, in which case it does nothing.  This
+ * also clears the TS-flag if the task we switched to has used the
+ * math co-processor latest.
+ */
+
+/*
+ */
+asmlinkage void resume(void);
+#define switch_to(prev,next,last)				\
+{								\
+  void *_last;							\
+  __asm__ __volatile__(						\
+  	"mov	r4, %1\n"					\
+	"mov	r5, %2\n"					\
+	"call	resume\n"					\
+	"mov	%0,r4\n"					\
+       : "=r" (_last)						\
+       : "r" (prev), "r" (next)					\
+       : "r4","r5","r7","r8","ra");	\
+  (last) = _last;						\
+}
+
+#define local_irq_enable() __asm__ __volatile__ (  \
+	"rdctl	r8, status\n"			   \
+	"ori	r8, r8, 1\n"			   \
+	"wrctl	status, r8\n"			   \
+	: : : "r8")	  
+
+#define local_irq_disable() __asm__ __volatile__ ( \
+	"rdctl	r8, status\n"			   \
+	"andi	r8, r8, 0xfffe\n"		   \
+	"wrctl	status, r8\n"			   \
+	: : : "r8")
+
+#define local_save_flags(x) __asm__ __volatile__ (	\
+	"rdctl	r8, status\n"				\
+	"mov	%0, r8\n"				\
+	:"=r" (x) : : "r8", "memory")
+
+#define local_irq_restore(x) __asm__ __volatile__ (	\
+	"mov	r8, %0\n"				\
+	"wrctl	status, r8\n"				\
+	: :"r" (x) : "r8", "memory")
+
+/* For spinlocks etc */
+#define local_irq_save(x) do { local_save_flags(x); local_irq_disable(); } while (0)
+
+#define	irqs_disabled()					\
+({							\
+	unsigned long flags;				\
+	local_save_flags(flags);			\
+	((flags & NIOS2_STATUS_PIE_MSK) == 0x0);	\
+})
+
+#define iret() __asm__ __volatile__ ("eret": : :"memory", "ea")
+
+/*
+ * Force strict CPU ordering.
+ * Not really required on m68k...
+ */
+#define nop()  asm volatile ("nop"::)
+#define mb()   asm volatile (""   : : :"memory")
+#define rmb()  asm volatile (""   : : :"memory")
+#define wmb()  asm volatile (""   : : :"memory")
+#define set_mb(var, value)     do { (void)xchg(&var, value); } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb()	mb()
+#define smp_rmb()	rmb()
+#define smp_wmb()	wmb()
+#define smp_read_barrier_depends()	read_barrier_depends()
+#else
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
+#define smp_read_barrier_depends()	do { } while(0)
+#endif
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((volatile struct __xchg_dummy *)(x))
+
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+  unsigned long tmp, flags;
+
+  local_irq_save(flags);
+
+  switch (size) {
+  case 1:
+    __asm__ __volatile__( \
+      "ldb	%0, %2\n" \
+      "stb	%1, %2\n" \
+    : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  case 2:
+    __asm__ __volatile__( \
+      "ldh	%0, %2\n" \
+      "sth	%1, %2\n" \
+    : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  case 4:
+    __asm__ __volatile__( \
+      "ldw	%0, %2\n" \
+      "stw	%1, %2\n" \
+    : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  }
+  local_irq_restore(flags);
+  return tmp;
+}
+
+#define arch_align_stack(x) (x)
+
+#include <asm-generic/cmpxchg.h>
+#include <asm-generic/cmpxchg-local.h>
+
+#endif /* _ASM_NIOS2_SYSTEM_H */
diff --git a/arch/nios2/include/asm/termbits.h b/arch/nios2/include/asm/termbits.h
new file mode 100644
index 0000000..3935b10
--- /dev/null
+++ b/arch/nios2/include/asm/termbits.h
@@ -0,0 +1 @@
+#include <asm-generic/termbits.h>
diff --git a/arch/nios2/include/asm/termios.h b/arch/nios2/include/asm/termios.h
new file mode 100644
index 0000000..280d78a
--- /dev/null
+++ b/arch/nios2/include/asm/termios.h
@@ -0,0 +1 @@
+#include <asm-generic/termios.h>
diff --git a/arch/nios2/include/asm/thread_info.h b/arch/nios2/include/asm/thread_info.h
new file mode 100644
index 0000000..dceeae7
--- /dev/null
+++ b/arch/nios2/include/asm/thread_info.h
@@ -0,0 +1,126 @@
+/* thread_info.h: NiosII low-level thread information
+ *
+ * Copyright (C) 2002  David Howells (dhowells@redhat.com)
+ * - Incorporating suggestions made by Linus Torvalds and Dave Miller
+ */
+
+#ifndef _ASM_NIOS2_THREAD_INFO_H
+#define _ASM_NIOS2_THREAD_INFO_H
+
+#include <asm/page.h>
+#include <asm/segment.h>
+
+/* thread information allocation */
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
+#define THREAD_SIZE_ORDER 1
+#define THREAD_SIZE 4096
+#define THREAD_MASK (THREAD_SIZE - 1UL)
+
+#ifdef __KERNEL__
+
+
+#ifndef __ASSEMBLY__
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants
+ *   must also be changed
+ */
+struct thread_info {
+	struct task_struct	*task;		/* main task structure */
+	struct exec_domain	*exec_domain;	/* execution domain */
+	unsigned long		flags;		/* low level flags */
+	__u32			cpu;		/* current CPU */
+	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
+
+	mm_segment_t		addr_limit;	/* thread address space:
+						   0-0x7FFFFFFF for user-thead
+						   0-0xFFFFFFFF for kernel-thread
+						*/
+	struct restart_block	restart_block;
+	struct pt_regs		*regs;
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+#define INIT_THREAD_INFO(tsk)			\
+{						\
+	.task		= &tsk,			\
+	.exec_domain	= &default_exec_domain,	\
+	.flags		= 0,			\
+	.cpu		= 0,			\
+	.preempt_count	= 1,			\
+	.addr_limit	= KERNEL_DS,		\
+	.restart_block	= {			\
+		.fn = do_no_restart_syscall,	\
+	},					\
+}
+
+#define init_thread_info	(init_thread_union.thread_info)
+#define init_stack		(init_thread_union.stack)
+
+/* how to get the thread information struct from C
+   usable only in supervisor mode */
+
+static inline struct thread_info *current_thread_info(void)
+{
+	struct thread_info *ti;
+	__asm__ __volatile__(
+		"mov	%0, sp\n"
+		"and	%0, %0, %1\n"
+		: "=&r"(ti)
+		: "r" (~(THREAD_SIZE-1))
+		);
+	return ti;
+
+}
+#endif /* !__ASSEMBLY__ */
+
+#define PREEMPT_ACTIVE		0x10000000
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files may need to
+ *   access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_SIGPENDING		2	/* signal pending */
+#define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+#define TIF_SYSCALL_AUDIT	4	/* syscall auditing active */
+#define TIF_SECCOMP		5	/* secure computing */
+#define TIF_RESTORE_SIGMASK	9	/* restore signal mask in do_signal() */
+#define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
+#define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_MEMDIE		18
+#define TIF_FREEZE		19
+#define TIF_SYSCALL_TRACE	31	/* syscall trace active */
+
+#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+#define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP		(1<<TIF_SECCOMP)
+#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
+#define _TIF_USEDFPU		(1<<TIF_USEDFPU)
+#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE		(1<<TIF_FREEZE)
+
+/* work to do on interrupt/exception return */
+#define _TIF_WORK_MASK		(0x0000ffef & ~_TIF_SECCOMP)
+/* work to do on any return to u-space */
+#define _TIF_ALLWORK_MASK	(0x8000ffff & ~_TIF_SECCOMP)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_NIOS2_THREAD_INFO_H */
diff --git a/arch/nios2/include/asm/timex.h b/arch/nios2/include/asm/timex.h
new file mode 100644
index 0000000..70d6c49
--- /dev/null
+++ b/arch/nios2/include/asm/timex.h
@@ -0,0 +1,14 @@
+#ifndef _ASM_NIOS2_TIMEX_H
+#define _ASM_NIOS2_TIMEX_H
+
+#include <asm/nios.h>
+
+#ifndef  TIMER_1MS_FREQ
+#error Your FPGA design does not contain a TIMER_1MS
+#endif
+
+#define CLOCK_TICK_RATE	 TIMER_1MS_FREQ /* Underlying HZ */
+
+#include <asm-generic/timex.h>
+
+#endif
diff --git a/arch/nios2/include/asm/tlb.h b/arch/nios2/include/asm/tlb.h
new file mode 100644
index 0000000..96543ec
--- /dev/null
+++ b/arch/nios2/include/asm/tlb.h
@@ -0,0 +1,23 @@
+#ifndef _ASM_NIOS2_TLB_H
+#define _ASM_NIOS2_TLB_H
+
+/*
+ * NiosII doesn't need any special per-pte or per-vma handling, except
+ * we need to flush cache for area to be unmapped.
+ */
+#define tlb_start_vma(tlb, vma) 				\
+	do {							\
+		if (!tlb->fullmm)				\
+			flush_cache_range(vma, vma->vm_start, vma->vm_end); \
+	}  while (0)
+#define tlb_end_vma(tlb, vma) do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
+
+void tlb_flush(struct mmu_gather *tlb);
+void local_tlb_flush_all(void);
+void initMMU(void);
+
+#include <linux/pagemap.h>
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_NIOS2_TLB_H */
diff --git a/arch/nios2/include/asm/tlbflush.h b/arch/nios2/include/asm/tlbflush.h
new file mode 100644
index 0000000..1af5727
--- /dev/null
+++ b/arch/nios2/include/asm/tlbflush.h
@@ -0,0 +1,33 @@
+#ifndef _ASM_NIOS2_TLBFLUSH_H
+#define _ASM_NIOS2_TLBFLUSH_H
+
+#include <linux/mm.h>
+
+/*
+ * TLB flushing:
+ *
+ *  - flush_tlb_all() flushes all processes TLB entries
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB entries
+ *  - flush_tlb_page(vma, vmaddr) flushes one page
+ *  - flush_tlb_range(vma, start, end) flushes a range of pages
+ *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
+ */
+extern void local_flush_tlb_all(void);
+extern void local_flush_tlb_mm(struct mm_struct *mm);
+extern void local_flush_tlb_range(struct vm_area_struct *vma,
+	unsigned long start, unsigned long end);
+extern void local_flush_tlb_kernel_range(unsigned long start,
+	unsigned long end);
+extern void local_flush_tlb_page(struct vm_area_struct *vma,
+				 unsigned long address);
+extern void local_flush_tlb_one(unsigned long vaddr);
+
+#define flush_tlb_all()			local_flush_tlb_all()
+#define flush_tlb_mm(mm)		local_flush_tlb_mm(mm)
+#define flush_tlb_range(vma,vmaddr,end)	local_flush_tlb_range(vma, vmaddr, end)
+#define flush_tlb_kernel_range(vmaddr,end) \
+	local_flush_tlb_kernel_range(vmaddr, end)
+#define flush_tlb_page(vma,page)	local_flush_tlb_page(vma, page)
+#define flush_tlb_one(vaddr)		local_flush_tlb_one(vaddr)
+
+#endif /* _ASM_NIOS2_TLBFLUSH_H */
diff --git a/arch/nios2/include/asm/tlbstats.h b/arch/nios2/include/asm/tlbstats.h
new file mode 100644
index 0000000..af193be
--- /dev/null
+++ b/arch/nios2/include/asm/tlbstats.h
@@ -0,0 +1,20 @@
+#ifndef _ASM_NIOS2_TLBSTATS_H_
+#define _ASM_NIOS2_TLBSTATS_H_
+
+struct tlb_stat {
+      uint32_t local_flush_tlb_mm;
+      uint32_t local_flush_tlb_one_pid;
+      uint32_t local_flush_tlb_range;
+      uint32_t local_flush_tlb_page;
+      uint32_t local_flush_tlb_kernel_range;
+      uint32_t local_flush_tlb_one;
+      uint32_t flush_tlb_pid;
+      uint32_t local_flush_tlb_all;
+      uint32_t tlb_flush;
+      uint32_t tlb_fast_handler;
+      uint32_t tlb_c_handler;
+      uint32_t do_page_fault_prot;
+      uint32_t do_page_fault;
+};
+
+#endif /* _ASM_NIOS2_TLBSTATS_H_ */
diff --git a/arch/nios2/include/asm/topology.h b/arch/nios2/include/asm/topology.h
new file mode 100644
index 0000000..5428f33
--- /dev/null
+++ b/arch/nios2/include/asm/topology.h
@@ -0,0 +1 @@
+#include <asm-generic/topology.h>
diff --git a/arch/nios2/include/asm/traps.h b/arch/nios2/include/asm/traps.h
new file mode 100644
index 0000000..dc64a95
--- /dev/null
+++ b/arch/nios2/include/asm/traps.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2004, Microtronix Datacom Ltd.
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef _ASM_NIOS2_TRAPS_H
+#define _ASM_NIOS2_TRAPS_H
+
+#define TRAP_ID_SYSCALL 0
+#define TRAP_ID_APPDEBUG 1
+#endif /* !(_ASM_NIOS2_TRAPS_H) */
diff --git a/arch/nios2/include/asm/types.h b/arch/nios2/include/asm/types.h
new file mode 100644
index 0000000..b9e79bc
--- /dev/null
+++ b/arch/nios2/include/asm/types.h
@@ -0,0 +1 @@
+#include <asm-generic/types.h>
diff --git a/arch/nios2/include/asm/uaccess.h b/arch/nios2/include/asm/uaccess.h
new file mode 100644
index 0000000..912be3c
--- /dev/null
+++ b/arch/nios2/include/asm/uaccess.h
@@ -0,0 +1,172 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ */
+#ifndef _ASM_NIOS2_UACCESS_H
+#define _ASM_NIOS2_UACCESS_H
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/thread_info.h>
+
+/* FIXME: Add comment
+ */
+extern int fixup_exception(struct pt_regs *regs, unsigned long address);
+struct exception_table_entry
+{
+	unsigned long insn;
+	unsigned long nextinsn;
+};
+
+
+/* Segment stuff
+ */
+#define USER_DS   (mm_segment_t){ 0x80000000UL }
+#define KERNEL_DS (mm_segment_t){ 0 }
+extern int segment_eq(mm_segment_t a, mm_segment_t b);
+extern mm_segment_t get_ds(void);
+extern void set_fs(mm_segment_t seg);
+extern mm_segment_t get_fs(void);
+
+
+/* Misc user access functions (implemented in uaccess.c)
+ * FIXME: copy_from_user, __copy_from_user_inatomic, copy_to_user and 
+ * __copy_to_user_inatomic can and should be inlined.
+ */
+extern long copy_from_user(void* to, const void __user *from, int n);
+extern long __copy_from_user(void* to, const void __user *from, int n);
+extern long __copy_from_user_inatomic(void* to, const void __user *from, int n);
+
+extern long copy_to_user(void __user *to, const void *from, long n);
+extern long __copy_to_user(void __user *to, const void *from, long n);
+extern long __copy_to_user_inatomic(void __user *to, const void *from, long n);
+
+#define VERIFY_READ    0
+#define VERIFY_WRITE   1
+
+/* These functions are implemented in uaccess.c
+ */
+extern long strncpy_from_user(char *__to, const char __user *__from, 
+                              long __len);
+extern long strnlen_user(const char __user *s, long n);
+
+__kernel_size_t __clear_user(void __user *addr, __kernel_size_t size);
+size_t clear_user(void __user *addr, __kernel_size_t size);
+
+/* Optimized macros
+ */
+#define access_ok(type,from,len)                                        \
+   (((signed long)(((long)get_fs().seg) &                               \
+                   ((long)(from) | (((long)from) + (len)) | len))) == 0)
+
+#define __get_user_asm(val, insn, addr, err)                         \
+   {                                                                 \
+                                                                     \
+      __asm__ __volatile__(                                          \
+        "       movi    %0, %3                                  \n"  \
+        "1:   " insn " %1, 0(%2)                                \n"  \
+        "       movi     %0, 0                                  \n"  \
+        "2:                                                     \n"  \
+        "       .section __ex_table,\"a\"                       \n"  \
+        "       .word 1b, 2b                                    \n"  \
+        "       .previous                                       "    \
+        : "=&r" (err), "=r" (val)                                    \
+        : "r" (addr), "i" (-EFAULT));                                \
+   }
+
+#define __get_user_unknown(val, size, ptr, err) do {           \
+      err = 0;                                                 \
+      if(copy_from_user(&(val), ptr, size)) {                  \
+         err = -EFAULT;                                        \
+      }                                                        \
+   } while(0)
+
+#define __get_user_common(val, size, ptr, err)                     \
+   do {                                                            \
+      switch (size) {                                              \
+         case 1: __get_user_asm(val, "ldbu", ptr, err); break;     \
+         case 2: __get_user_asm(val, "ldhu", ptr, err); break;     \
+         case 4: __get_user_asm(val, "ldw", ptr, err); break;      \
+         default: __get_user_unknown(val, size, ptr, err); break;  \
+      }                                                            \
+   } while (0)
+
+
+#define __get_user(x,ptr)                                               \
+   ({                                                                   \
+      long __gu_err = -EFAULT;                                          \
+      const __typeof__(*(ptr)) __user * __gu_ptr = (ptr);               \
+      unsigned long __gu_val; /* FIXME: should be __typeof__ */         \
+      __get_user_common(__gu_val, sizeof(*(ptr)), __gu_ptr, __gu_err);  \
+      (x) = (__typeof__(x))__gu_val;                                    \
+      __gu_err;                                                         \
+   })
+
+#define get_user(x,ptr)                                                 \
+   ({                                                                   \
+      long __gu_err = -EFAULT;                                          \
+      const __typeof__(*(ptr)) __user * __gu_ptr = (ptr);               \
+      unsigned long __gu_val = 0;                                       \
+      if (likely(access_ok(VERIFY_READ,  __gu_ptr, sizeof(*__gu_ptr)))) { \
+         __get_user_common(__gu_val, sizeof(*__gu_ptr), __gu_ptr, __gu_err); \
+      }                                                                 \
+      (x) = (__typeof__(x))__gu_val;                                    \
+      __gu_err;                                                         \
+   })
+
+#define __put_user_asm(val, insn, ptr,err)                           \
+   {                                                                 \
+      __asm__ __volatile__(                                          \
+        "       movi    %0, %3                                  \n"  \
+        "1:   " insn " %1, 0(%2)                                \n"  \
+        "       movi     %0, 0                                  \n"  \
+        "2:                                                     \n"  \
+        "       .section __ex_table,\"a\"                       \n"  \
+        "       .word 1b, 2b                                    \n"  \
+        "       .previous                                       \n"  \
+        : "=&r" (err)                                                \
+        : "r" (val), "r" (ptr), "i" (-EFAULT));                      \
+   }
+
+#define __put_user_unknown(val, size, ptr, err) do {           \
+      err = 0;                                                 \
+      if(copy_to_user(ptr, &(val), size)) {                    \
+         err = -EFAULT;                                        \
+      }                                                        \
+   } while(0)
+
+#define __put_user_common(val, size, ptr, err)                    \
+   do {                                                           \
+      switch (size) {                                             \
+         case 1: __put_user_asm(val, "stb", ptr, err); break;     \
+         case 2: __put_user_asm(val, "sth", ptr, err); break;     \
+         case 4: __put_user_asm(val, "stw", ptr, err); break;     \
+         default: __put_user_unknown(val, size, ptr, err); break; \
+      }                                                           \
+   } while(0)
+
+#define __put_user(x, ptr)                                              \
+   ({                                                                   \
+      long __pu_err = -EFAULT;                                          \
+      __typeof__(*(ptr)) __user * __pu_ptr = (ptr);                     \
+      __typeof__(*(ptr)) __pu_val = (__typeof(*ptr))(x);                \
+      if(likely(access_ok(VERIFY_WRITE, __pu_ptr, sizeof(*__pu_ptr))))  \
+         __put_user_common(__pu_val, sizeof(*__pu_ptr), __pu_ptr, __pu_err); \
+      __pu_err;                                                         \
+   })
+
+#define put_user(x, ptr)                                                \
+   ({                                                                   \
+      long __pu_err = -EFAULT;                                          \
+      __typeof__(*(ptr)) __user * __pu_ptr = (ptr);                     \
+      __typeof__(*(ptr)) __pu_val = (__typeof(*ptr))(x);                \
+      if(likely(access_ok(VERIFY_WRITE, __pu_ptr, sizeof(*__pu_ptr))))  \
+         __put_user_common(__pu_val, sizeof(*__pu_ptr), __pu_ptr, __pu_err); \
+      __pu_err;                                                         \
+   })
+
+#endif /* _ASM_NIOS2_UACCESS_H */
diff --git a/arch/nios2/include/asm/ucontext.h b/arch/nios2/include/asm/ucontext.h
new file mode 100644
index 0000000..1f12705
--- /dev/null
+++ b/arch/nios2/include/asm/ucontext.h
@@ -0,0 +1,47 @@
+#ifndef _ASM_NIOS2_UCONTEXT_H
+#define _ASM_NIOS2_UCONTEXT_H
+
+/*--------------------------------------------------------------------
+ *
+ * include/asm-nios2/ucontext.h
+ *
+ * Derived from M68knommu
+ *
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Jan/20/2004		dgt	    NiosII
+ *
+ ---------------------------------------------------------------------*/
+
+
+typedef int greg_t;
+#define NGREG 32
+typedef greg_t gregset_t[NGREG];
+
+struct mcontext {
+	int version;
+	gregset_t gregs;
+};
+
+#define MCONTEXT_VERSION 2
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct mcontext	  uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif
diff --git a/arch/nios2/include/asm/unaligned.h b/arch/nios2/include/asm/unaligned.h
new file mode 100644
index 0000000..6cecbbb
--- /dev/null
+++ b/arch/nios2/include/asm/unaligned.h
@@ -0,0 +1 @@
+#include <asm-generic/unaligned.h>
diff --git a/arch/nios2/include/asm/unistd.h b/arch/nios2/include/asm/unistd.h
new file mode 100644
index 0000000..f0e9d29
--- /dev/null
+++ b/arch/nios2/include/asm/unistd.h
@@ -0,0 +1,415 @@
+#ifndef _ASM_NIOS2_UNISTD_H_
+#define _ASM_NIOS2_UNISTD_H_
+
+/*--------------------------------------------------------------------
+ *
+ * include/asm-nios2/unistd.h
+ *
+ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al
+ *
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * This file was copied from nios2 and reworked.
+ *
+ * Dec/12/2008    frma/ivho     Ported to nios2 with mmu.
+ *
+ ---------------------------------------------------------------------*/
+
+
+#include <asm/traps.h>
+
+#if defined(__ASSEMBLY__) || defined(ASSEMBLER)
+
+#define UR ERROR
+
+#else
+
+extern int unresolved_symbol;
+#define UR unresolved_symbol
+
+#endif
+
+/* TRAP 0 isr expects the the syscall # in r3, and arguments in r4, r5, ...
+ * Return value in r2 and error/ok flag in r7.
+ */
+
+#define __NR_restart_syscall      0
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_chown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_oldolduname	 59
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_getrlimit		 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_olduname		109
+#define __NR_iopl		/* 110 */ not supported
+#define __NR_vhangup		111
+#define __NR_idle		/* 112 */ Obsolete
+#define __NR_nios2cmpxchg	113
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_cacheflush		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync              144 /* obsolete */
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_getpagesize	166
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl		172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread		180
+#define __NR_pwrite		181
+#define __NR_lchown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_ugetrlimit		191
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_chown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_lchown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root		217
+/* 218 unused */
+/* 219 unused */
+#define __NR_getdents64		220
+#define __NR_gettid		221
+#define __NR_tkill		222
+#define __NR_setxattr		223
+#define __NR_lsetxattr		224
+#define __NR_fsetxattr		225
+#define __NR_getxattr		226
+#define __NR_lgetxattr		227
+#define __NR_fgetxattr		228
+#define __NR_listxattr		229
+#define __NR_llistxattr		230
+#define __NR_flistxattr		231
+#define __NR_removexattr	232
+#define __NR_lremovexattr	233
+#define __NR_fremovexattr	234
+#define __NR_futex		235
+#define __NR_sendfile64		236
+#define __NR_mincore		237
+#define __NR_madvise		238
+#define __NR_fcntl64		239
+#define __NR_readahead		240
+#define __NR_io_setup		241
+#define __NR_io_destroy		242
+#define __NR_io_getevents	243
+#define __NR_io_submit		244
+#define __NR_io_cancel		245
+#define __NR_fadvise64		246
+#define __NR_exit_group		247
+#define __NR_lookup_dcookie	248
+#define __NR_epoll_create	249
+#define __NR_epoll_ctl		250
+#define __NR_epoll_wait		251
+#define __NR_remap_file_pages	252
+#define __NR_set_tid_address	253
+#define __NR_timer_create	254
+#define __NR_timer_settime	255
+#define __NR_timer_gettime	256
+#define __NR_timer_getoverrun	257
+#define __NR_timer_delete	258
+#define __NR_clock_settime	259
+#define __NR_clock_gettime	260
+#define __NR_clock_getres	261
+#define __NR_clock_nanosleep	262
+#define __NR_statfs64		263
+#define __NR_fstatfs64		264
+#define __NR_tgkill		265
+#define __NR_utimes		266
+#define __NR_fadvise64_64	267
+#define __NR_mbind		268
+#define __NR_get_mempolicy	269
+#define __NR_set_mempolicy	270
+#define __NR_mq_open		271
+#define __NR_mq_unlink		272
+#define __NR_mq_timedsend	273
+#define __NR_mq_timedreceive	274
+#define __NR_mq_notify		275
+#define __NR_mq_getsetattr	276
+#define __NR_waitid		277
+#define __NR_sys_setaltroot	278
+#define __NR_add_key		279
+#define __NR_request_key	280
+#define __NR_keyctl		281
+#define __NR_ioprio_set		282
+#define __NR_ioprio_get		283
+#define __NR_inotify_init	284
+#define __NR_inotify_add_watch	285
+#define __NR_inotify_rm_watch	286
+#define __NR_migrate_pages	287
+#define __NR_openat		288
+#define __NR_mkdirat		289
+#define __NR_mknodat		290
+#define __NR_fchownat		291
+#define __NR_futimesat		292
+#define __NR_fstatat64		293
+#define __NR_unlinkat		294
+#define __NR_renameat		295
+#define __NR_linkat		296
+#define __NR_symlinkat		297
+#define __NR_readlinkat		298
+#define __NR_fchmodat		299
+#define __NR_faccessat		300
+#define __NR_pselect6		301
+#define __NR_ppoll		302
+#define __NR_unshare		303
+#define __NR_set_robust_list	304
+#define __NR_get_robust_list	305
+#define __NR_splice		306
+#define __NR_sync_file_range	307
+#define __NR_tee		308
+#define __NR_vmsplice		309
+#define __NR_move_pages		310
+#define __NR_sched_setaffinity	311
+#define __NR_sched_getaffinity	312
+#define __NR_kexec_load		313
+#define __NR_getcpu		314
+#define __NR_epoll_pwait	315
+#define __NR_utimensat		316
+#define __NR_signalfd		317
+#define __NR_timerfd_create	318
+#define __NR_eventfd		319
+#define __NR_pread64		320
+#define __NR_pwrite64		321
+#define __NR_fallocate		322
+#define __NR_timerfd_settime	323
+#define __NR_timerfd_gettime	324
+#define __NR_signalfd4		325
+#define __NR_eventfd2		326
+#define __NR_epoll_create1	327
+#define __NR_dup3		328
+#define __NR_pipe2		329
+#define __NR_inotify_init1	330
+#define __NR_preadv		331
+#define __NR_pwritev		332
+#define __NR_rt_tgsigqueueinfo	333
+#define __NR_perf_event_open	334
+
+#define NR_syscalls                     335
+
+#ifdef __KERNEL__
+
+#define __ARCH_WANT_IPC_PARSE_VERSION
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_SGETMASK
+#define __ARCH_WANT_SYS_SIGNAL
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+#define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
+
+#endif  /* __KERNEL__ */
+
+#endif  /* _ASM_NIOS2_UNISTD_H_ */
diff --git a/arch/nios2/include/asm/user.h b/arch/nios2/include/asm/user.h
new file mode 100644
index 0000000..61586f5
--- /dev/null
+++ b/arch/nios2/include/asm/user.h
@@ -0,0 +1,136 @@
+#ifndef _ASM_NIOS2_USER_H
+#define _ASM_NIOS2_USER_H
+
+/*--------------------------------------------------------------------
+ *
+ * include/asm-nios2/user.h
+ *
+ * Derived from M68knommu
+ *
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Jan/20/2004		dgt	    NiosII
+ *
+ ---------------------------------------------------------------------*/
+
+
+#include <asm/page.h>
+
+/* Core file format: The core file is written in such a way that gdb
+   can understand it and provide useful information to the user (under
+   linux we use the 'trad-core' bfd).  There are quite a number of
+   obstacles to being able to view the contents of the floating point
+   registers, and until these are solved you will not be able to view the
+   contents of them.  Actually, you can read in the core file and look at
+   the contents of the user struct to find out what the floating point
+   registers contain.
+   The actual file contents are as follows:
+   UPAGE: 1 page consisting of a user struct that tells gdb what is present
+   in the file.  Directly after this is a copy of the task_struct, which
+   is currently not used by gdb, but it may come in useful at some point.
+   All of the registers are stored as part of the upage.  The upage should
+   always be only one page.
+   DATA: The data area is stored.  We use current->end_text to
+   current->brk to pick up all of the user variables, plus any memory
+   that may have been malloced.  No attempt is made to determine if a page
+   is demand-zero or if a page is totally unused, we just cover the entire
+   range.  All of the addresses are rounded in such a way that an integral
+   number of pages is written.
+   STACK: We need the stack information in order to get a meaningful
+   backtrace.  We need to write the data from (esp) to
+   current->start_stack, so we round each of these off in order to be able
+   to write an integer number of pages.
+   The minimum core file size is 3 pages, or 12288 bytes.
+*/
+
+struct user_m68kfp_struct {
+	unsigned long  fpregs[8*3];	/* fp0-fp7 registers */
+	unsigned long  fpcntl[3];	/* fp control regs */
+};
+
+/* This is needs more work, probably should look like gdb useage */
+struct user_regs_struct {
+	unsigned long  r8;		/* r8-r15 Caller-saved GP registers */
+	unsigned long  r9;
+	unsigned long  r10;
+	unsigned long  r11;
+	unsigned long  r12;
+	unsigned long  r13;
+	unsigned long  r14;
+	unsigned long  r15;
+	unsigned long  r1;		/* Assembler temporary */
+	unsigned long  r2;		/* Retval LS 32bits */
+	unsigned long  r3;		/* Retval MS 32bits */
+	unsigned long  r4;		/* r4-r7 Register arguments */
+	unsigned long  r5;
+	unsigned long  r6;
+	unsigned long  r7;
+	unsigned long  orig_r2;		/* Copy of r2 ?? */
+	unsigned long  ra;		/* Return address */
+	unsigned long  fp;		/* Frame pointer */
+	unsigned long  sp;		/* Stack pointer */
+	unsigned long  gp;		/* Global pointer */
+	unsigned long  estatus;
+	unsigned long  ea;		/* Exception return address (pc) */
+	unsigned long  orig_r7;
+
+	unsigned long  r16;		/* r16-r23 Callee-saved GP registers */
+	unsigned long  r17;
+	unsigned long  r18;
+	unsigned long  r19;
+	unsigned long  r20;
+	unsigned long  r21;
+	unsigned long  r22;
+	unsigned long  r23;
+	unsigned long  sw_fp;
+	unsigned long  sw_gp;
+	unsigned long  sw_ra;
+};
+
+	
+/* When the kernel dumps core, it starts by dumping the user struct -
+   this will be used by gdb to figure out where the data and stack segments
+   are within the file, and what virtual addresses to use. */
+struct user{
+/* We start with the registers, to mimic the way that "memory" is returned
+   from the ptrace(3,...) function.  */
+  struct user_regs_struct regs;	/* Where the registers are actually stored */
+/* ptrace does not yet supply these.  Someday.... */
+  int u_fpvalid;		/* True if math co-processor being used. */
+                                /* for this mess. Not yet used. */
+  struct user_m68kfp_struct m68kfp; /* Math Co-processor registers. */
+/* The rest of this junk is to help gdb figure out what goes where */
+  unsigned long int u_tsize;	/* Text segment size (pages). */
+  unsigned long int u_dsize;	/* Data segment size (pages). */
+  unsigned long int u_ssize;	/* Stack segment size (pages). */
+  unsigned long start_code;     /* Starting virtual address of text. */
+  unsigned long start_stack;	/* Starting virtual address of stack area.
+				   This is actually the bottom of the stack,
+				   the top of the stack is always found in the
+				   esp register.  */
+  long int signal;     		/* Signal that caused the core dump. */
+  int reserved;			/* No longer used */
+  unsigned long u_ar0;
+				/* Used by gdb to help find the values for */
+				/* the registers. */
+  struct user_m68kfp_struct* u_fpstate;	/* Math Co-processor pointer. */
+  unsigned long magic;		/* To uniquely identify a core file */
+  char u_comm[32];		/* User command that was responsible */
+};
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif  /* _ASM_NIOS2_USER_H */
diff --git a/arch/nios2/kernel/Makefile b/arch/nios2/kernel/Makefile
new file mode 100644
index 0000000..bdc0869
--- /dev/null
+++ b/arch/nios2/kernel/Makefile
@@ -0,0 +1,24 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+extra-y := head.o vmlinux.lds
+
+obj-y   := entry.o traps.o irq.o syscall.o syscalltable.o \
+	    process.o signal.o setup.o sys_nios2.o \
+	    usb.o  init_task.o \
+	    time.o ptrace.o start.o nios2_ksyms.o insnemu.o config.o
+
+obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_CONSOLE) += console.o
+obj-$(CONFIG_PIO_DEVICES) += pio.o
+obj-$(CONFIG_AVALON_DMA) += dma.o
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+#obj-$(CONFIG_NIOS_DEBUG_DEV) += debugdev.o
+
+
diff --git a/arch/nios2/kernel/asm-offsets.c b/arch/nios2/kernel/asm-offsets.c
new file mode 100644
index 0000000..93a4867
--- /dev/null
+++ b/arch/nios2/kernel/asm-offsets.c
@@ -0,0 +1,140 @@
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ */
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/ptrace.h>
+#include <asm/irq.h>
+#include <asm/hardirq.h>
+#include <asm/nios.h>
+#include <asm/tlbstats.h>
+
+#define DEFINE(sym, val) \
+        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+int main(void)
+{
+
+	/* offsets into the task struct */
+	DEFINE(TASK_STATE, offsetof(struct task_struct, state));
+	DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+	DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+	DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
+	DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+/*	DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack));*/
+	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+	DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+
+	/* offsets into the irq_cpustat_t struct */
+	DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
+
+	/* offsets into the thread struct */
+	DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
+	DEFINE(THREAD_KPSR, offsetof(struct thread_struct, kpsr));
+	DEFINE(THREAD_FLAGS, offsetof(struct thread_struct, flags));
+
+	/* offsets into the pt_regs */
+	DEFINE(PT_ORIG_R2, offsetof(struct pt_regs, orig_r2));
+	DEFINE(PT_ORIG_R7, offsetof(struct pt_regs, orig_r7));
+	DEFINE(PT_R1, offsetof(struct pt_regs, r1));
+	DEFINE(PT_R2, offsetof(struct pt_regs, r2));
+	DEFINE(PT_R3, offsetof(struct pt_regs, r3));
+	DEFINE(PT_R4, offsetof(struct pt_regs, r4));
+	DEFINE(PT_R5, offsetof(struct pt_regs, r5));
+	DEFINE(PT_R6, offsetof(struct pt_regs, r6));
+	DEFINE(PT_R7, offsetof(struct pt_regs, r7));
+	DEFINE(PT_R8, offsetof(struct pt_regs, r8));
+	DEFINE(PT_R9, offsetof(struct pt_regs, r9));
+	DEFINE(PT_R10, offsetof(struct pt_regs, r10));
+	DEFINE(PT_R11, offsetof(struct pt_regs, r11));
+	DEFINE(PT_R12, offsetof(struct pt_regs, r12));
+	DEFINE(PT_R13, offsetof(struct pt_regs, r13));
+	DEFINE(PT_R14, offsetof(struct pt_regs, r14));
+	DEFINE(PT_R15, offsetof(struct pt_regs, r15));
+	DEFINE(PT_EA, offsetof(struct pt_regs, ea));
+	DEFINE(PT_RA, offsetof(struct pt_regs, ra));
+	DEFINE(PT_FP, offsetof(struct pt_regs, fp));
+	DEFINE(PT_SP, offsetof(struct pt_regs, sp));
+	DEFINE(PT_GP, offsetof(struct pt_regs, gp));
+	DEFINE(PT_ESTATUS, offsetof(struct pt_regs, estatus));
+	DEFINE(PT_REGS_SIZE, sizeof(struct pt_regs));
+
+	/* offsets into the switch_stack */
+	DEFINE(SW_R16, offsetof(struct switch_stack, r16));
+	DEFINE(SW_R17, offsetof(struct switch_stack, r17));
+	DEFINE(SW_R18, offsetof(struct switch_stack, r18));
+	DEFINE(SW_R19, offsetof(struct switch_stack, r19));
+	DEFINE(SW_R20, offsetof(struct switch_stack, r20));
+	DEFINE(SW_R21, offsetof(struct switch_stack, r21));
+	DEFINE(SW_R22, offsetof(struct switch_stack, r22));
+	DEFINE(SW_R23, offsetof(struct switch_stack, r23));
+	DEFINE(SW_FP, offsetof(struct switch_stack, fp));
+	DEFINE(SW_GP, offsetof(struct switch_stack, gp));
+	DEFINE(SW_RA, offsetof(struct switch_stack, ra));
+	DEFINE(SWITCH_STACK_SIZE, sizeof(struct switch_stack));
+
+	DEFINE(ESTATUS_EU_ASM, ESTATUS_EU);
+
+	DEFINE(NIOS2_STATUS_PIE_MSK_ASM, NIOS2_STATUS_PIE_MSK);  
+	DEFINE(NIOS2_STATUS_PIE_OFST_ASM, NIOS2_STATUS_PIE_OFST); 
+	DEFINE(NIOS2_STATUS_U_MSK_ASM, NIOS2_STATUS_U_MSK);    
+	DEFINE(NIOS2_STATUS_U_OFST_ASM, NIOS2_STATUS_U_OFST);   
+
+	/* Offsets in thread_info structure, used in assembly code */
+	DEFINE(TI_TASK, offsetof(struct thread_info, task));
+	DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
+	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+	DEFINE(TI_PREEMPT_COUNT, offsetof(struct thread_info, preempt_count));
+
+	DEFINE(PREEMPT_ACTIVE_ASM, PREEMPT_ACTIVE);
+
+	DEFINE(THREAD_SIZE_ASM, THREAD_SIZE);
+
+	DEFINE(TIF_SYSCALL_TRACE_ASM, TIF_SYSCALL_TRACE);
+	DEFINE(TIF_SIGPENDING_ASM, TIF_SIGPENDING);
+	DEFINE(TIF_NEED_RESCHED_ASM, TIF_NEED_RESCHED);
+	DEFINE(TIF_POLLING_NRFLAG_ASM, TIF_POLLING_NRFLAG);
+
+	DEFINE(_TIF_SYSCALL_TRACE_ASM, _TIF_SYSCALL_TRACE);
+	DEFINE(_TIF_SIGPENDING_ASM, _TIF_SIGPENDING);
+	DEFINE(_TIF_NEED_RESCHED_ASM, _TIF_NEED_RESCHED);
+	DEFINE(_TIF_POLLING_NRFLAG_ASM, _TIF_POLLING_NRFLAG);
+
+	DEFINE(_TIF_WORK_MASK_ASM, _TIF_WORK_MASK);
+
+	/* TLB statistics
+	 */
+	DEFINE(STAT_TLB_FAST_HANDLER, offsetof(struct tlb_stat, tlb_fast_handler));
+
+	/* Currently not used by assembly...
+	 */
+	DEFINE(LINUX_SDRAM_START, DDR2_TOP_BASE);
+	DEFINE(LINUX_SDRAM_END, DDR2_TOP_BASE+DDR2_TOP_SPAN);
+	
+	/* Cache defines
+	 */
+	DEFINE(NIOS2_ICACHE_SIZE, ICACHE_SIZE);
+	DEFINE(NIOS2_ICACHE_LINE_SIZE, ICACHE_LINE_SIZE);
+	DEFINE(NIOS2_DCACHE_SIZE, DCACHE_SIZE);
+	DEFINE(NIOS2_DCACHE_LINE_SIZE, DCACHE_LINE_SIZE);
+
+	/* Excpetion addresses (virtual 0xc0000000 addresses)
+	 */	
+   DEFINE(KERNEL_REGION_BASE_ASM, KERNEL_REGION_BASE);
+	DEFINE(CPU_EXCEPT_VIRT_ADDRESS_ASM, EXCEPTION_ADDR);
+	DEFINE(CPU_FAST_TLB_MISS_EXCEPTION_VIRT_ADDR_ASM,  FAST_TLB_MISS_EXCEPTION_ADDR);
+	
+
+	return 0;
+}
diff --git a/arch/nios2/kernel/config.c b/arch/nios2/kernel/config.c
new file mode 100644
index 0000000..2f4fb63
--- /dev/null
+++ b/arch/nios2/kernel/config.c
@@ -0,0 +1,1571 @@
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/ads7846.h>
+#include <linux/fb.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb/isp1362.h>
+#endif
+#include <linux/ata_platform.h>
+#include <linux/i2c.h>
+#include <linux/i2c-ocores.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/altjuart.h>
+#include <linux/altuart.h>
+#include <linux/nios_mmc.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/gpio_mouse.h>
+
+/*
+ *	Altera JTAG UART
+ */
+
+static struct altera_jtaguart_platform_uart nios2_jtaguart_platform[] = {
+#ifdef JTAG_UART_BASE
+	{
+	 .mapbase = JTAG_UART_BASE,
+	 .irq = JTAG_UART_IRQ,
+	 },
+#endif
+	{},
+};
+
+static struct platform_device nios2_jtaguart = {
+	.name = "altera_jtaguart",
+	.id = 0,
+	.dev.platform_data = nios2_jtaguart_platform,
+};
+
+/*
+ *	Altera UART
+ */
+
+static struct altera_uart_platform_uart nios2_uart_platform[] = {
+#ifdef UART0_BASE
+	{
+	 .mapbase = UART0_BASE,
+	 .irq = UART0_IRQ,
+	 .uartclk = UART0_FREQ,
+	 },
+#endif
+#ifdef UART1_BASE
+	{
+	 .mapbase = UART1_BASE,
+	 .irq = UART1_IRQ,
+	 .uartclk = UART1_FREQ,
+	 },
+#endif
+#ifdef UART2_BASE
+	{
+	 .mapbase = UART2_BASE,
+	 .irq = UART2_IRQ,
+	 .uartclk = UART2_FREQ,
+	 },
+#endif
+#ifdef UART3_BASE
+	{
+	 .mapbase = UART3_BASE,
+	 .irq = UART3_IRQ,
+	 .uartclk = UART3_FREQ,
+	 },
+#endif
+	{},
+};
+
+static struct platform_device nios2_uart = {
+	.name = "altera_uart",
+	.id = 0,
+	.dev.platform_data = nios2_uart_platform,
+};
+
+/*
+ *	openip gpio
+ */
+
+#ifdef CONFIG_GENERIC_GPIO
+resource_size_t nios2_gpio_mapbase;
+
+static void nios2_gpio_init(void)
+{
+	nios2_gpio_mapbase = (resource_size_t)ioremap(GPIO_0_BASE, 32);
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+	gpio_direction_output(6,1); /* output only I2C SCLK on NEEK */
+	gpio_direction_output(0,1);
+	gpio_direction_output(4,1);
+	gpio_direction_output(3,0);
+#endif
+}
+#else
+static void nios2_gpio_init(void) {}
+#endif /* CONFIG_GENERIC_GPIO */
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static struct gpio_led nios2_led_pins[] = {
+	{
+		.name		= "led0",
+		.default_trigger = "heartbeat", /* optional */
+		.gpio		= 2, /* FIXME: gpio pin assignment */
+		.active_low	= 1,
+	},
+};
+
+static struct gpio_led_platform_data nios2_led_data = {
+	.num_leds		= ARRAY_SIZE(nios2_led_pins),
+	.leds			= nios2_led_pins,
+};
+
+static struct platform_device gpio_leds_device = {
+	.name			= "leds-gpio",
+	.id			= -1,
+	.dev.platform_data	= &nios2_led_data,
+};
+#endif
+
+#if defined(CONFIG_MOUSE_GPIO) || defined(CONFIG_MOUSE_GPIO_MODULE)
+static struct gpio_mouse_platform_data nios2_gpio_mouse_data = {
+	.polarity	= GPIO_MOUSE_POLARITY_ACT_LOW,
+	{
+		{
+			.up		= 8, /* FIXME: gpio pin assignment */
+			.down		= 9,
+			.left		= 10,
+			.right		= 11,
+			.bleft		= 12,
+			.bmiddle	= 13,
+			.bright		= 14,
+		},
+	},
+	.scan_ms	= 10,
+};
+
+static struct platform_device gpio_mouse_device = {
+	.name		= "gpio_mouse",
+	.id		= 0,
+	.dev		= {
+		.platform_data = &nios2_gpio_mouse_data,
+	},
+};
+#endif
+
+/*
+ *	MTD map, CFI flash, NAND flash, SPI/EPCS flash
+ */
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition nios2_partitions[] = {
+#if defined(CONFIG_ALTERA_STRATIX_II) || defined(CONFIG_ALTERA_CYCLONE_II)
+	{
+	 .name = "romfs/jffs2",
+	 .size = 0x600000,
+	 .offset = 0x200000,
+	 },
+	{
+	 .name = "loader/kernel",
+	 .size = 0x200000,
+	 .offset = 0,
+	 },
+	{
+	 .name = "User configuration",
+	 .size = 0x400000,
+	 .offset = 0x800000,
+	 },
+	{
+	 .name = "safe configuration",
+	 .size = 0x400000,
+	 .offset = 0xc00000,
+	 .mask_flags = MTD_WRITEABLE,	/* force read-only */
+	 }
+#elif defined(CONFIG_ALTERA_STRATIX_PRO)
+	{
+	 .name = "romfs/jffs2",
+	 .size = 0x200000,
+	 .offset = 0x200000,
+	 },
+	{
+	 .name = "loader/kernel",
+	 .size = 0x200000,
+	 .offset = 0,
+	 },
+	{
+	 .name = "User configuration",
+	 .size = 0x200000,
+	 .offset = 0x400000,
+	 },
+	{
+	 .name = "safe configuration",
+	 .size = 0x200000,
+	 .offset = 0x600000,
+	 .mask_flags = MTD_WRITEABLE,	/* force read-only */
+	 }
+#elif defined(CONFIG_ALTERA_DE2)
+	{
+	 .name = "romfs/jffs2",
+	 .size = 0x200000,
+	 .offset = 0x200000,
+	 },
+	{
+	 .name = "loader/kernel",
+	 .size = 0x200000,
+	 .offset = 0,
+	 }
+#elif defined(CONFIG_ALTERA_NEEK_C3)
+	{
+	 .name = "romfs/jffs2",
+	 .size = 0x300000,
+	 .offset = 0xd00000,
+	 },
+	{
+	 .name = "catalog",
+	 .size = 0x020000,
+	 .offset = 0,
+	 },
+	{
+	 .name = "application",
+	 .size = 0xb80000,
+	 .offset = 0x180000,
+	 },
+	{
+	 .name = "selector",
+	 .size = 0x160000,
+	 .offset = 0x020000,
+	 .mask_flags = MTD_WRITEABLE,	/* force read-only */
+	 }
+#elif defined(CONFIG_ALTERA_CYCLONE_III)
+	{
+	 .name = "userspace",
+	 .size =   0x02800000, /* 40Mb */
+	 .offset = 0x00000000,
+	},
+	{
+	 .name = "U-Boot",
+	 .size =   0x00100000, 
+	 .offset = 0x02800000,
+	},
+	{
+	 .name = "uImage1",
+	 .size =   0x00400000, 
+	 .offset = 0x02900000,
+	},
+	{
+	 .name = "uImage2",
+	 .size =   0x00400000, 
+	 .offset = 0x02d00000,
+	},
+	{
+	 .name = "uImage3",
+	 .size =   0x00400000, 
+	 .offset = 0x03100000,
+	},
+	
+	{
+	 .name = "DEFAULT_MMU",
+	 .size =   0x00380000,
+	 .offset = 0x03500000,
+	 },
+	{
+	 .name = "MAXIMUM_MMU",
+	 .size =   0x00380000,
+	 .offset = 0x03880000,
+	 },
+	{
+	 .name = "USER_IMAGE",
+	 .size =   0x00380000,
+	 .offset = 0x03c00000,
+	 },
+	{
+	  .name = "options-bits",
+	  .size =   0x00020000,
+	  .offset = 0x03f80000,
+	}
+#else
+	{
+	 .name = "romfs/jffs2",
+	 .size = 0x400000,
+	 .offset = 0x200000,
+	 },
+	{
+	 .name = "loader/kernel",
+	 .size = 0x200000,
+	 .offset = 0,
+	 },
+	{
+	 .name = "User configuration",
+	 .size = 0x100000,
+	 .offset = 0x600000,
+	 },
+	{
+	 .name = "safe configuration",
+	 .size = 0x100000,
+	 .offset = 0x700000,
+	 .mask_flags = MTD_WRITEABLE,	/* force read-only */
+	 }
+#endif
+};
+
+static struct physmap_flash_data nios2_flash_data = {
+#if defined(CONFIG_ALTERA_NEEK_C3) || defined(CONFIG_ALTERA_CYCLONE_III)
+	.width = 2,		/* 16 bits data bus */
+#else
+	.width = 1,		/* 8 bits data bus */
+#endif
+	.parts = nios2_partitions,
+	.nr_parts = ARRAY_SIZE(nios2_partitions),
+};
+
+static struct resource nios2_flash_resource = {
+#if defined(CFI_FLASH_0_BASE)
+	.start = CFI_FLASH_0_BASE,
+	.end = CFI_FLASH_0_BASE + CFI_FLASH_0_SPAN - 1,
+#else
+	.start = EXT_FLASH_BASE,
+	.end = EXT_FLASH_BASE + EXT_FLASH_SPAN - 1,
+#endif
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device cfi_flash_device = {
+	.name = "physmap-flash",
+	.id = 0,
+	.dev = {
+		.platform_data = &nios2_flash_data,
+		},
+	.num_resources = 1,
+	.resource = &nios2_flash_resource,
+};
+#endif
+
+#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition nios2_plat_nand_partitions[] = {
+	{
+		.name   = "linux kernel(nand)",
+		.size   = 0x400000,
+		.offset = 0,
+	}, {
+		.name   = "file system(nand)",
+		.size   = MTDPART_SIZ_FULL,
+		.offset = MTDPART_OFS_APPEND,
+	},
+};
+#endif
+
+#define NIOS2_NAND_PLAT_CLE 2
+#define NIOS2_NAND_PLAT_ALE 3
+static void nios2_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+
+	if (cmd == NAND_CMD_NONE)
+		return;
+
+	if (ctrl & NAND_CLE)
+		writeb(cmd, this->IO_ADDR_W + (1 << NIOS2_NAND_PLAT_CLE));
+	else
+		writeb(cmd, this->IO_ADDR_W + (1 << NIOS2_NAND_PLAT_ALE));
+}
+
+#undef NIOS2_NAND_PLAT_READY    /* FIXME: define gpio pin assignment to R/B NAND */
+#ifdef NIOS2_NAND_PLAT_READY 
+static int nios2_plat_nand_dev_ready(struct mtd_info *mtd)
+{
+	return gpio_get_value(NIOS2_NAND_PLAT_READY);
+}
+#endif
+
+static struct platform_nand_data nios2_plat_nand_data = {
+	.chip = {
+		.chip_delay = 30, /* FIXME: tR of your nand chip */
+#ifdef CONFIG_MTD_PARTITIONS
+		.partitions = nios2_plat_nand_partitions,
+		.nr_partitions = ARRAY_SIZE(nios2_plat_nand_partitions),
+#endif
+	},
+	.ctrl = {
+		.cmd_ctrl  = nios2_plat_nand_cmd_ctrl,
+#ifdef NIOS2_NAND_PLAT_READY
+		.dev_ready = nios2_plat_nand_dev_ready,
+#endif
+	},
+};
+
+static struct resource nios2_plat_nand_resources = {
+	.start = NAND_FLASH_0_BASE,
+	.end   = NAND_FLASH_0_BASE + 12,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device async_nand_device = {
+	.name = "gen_nand",
+	.id = -1,
+	.num_resources = 1,
+	.resource = &nios2_plat_nand_resources,
+	.dev = {
+		.platform_data = &nios2_plat_nand_data,
+	},
+};
+
+static void nios2_plat_nand_init(void)
+{
+#ifdef NIOS2_NAND_PLAT_READY
+	gpio_request(NIOS2_NAND_PLAT_READY, "nios2_nand_plat");
+#endif
+}
+#else
+static void nios2_plat_nand_init(void) {}
+#endif
+
+#if (defined(CONFIG_SPI_ALTERA)  || defined(CONFIG_SPI_ALTERA_MODULE)) && defined(EPCS_CONTROLLER_BASE)
+#define EPCS_SPI_OFFSET 0x200	/* FIXME */
+static struct resource epcs_controller_resource[] = {
+	[0] = {
+	       .start = EPCS_CONTROLLER_BASE + EPCS_SPI_OFFSET,
+	       .end = EPCS_CONTROLLER_BASE + EPCS_SPI_OFFSET + 31,
+	       .flags = IORESOURCE_MEM,
+	       },
+	[1] = {
+	       .start = EPCS_CONTROLLER_IRQ,
+	       .end = EPCS_CONTROLLER_IRQ,
+	       .flags = IORESOURCE_IRQ,
+	       },
+};
+
+static struct platform_device epcs_controller_device = {
+	.name = "altspi",
+	.id = 0,		/* Bus number */
+	.num_resources = ARRAY_SIZE(epcs_controller_resource),
+	.resource = epcs_controller_resource,
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition nios2_spi_flash_partitions[] = {
+#if defined(CONFIG_ALTERA_STRATIX_II) || defined(CONFIG_ALTERA_CYCLONE_II)
+	{
+	 .name = "romfs/jffs2",
+	 .size = 0x400000,
+	 .offset = 0x400000,
+	 },
+	{
+	 .name = "fpga configuration",
+	 .size = 0x400000,
+	 .offset = 0,
+	 }
+#else
+	{
+	 .name = "romfs/jffs2",
+	 .size = 0x180000,
+	 .offset = 0x80000,
+	 },
+	{
+	 .name = "fpga configuration",
+	 .size = 0x80000,
+	 .offset = 0,
+	 }
+#endif
+};
+
+static struct flash_platform_data nios2_spi_flash_data = {
+	.name = "m25p80",
+	.parts = nios2_spi_flash_partitions,
+	.nr_parts = ARRAY_SIZE(nios2_spi_flash_partitions),
+#if defined(CONFIG_ALTERA_STRATIX_II) || defined(CONFIG_ALTERA_CYCLONE_II)
+	.type = "m25p64",	/* depend on the actual size of spi flash */
+#else
+	.type = "m25p16",	/* depend on the actual size of spi flash */
+#endif
+};
+#endif
+
+/*
+ *	Altera SPI, MMC
+ */
+
+#if (defined(CONFIG_SPI_ALTERA)  || defined(CONFIG_SPI_ALTERA_MODULE)) && defined(TOUCH_PANEL_SPI_BASE)
+static struct resource touch_panel_spi_resource[] = {
+	[0] = {
+	       .start = TOUCH_PANEL_SPI_BASE,
+	       .end = TOUCH_PANEL_SPI_BASE + 31,
+	       .flags = IORESOURCE_MEM,
+	       },
+	[1] = {
+	       .start = TOUCH_PANEL_SPI_IRQ,
+	       .end = TOUCH_PANEL_SPI_IRQ,
+	       .flags = IORESOURCE_IRQ,
+	       },
+};
+
+static struct platform_device touch_panel_spi_device = {
+	.name = "altspi",
+	.id = 1,		/* Bus number */
+	.num_resources = ARRAY_SIZE(touch_panel_spi_resource),
+	.resource = touch_panel_spi_resource,
+};
+#endif /* spi master and devices */
+
+#if (defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)) && \
+	defined(TOUCH_PANEL_PEN_IRQ_N_BASE)
+
+#define ALTERA_PIO_IO_EXTENT      16
+#define ALTERA_PIO_DATA           0
+#define ALTERA_PIO_DIRECTION      4
+#define ALTERA_PIO_IRQ_MASK       8
+#define ALTERA_PIO_EDGE_CAP       12
+
+static unsigned long ads7843_pendown_base;
+static void ads7843_pendown_init(void)
+{
+	ads7843_pendown_base =
+	    ioremap(TOUCH_PANEL_PEN_IRQ_N_BASE, ALTERA_PIO_IO_EXTENT);
+	writel(0, ads7843_pendown_base + ALTERA_PIO_EDGE_CAP);	/* clear edge */
+	writel(1, ads7843_pendown_base + ALTERA_PIO_IRQ_MASK);	/* enable irq */
+}
+
+static int ads7843_pendown_state(void)
+{
+	unsigned d;
+	d = readl(ads7843_pendown_base + ALTERA_PIO_DATA);	/* read pen */
+	writel(0, ads7843_pendown_base + ALTERA_PIO_EDGE_CAP);	/* clear edge */
+	return ~d & 1;		/* Touchscreen PENIRQ */
+}
+
+static struct ads7846_platform_data ads_info = {
+	.model = 7843,
+	.x_min = 150,
+	.x_max = 3830,
+	.y_min = 190,
+	.y_max = 3830,
+	.vref_delay_usecs = 100,
+	.x_plate_ohms = 450,
+	.y_plate_ohms = 250,
+	.pressure_max = 15000,
+	.debounce_max = 1,
+	.debounce_rep = 0,
+	.debounce_tol = (~0),
+	.get_pendown_state = ads7843_pendown_state,
+};
+#endif
+
+#if (defined(CONFIG_SPI_ALTERA)  || defined(CONFIG_SPI_ALTERA_MODULE)) && defined(MMC_SPI_BASE)
+static struct resource mmc_spi_resource[] = {
+	[0] = {
+	       .start = MMC_SPI_BASE,
+	       .end = MMC_SPI_BASE + MMC_SPI_SPAN - 1,
+	       .flags = IORESOURCE_MEM,
+	       },
+	[1] = {
+	       .start = MMC_SPI_IRQ,
+	       .end = MMC_SPI_IRQ,
+	       .flags = IORESOURCE_IRQ,
+	       },
+};
+
+static struct platform_device mmc_spi_device = {
+	.name = "altspi",
+	.id = 2,		/* Bus number */
+	.num_resources = ARRAY_SIZE(mmc_spi_resource),
+	.resource = mmc_spi_resource,
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_SPI_GPIO) || defined(CONFIG_SPI_GPIO_MODULE)
+#include <linux/spi/spi_gpio.h>
+
+struct spi_gpio_platform_data nios2_spi_gpio_3_platform_data = {
+	.sck = 8, /* FIXME: gpio pin assignment */
+	.mosi = 9,
+	.miso = 10,
+	.num_chipselect = 1,
+};
+
+static struct platform_device nios2_spi_gpio_3_device = {
+	.name		= "spi_gpio",
+	.id = 3,		/* Bus number */
+	.dev	= {
+		.platform_data	= &nios2_spi_gpio_3_platform_data,
+	},
+};
+#endif
+
+#if defined(CONFIG_SPI) || defined(CONFIG_SPI_MODULE)
+static struct spi_board_info nios2_spi_devices[] = {
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+	{
+	 /* the modalias must be the same as spi device driver name */
+	 .modalias = "m25p80",	/* Name of spi_driver for this device */
+	 .max_speed_hz = 25000000,	/* max spi clock (SCK) speed in HZ */
+	 .bus_num = 0,		/* bus number */
+	 .chip_select = 0,
+	 .platform_data = &nios2_spi_flash_data,
+	 },
+#endif
+
+#if (defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)) && \
+	defined(TOUCH_PANEL_PEN_IRQ_N_BASE)
+	{
+	 .modalias = "ads7846",
+	 .chip_select = 0,
+	 .max_speed_hz = 125000 * 26,	/* (max sample rate @ 3V) * (cmd + data + overhead) */
+	 .bus_num = 1,		/* must match spi host bus number of touch panel spi  */
+	 .platform_data = &ads_info,
+	 .irq = TOUCH_PANEL_PEN_IRQ_N_IRQ
+	 },
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+	{
+	 .modalias = "mmc_spi",
+	 .max_speed_hz = 25000000,
+	 .bus_num = 2,		/* must match spi host bus number of mmc spi  */
+	 .chip_select = 0,
+	 },
+#endif
+
+#if defined(CONFIG_EEPROM_AT25) || defined(CONFIG_EEPROM_AT25_MODULE)
+	{
+	 .modalias = "at25",
+	 .max_speed_hz = 25000000,
+	 .bus_num = 3,		/* must match spi host bus*/
+	 .chip_select = 0,
+	 .controller_data = (void *) 11, /* FIXME: gpio pin assignment of CS */
+	 },
+#endif
+
+};
+#endif
+
+/*
+ *	PFS Tech SD/SDIO/MMC Host
+ */
+
+/* Map sdio_host to sdio if it exists */
+#if defined(SDIO_HOST_BASE)
+#define SDIO_BASE SDIO_HOST_BASE
+#define SDIO_IRQ SDIO_HOST_IRQ
+#define SDIO_FREQ SDIO_HOST_FREQ
+#endif
+
+#if (defined(CONFIG_MMC_NIOS) || defined(CONFIG_MMC_NIOS_MODULE)) && defined(SDIO_BASE)
+
+static struct nios_mmc_platform_mmc nios2_mmc_platform[] = {
+	{
+	 .mapbase = SDIO_BASE,
+	 .irq = SDIO_IRQ,
+	 .clk_src = SDIO_FREQ,
+	 },
+};
+
+static struct resource nios_mmc_resources[] = {
+	[0] = {
+		.start = SDIO_BASE,
+		.end = SDIO_BASE + (16*4-1),
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = SDIO_IRQ,
+		.end = SDIO_IRQ,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+static struct platform_device nios_mmc_device = {
+	.name = "nios_mmc",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(nios_mmc_resources),
+	.resource = nios_mmc_resources,
+	.dev.platform_data = nios2_mmc_platform,
+};
+
+#endif
+
+/*
+ *	Altera CF IDE
+ */
+
+#if defined(CF_IDE_BASE)
+/* Use PATA_ALTERA_CF in preference to PATA_PLATFORM */
+#if defined(CONFIG_PATA_ALTERA_CF) || defined(CONFIG_PATA_ALTERA_CF_MODULE)
+#define USE_PATA_ALTERA_CF
+#elif defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define USE_PATA_PLATFORM
+#endif
+#endif
+
+#ifdef USE_PATA_ALTERA_CF
+static struct resource cf_resources[] = {
+	{
+	 .start = CF_IDE_BASE,
+	 .end = CF_IDE_BASE + 63,
+	 .flags = IORESOURCE_MEM,
+	 },
+	{
+	 .start = CF_IDE_IRQ,
+	 .end = CF_IDE_IRQ,
+	 .flags = IORESOURCE_IRQ,
+	 },
+	{
+	 .start = CF_CTL_BASE,
+	 .end = CF_CTL_BASE + 15,
+	 .flags = IORESOURCE_MEM,
+	 },
+	{
+	 .start = CF_CTL_IRQ,
+	 .end = CF_CTL_IRQ,
+	 .flags = IORESOURCE_IRQ,
+	 },
+};
+
+static struct platform_device cf_device = {
+	.name = "pata_altera_cf",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(cf_resources),
+	.resource = cf_resources,
+};
+#endif
+
+#ifdef USE_PATA_PLATFORM
+static struct pata_platform_info cf_platform_data = {
+	.ioport_shift = 2,
+};
+
+static struct resource cf_resources[] = {
+	{
+	 .start = CF_IDE_BASE,
+	 .end = CF_IDE_BASE + 31,
+	 .flags = IORESOURCE_MEM,
+	 },
+	{
+	 .start = CF_IDE_BASE + 56,
+	 .end = CF_IDE_BASE + 56 + 3,
+	 .flags = IORESOURCE_MEM,
+	 },
+	{
+	 .start = CF_IDE_IRQ,
+	 .end = CF_IDE_IRQ,
+	 .flags = IORESOURCE_IRQ,
+	 },
+};
+
+static struct platform_device cf_device = {
+	.name = "pata_platform",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(cf_resources),
+	.resource = cf_resources,
+	.dev = {
+		.platform_data = &cf_platform_data,
+		}
+};
+
+#define ALTERA_CF_CTL_STATUS            	0
+#define ALTERA_CF_IDE_CTL               	4
+#define ALTERA_CF_CTL_STATUS_PRESENT_MSK       (0x1)
+#define ALTERA_CF_CTL_STATUS_POWER_MSK         (0x2)
+#define ALTERA_CF_CTL_STATUS_RESET_MSK         (0x4)
+#define ALTERA_CF_CTL_STATUS_IRQ_EN_MSK        (0x8)
+#define ALTERA_CF_IDE_CTL_IRQ_EN_MSK           (0x1)
+
+static void __init cf_init(unsigned ctl_base)
+{
+	unsigned ctl = ioremap(ctl_base, 16);
+	writel(0, ctl + ALTERA_CF_IDE_CTL);	/* disable ide irq */
+	writel(ALTERA_CF_CTL_STATUS_RESET_MSK, ctl + ALTERA_CF_CTL_STATUS);	/* power down */
+	msleep(500);		/* 0.5 sec delay */
+	writel(ALTERA_CF_CTL_STATUS_POWER_MSK, ctl + ALTERA_CF_CTL_STATUS);	/* power up */
+	msleep(500);		/* 0.5 sec delay */
+	writel(ALTERA_CF_IDE_CTL_IRQ_EN_MSK, ctl + ALTERA_CF_IDE_CTL);	/* enable ide irq */
+}
+#endif
+
+/*
+ *	Opencore I2C , gpio I2C
+ */
+
+/* if you have multiple i2c buses, you may have to register different board info for each of them */
+static struct i2c_board_info __initdata nios2_i2c_0_board_info[] = {
+#if defined(CONFIG_RTC_DRV_DS1307) || defined(CONFIG_RTC_DRV_DS1307_MODULE)
+	{
+		I2C_BOARD_INFO("ds1307", 0x68),
+	},
+#endif
+};
+
+static struct i2c_board_info __initdata nios2_i2c_1_board_info[] = {
+#if defined(CONFIG_EEPROM_AT24) || defined(CONFIG_EEPROM_AT24_MODULE)
+	{
+		I2C_BOARD_INFO("24c00", 0x50), /* microchip 24lc00 */
+	},
+#endif
+};
+
+#if (defined(CONFIG_I2C_OCORES) || defined(CONFIG_I2C_OCORES_MODULE)) && defined(I2C_0_BASE)
+static struct resource i2c_oc_0_resources[] = {
+	[0] = {
+	       .start = I2C_0_BASE,
+	       .end = I2C_0_BASE + 31,
+	       .flags = IORESOURCE_MEM,
+	       },
+	[1] = {
+	       .start = I2C_0_IRQ,
+	       .end = I2C_0_IRQ,
+	       .flags = IORESOURCE_IRQ,
+	       },
+};
+
+static struct ocores_i2c_platform_data i2c_oc_0_platform_data = {
+	.regstep = 4,		/* four bytes between registers */
+	.clock_khz = I2C_0_FREQ / 1000,	/* input clock */
+};
+
+static struct platform_device i2c_oc_0_device = {
+	.name = "ocores-i2c",
+	.id = 0,
+	.dev = {
+		.platform_data = &i2c_oc_0_platform_data,
+		},
+	.num_resources = ARRAY_SIZE(i2c_oc_0_resources),
+	.resource = i2c_oc_0_resources,
+};
+#endif
+
+#if (defined(CONFIG_I2C_OCORES) || defined(CONFIG_I2C_OCORES_MODULE)) && defined(I2C_1_BASE)
+static struct resource i2c_oc_1_resources[] = {
+	[0] = {
+	       .start = I2C_1_BASE,
+	       .end = I2C_1_BASE + 31,
+	       .flags = IORESOURCE_MEM,
+	       },
+	[1] = {
+	       .start = I2C_1_IRQ,
+	       .end = I2C_1_IRQ,
+	       .flags = IORESOURCE_IRQ,
+	       },
+};
+
+static struct ocores_i2c_platform_data i2c_oc_1_platform_data = {
+	.regstep = 4,		/* four bytes between registers */
+	.clock_khz = I2C_1_FREQ / 1000,	/* input clock */
+};
+
+static struct platform_device i2c_oc_1_device = {
+	.name = "ocores-i2c",
+	.id = 1,
+	.dev = {
+		.platform_data = &i2c_oc_1_platform_data,
+		},
+	.num_resources = ARRAY_SIZE(i2c_oc_1_resources),
+	.resource = i2c_oc_1_resources,
+};
+#endif
+
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+#include <linux/i2c-gpio.h>
+
+static struct i2c_gpio_platform_data i2c_gpio_0_data = {
+	.sda_pin		= 7, /* FIXME: gpio pin assignment */
+	.scl_pin		= 6, /* FIXME: gpio pin assignment */
+	.sda_is_open_drain	= 0,
+	.scl_is_open_drain	= 0,
+	.scl_is_output_only	= 1,
+	.udelay			= 40,
+};
+
+static struct platform_device i2c_gpio_0_device = {
+	.name		= "i2c-gpio",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &i2c_gpio_0_data,
+	},
+};
+
+static struct i2c_gpio_platform_data i2c_gpio_1_data = {
+	.sda_pin		= 1, /* FIXME: gpio pin assignment */
+	.scl_pin		= 0, /* FIXME: gpio pin assignment */
+	.sda_is_open_drain	= 0,
+	.scl_is_open_drain	= 0,
+	.scl_is_output_only	= 1,
+	.udelay			= 40,
+};
+
+static struct platform_device i2c_gpio_1_device = {
+	.name		= "i2c-gpio",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &i2c_gpio_1_data,
+	},
+};
+
+static struct i2c_gpio_platform_data i2c_gpio_2_data = {
+	.sda_pin		= 5, /* FIXME: gpio pin assignment */
+	.scl_pin		= 4, /* FIXME: gpio pin assignment */
+	.sda_is_open_drain	= 0,
+	.scl_is_open_drain	= 0,
+	.scl_is_output_only	= 1,
+	.udelay			= 40,
+};
+
+static struct platform_device i2c_gpio_2_device = {
+	.name		= "i2c-gpio",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &i2c_gpio_2_data,
+	},
+};
+#endif
+
+/*
+ *	One wire
+ */
+
+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
+#include <linux/w1-gpio.h>
+
+static struct w1_gpio_platform_data nios2_w1_gpio_0_data = {
+	.pin		= 7, /* FIXME: gpio pin assignment */
+	.is_open_drain	= 0,
+};
+
+static struct platform_device nios2_w1_gpio_0_device = {
+	.name			= "w1-gpio",
+	.id			= -1,
+	.dev.platform_data	= &nios2_w1_gpio_0_data,
+};
+#endif
+
+/*
+ *	Altera PS2
+ */
+
+#if defined(CONFIG_SERIO_ALTPS2) && defined(PS2_0_BASE)
+static struct resource altps2_0_resources[] = {
+	[0] = {
+		.start		= PS2_0_BASE,
+		.end		= PS2_0_BASE + 0x8 - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= PS2_0_IRQ,
+		.end		= PS2_0_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+static struct platform_device altps2_0_device = {
+	.name		= "altps2",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(altps2_0_resources),
+	.resource	= altps2_0_resources,
+};
+
+#if defined(PS2_1_BASE)
+static struct resource altps2_1_resources[] = {
+	[0] = {
+		.start		= PS2_1_BASE,
+		.end		= PS2_1_BASE + 0x8 - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= PS2_1_IRQ,
+		.end		= PS2_1_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+static struct platform_device altps2_1_device = {
+	.name		= "altps2",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(altps2_1_resources),
+	.resource	= altps2_1_resources,
+};
+#endif
+#endif
+
+/*
+ *	Altera Remote update
+ */
+
+#if defined(CONFIG_ALTERA_REMOTE_UPDATE) && defined(ALTREMOTE_BASE)
+static struct resource altremote_resources[] = {
+  [0] = {
+    .start    = ALTREMOTE_BASE,
+    .end    = ALTREMOTE_BASE + 0x200 - 1,
+    .flags    = IORESOURCE_MEM,
+  },
+};
+static struct platform_device altremote_device = {
+  .name   = "altremote",
+  .id   = 0,
+  .num_resources  = ARRAY_SIZE(altremote_resources),
+  .resource = altremote_resources,
+};
+#endif
+
+/*
+ *	Ethernet, Altera TSE
+ */
+
+#if defined(CONFIG_SMC91X) && defined(ENET_BASE)
+#ifndef LAN91C111_REGISTERS_OFFSET
+#define LAN91C111_REGISTERS_OFFSET 0x300
+#endif
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start		= ENET_BASE + LAN91C111_REGISTERS_OFFSET,
+		.end		= ENET_BASE + LAN91C111_REGISTERS_OFFSET + 0x100 - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= ENET_IRQ,
+		.end		= ENET_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_DM9000) && defined(DM9000_BASE)
+#include <linux/dm9000.h>
+static struct resource dm9k_resource[] = {
+	[0] = {
+		.start = DM9000_BASE,
+		.end   = DM9000_BASE + 3,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DM9000_BASE + 4,
+		.end   = DM9000_BASE + 4 + 3,
+		.flags = IORESOURCE_MEM,
+	},
+	[2] = {
+		.start = DM9000_IRQ,
+		.end   = DM9000_IRQ,
+		.flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
+	}
+
+};
+static struct dm9000_plat_data dm9k_platdata = {
+	.flags		= DM9000_PLATF_16BITONLY,
+};
+static struct platform_device dm9k_device = {
+	.name		= "dm9000",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dm9k_resource),
+	.resource	= dm9k_resource,
+	.dev		= {
+		.platform_data = &dm9k_platdata,
+	}
+};
+#endif
+
+#if defined (CONFIG_ATSE)
+/* Altera Triple Speed Ethernet */
+#include         "../drivers/net/atse.h"
+static struct resource atse_resource[] = {
+	[0] = {
+		.start = na_descriptor_memory_s1,
+		.end   = na_descriptor_memory_s1 + 0x2000 - 1,   /* code from sopc file */
+		.name  = ATSE_RESOURCE_NAME_STR_DESC_MEM,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = na_sgdma_rx_csr,
+		.end   = na_sgdma_rx_csr + 0x400 - 1,  /* code from sopc file */
+		.name  = ATSE_RESOURCE_NAME_STR_SGDMA_RX_MEM,
+		.flags = IORESOURCE_MEM,
+	},
+	[2] = {
+		.start = na_sgdma_tx,
+		.end   = na_sgdma_tx + 0x400 - 1,  /* code from sopc file */
+		.name  = ATSE_RESOURCE_NAME_STR_SGDMA_TX_MEM,
+		.flags = IORESOURCE_MEM,
+	},
+	[3] = {
+		.start = na_sgdma_rx_csr_irq,
+		.end   = na_sgdma_rx_csr_irq,
+		.name  = ATSE_RESOURCE_NAME_STR_SGDMA_RX_IRQ,
+		.flags = IORESOURCE_IRQ,
+	},
+	[4] = {
+		.start = na_sgdma_tx_irq,
+		.end   = na_sgdma_tx_irq,
+		.name  = ATSE_RESOURCE_NAME_STR_SGDMA_TX_IRQ,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static struct atse_plat_data atse_platdata = {
+	.flags		= 1,
+};
+
+static struct platform_device atse_device = {
+	/* the name string must be the same as in struct patform_driver */
+	.name		= ATSE_CARDNAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(atse_resource),
+	.resource	= atse_resource,
+	.dev		= {
+		.platform_data = &atse_platdata,
+	}
+};
+static void atse_device_init(void)
+{
+	/* write eth hardware address to MAC registers */
+	unsigned int mac_reg_0;
+	unsigned int mac_reg_1 = 0x0;
+	/*
+	mac_reg_0 = excalibur_enet_hwaddr[0]   | 
+		excalibur_enet_hwaddr[1] << 8  |
+		excalibur_enet_hwaddr[2] << 16 |
+		excalibur_enet_hwaddr[3] << 24;
+
+	mac_reg_1 = excalibur_enet_hwaddr[4] | excalibur_enet_hwaddr[5] << 8;
+	*/
+	mac_reg_0 = 0x00   |
+		0x07 << 8  |
+		0xED << 16 |
+		0x0D << 24;
+
+	mac_reg_1 = 0x09   |
+		0x19 << 8  ;
+
+	writel(mac_reg_0, ATSE_MAC_REG_MAC_ADDR_0);
+	writel(mac_reg_1, ATSE_MAC_REG_MAC_ADDR_1);
+}
+#else
+static void atse_device_init(void) {}
+#endif /* CONFIG_ATSE */
+
+/* Altera Triple Speed Ethernet (SLS) */
+
+#if defined (CONFIG_ALT_TSE)
+
+#include         "../drivers/net/altera_tse.h"
+
+#define na_tse_mac_control_port TSE_MAC_BASE
+
+#define na_sgdma_rx_csr         SGDMA_RX_BASE
+#define na_sgdma_tx             SGDMA_TX_BASE
+
+#ifdef DESCRIPTOR_MEMORY_BASE
+#define na_descriptor_memory DESCRIPTOR_MEMORY_BASE
+#define na_descriptor_memory_size DESCRIPTOR_MEMORY_SPAN
+#endif
+
+#define na_sgdma_rx_csr_irq SGDMA_RX_IRQ
+#define na_sgdma_tx_irq SGDMA_TX_IRQ
+
+static struct resource alt_tse_resource[] = {
+
+  [0] = {
+    .start = na_tse_mac_control_port,
+    .end   = na_tse_mac_control_port + 0x400 - 1, /* code from sopc file */
+    .name  = TSE_RESOURCE_MAC_DEV,
+    .flags = IORESOURCE_MEM,
+  },
+  [1] = {
+    .start = na_sgdma_rx_csr,
+    .end   = na_sgdma_rx_csr + 0x400 - 1,         /* code from sopc file */
+    .name  = TSE_RESOURCE_SGDMA_RX_DEV,
+    .flags = IORESOURCE_MEM,
+  },
+  [2] = {
+    .start = na_sgdma_tx,
+    .end   = na_sgdma_tx + 0x400 - 1,             /* code from sopc file */
+    .name  = TSE_RESOURCE_SGDMA_TX_DEV,
+    .flags = IORESOURCE_MEM,
+  },
+  [3] = {
+    .start = na_sgdma_rx_csr_irq,
+    .end   = na_sgdma_rx_csr_irq,
+    .name  = TSE_RESOURCE_SGDMA_RX_IRQ,
+    .flags = IORESOURCE_IRQ,
+  },
+  [4] = {
+    .start = na_sgdma_tx_irq,
+    .end   = na_sgdma_tx_irq,
+    .name  = TSE_RESOURCE_SGDMA_TX_IRQ,
+    .flags = IORESOURCE_IRQ,
+  },
+
+#ifdef na_descriptor_memory
+  [5] = {
+      .start = na_descriptor_memory,
+      .end   = na_descriptor_memory + na_descriptor_memory_size - 1,      /* code from sopc file */
+      .name  = TSE_RESOURCE_SGDMA_DES_DEV,
+      .flags = IORESOURCE_MEM,
+  },
+#else
+  [5] = {
+      .start = 0,
+      .end   = 0,                                 /* code from sopc file */
+      .name  = TSE_RESOURCE_SGDMA_DES_DEV,
+      .flags = IORESOURCE_MEM,
+  },
+#endif
+
+#ifdef CONFIG_PHY_IRQ_PRESENCE
+  [6] = {
+      .start = 0,
+      .end   = 0,                                 /* code from sopc file */
+      .name  = TSE_RESOURCE_SGDMA_PHY_DEV,
+      .flags = IORESOURCE_MEM,
+  },
+  [7] = {
+      .start = 0,
+      .end   = 0,                                 /* code from sopc file */
+      .name  = TSE_RESOURCE_SGDMA_PHY_IRQ,
+      .flags = IORESOURCE_IRQ,
+  },
+#endif
+
+};
+
+    
+static struct alt_tse_mdio_private alt_tse_mdio_private = {
+	.irq = {
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+		PHY_POLL,
+	}
+};
+
+     
+static struct platform_device alt_tse_mdio_device = {
+	.name	= ALT_TSE_MDIO_NAME,
+	.id	= 0,
+	.num_resources  = ARRAY_SIZE(alt_tse_resource),
+	.resource = alt_tse_resource,
+	.dev	= {
+	  .platform_data = &alt_tse_mdio_private,
+	}
+};
+
+/* all of this, except mii_id can be changed with ethtool */
+static struct alt_tse_config tsemac0_config = {
+	.mii_id = 0, /* should match alt_tse_mdio_device->id from above */
+	.phy_addr = 18,
+	.tse_supported_modes =  PHY_GBIT_FEATURES,
+/*
+	supported modes can be 
+		SUPPORTED_10baseT_Half 
+		SUPPORTED_10baseT_Full 
+		SUPPORTED_100baseT_Half 
+		SUPPORTED_100baseT_Full 
+		SUPPORTED_Autoneg 
+		SUPPORTED_TP 
+		SUPPORTED_MII  ----------  Up to here is PHY_BASIC_FEATURES
+		SUPPORTED_1000baseT_Half
+		SUPPORTED_1000baseT_Full -- here PHY_GBIT_FEATURES
+*/
+	.interface = PHY_INTERFACE_MODE_RGMII_ID,
+/*	Interfaces can be
+		PHY_INTERFACE_MODE_MII
+		PHY_INTERFACE_MODE_GMII
+		PHY_INTERFACE_MODE_SGMII
+		PHY_INTERFACE_MODE_TBI
+		PHY_INTERFACE_MODE_RMII
+		PHY_INTERFACE_MODE_RGMII
+		PHY_INTERFACE_MODE_RGMII_ID
+		PHY_INTERFACE_MODE_RGMII_RXID
+		PHY_INTERFACE_MODE_RGMII_TXID
+		PHY_INTERFACE_MODE_RTBI
+*/
+	.flags = 0,  /* these are apparently phy specific... */
+	
+	.autoneg = AUTONEG_ENABLE,
+	/* speed and duplex only valid if autoneg is AUTONED_DISABLE */
+	.speed = SPEED_100, /* SPEED_10, SPEED_100, SPEED_1000 */
+	.duplex = DUPLEX_HALF, /* DUPLEX_HALF, DUPLEX_FULL */
+
+	.rx_fifo_depth = ALT_TSE_TX_RX_FIFO_DEPTH,
+        .tx_fifo_depth = ALT_TSE_TX_RX_FIFO_DEPTH,
+        .ethaddr = {0x00 , 0x70 , 0xed , 0x11 , 0x12 , 0x12},
+};
+
+static struct platform_device alt_tse_device = {
+  /* the name string must be the same as in struct patform_driver */
+  .name   = ALT_TSE_NAME,
+  .id   = 0,
+  .num_resources  = ARRAY_SIZE(alt_tse_resource),
+  .resource = alt_tse_resource,
+  .dev    = {
+    .platform_data = &tsemac0_config,
+  }
+};   
+
+static void __init parse_mac_addr(struct alt_tse_config *tse_config, char *macstr)
+{
+        int i, j;
+        unsigned char result, value;
+
+        for (i = 0; i < 6; i++) {
+                result = 0;
+
+                if (i != 5 && *(macstr + 2) != ':')
+                        return;
+
+                for (j = 0; j < 2; j++) {
+                        if (isxdigit(*macstr)
+                            && (value =
+                                isdigit(*macstr) ? *macstr -
+                                '0' : toupper(*macstr) - 'A' + 10) < 16) {
+                                result = result * 16 + value;
+                                macstr++;
+                        } else
+                                return;
+                }
+
+                macstr++;
+//                tse_config->ethaddr[i] = result;
+                tse_config->ethaddr[i] = result;
+       }
+
+}
+
+
+static int __init setup_tsemac0(char *s)
+{
+        printk(KERN_INFO "Altera TSE MAC 0 ethaddr = %s\n", s);
+        parse_mac_addr((struct alt_tse_config*) &tsemac0_config, s);
+        return 0;
+}
+
+__setup("tsemac0=", setup_tsemac0);
+
+
+static void tse_device_init(void)
+{
+#ifndef na_descriptor_memory
+	alt_tse_resource[5].start = kmalloc(ALT_TSE_TOTAL_SGDMA_DESC_SIZE, GFP_KERNEL);
+	if (!alt_tse_resource[5].start)
+		return -ENOMEM;
+	alt_tse_resource[5].end   = alt_tse_resource[5].start + ALT_TSE_TOTAL_SGDMA_DESC_SIZE;
+#endif
+}
+#else
+static void tse_device_init(void) {}
+#endif 
+
+#if defined(CONFIG_ETHOC) || defined(CONFIG_ETHOC_MODULE)
+#include <linux/etherdevice.h>
+#include <net/ethoc.h>
+
+#define ETHOC_USE_SRAM_BUFFER 0 /* 0 for dma_alloc from system memory */
+#define na_igor_mac IGOR_MAC_BASE
+#define na_igor_mac_irq IGOR_MAC_IRQ
+#define na_ssram SSRAM_BASE
+#define na_ssram_end (SSRAM_BASE + SSRAM_SPAN)
+
+static struct ethoc_platform_data ethoc_platdata = {
+	.hwaddr = { 0x00,0x07,0xed,0x0a,0x03,0x29 },
+	.phy_id = -1,
+};
+
+static struct resource ethoc_resources[] = {
+	{
+	 .start = na_igor_mac,
+	 .end = na_igor_mac + 0xfff,
+	 .flags = IORESOURCE_MEM,
+	 },
+#if ETHOC_USE_SRAM_BUFFER
+	{
+	 .start = na_ssram,
+	 .end = na_ssram_end -1,
+	 .flags = IORESOURCE_MEM,
+	 },
+#endif
+	{
+	 .start = na_igor_mac_irq,
+	 .end = na_igor_mac_irq,
+	 .flags = IORESOURCE_IRQ,
+	 },
+};
+
+static struct platform_device ethoc_device = {
+	.name = "ethoc",
+	.id = -1,
+	.dev = {
+		.platform_data = &ethoc_platdata,
+		},
+	.num_resources = ARRAY_SIZE(ethoc_resources),
+	.resource = ethoc_resources,
+};
+#endif
+
+
+/*
+ *	Nios2 platform devices
+ */
+
+static struct platform_device *nios2_devices[] __initdata = {
+	&nios2_jtaguart,
+
+	&nios2_uart,
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+	&gpio_leds_device,
+#endif
+
+#if defined(CONFIG_MOUSE_GPIO) || defined(CONFIG_MOUSE_GPIO_MODULE)
+	&gpio_mouse_device,
+#endif
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+	&cfi_flash_device,
+#endif
+
+#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+	&async_nand_device,
+#endif
+
+#if (defined(CONFIG_SPI_ALTERA)  || defined(CONFIG_SPI_ALTERA_MODULE)) && defined(EPCS_CONTROLLER_BASE)
+	&epcs_controller_device,
+#endif
+
+#if (defined(CONFIG_SPI_ALTERA)  || defined(CONFIG_SPI_ALTERA_MODULE)) && defined(TOUCH_PANEL_SPI_BASE)
+	&touch_panel_spi_device,
+#endif
+
+#if (defined(CONFIG_SPI_ALTERA)  || defined(CONFIG_SPI_ALTERA_MODULE)) && defined(MMC_SPI_BASE)
+	&mmc_spi_device,
+#endif
+
+#if defined(CONFIG_SPI_GPIO) || defined(CONFIG_SPI_GPIO_MODULE)
+	&nios2_spi_gpio_3_device,
+#endif
+
+#if (defined(CONFIG_MMC_NIOS) || defined(CONFIG_MMC_NIOS_MODULE)) && defined(SDIO_BASE)
+	&nios_mmc_device,
+#endif
+
+#if defined(USE_PATA_PLATFORM) || defined(USE_PATA_ALTERA_CF)
+	&cf_device,
+#endif
+
+#if (defined(CONFIG_I2C_OCORES) || defined(CONFIG_I2C_OCORES_MODULE)) && defined(I2C_0_BASE)
+	&i2c_oc_0_device,
+#endif
+#if (defined(CONFIG_I2C_OCORES) || defined(CONFIG_I2C_OCORES_MODULE)) && defined(I2C_1_BASE)
+	&i2c_oc_1_device,
+#endif
+
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+	&i2c_gpio_0_device,
+	&i2c_gpio_1_device,
+	&i2c_gpio_2_device,
+#endif
+
+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
+	&nios2_w1_gpio_0_device,
+#endif
+
+#if defined(CONFIG_SERIO_ALTPS2) && defined(PS2_0_BASE)
+	&altps2_0_device,
+#endif
+#if defined(CONFIG_SERIO_ALTPS2) && defined(PS2_1_BASE)
+	&altps2_1_device,
+#endif
+
+#if defined(CONFIG_ALTERA_REMOTE_UPDATE) && defined(ALTREMOTE_BASE)
+	&altremote_device,
+#endif
+
+#if defined(CONFIG_SMC91X) && defined(ENET_BASE)
+	&smc91x_device,
+#endif
+
+#if defined(CONFIG_DM9000) && defined(DM9000_BASE)
+	&dm9k_device,
+#endif
+
+#if defined (CONFIG_ATSE)
+	&atse_device,
+#endif
+
+#if defined (CONFIG_ALT_TSE)
+	&alt_tse_mdio_device,
+	&alt_tse_device,
+#endif
+
+#if defined(CONFIG_ETHOC) || defined(CONFIG_ETHOC_MODULE)
+	&ethoc_device,
+#endif
+};
+
+static int __init init_BSP(void)
+{
+	printk(KERN_INFO "%s(): registering device resources\n", __func__);
+	nios2_gpio_init();
+#ifdef USE_PATA_PLATFORM
+	cf_init(CF_CTL_BASE);
+#endif
+	nios2_plat_nand_init();
+	atse_device_init();
+	tse_device_init();
+	i2c_register_board_info(0, nios2_i2c_0_board_info,
+				ARRAY_SIZE(nios2_i2c_0_board_info));
+	i2c_register_board_info(1, nios2_i2c_1_board_info,
+				ARRAY_SIZE(nios2_i2c_1_board_info));
+	platform_add_devices(nios2_devices, ARRAY_SIZE(nios2_devices));
+
+#if defined(CONFIG_SPI) || defined(CONFIG_SPI_MODULE)
+
+#if (defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)) && \
+	defined(TOUCH_PANEL_PEN_IRQ_N_BASE)
+	ads7843_pendown_init();
+#endif
+
+	spi_register_board_info(nios2_spi_devices,
+				ARRAY_SIZE(nios2_spi_devices));
+#endif
+	return 0;
+}
+
+arch_initcall(init_BSP);
diff --git a/arch/nios2/kernel/dma.c b/arch/nios2/kernel/dma.c
new file mode 100644
index 0000000..094afa3
--- /dev/null
+++ b/arch/nios2/kernel/dma.c
@@ -0,0 +1,338 @@
+/*
+ * arch/nios2nommu/kernel/dma.c
+ *
+ * Copyright (C) 2005 Microtronix Datacom Ltd
+ *
+ * PC like DMA API for Nios's DMAC.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Written by Wentao Xu <wentao@microtronix.com>
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+/* nios2 dma controller register map */
+#define REG_DMA_STATUS		0
+#define REG_DMA_READADDR	4
+#define REG_DMA_WRITEADDR	8
+#define REG_DMA_LENGTH		12
+#define	REG_DMA_CONTROL		24
+
+/* status register bits definition */
+#define ST_DONE			0x01
+#define ST_BUSY			0x02
+#define ST_REOP			0x04
+#define ST_WROP			0x08
+#define ST_LEN			0x10
+
+/* control register bits definition */
+#define CT_BYTE			0x01
+#define CT_HW			0x02
+#define CT_WORD			0x04
+#define CT_GO			0x08
+#define CT_IEEN			0x10
+#define CT_REEN			0x20
+#define CT_WEEN			0x40
+#define CT_LEEN			0x80
+#define CT_RCON			0x100
+#define CT_WCON			0x200
+#define CT_DOUBLE		0x400
+#define CT_QUAD			0x800
+
+struct dma_channel {
+	unsigned int addr;  /* control address */
+	unsigned int irq;	/* interrupt number */
+	atomic_t idle;
+	unsigned int mode;  /* dma mode: width, stream etc */
+	int (*handler)(void*, int );
+	void*	user;
+	
+	char id[16];
+	char dev_id[16];
+};
+static struct dma_channel dma_channels[]={
+#ifdef na_dma_0
+	{
+		.addr	= na_dma_0,
+		.irq	= na_dma_0_irq,
+		.idle	= ATOMIC_INIT(1),
+	},
+#endif
+#ifdef na_dma_1
+	{
+		.addr	= na_dma_1,
+		.irq	= na_dma_1_irq,
+		.idle	= ATOMIC_INIT(1),
+	},
+#endif
+};
+
+#define MAX_DMA_CHANNELS	ARRAY_SIZE(dma_channels)
+
+void enable_dma(unsigned int dmanr)
+{
+	if (dmanr < MAX_DMA_CHANNELS) {
+		unsigned int ctl = dma_channels[dmanr].mode;
+		ctl |= CT_GO | CT_IEEN;
+		outl(ctl, dma_channels[dmanr].addr+REG_DMA_CONTROL);
+	}
+}
+
+void disable_dma(unsigned int dmanr)
+{
+	if (dmanr < MAX_DMA_CHANNELS) {
+		unsigned int ctl = dma_channels[dmanr].mode;
+		ctl &= ~(CT_GO | CT_IEEN);
+		outl(ctl, dma_channels[dmanr].addr+REG_DMA_CONTROL);
+	}
+}
+
+void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+	if (dmanr < MAX_DMA_CHANNELS) {
+		dma_channels[dmanr].mode |= CT_LEEN;
+		outl(count, dma_channels[dmanr].addr+REG_DMA_LENGTH);
+	}
+}
+
+int get_dma_residue(unsigned int dmanr)
+{
+	int result =-1;
+	if (dmanr < MAX_DMA_CHANNELS) {
+		result = inl(dma_channels[dmanr].addr+REG_DMA_LENGTH);
+	}
+	return result;
+}
+
+int request_dma(unsigned int chan, const char *dev_id)
+{
+	struct dma_channel *channel;
+
+	if ( chan >= MAX_DMA_CHANNELS) {
+		return -EINVAL;
+	}
+
+	channel = &dma_channels[chan];
+	
+	if (!atomic_dec_and_test(&channel->idle)) {
+		return -EBUSY;
+	}
+
+	strlcpy(channel->dev_id, dev_id, sizeof(channel->dev_id));
+	channel->handler=NULL;
+	channel->user=NULL;
+	channel->mode =0;
+
+	return 0;
+}
+
+void free_dma(unsigned int chan)
+{
+	if ( chan < MAX_DMA_CHANNELS) {
+		dma_channels[chan].handler=NULL;
+		dma_channels[chan].user=NULL;
+		atomic_set(&dma_channels[chan].idle, 1);
+	}
+}
+
+int nios2_request_dma(const char *dev_id)
+{
+	int chann;
+
+	for ( chann=0; chann < MAX_DMA_CHANNELS; chann++) {
+		if (request_dma(chann, dev_id)==0)
+			return chann;
+	}
+
+	return -EINVAL;
+}
+void nios2_set_dma_handler(unsigned int dmanr, int (*handler)(void*, int), void* user)
+{
+	if (dmanr < MAX_DMA_CHANNELS) {
+		dma_channels[dmanr].handler=handler;
+		dma_channels[dmanr].user=user;
+	}	
+}
+#define NIOS2_DMA_WIDTH_MASK	(CT_BYTE | CT_HW | CT_WORD | CT_DOUBLE | CT_QUAD)
+#define NIOS2_MODE_MASK (NIOS2_DMA_WIDTH_MASK | CT_REEN | CT_WEEN | CT_LEEN | CT_RCON | CT_WCON)
+void nios2_set_dma_data_width(unsigned int dmanr, unsigned int width)
+{
+	if (dmanr < MAX_DMA_CHANNELS) {		
+		 dma_channels[dmanr].mode &= ~NIOS2_DMA_WIDTH_MASK;
+		 switch (width) {
+		 	case 1:
+			dma_channels[dmanr].mode |= CT_BYTE;
+			break;
+			case 2:
+			dma_channels[dmanr].mode |= CT_HW;
+			break;
+			case 8:
+			dma_channels[dmanr].mode |= CT_DOUBLE;
+			break;
+			case 16:
+			dma_channels[dmanr].mode |= CT_QUAD;
+			break;
+			case 4:
+			default:
+			dma_channels[dmanr].mode |= CT_WORD;
+			break;			
+		 }
+	}
+}
+
+void nios2_set_dma_rcon(unsigned int dmanr,unsigned int set)
+{
+	if (dmanr < MAX_DMA_CHANNELS) {		
+		 dma_channels[dmanr].mode &= ~(CT_REEN | CT_RCON);
+		 if (set)
+		 	dma_channels[dmanr].mode |= (CT_REEN | CT_RCON);
+	}
+}
+void nios2_set_dma_wcon(unsigned int dmanr,unsigned int set)
+{
+	if (dmanr < MAX_DMA_CHANNELS) {		
+		 dma_channels[dmanr].mode &= ~(CT_WEEN | CT_WCON);
+		 if (set)
+		 	dma_channels[dmanr].mode |= (CT_WEEN | CT_WCON);
+	}
+}
+void nios2_set_dma_mode(unsigned int dmanr, unsigned int mode)
+{
+	if (dmanr < MAX_DMA_CHANNELS) {
+		/* set_dma_mode is only allowed to change the bus width,
+		   stream setting, etc.
+		 */
+		 mode &= NIOS2_MODE_MASK;
+		 dma_channels[dmanr].mode &= ~NIOS2_MODE_MASK;
+		 dma_channels[dmanr].mode |= mode;
+	}
+}
+
+void nios2_set_dma_raddr(unsigned int dmanr, unsigned int a)
+{
+	if (dmanr < MAX_DMA_CHANNELS) {
+		outl(a, dma_channels[dmanr].addr+REG_DMA_READADDR);
+	}
+}
+void nios2_set_dma_waddr(unsigned int dmanr, unsigned int a)
+{
+	if (dmanr < MAX_DMA_CHANNELS) {
+		outl(a, dma_channels[dmanr].addr+REG_DMA_WRITEADDR);
+	}
+}
+
+
+static irqreturn_t dma_isr(int irq, void *dev_id)
+{
+	struct dma_channel	*chann=(struct dma_channel*)dev_id;
+	
+	if (chann) {		
+		int status = inl(chann->addr+REG_DMA_STATUS);
+		/* ack the interrupt, and clear the DONE bit */
+		outl(0, chann->addr+REG_DMA_STATUS);
+		/* call the peripheral callback */
+		if (chann->handler)
+			chann->handler(chann->user, status);
+	}
+
+	return IRQ_HANDLED;
+}
+
+
+
+#ifdef CONFIG_PROC_FS
+static int proc_dma_show(struct seq_file *m, void *v)
+{
+	int i;
+
+	for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) {
+		if (!atomic_read(&dma_channels[i].idle)) {
+		    seq_printf(m, "%2d: %s\n", i,
+			       dma_channels[i].dev_id);
+		}
+	}
+	return 0;
+}
+
+static int proc_dma_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_dma_show, NULL);
+}
+
+static const struct file_operations proc_dma_operations = {
+	.open		= proc_dma_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init proc_dma_init(void)
+{
+	return proc_create("dma", 0, NULL, &proc_dma_operations) != NULL;
+}
+
+__initcall(proc_dma_init);
+
+#endif /* CONFIG_PROC_FS */
+
+int __init init_dma(void)
+{
+	int i;
+		
+	for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) {
+		sprintf(dma_channels[i].id, "dmac-%d", i);
+		/* disable the dmac channel */
+		disable_dma(i);
+		/* request irq*/
+		if (request_irq(dma_channels[i].irq, dma_isr, 0, dma_channels[i].id, (void*)&dma_channels[i])){
+			printk("DMA controller %d failed to get irq %d\n", i, dma_channels[i].irq);
+			atomic_set(&dma_channels[i].idle, 0);
+		}
+	}
+	return 0;
+}
+
+static void __exit exit_dma(void)
+{
+	int i;
+		
+	for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) {
+		/* disable the dmac channel */
+		disable_dma(i);
+		free_irq(dma_channels[i].irq, dma_channels[i].id);
+	}
+}
+
+module_init(init_dma);
+module_exit(exit_dma);
+
+MODULE_LICENSE("GPL");
+
+//EXPORT_SYMBOL(claim_dma_lock);
+//EXPORT_SYMBOL(release_dma_lock);
+EXPORT_SYMBOL(enable_dma);
+EXPORT_SYMBOL(disable_dma);
+EXPORT_SYMBOL(set_dma_count);
+EXPORT_SYMBOL(get_dma_residue);
+EXPORT_SYMBOL(request_dma);
+EXPORT_SYMBOL(free_dma);
+EXPORT_SYMBOL(nios2_request_dma);
+EXPORT_SYMBOL(nios2_set_dma_handler);
+EXPORT_SYMBOL(nios2_set_dma_data_width);
+EXPORT_SYMBOL(nios2_set_dma_rcon);
+EXPORT_SYMBOL(nios2_set_dma_wcon);
+EXPORT_SYMBOL(nios2_set_dma_mode);
+EXPORT_SYMBOL(nios2_set_dma_raddr);
+EXPORT_SYMBOL(nios2_set_dma_waddr);
+
diff --git a/arch/nios2/kernel/early_printk.c b/arch/nios2/kernel/early_printk.c
new file mode 100644
index 0000000..0346b51
--- /dev/null
+++ b/arch/nios2/kernel/early_printk.c
@@ -0,0 +1,80 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ */
+#include <linux/console.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+#if JTAG_UART_BASE > 0x20000000
+#error Cannot map JTAG uart directly to IO_REGION
+#error please disable early console
+#endif
+
+#define ALTERA_JTAGUART_CONTROL_REG               4
+
+#define ALTERA_JTAGUART_CONTROL_WSPACE_MSK        (0xFFFF0000)
+#define ALTERA_JTAGUART_CONTROL_AC_MSK            (0x00000400)
+
+static void early_console_write(struct console *con, const char *s, unsigned n)
+{
+  unsigned long base = JTAG_UART_BASE + IO_REGION_BASE;
+  unsigned long status;
+
+  while (n-- && *s) {
+     status = __builtin_ldwio((void *)(base + ALTERA_JTAGUART_CONTROL_REG));
+     while((status & ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) 
+     {
+#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
+        if ((status & ALTERA_JTAGUART_CONTROL_AC_MSK) == 0) {
+           return;	/* no connection activity */
+        }
+#endif
+        status = __builtin_ldwio((void *)(base + ALTERA_JTAGUART_CONTROL_REG));
+     }
+     __builtin_stwio((void *)base, *s++);
+   }
+}
+
+static struct console early_console = {
+	.name	= "early",
+	.write	= early_console_write,
+	.flags	= CON_PRINTBUFFER | CON_BOOT,
+	.index	= -1
+};
+
+void __init setup_early_printk(void)
+{
+#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
+  {
+    unsigned long base = JTAG_UART_BASE + IO_REGION_BASE;
+    unsigned long status;
+    
+    /* Clear activity bit so BYPASS doesn't stall if we've used jtag for 
+     * downloading the kernel. This might cause early data to be lost even 
+     * if the jtag terminal is running.
+     */
+    status = __builtin_ldwio((void *)(base + ALTERA_JTAGUART_CONTROL_REG));
+    __builtin_stwio((void *)(base + ALTERA_JTAGUART_CONTROL_REG), 
+		    status | ALTERA_JTAGUART_CONTROL_AC_MSK);
+  }
+#endif
+
+   register_console(&early_console);
+   early_console_write(0, "Early printk initialized\n", 80);
+}
+
+void __init disable_early_printk(void)
+{
+}
diff --git a/arch/nios2/kernel/entry.S b/arch/nios2/kernel/entry.S
new file mode 100644
index 0000000..e2d0460
--- /dev/null
+++ b/arch/nios2/kernel/entry.S
@@ -0,0 +1,596 @@
+/*
+ * linux/arch/nios2/kernel/entry.S
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ *
+ * Based on:
+ *
+ * linux/arch/nios2/kernel/entry.S	
+ *
+ *  Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 2000  Lineo Inc. (www.lineo.com)
+ *  Copyright (C) 2004  Microtronix Datacom Ltd.
+ *
+ * Based on:
+ *
+ *  linux/arch/m68knommu/kernel/entry.S
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ * ColdFire support by Greg Ungerer (gerg@snapgear.com)
+ * 5307 fixes by David W. Miller
+ * linux 2.4 support David McCullough <davidm@snapgear.com>
+ */
+
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/asm-macros.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/entry.h>
+#include <asm/unistd.h>
+#include <asm/traps.h>
+#include <asm/processor.h>
+
+.macro GET_THREAD_INFO reg 
+.if THREAD_SIZE & 0xffff0000
+	andhi	\reg, sp, %hi(~(THREAD_SIZE-1))
+.else
+	addi	\reg, r0, %lo(~(THREAD_SIZE-1))
+	and	\reg, \reg, sp
+.endif
+.endm
+
+/* FIXME: Lots of these exceptions needs to be handled
+ */ 
+.data
+exception_table:
+        .word   unhandled_exception	// 0 - Reset
+        .word   unhandled_exception	// 1 - Processor only reset
+        .word   external_interrupt	// 2 - Interrupt
+        .word   handle_trap		// 3 - trap instruction
+
+        .word   instruction_trap	// 4 - Unimplemented instruction
+        .word   handle_illegal		// 5 - Illegal instruction
+        .word   handle_unaligned	// 6 - Misaligned data access
+        .word   handle_unaligned	// 7 - Misaligned destination address
+
+        .word   handle_diverror		// 8 - Division error
+        .word   protection_exception_ba	// 9 - Supervisor only instr. access
+        .word   protection_exception_instr // 10 - Supervisor only instr.
+        .word   protection_exception_ba	// 11 - Supervisor only data address
+
+        .word   unhandled_exception	// 12 - tlb double fault.
+        .word   protection_exception_pte// 13 - tlb permission violation (x)
+        .word   protection_exception_pte// 14 - tlb permission violation (r)
+        .word   protection_exception_pte// 15 - tlb permission violation (w)
+	
+        .word   unhandled_exception	// 16 - MPU region violation
+
+	
+trap_table:
+	.word	handle_system_call	// 0 
+	.word	instruction_trap	// 1
+	.word	instruction_trap	// 2
+	.word	instruction_trap	// 3
+	.word	instruction_trap	// 4
+	.word	instruction_trap	// 5
+	.word	instruction_trap	// 6
+	.word	instruction_trap	// 7
+	.word	instruction_trap	// 8
+	.word	instruction_trap	// 9
+	.word	instruction_trap	// 10
+	.word	instruction_trap	// 11
+	.word	instruction_trap	// 12
+	.word	instruction_trap	// 13
+	.word	instruction_trap	// 14
+	.word	instruction_trap	// 15
+	.word	instruction_trap	// 16
+	.word	instruction_trap	// 17
+	.word	instruction_trap	// 18
+	.word	instruction_trap	// 19
+	.word	instruction_trap	// 20
+	.word	instruction_trap	// 21
+	.word	instruction_trap	// 22
+	.word	instruction_trap	// 23
+	.word	instruction_trap	// 24
+	.word	instruction_trap	// 25
+	.word	instruction_trap	// 26
+	.word	instruction_trap	// 27
+	.word	instruction_trap	// 28
+	.word	instruction_trap	// 29
+	.word	instruction_trap	// 30
+	.word	handle_breakpoint	// 31
+	
+.text
+.set noat
+.set nobreak
+
+
+ENTRY(inthandler)
+	SAVE_ALL
+	/* Clear EH bit before we get a new excpetion in the kernel
+	 * and after we have saved it to the exception frame. This is done
+	 * wheter it's trap, tlb-miss or interrupt. If we don't do this
+	 * estatus is not updated the next exception.
+	 */	
+	rdctl	r24,status
+	movi	r9,-5
+	and	r24,r24,r9
+	wrctl	status,r24
+
+	/* Read cause and vector and branch to the associated handler (
+         */
+	mov	r4,sp
+        rdctl   r5,ctl7
+        movia   r9,exception_table
+        add     r24,r9,r5
+        ldw     r24,0(r24)
+        jmp     r24
+
+
+/***********************************************************************
+ * Handle traps
+ ***********************************************************************
+ */
+ENTRY(handle_trap)
+	ldw	r24,-4(ea)	// instruction that caused the exception
+	srli	r24,r24,4
+	andi	r24,r24,0x7c
+	movia	r9,trap_table
+	add	r24,r24,r9
+	ldw	r24,0(r24)
+	jmp	r24
+
+	
+/***********************************************************************
+ * Handle system calls
+ ***********************************************************************
+ */
+ENTRY(handle_system_call)
+	/* Enable interrupts
+	 */
+	rdctl	r10,status		
+	ori	r10,r10,0x0001
+	wrctl	status,r10
+	
+	/* Reload registers destroyed by common code.
+	 */
+	ldw	r4,PT_R4(sp)
+	ldw	r5,PT_R5(sp)
+	
+	/* Check that the requested system call is within limits
+	 */
+	movui	r1,NR_syscalls
+	bgtu	r2,r1,ret_invsyscall
+	slli	r1,r2,2
+	movhi	r11,%hiadj(sys_call_table)
+	add	r1,r1,r11
+	ldw	r1,%lo(sys_call_table)(r1)
+	beq	r1,r0,ret_invsyscall
+
+	/* Get thread info pointer
+	 */
+	movi	r11,%lo(0xfffff000)	
+	and	r11,sp,r11
+	ldw	r11,TI_FLAGS(r11)
+
+	/* If someone is ptrace:ing us, take the long way.
+	 */
+	BTBNZ	r11,r11,TIF_SYSCALL_TRACE_ASM,traced_system_call
+#if 0
+	SAVE_SWITCH_STACK
+	mov	r9,r8
+	mov	r8,r7
+	mov	r6,r5
+	mov	r5,r4
+	mov	r4,r2
+	call	print_syscall
+	RESTORE_SWITCH_STACK
+	ldw	r2,PT_R2(sp)
+	ldw	r4,PT_R4(sp)
+	ldw	r5,PT_R5(sp)
+	ldw	r6,PT_R6(sp)
+	ldw	r7,PT_R7(sp)
+	ldw	r8,PT_R8(sp)
+	ldw	r9,PT_R9(sp)
+#endif
+
+	
+	/* Execute the system call
+	 */
+	callr	r1
+	
+	/* If the syscall returns a negative result:
+	 *   Set r7 to 1 to indicate error,
+	 *   Negate r2 to get a positive error code
+	 * If the syscall returns zero or a positive value:
+	 *   Set r7 to 0.
+	 * The sigreturn system calls will skip the code below by
+	 * adding to register ra. To avoid destroying registers
+	 * 
+ 	 * FIXME: We probably need an orig_r7
+	 */
+translate_rc_and_ret:
+	movi	r1,0
+	bge	r2,zero,3f
+	sub	r2,zero,r2
+	movi	r1,1
+3:	
+	stw	r2,PT_R2(sp)
+	stw	r1,PT_R7(sp)
+end_translate_rc_and_ret:
+
+#if 0
+	SAVE_SWITCH_STACK
+	mov	r4,r2
+	mov	r5,r1
+	call	print_syscall_ret
+	RESTORE_SWITCH_STACK
+#endif
+	
+ret_from_exception:
+	ldw	r1,PT_ESTATUS(sp)
+	TSTBNZ	r1,r1,ESTATUS_EU_ASM,Luser_return	/* if so, skip resched, signals */
+
+restore_all:
+	rdctl	r10,status			/* disable intrs */
+	andi	r10,r10,0xfffe
+	wrctl	status, r10
+	RESTORE_ALL
+	eret
+
+	/* If the syscall number was invalid return ENOSYS
+	*/
+ret_invsyscall:
+	movi	r2,-LENOSYS
+	br translate_rc_and_ret
+
+
+	/* This implements the same as above, except it calls
+	 * syscall_trace before and after the syscall in order
+	 * for utilities like strace and gdb to work.
+	 */
+traced_system_call:
+	SAVE_SWITCH_STACK
+	call	syscall_trace
+	RESTORE_SWITCH_STACK
+	
+	/* r2 and r7-r9 might be destroyed  by syscall_trace and we need to restore
+	 * them before calling our syscall.
+	 */
+	ldw	r2,PT_R2(sp)
+	ldw	r4,PT_R4(sp)
+	ldw	r5,PT_R5(sp)
+	ldw	r6,PT_R6(sp)
+	ldw	r7,PT_R7(sp)
+	ldw	r8,PT_R8(sp)
+	ldw	r9,PT_R9(sp)
+
+	/* Fetch the syscall function, we don't need to check the boundaries
+	 * since this is already done.
+	 */
+	slli	r1,r2,2
+	movhi	r11,%hiadj(sys_call_table)
+	add	r1,r1,r11
+	ldw	r1,%lo(sys_call_table)(r1)
+
+	callr	r1
+	
+	/* If the syscall returns a negative result:
+	 *   Set r7 to 1 to indicate error,
+	 *   Negate r2 to get a positive error code
+	 * If the syscall returns zero or a positive value:
+	 *   Set r7 to 0.
+	 * The sigreturn system calls will skip the code below by
+	 * adding to register ra. To avoid destroying registers
+	 * 
+ 	 * FIXME: We probably need an orig_r7
+	 */
+translate_rc_and_ret2:
+	movi	r1,0
+	bge	r2,zero,4f
+	sub	r2,zero,r2
+	movi	r1,1
+4:	
+	stw	r2,PT_R2(sp)
+	stw	r1,PT_R7(sp)
+end_translate_rc_and_ret2:
+	SAVE_SWITCH_STACK
+	call	syscall_trace
+	RESTORE_SWITCH_STACK
+	br ret_from_exception
+
+Luser_return:
+	GET_THREAD_INFO	r11			/* get thread_info pointer */
+	ldw	r10,TI_FLAGS(r11)		/* get thread_info->flags */
+	ANDI32	r11,r10,_TIF_WORK_MASK_ASM
+	beq	r11,r0,restore_all		/* Nothing to do */
+	BTBZ	r1,r10,TIF_NEED_RESCHED_ASM,Lsignal_return
+
+Lwork_resched:
+	call	schedule
+	br	ret_from_exception
+
+Lsignal_return:
+	BTBZ	r1,r10,TIF_SIGPENDING_ASM,restore_all
+	mov	r5,sp			/* pt_regs */
+	SAVE_SWITCH_STACK
+	CLR	r4			/* oldset = 0 */
+	movi	r6,1			/* syscall */
+	call	do_signal
+	RESTORE_SWITCH_STACK
+	br	restore_all
+
+
+
+/***********************************************************************
+ * Handle external interrupts.
+ ***********************************************************************
+ */
+/*
+ * This is the generic interrupt handler (for all hardware interrupt
+ * sources). It figures out the vector number and calls the appropriate
+ * interrupt service routine directly.
+ */
+external_interrupt:	
+	rdctl	r12,ipending
+	rdctl	r9,ienable
+	and	r12,r12,r9
+
+	movi	r24,-1
+	stw	r24,PT_ORIG_R2(sp)
+	
+	/* 
+	 * Process an external hardware interrupt. 
+	 */
+
+	addi	ea,ea,-4		/* re-issue the interrupted instruction */
+	stw	ea,PT_EA(sp)
+2:	movi	r4,%lo(-1)		/* Start from bit position 0, highest priority */
+					/* This is the IRQ # for handler call */
+1:	andi	r10,r12,1		/* Isolate bit we are interested in */
+	srli	r12,r12,1		/* shift count is costly without hardware multiplier */
+	addi	r4,r4,1
+	beq	r10,r0,1b
+	mov	r5,sp			/* Setup pt_regs pointer for handler call */
+	call	do_IRQ
+	rdctl	r12,ipending		/* check again if irq still pending */
+	rdctl	r9,ienable		/* Isolate possible interrupts */
+	and	r12,r12,r9
+	bne	r12,r0,2b		
+	/* br	ret_from_interrupt */	/* fall throught to ret_from_interrupt */
+
+ENTRY(ret_from_interrupt)
+	ldw	r1,PT_ESTATUS(sp)	/* check if returning to kernel */
+	TSTBNZ	r1,r1,ESTATUS_EU_ASM,Luser_return
+
+#ifdef CONFIG_PREEMPT
+	GET_THREAD_INFO	r1
+	ldw	r4,TI_PREEMPT_COUNT(r1)
+	bne	r4,r0,restore_all
+
+need_resched:
+	ldw	r4,TI_FLAGS(r1)		// ? Need resched set
+	BTBZ	r10,r4,TIF_NEED_RESCHED_ASM,restore_all
+	ldw	r4,PT_ESTATUS(sp)	// ? Interrupts off
+	BTBZ	r10,r4,NIOS2_STATUS_PIE_OFST_ASM,restore_all
+	movia	r4,PREEMPT_ACTIVE_ASM
+	stw	r4,TI_PREEMPT_COUNT(r1)
+	rdctl	r10,status		/* enable intrs again */
+	ori	r10,r10,0x0001
+	wrctl	status,r10
+	PUSH	r1
+	call	schedule
+	POP	r1
+	mov	r4,r0
+	stw	r4,TI_PREEMPT_COUNT(r1)
+	rdctl	r10,status		/* disable intrs */
+	andi	r10,r10,0xfffe
+	wrctl	status, r10
+	br	need_resched
+#else
+	br	restore_all
+#endif
+
+/***********************************************************************
+ * Syscalls implemented in assembly
+ ***********************************************************************
+ */
+
+ENTRY(sys_nios2cmpxchg)
+	
+	// r4 pointer to exchange variable
+	// r5 old value
+	// r6 new value
+	// r8 - old interrupt status (assert this to enabled?)
+	// r9 - temp
+	// Disable interrupts (keep old status in r8)
+        rdctl   r8,status
+        andi    r9,r8,0xfffe
+        wrctl   status,r9
+
+	// Make sure we skip the r2/r7 translation code when we return.
+        addi    ra,ra,(end_translate_rc_and_ret-translate_rc_and_ret)
+
+ldw1:	ldw     r2, 0(r4)
+        bne     r2, r5, .L6
+
+	// We had a match, store the new value
+stw1:	stw     r6, 0(r4)
+.L6:
+	// Reenable interrupts
+        wrctl   status,r8
+	
+	// Store return value
+	stw	r2,PT_R2(sp)
+	// Indicate everything is ok
+	movi	r2,0
+	stw	r2,PT_R7(sp)
+        ret
+fault:
+        movi    r2,EFAULT
+	stw	r2,PT_R2(sp)
+	movi    r2,1
+	stw	r2,PT_R7(sp)
+        wrctl   status,r8
+        ret
+
+	// setup the exception table
+	.section __ex_table,"a"
+        .word ldw1, fault
+	.word stw1, fault
+        .previous
+
+
+	
+/***********************************************************************
+ * A few syscall wrappers
+ ***********************************************************************
+ */
+
+ENTRY(sys_fork)
+	mov	r4,sp
+	SAVE_SWITCH_STACK
+	call	nios2_fork
+	RESTORE_SWITCH_STACK
+	ret
+
+ENTRY(sys_vfork)
+	mov	r4,sp
+	SAVE_SWITCH_STACK
+	call	nios2_vfork
+	RESTORE_SWITCH_STACK
+	ret
+
+ENTRY(sys_execve)
+	mov	r4,sp
+	SAVE_SWITCH_STACK
+	call	nios2_execve
+	RESTORE_SWITCH_STACK
+	ret
+
+ENTRY(sys_clone)
+	mov	r4,sp
+	SAVE_SWITCH_STACK
+	call	nios2_clone
+	RESTORE_SWITCH_STACK
+	ret
+
+ENTRY(sys_sigsuspend)
+	mov	r4,sp
+	SAVE_SWITCH_STACK
+	call	do_sigsuspend
+	RESTORE_SWITCH_STACK
+	ret
+
+ENTRY(sys_rt_sigsuspend)
+	mov	r4,sp
+	SAVE_SWITCH_STACK
+	call	do_rt_sigsuspend
+	RESTORE_SWITCH_STACK
+	ret
+
+ENTRY(sys_sigreturn)
+	mov	r4,sp
+	SAVE_SWITCH_STACK
+	call	do_sigreturn
+	RESTORE_SWITCH_STACK
+	addi	ra,ra,(end_translate_rc_and_ret-translate_rc_and_ret)
+	ret
+
+ENTRY(sys_sigaltstack)
+	ldw	r4,PT_R4(sp)
+	ldw	r5,PT_R5(sp)
+	ldw	r6,PT_SP(sp)
+	SAVE_SWITCH_STACK
+	call	do_sigaltstack
+	RESTORE_SWITCH_STACK
+	ret
+
+ENTRY(sys_rt_sigreturn)
+	SAVE_SWITCH_STACK
+	mov	r4,sp
+	call	do_rt_sigreturn
+	RESTORE_SWITCH_STACK
+	addi	ra,ra,(end_translate_rc_and_ret-translate_rc_and_ret)
+	ret
+
+/***********************************************************************
+ * A few other wrappers and stubs
+ ***********************************************************************
+ */
+protection_exception_pte:
+	rdctl r6,pteaddr
+	slli r6,r6,10
+	call protection_exception_c
+	br ret_from_exception
+	
+protection_exception_ba:
+	rdctl r6,badaddr
+	call protection_exception_c
+	br ret_from_exception
+
+protection_exception_instr:
+	call handle_supervisor_instr
+	br ret_from_exception
+	
+handle_breakpoint:
+	call breakpoint_c
+	br ret_from_exception
+
+handle_unaligned:
+	call handle_unaligned_c
+	br ret_from_exception
+	
+handle_illegal:
+	call handle_illegal_c
+	br ret_from_exception
+
+handle_diverror:
+	call handle_illegal_c
+	br ret_from_exception
+
+/*
+ * Beware - when entering resume, prev (the current task) is
+ * in r4, next (the new task) is in r5, don't change these
+ * registers.
+ */
+ENTRY(resume)
+
+	rdctl	r7,status			/* save thread status reg */
+	stw	r7,TASK_THREAD+THREAD_KPSR(r4)	
+
+	andi	r7,r7,0x0fffe			/* disable interrupts */
+	wrctl	status,r7
+
+	SAVE_SWITCH_STACK
+	stw	sp,TASK_THREAD+THREAD_KSP(r4)	/* save kernel stack pointer */
+	ldw	sp,TASK_THREAD+THREAD_KSP(r5)	/* restore new thread stack */
+	movia	r24,_current_thread		/* save thread */
+	GET_THREAD_INFO r1
+	stw	r1,0(r24)
+	RESTORE_SWITCH_STACK
+	
+	ldw	r7,TASK_THREAD+THREAD_KPSR(r5)	/* restore thread status reg */
+	wrctl	status,r7
+	ret
+
+ENTRY(ret_from_fork)
+	call	schedule_tail
+	br	ret_from_exception
+
+
diff --git a/arch/nios2/kernel/head.S b/arch/nios2/kernel/head.S
new file mode 100644
index 0000000..7963f27
--- /dev/null
+++ b/arch/nios2/kernel/head.S
@@ -0,0 +1,260 @@
+/*
+ * linux/arch/nios2/kernel/head.S
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ *
+ * Based on:
+
+ * head.S for Altera's Excalibur development board with nios processor
+ *
+ * (c) Vic Phillips, Microtronix Datacom Ltd., 2001
+ * (C) Copyright 2004  Microtronix Datacom Ltd
+ *
+ * Based on the following from the Excalibur sdk distribution:
+ *	NA_MemoryMap.s, NR_JumpToStart.s, NR_Setup.s, NR_CWPManager.s
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+#include <asm/asm-macros.h>
+
+
+#ifdef CONFIG_CRC_CHECK
+/**********************************************/
+/* Define where the CRC table lives in flash. */
+/* The __CRC_Sector_Size is the flash sector  */
+/* size for the address range.                */
+/**********************************************/
+
+	GEQU	__CRC_Table_Begin,(na_flash)+0x4000   /* Second sector of main board flash */
+	GEQU	__CRC_Sector_Size,0x2000
+#endif
+
+/*
+ * This global variable is used as an extension to the nios'
+ * STATUS register to emulate a user/supervisor mode.
+ */
+	.data
+	.align	2
+	.set noat
+
+	.global _current_thread
+_current_thread:
+	.long	0
+/*
+ * Input(s): passed from u-boot
+ *   r4 - Optional pointer to a board information structure.
+ *   r5 - Optional pointer to the physical starting address of the init RAM
+ *        disk.
+ *   r6 - Optional pointer to the physical ending address of the init RAM
+ *        disk.
+ *   r7 - Optional pointer to the physical starting address of any kernel
+ *        command-line parameters.
+ */
+
+/*
+ * First executable code - detected and jumped to by the ROM bootstrap
+ * if the code resides in flash (looks for "Nios" at offset 0x0c from
+ * the potential executable image).
+ */
+	__HEAD
+	.global _start
+_start:
+	/* Disable intruction trace
+	 */
+#ifdef COMPILE_FOR_ISS
+	rdctl	r2,ctl6
+	movi	r1,-9
+	and	r2,r2,r1
+	movi	r1,-17
+	and	r2,r2,r1
+	wrctl	ctl6,r2
+
+	/* Initialize all memory
+	 */
+	movi	r1,(KERNEL_REGION_BASE_ASM|LINUX_SDRAM_END)
+	movia	r2,_end
+	sub	r1,r1,r2
+1:	stw	r0,0(r2)
+	addi	r2,r2,4
+	subi	r1,r1,4
+	bne	r1,r0,1b
+#endif
+
+	wrctl	status,r0		/* Disable interrupts */
+	
+	/* Flush all cache lines within the instruction cache
+ 	 */
+	movia	r1,NIOS2_ICACHE_SIZE
+	movui	r2,NIOS2_ICACHE_LINE_SIZE
+
+text_flush:
+	flushi	r1
+	sub	r1,r1,r2
+	bgt	r1,r0,text_flush
+	br	1f
+
+	/* This is the default location for the exception 
+	 * handler. Code in jump to our handler
+	 */
+exc_hook:
+	movia	r24,inthandler
+	jmp	r24
+	
+fast_handler_start:
+	nextpc et
+helper:	
+	stw     r3,r3save-helper(et)
+
+#if 1
+	/* Fast handler statistics
+ 	 */
+	movia	et, statistics
+	ldw	r3,STAT_TLB_FAST_HANDLER(et)
+	addi	r3,r3,1
+	stw	r3,STAT_TLB_FAST_HANDLER(et)
+#endif	
+	rdctl   r3,pteaddr
+	srli    r3,r3,12
+	slli	r3,r3,2
+	movia	et,pgd_current
+	
+	ldw	et,0(et)	
+	add	r3,et,r3	
+	ldw	et,0(r3)
+
+	rdctl	r3,pteaddr
+	andi	r3,r3,0xfff
+	add	et,r3,et
+	ldw	et,0(et)
+	wrctl	tlbacc,et
+	nextpc	et
+helper2:	
+	ldw	r3,r3save-helper2(et)
+	subi	ea,ea,4	
+	eret		
+r3save:	
+	.word 0x0
+fast_handler_end:
+
+1:		
+	/*
+	 * After flushing the instruction cache, we must flush the data
+	 * cache.
+	 */
+
+	movia	r1,NIOS2_DCACHE_SIZE
+	movi	r2,NIOS2_DCACHE_LINE_SIZE
+
+data_flush:
+	flushd	0(r1)
+	sub	r1,r1,r2
+	bgt	r1,r0,data_flush
+
+	nextpc	r1			/* Find out where we are */
+chkadr:	
+	movia	r2,chkadr
+	beq	r1,r2,finish_move	/* We are running in RAM done */
+	addi	r1,r1,(_start - chkadr)	/* Source */
+	movia	r2,_start		/* Destination */
+	movia	r3,__bss_start		/* End of copy */
+	
+loop_move:				// r1: src, r2: dest, r3: last dest
+	ldw	r8,0(r1)		// load a word from [r1]
+	stw	r8,0(r2)		// stort a word to dest [r2]
+	flushd	0(r2)			// Flush cache for safty
+	addi 	r1,r1,4			// inc the src addr
+	addi	r2,r2,4			// inc the dest addr
+	blt	r2,r3,loop_move
+		
+	movia	r1,finish_move		// VMA(_start)->l1
+	jmp	r1			// jmp to _start	
+
+finish_move:
+	/* FIXME: What about overlap of src and dst address ??
+	 */
+	/*	Copy an instruction sequence to put at the exception address */
+        movia	r2,exc_hook
+        movia	r3,CPU_EXCEPT_VIRT_ADDRESS_ASM
+        ldw     r1,0(r2)
+        stw     r1,0(r3)
+        ldw     r1,4(r2)
+        stw     r1,4(r3)
+        ldw     r1,8(r2)
+        stw     r1,8(r3)
+        flushd  0(r3)
+        flushd  4(r3)
+        flushd  8(r3)
+        flushi  r3
+        addi    r3,r3,4
+        flushi  r3
+        addi    r3,r3,4
+        flushi  r3
+
+	/* FIXME: What about overlap of src and dst address ??
+	 */
+	
+	/* Copy the fast tlb-handler
+	 * FIXME: What if it's already on the right address ?
+	 */
+	movia   r2,fast_handler_start
+	movia   r8,fast_handler_end
+	movia	r3,CPU_FAST_TLB_MISS_EXCEPTION_VIRT_ADDR_ASM
+1:	
+	ldw	r1,0(r2)
+	stw	r1,0(r3)
+	flushd  0(r3)
+	flushi  r3
+	addi	r2,r2,4
+	addi	r3,r3,4
+	bne	r2,r8,1b
+
+	// Mask off all possible interrupts
+	wrctl	ienable,r0		
+
+	/* Clear .bss
+	 */
+	movia	r2,__bss_start		// presume nothing is between
+	movia	r1,_end			// the .bss and _end.
+1:
+	stb	r0,0(r2)
+	addi	r2,r2,1
+	bne	r1,r2,1b
+
+	/* Call main() with interrupts disabled
+	 */
+	movia	r1,init_thread_union	// set stack at top of the task union
+	addi	sp,r1,THREAD_SIZE_ASM
+	movia	r2,_current_thread	// Remember current thread
+	stw	r1,0(r2)
+
+	movia	r1,nios2_boot_init	// save args r4-r7 passed from u-boot
+	callr	r1
+	
+	movia	r1,main			// call main as a subroutine
+	callr	r1
+
+	//------------------------------------------------------------------
+	// If we return from main,  break to the oci debugger and buggered we are
+	//
+	break	
+
+	/* End of startup code */
+.set at
+
+
diff --git a/arch/nios2/kernel/init_task.c b/arch/nios2/kernel/init_task.c
new file mode 100644
index 0000000..7899c60
--- /dev/null
+++ b/arch/nios2/kernel/init_task.c
@@ -0,0 +1,68 @@
+/*--------------------------------------------------------------------
+ *
+ * arch/nios2/kernel/init_task.c
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ *
+ * Based on:
+ *
+ * arch/nios2nommu/kernel/init_task.c
+ *
+ * Ported from arch/m68knommu/kernel/init_task.c
+ *
+ * Copyright (C) 2003, Microtronix Datacom Ltd.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * Jan/20/2004		dgt	    NiosII
+ *
+ ---------------------------------------------------------------------*/
+
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/init_task.h>
+#include <linux/fs.h>
+#include <linux/mqueue.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+__asm__(".align 2");
+struct task_struct init_task = INIT_TASK(init_task);
+
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by having a special
+ * "init_task" linker map entry..
+ */
+union thread_union init_thread_union __init_task_data =
+	{ INIT_THREAD_INFO(init_task) };
diff --git a/arch/nios2/kernel/insnemu.S b/arch/nios2/kernel/insnemu.S
new file mode 100644
index 0000000..e0218e1
--- /dev/null
+++ b/arch/nios2/kernel/insnemu.S
@@ -0,0 +1,586 @@
+/******************************************************************************
+*                                                                             *
+* License Agreement                                                           *
+*                                                                             *
+* Copyright (c) 2003 Altera Corporation, San Jose, California, USA.           *
+* All rights reserved.                                                        *
+*                                                                             *
+* Permission is hereby granted, free of charge, to any person obtaining a     *
+* copy of this software and associated documentation files (the "Software"),  *
+* to deal in the Software without restriction, including without limitation   *
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,    *
+* and/or sell copies of the Software, and to permit persons to whom the       *
+* Software is furnished to do so, subject to the following conditions:        *
+*                                                                             *
+* The above copyright notice and this permission notice shall be included in  *
+* all copies or substantial portions of the Software.                         *
+*                                                                             *
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  *
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,    *
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      *
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING     *
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER         *
+* DEALINGS IN THE SOFTWARE.                                                   *
+*                                                                             *
+* This agreement shall be governed in all respects by the laws of the State   *
+* of California and by the laws of the United States of America.              *
+*                                                                             *
+******************************************************************************/
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/asm-macros.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/entry.h>
+#include <asm/unistd.h>
+#include <asm/traps.h>
+#include <asm/processor.h>
+
+.set noat
+.set nobreak
+	
+     /*
+      * Explicitly allow the use of r1 (the assembler temporary register)
+      * within this code. This register is normally reserved for the use of
+      * the compiler.
+      */
+
+ENTRY(instruction_trap)
+	RESTORE_ALL	// Clean off our save & setup for emulation
+	
+    /* INSTRUCTION EMULATION
+    *  ---------------------
+    *
+    * Nios II processors generate exceptions for unimplemented instructions.
+    * The routines below emulate these instructions.  Depending on the
+    * processor core, the only instructions that might need to be emulated
+    * are div, divu, mul, muli, mulxss, mulxsu, and mulxuu.
+    *
+    * The emulations match the instructions, except for the following
+    * limitations:
+    *
+    * 1) The emulation routines do not emulate the use of the exception
+    *    temporary register (et) as a source operand because the exception
+    *    handler already has modified it.
+    *
+    * 2) The routines do not emulate the use of the stack pointer (sp) or the
+    *    exception return address register (ea) as a destination because
+    *    modifying these registers crashes the exception handler or the
+    *    interrupted routine.
+    *
+    * Detailed Design
+    * ---------------
+    *
+    * The emulation routines expect the contents of integer registers r0-r31
+    * to be on the stack at addresses sp, 4(sp), 8(sp), ... 124(sp).  The
+    * routines retrieve source operands from the stack and modify the
+    * destination register's value on the stack prior to the end of the
+    * exception handler.  Then all registers except the destination register
+    * are restored to their previous values.
+    *
+    * The instruction that causes the exception is found at address -4(ea).
+    * The instruction's OP and OPX fields identify the operation to be
+    * performed.
+    *
+    * One instruction, muli, is an I-type instruction that is identified by
+    * an OP field of 0x24.
+    *
+    * muli   AAAAA,BBBBB,IIIIIIIIIIIIIIII,-0x24-
+    *           27    22                6      0    <-- LSB of field
+    *
+    * The remaining emulated instructions are R-type and have an OP field
+    * of 0x3a.  Their OPX fields identify them.
+    *
+    * R-type AAAAA,BBBBB,CCCCC,XXXXXX,NNNNN,-0x3a-
+    *           27    22    17     11     6      0  <-- LSB of field
+    * 
+    * 
+    * Opcode Encoding.  muli is identified by its OP value.  Then OPX & 0x02
+    * is used to differentiate between the division opcodes and the remaining
+    * multiplication opcodes.
+    *
+    * Instruction   OP      OPX    OPX & 0x02
+    * -----------   ----    ----   ----------
+    * muli          0x24
+    * divu          0x3a    0x24         0
+    * div           0x3a    0x25         0
+    * mul           0x3a    0x27      != 0
+    * mulxuu        0x3a    0x07      != 0
+    * mulxsu        0x3a    0x17      != 0
+    * mulxss        0x3a    0x1f      != 0
+    */
+
+
+    /*
+    * Save everything on the stack to make it easy for the emulation routines
+    * to retrieve the source register operands.
+    */
+
+    addi sp, sp, -128
+    stw zero,  0(sp)    // Save zero on stack to avoid special case for r0.
+    stw r1,    4(sp)
+    stw r2,    8(sp)
+    stw r3,   12(sp)
+    stw r4,   16(sp)
+    stw r5,   20(sp)
+    stw r6,   24(sp)
+    stw r7,   28(sp)
+    stw r8,   32(sp)
+    stw r9,   36(sp)
+    stw r10,  40(sp)
+    stw r11,  44(sp)
+    stw r12,  48(sp)
+    stw r13,  52(sp)
+    stw r14,  56(sp)
+    stw r15,  60(sp)
+    stw r16,  64(sp)
+    stw r17,  68(sp)
+    stw r18,  72(sp)
+    stw r19,  76(sp)
+    stw r20,  80(sp)
+    stw r21,  84(sp)
+    stw r22,  88(sp)
+    stw r23,  92(sp)
+                        // Don't bother to save et.  It's already been changed.
+    stw bt,  100(sp)
+    stw gp,  104(sp)
+    stw sp,  108(sp)
+    stw fp,  112(sp)
+                        // Don't bother to save ea.  It's already been changed.
+    stw ba,  120(sp)
+    stw ra,  124(sp)
+
+
+    /*
+    * Split the instruction into its fields.  We need 4*A, 4*B, and 4*C as
+    * offsets to the stack pointer for access to the stored register values.
+    */
+    ldw r2,-4(ea)       // r2 = AAAAA,BBBBB,IIIIIIIIIIIIIIII,PPPPPP
+    roli r3,r2,7        // r3 = BBB,IIIIIIIIIIIIIIII,PPPPPP,AAAAA,BB
+    roli r4,r3,3        // r4 = IIIIIIIIIIIIIIII,PPPPPP,AAAAA,BBBBB
+    roli r5,r4,2        // r5 = IIIIIIIIIIIIII,PPPPPP,AAAAA,BBBBB,II
+    srai r4,r4,16       // r4 = (sign-extended) IMM16
+    roli r6,r5,5        // r6 = XXXX,NNNNN,PPPPPP,AAAAA,BBBBB,CCCCC,XX
+    andi r2,r2,0x3f     // r2 = 00000000000000000000000000,PPPPPP
+    andi r3,r3,0x7c     // r3 = 0000000000000000000000000,AAAAA,00
+    andi r5,r5,0x7c     // r5 = 0000000000000000000000000,BBBBB,00
+    andi r6,r6,0x7c     // r6 = 0000000000000000000000000,CCCCC,00
+
+    /* Now
+    * r2 = OP
+    * r3 = 4*A
+    * r4 = IMM16 (sign extended)
+    * r5 = 4*B
+    * r6 = 4*C
+    */
+
+
+    /*
+    * Get the operands.
+    *
+    * It is necessary to check for muli because it uses an I-type instruction
+    * format, while the other instructions are have an R-type format.
+    *
+    *  Prepare for either multiplication or division loop.
+    *  They both loop 32 times.
+    */
+    movi r14,32
+
+    add  r3,r3,sp       // r3 = address of A-operand.
+    ldw  r3,0(r3)       // r3 = A-operand.
+    movi r7,0x24        // muli opcode (I-type instruction format)
+    beq r2,r7,mul_immed // muli doesn't use the B register as a source
+
+    add  r5,r5,sp       // r5 = address of B-operand.
+    ldw  r5,0(r5)       // r5 = B-operand.
+                        // r4 = SSSSSSSSSSSSSSSS,-----IMM16------
+                        // IMM16 not needed, align OPX portion
+                        // r4 = SSSSSSSSSSSSSSSS,CCCCC,-OPX--,00000
+    srli r4,r4,5        // r4 = 00000,SSSSSSSSSSSSSSSS,CCCCC,-OPX--
+    andi r4,r4,0x3f     // r4 = 00000000000000000000000000,-OPX--
+
+    /* Now
+    * r2 = OP
+    * r3 = src1
+    * r5 = src2
+    * r4 = OPX (no longer can be muli)
+    * r6 = 4*C
+    */
+
+
+
+    /*
+    *  Multiply or Divide?
+    */
+    andi r7,r4,0x02    // For R-type multiply instructions, OPX & 0x02 != 0
+    bne r7,zero,multiply
+
+
+    /* DIVISION
+    *
+    * Divide an unsigned dividend by an unsigned divisor using
+    * a shift-and-subtract algorithm.  The example below shows
+    * 43 div 7 = 6 for 8-bit integers.  This classic algorithm uses a
+    * single register to store both the dividend and the quotient,
+    * allowing both values to be shifted with a single instruction.
+    *
+    *                               remainder dividend:quotient
+    *                               --------- -----------------
+    *   initialize                   00000000     00101011:
+    *   shift                        00000000     0101011:_
+    *   remainder >= divisor? no     00000000     0101011:0
+    *   shift                        00000000     101011:0_
+    *   remainder >= divisor? no     00000000     101011:00
+    *   shift                        00000001     01011:00_
+    *   remainder >= divisor? no     00000001     01011:000
+    *   shift                        00000010     1011:000_
+    *   remainder >= divisor? no     00000010     1011:0000
+    *   shift                        00000101     011:0000_
+    *   remainder >= divisor? no     00000101     011:00000
+    *   shift                        00001010     11:00000_
+    *   remainder >= divisor? yes    00001010     11:000001
+    *       remainder -= divisor   - 00000111
+    *                              ----------
+    *                                00000011     11:000001
+    *   shift                        00000111     1:000001_
+    *   remainder >= divisor? yes    00000111     1:0000011
+    *       remainder -= divisor   - 00000111
+    *                              ----------
+    *                                00000000     1:0000011
+    *   shift                        00000001     :0000011_
+    *   remainder >= divisor? no     00000001     :00000110
+    *
+    * The quotient is 00000110.
+    */
+
+divide:
+    /*
+    *  Prepare for division by assuming the result
+    *  is unsigned, and storing its "sign" as 0.
+    */
+    movi r17,0
+
+
+    // Which division opcode?
+    xori r7,r4,0x25         // OPX of div
+    bne r7,zero,unsigned_division
+
+
+    /*
+    *  OPX is div.  Determine and store the sign of the quotient.
+    *  Then take the absolute value of both operands.
+    */
+    xor r17,r3,r5       // MSB contains sign of quotient
+    bge r3,zero,dividend_is_nonnegative
+    sub r3,zero,r3      // -r3
+dividend_is_nonnegative:
+    bge r5,zero,divisor_is_nonnegative
+    sub r5,zero,r5      // -r5
+divisor_is_nonnegative:
+
+
+unsigned_division:
+    // Initialize the unsigned-division loop.
+    movi r13,0          // remainder = 0
+
+    /* Now
+    * r3 = dividend : quotient
+    * r4 = 0x25 for div, 0x24 for divu
+    * r5 = divisor
+    * r13 = remainder
+    * r14 = loop counter (already initialized to 32)
+    * r17 = MSB contains sign of quotient
+    */
+
+
+    /*
+    *   for (count = 32; count > 0; --count)
+    *   {
+    */
+divide_loop:
+
+    /*
+    *       Division:
+    *
+    *       (remainder:dividend:quotient) <<= 1;
+    */
+    slli r13,r13,1
+    cmplt r7,r3,zero        // r7 = MSB of r3
+    or r13,r13,r7
+    slli r3,r3,1
+
+
+    /*
+    *       if (remainder >= divisor)
+    *       {
+    *           set LSB of quotient
+    *           remainder -= divisor;
+    *       }
+    */
+    bltu r13,r5,div_skip
+    ori r3,r3,1
+    sub r13,r13,r5
+div_skip:
+
+    /*
+    *   }
+    */
+    subi r14,r14,1
+    bne r14,zero,divide_loop
+
+
+    /* Now
+    * r3 = quotient
+    * r4 = 0x25 for div, 0x24 for divu
+    * r6 = 4*C
+    * r17 = MSB contains sign of quotient
+    */
+
+    
+    /*
+    *  Conditionally negate signed quotient.  If quotient is unsigned,
+    *  the sign already is initialized to 0.
+    */
+    bge r17,zero,quotient_is_nonnegative
+    sub r3,zero,r3      // -r3
+quotient_is_nonnegative:
+
+
+    /*
+    *  Final quotient is in r3.
+    */
+    add r6,r6,sp
+    stw r3,0(r6)           // write quotient to stack
+    br restore_registers
+
+
+
+
+    /* MULTIPLICATION
+    *
+    * A "product" is the number that one gets by summing a "multiplicand"
+    * several times.  The "multiplier" specifies the number of copies of the
+    * multiplicand that are summed.
+    *
+    * Actual multiplication algorithms don't use repeated addition, however.
+    * Shift-and-add algorithms get the same answer as repeated addition, and
+    * they are faster.  To compute the lower half of a product (pppp below)
+    * one shifts the product left before adding in each of the partial products
+    * (a * mmmm) through (d * mmmm).
+    *
+    * To compute the upper half of a product (PPPP below), one adds in the
+    * partial products (d * mmmm) through (a * mmmm), each time following the
+    * add by a right shift of the product.
+    *
+    *     mmmm
+    *   * abcd
+    *   ------
+    *     ####  = d * mmmm
+    *    ####   = c * mmmm
+    *   ####    = b * mmmm
+    *  ####     = a * mmmm
+    * --------
+    * PPPPpppp
+    *
+    * The example above shows 4 partial products.  Computing actual Nios II
+    * products requires 32 partials.
+    *
+    * It is possible to compute the result of mulxsu from the result of mulxuu
+    * because the only difference between the results of these two opcodes is
+    * the value of the partial product associated with the sign bit of rA.
+    *
+    *   mulxsu = mulxuu - (rA < 0) ? rB : 0;
+    *
+    * It is possible to compute the result of mulxss from the result of mulxsu
+    * because the only difference between the results of these two opcodes is
+    * the value of the partial product associated with the sign bit of rB.
+    *
+    *   mulxss = mulxsu - (rB < 0) ? rA : 0;
+    *
+    */
+
+mul_immed:
+    // Opcode is muli.  Change it into mul for remainder of algorithm.
+    mov r6,r5              // Field B is dest register, not field C.
+    mov r5,r4              // Field IMM16 is src2, not field B.
+    movi r4,0x27           // OPX of mul is 0x27
+
+multiply:
+    // Initialize the multiplication loop.
+    movi r9,0           // mul_product    = 0
+    movi r10,0          // mulxuu_product = 0
+    mov r11,r5          // save original multiplier for mulxsu and mulxss
+    mov r12,r5          // mulxuu_multiplier (will be shifted)
+    movi r16,1          // used to create "rori B,A,1" from "ror B,A,r16"
+
+    /* Now
+    * r3 = multiplicand
+    * r5 = mul_multiplier
+    * r6 = 4 * dest_register (used later as offset to sp)
+    * r7 = temp
+    * r9 = mul_product
+    * r10 = mulxuu_product
+    * r11 = original multiplier
+    * r12 = mulxuu_multiplier
+    * r14 = loop counter (already initialized)
+    * r16 = 1
+    */
+
+
+    /*
+    *   for (count = 32; count > 0; --count)
+    *   {
+    */
+multiply_loop:
+
+    /*
+    *       mul_product <<= 1;
+    *       lsb = multiplier & 1;
+    */
+    slli r9,r9,1
+    andi r7,r12,1
+
+    /*
+    *       if (lsb == 1)
+    *       {
+    *           mulxuu_product += multiplicand;
+    *       }
+    */
+    beq r7,zero,mulx_skip
+    add r10,r10,r3
+    cmpltu r7,r10,r3    // Save the carry from the MSB of mulxuu_product.
+    ror r7,r7,r16       // r7 = 0x80000000 on carry, or else 0x00000000
+mulx_skip:
+
+    /*
+    *       if (MSB of mul_multiplier == 1)
+    *       {
+    *           mul_product += multiplicand;
+    *       }
+    */
+    bge r5,zero,mul_skip
+    add r9,r9,r3
+mul_skip:
+
+    /*
+    *       mulxuu_product >>= 1;           logical shift
+    *       mul_multiplier <<= 1;           done with MSB
+    *       mulx_multiplier >>= 1;          done with LSB
+    */
+    srli r10,r10,1
+    or r10,r10,r7           // OR in the saved carry bit.
+    slli r5,r5,1
+    srli r12,r12,1
+
+
+    /*
+    *   }
+    */
+    subi r14,r14,1
+    bne r14,zero,multiply_loop
+
+
+    /*
+    *  Multiply emulation loop done.
+    */
+
+    /* Now
+    * r3 = multiplicand
+    * r4 = OPX
+    * r6 = 4 * dest_register (used later as offset to sp)
+    * r7 = temp
+    * r9 = mul_product
+    * r10 = mulxuu_product
+    * r11 = original multiplier
+    */
+
+
+    // Calculate address for result from 4 * dest_register
+    add r6,r6,sp
+
+
+    /*
+    *  Select/compute the result based on OPX.
+    */
+
+
+    // OPX == mul?  Then store.
+    xori r7,r4,0x27
+    beq r7,zero,store_product
+
+    // It's one of the mulx.. opcodes.  Move over the result.
+    mov r9,r10
+
+    // OPX == mulxuu?  Then store.
+    xori r7,r4,0x07
+    beq r7,zero,store_product
+
+    // Compute mulxsu
+    //
+    // mulxsu = mulxuu - (rA < 0) ? rB : 0;
+    //
+    bge r3,zero,mulxsu_skip
+    sub r9,r9,r11
+mulxsu_skip:
+
+    // OPX == mulxsu?  Then store.
+    xori r7,r4,0x17
+    beq r7,zero,store_product
+
+    // Compute mulxss
+    //
+    // mulxss = mulxsu - (rB < 0) ? rA : 0;
+    //
+    bge r11,zero,mulxss_skip
+    sub r9,r9,r3
+mulxss_skip:
+    // At this point, assume that OPX is mulxss, so store
+
+
+store_product:
+    stw  r9,0(r6)
+
+
+restore_registers:
+                        // No need to restore r0.
+    ldw r1,    4(sp)
+    ldw r2,    8(sp)
+    ldw r3,   12(sp)
+    ldw r4,   16(sp)
+    ldw r5,   20(sp)
+    ldw r6,   24(sp)
+    ldw r7,   28(sp)
+    ldw r8,   32(sp)
+    ldw r9,   36(sp)
+    ldw r10,  40(sp)
+    ldw r11,  44(sp)
+    ldw r12,  48(sp)
+    ldw r13,  52(sp)
+    ldw r14,  56(sp)
+    ldw r15,  60(sp)
+    ldw r16,  64(sp)
+    ldw r17,  68(sp)
+    ldw r18,  72(sp)
+    ldw r19,  76(sp)
+    ldw r20,  80(sp)
+    ldw r21,  84(sp)
+    ldw r22,  88(sp)
+    ldw r23,  92(sp)
+    ldw et,   96(sp)
+    ldw bt,  100(sp)
+    ldw gp,  104(sp)
+                        // Don't corrupt sp.
+    ldw fp,  112(sp)
+                        // Don't corrupt ea.
+    ldw ba,  120(sp)
+    ldw ra,  124(sp)
+    addi sp, sp, 128
+    eret
+
+.set at
+.set break
+
diff --git a/arch/nios2/kernel/irq.c b/arch/nios2/kernel/irq.c
new file mode 100644
index 0000000..6dafa08
--- /dev/null
+++ b/arch/nios2/kernel/irq.c
@@ -0,0 +1,104 @@
+/*
+ *	irq.c
+ *
+ *	(C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
+ *	(C) Copyright 2008, Thomas Chou <thomas@wytron.com.tw>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/kernel_stat.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+
+#define IENABLE 3
+
+asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
+{
+	struct pt_regs *oldregs = set_irq_regs(regs);
+
+	irq_enter();
+	generic_handle_irq(irq);
+	irq_exit();
+
+	set_irq_regs(oldregs);
+}
+
+static void chip_unmask(unsigned int irq)
+{
+	unsigned ien;
+	ien = __builtin_rdctl(IENABLE);
+	ien |= (1 << irq);
+	__builtin_wrctl(IENABLE, ien);
+}
+
+static void chip_mask(unsigned int irq)
+{
+	unsigned ien;
+	ien = __builtin_rdctl(IENABLE);
+	ien &= ~(1 << irq);
+	__builtin_wrctl(IENABLE, ien);
+}
+
+static void chip_ack(unsigned int irq)
+{
+}
+
+static int chip_set_type(unsigned int irq, unsigned int flow_type)
+{
+	return 0;
+}
+
+static struct irq_chip m_irq_chip = {
+	.name = "NIOS2-INTC",
+	.unmask = chip_unmask,
+	.mask = chip_mask,
+	.ack = chip_ack,
+	.set_type = chip_set_type,
+};
+
+void __init init_IRQ(void)
+{
+	int irq;
+
+	for (irq = 0; (irq < NR_IRQS); irq++) {
+		irq_desc[irq].status = IRQ_DISABLED;
+		irq_desc[irq].action = NULL;
+		irq_desc[irq].depth = 1;
+		irq_desc[irq].chip = &m_irq_chip;
+		irq_desc[irq].handle_irq = handle_level_irq;
+	}
+}
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+	struct irqaction *ap;
+	int irq = *((loff_t *) v);
+
+	if (irq == 0)
+		seq_puts(p, "           CPU0\n");
+
+	if (irq < NR_IRQS) {
+		ap = irq_desc[irq].action;
+		if (ap) {
+			seq_printf(p, "%3d: ", irq);
+			seq_printf(p, "%10u ", kstat_irqs(irq));
+			seq_printf(p, "%14s  ", irq_desc[irq].chip->name);
+
+			seq_printf(p, "%s", ap->name);
+			for (ap = ap->next; ap; ap = ap->next)
+				seq_printf(p, ", %s", ap->name);
+			seq_putc(p, '\n');
+		}
+	}
+
+	return 0;
+}
diff --git a/arch/nios2/kernel/module.c b/arch/nios2/kernel/module.c
new file mode 100644
index 0000000..e0e9637
--- /dev/null
+++ b/arch/nios2/kernel/module.c
@@ -0,0 +1,203 @@
+/*  Kernel module help for Nios2.
+    Copyright (C) 2004 Microtronix Datacom Ltd.
+    Copyright (C) 2001,03  Rusty Russell
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+    
+    Written by Wentao Xu <xuwentao@microtronix.com>
+*/
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <asm/pgtable.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(fmt , ...)
+#endif
+
+/* FIXME:  modules should NOT be allocated with kmalloc
+ * for (obvious) reasons. But we do it for now to avoid
+ * relocation issues. CALL26/PCREL26 cannot reach 
+ * from 0x80000000 (vmalloc area) to 0xc00000000 (kernel)
+ * (kmalloc returns addresses in 0xc0000000)
+ *
+ * We should really have some trampolines for this instead.
+ */
+#if 0
+void *module_alloc(unsigned long size)
+{
+	if (size == 0)
+		return NULL;
+	return vmalloc(size);
+}
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+ 	vfree(module_region);
+	/* FIXME: If module_region == mod->init_region, trim exception
+           table entries. */
+}
+
+#else
+void *module_alloc(unsigned long size)
+{
+	if (size == 0)
+		return NULL;
+	return kmalloc(size, GFP_KERNEL);
+}
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+         kfree(module_region);
+	/* FIXME: If module_region == mod->init_region, trim exception
+           table entries. */
+}
+
+#endif
+
+/* We don't need anything special. */
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+			      Elf_Shdr *sechdrs,
+			      char *secstrings,
+			      struct module *mod)
+{
+	return 0;
+}
+
+int apply_relocate(Elf32_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	printk(KERN_ERR "module %s: NO-ADD RELOCATION unsupported\n",
+	       me->name);
+	return -ENOEXEC;
+}
+
+
+int apply_relocate_add (Elf32_Shdr *sechdrs, const char *strtab,
+			unsigned int symindex, unsigned int relsec,
+			struct module *mod)
+{
+	unsigned int i;
+	Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
+
+	DEBUGP ("Applying relocate section %u to %u\n", relsec,
+		sechdrs[relsec].sh_info);
+
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof (*rela); i++) {
+		/* This is where to make the change */
+		uint32_t word;
+		uint32_t *loc
+			= ((void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			   + rela[i].r_offset);
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
+		Elf32_Sym *sym
+			= ((Elf32_Sym *)sechdrs[symindex].sh_addr
+			   + ELF32_R_SYM (rela[i].r_info));
+		uint32_t v = sym->st_value + rela[i].r_addend;
+		DEBUGP("reltype %d 0x%x name:<%s>\n", ELF32_R_TYPE (rela[i].r_info),
+		       rela[i].r_offset,
+		       strtab+sym->st_name);
+
+		switch (ELF32_R_TYPE (rela[i].r_info)) {
+		case R_NIOS2_NONE:
+			break;
+			
+		case R_NIOS2_BFD_RELOC_32:
+			*loc += v;
+			break;
+			
+		case R_NIOS2_PCREL16:
+			v -= (uint32_t)loc + 4;
+			if ((int32_t)v > 0x7fff ||
+					(int32_t)v < -(int32_t)0x8000) {
+				printk(KERN_ERR
+				       "module %s: relocation overflow\n",
+				       mod->name);
+				return -ENOEXEC;
+			}
+			word = *loc;
+			*loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
+			break;
+			
+		case R_NIOS2_CALL26:
+			if (v & 3) {
+				printk(KERN_ERR
+				       "module %s: dangerous relocation\n",
+				       mod->name);
+				return -ENOEXEC;
+			}
+			if ((v >> 28) != ((uint32_t)loc >> 28)) {
+				printk(KERN_ERR
+				       "module %s: relocation overflow\n",
+				       mod->name);
+				return -ENOEXEC;
+			}
+			*loc = (*loc & 0x3f) | ((v >> 2) << 6);
+			break;
+			
+		case R_NIOS2_HI16:
+			word = *loc;
+			*loc = ((((word >> 22) << 16) | ((v >>16) & 0xffff)) << 6) | 
+					(word & 0x3f);
+			break;
+					
+		case R_NIOS2_LO16:
+			word = *loc;
+			*loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | 
+					(word & 0x3f);
+			break;
+					
+		case R_NIOS2_HIADJ16:
+			{
+				Elf32_Addr word2;
+				
+				word = *loc;
+				word2 = ((v >> 16) + ((v >> 15) & 1)) & 0xffff;
+				*loc = ((((word >> 22) << 16) | word2) << 6) | 
+						(word & 0x3f);
+			}
+			break;
+
+		default:
+			printk (KERN_ERR "module %s: Unknown reloc: %u\n",
+				mod->name, ELF32_R_TYPE (rela[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+
+	return 0;
+}
+
+int module_finalize(const Elf_Ehdr *hdr,
+		    const Elf_Shdr *sechdrs,
+		    struct module *me)
+{
+	return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+}
diff --git a/arch/nios2/kernel/nios2_ksyms.c b/arch/nios2/kernel/nios2_ksyms.c
new file mode 100644
index 0000000..dc3a06b
--- /dev/null
+++ b/arch/nios2/kernel/nios2_ksyms.c
@@ -0,0 +1,101 @@
+/*--------------------------------------------------------------------
+ *
+ * arch/nios2nommu/kernel/nios_ksyms.c
+ *
+ * Derived from Nios1
+ *
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * vic - copied from v850
+ * Jan/20/2004		dgt	    NiosII
+ *
+ ---------------------------------------------------------------------*/
+
+
+//;dgt2;tmp;
+
+#include <linux/module.h>
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+
+#include <asm/setup.h>
+#include <asm/pgalloc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/checksum.h>
+#include <asm/hardirq.h>
+#include <asm/current.h>
+
+/* platform dependent support */
+
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(__iounmap);
+
+EXPORT_SYMBOL(kernel_thread);
+
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memmove);
+
+EXPORT_SYMBOL(get_wchan);
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler...  (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __gcc_bcmp(void);
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __cmpdi2(void);
+extern void __divdi3(void);
+extern void __divsi3(void);
+extern void __lshrdi3(void);
+extern void __moddi3(void);
+extern void __modsi3(void);
+extern void __muldi3(void);
+extern void __mulsi3(void);
+extern void __negdi2(void);
+extern void __ucmpdi2(void);
+extern void __udivdi3(void);
+extern void __udivmoddi4(void);
+extern void __udivsi3(void);
+extern void __umoddi3(void);
+extern void __umodsi3(void);
+
+        /* gcc lib functions */
+EXPORT_SYMBOL(__gcc_bcmp);
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__cmpdi2);
+EXPORT_SYMBOL(__divdi3);
+EXPORT_SYMBOL(__divsi3);
+EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__moddi3);
+EXPORT_SYMBOL(__modsi3);
+EXPORT_SYMBOL(__muldi3);
+EXPORT_SYMBOL(__mulsi3);
+EXPORT_SYMBOL(__negdi2);
+EXPORT_SYMBOL(__ucmpdi2);
+EXPORT_SYMBOL(__udivdi3);
+EXPORT_SYMBOL(__udivmoddi4);
+EXPORT_SYMBOL(__udivsi3);
+EXPORT_SYMBOL(__umoddi3);
+EXPORT_SYMBOL(__umodsi3);
diff --git a/arch/nios2/kernel/pio.c b/arch/nios2/kernel/pio.c
new file mode 100644
index 0000000..a03c77b
--- /dev/null
+++ b/arch/nios2/kernel/pio.c
@@ -0,0 +1,153 @@
+/*
+ *  linux/arch/nios2nommu/kernel/pio.c
+ *  "Example" drivers(LEDs and 7 seg displays) of the PIO interface
+ *  on Nios Development Kit.
+ *
+ *  Copyright (C) 2004 Microtronix Datacom Ltd
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ * 
+ *  Written by Wentao Xu <wentao@microtronix.com>
+ */
+ 
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+#include <asm/pio_struct.h>
+
+MODULE_AUTHOR("Microtronix Datacom Ltd.");
+MODULE_DESCRIPTION("Drivers of PIO devices (LEDs and 7 seg) on Nios kit");
+MODULE_LICENSE("GPL");
+
+#define PIO_LED_IO  USER_LED_PIO_8OUT_BASE
+
+#ifdef CONFIG_PIO_SEG
+#error "Not supported, please fix implementation"
+/* The 7-seg driver was is not included in the "current" design
+ * should be easy to fix though, just add ioremap as in the led driver
+ */
+#endif
+
+#define PDEBUG printk
+
+/* routines for 7-segment hex display */
+#ifdef CONFIG_PIO_SEG
+static unsigned char _hex_digits_data[] = {
+	0x01, 0x4f, 0x12, 0x06, 0x4c, /* 0-4 */
+	0x24, 0x20, 0x0f, 0x00, 0x04, /* 5-9 */
+	0x08, 0x60, 0x72, 0x42, 0x30, /* a-e */
+	0x38                      	  /* f   */
+};
+
+void pio_seg_write(int value)
+{
+  int led_value;
+
+  /* Left Hand Digit, goes to PIO bits 8-14 */
+  led_value = _hex_digits_data[value & 0xF];
+  led_value |= (_hex_digits_data[(value >> 4) & 0xF]) << 8;
+
+  outl(led_value, &(PIO_SEG_IO->np_piodata));
+}
+
+static void __init pio_seg_init(void)
+{
+	pio_seg_write(0);
+}
+#endif
+
+
+/* routines for LED display */
+#ifdef CONFIG_PIO_LED
+static  np_pio *pio_led;
+
+void pio_led_write(int value)
+{
+    //outl(-1, &pio->np_piodirection); 
+   	outl(value, &pio_led->np_piodata);
+}
+
+static void __init pio_led_init(void)
+{
+  pio_led =(np_pio *)ioremap(PIO_LED_IO, sizeof(np_pio));	
+    outl(-1, &pio_led->np_piodirection); 
+    outl(0x0, &pio_led->np_piodata);
+}
+#endif
+
+/* timing routines */
+#if defined(CONFIG_PIO_SEG) || defined(CONFIG_PIO_LED)
+static struct timer_list display_timer;
+static int restart_timer=1;
+static int timer_counter=0;
+static void display_timeout(unsigned long unused)
+{
+#ifdef CONFIG_PIO_SEG
+	pio_seg_write(++timer_counter);
+#endif	
+
+#ifdef CONFIG_PIO_LED
+	pio_led_write(++timer_counter);
+#endif
+	if (restart_timer) {
+		display_timer.expires = jiffies + HZ; /* one second */
+		add_timer(&display_timer);
+	}
+}
+#endif
+
+int __init pio_init(void)
+{
+        printk(KERN_INFO "Altera example PIO driver\n");
+#ifdef CONFIG_PIO_SEG
+	request_mem_region((unsigned long)PIO_SEG_IO, sizeof(np_pio), "pio_7seg");
+	pio_seg_init();
+#endif	
+
+#ifdef CONFIG_PIO_LED
+	request_mem_region((unsigned long)PIO_LED_IO, sizeof(np_pio), "pio_led");
+	pio_led_init();
+#endif
+
+#if defined(CONFIG_PIO_SEG) || defined(CONFIG_PIO_LED)
+	/* init timer */
+	init_timer(&display_timer);
+	display_timer.function = display_timeout;
+	display_timer.data = 0;
+	display_timer.expires = jiffies + HZ * 10; /* 10 seconds */
+	add_timer(&display_timer);
+#endif
+
+	return 0;
+}
+
+static void __exit pio_exit(void)
+{
+#ifdef CONFIG_PIO_SEG
+	pio_seg_write(0);
+	release_mem_region((unsigned long)PIO_SEG_IO, sizeof(np_pio));
+#endif	
+
+#ifdef CONFIG_PIO_LED
+	pio_led_write(0);
+	release_mem_region((unsigned long)PIO_LED_IO, sizeof(np_pio));
+	iounmap((void *)pio_led);
+#endif
+
+#if defined(CONFIG_PIO_SEG) || defined(CONFIG_PIO_LED)
+	restart_timer=0;
+	del_timer_sync(&display_timer);
+#endif
+}
+module_init(pio_init);
+module_exit(pio_exit);
+
diff --git a/arch/nios2/kernel/process.c b/arch/nios2/kernel/process.c
new file mode 100644
index 0000000..139df92
--- /dev/null
+++ b/arch/nios2/kernel/process.c
@@ -0,0 +1,464 @@
+/*--------------------------------------------------------------------
+ *
+ * arch/nios2/kernel/process.c
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ *
+ * Derived from arch/nios2nommu/kernel/process.c
+ *
+ * Derived from M68knommu
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *  Copyright (C) 2000-2002, David McCullough <davidm@snapgear.com>
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ *  68060 fixes by Jesper Skov
+ * Jan/20/2004		dgt	    NiosII
+ *                            rdusp() === (pt_regs *) regs->sp
+ *                            Monday:
+ *                             asm-nios2nommu\processor.h now bears
+ *                              inline thread_saved_pc
+ *                                      (struct thread_struct *t)
+ *                             Friday: it's back here now
+ *
+ ---------------------------------------------------------------------*/
+
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/err.h>
+
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+#include <asm/cacheflush.h>
+
+#define print_mark(...)
+#define printd(...)
+
+asmlinkage void ret_from_fork(void);
+
+/*
+ * The following aren't currently used.
+ */
+void (*pm_idle)(void) = NULL;
+EXPORT_SYMBOL(pm_idle);
+
+void (*pm_power_off)(void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
+
+void default_idle(void)
+{
+	local_irq_disable();
+	if (!need_resched()) {
+		local_irq_enable();
+		__asm__("nop");   // was asm sleep
+	} else
+		local_irq_enable();
+}
+
+void (*idle)(void) = default_idle;
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle(void)
+{
+	while (1) {
+		while (!need_resched())
+			idle();
+		preempt_enable_no_resched();
+		schedule();
+		preempt_disable();
+	}
+}
+
+/*
+ * The development boards have no way to pull a board
+ * reset. Just jump to the cpu reset address and let
+ * the boot loader take care of resetting periperals
+ */
+void machine_restart(char * __unused)
+{
+	local_irq_disable();
+	if (__builtin_ldwio((void *)RESET_ADDR) == 0xffffffffUL){
+	  printk("boot loader not installed, refusing to jump to "
+            "jump to reset addr 0x%lx\n", (unsigned long)RESET_ADDR);		 
+	  for (;;);
+	}
+	__asm__ __volatile__ (
+	"jmp	%0\n\t"
+	: 
+	: "r" (RESET_ADDR)
+	: "r4");
+}
+
+EXPORT_SYMBOL(machine_restart);
+
+void machine_halt(void)
+{
+	local_irq_disable();
+	for (;;);
+}
+
+EXPORT_SYMBOL(machine_halt);
+
+void exit_thread(void)
+{
+}
+
+void release_thread(struct task_struct *dead_task)
+{
+	/* nothing to do ... */
+}
+
+/*
+ * There is no way to power off the development
+ * boards. So just spin lock for now. If you have
+ * your own board with power down circuits add you
+ * specific code here.
+ */
+
+void machine_power_off(void)
+{
+	local_irq_disable();
+	for (;;);
+}
+
+EXPORT_SYMBOL(machine_power_off);
+
+void show_regs(struct pt_regs * regs)
+{
+	printk(KERN_NOTICE "\n");
+
+	printk(KERN_NOTICE "r1:  %08lx r2:  %08lx r3:  %08lx r4:  %08lx\n",
+	       regs->r1,  regs->r2,  regs->r3,  regs->r4);
+
+	printk(KERN_NOTICE "r5:  %08lx r6:  %08lx r7:  %08lx r8:  %08lx\n",
+	       regs->r5,  regs->r6,  regs->r7,  regs->r8);
+
+	printk(KERN_NOTICE "r9:  %08lx r10: %08lx r11: %08lx r12: %08lx\n",
+	       regs->r9,  regs->r10, regs->r11, regs->r12);
+
+	printk(KERN_NOTICE "r13: %08lx r14: %08lx r15: %08lx\n",
+	       regs->r13, regs->r14, regs->r15);
+
+	printk(KERN_NOTICE "ra:  %08lx fp:  %08lx sp:  %08lx gp:  %08lx\n",
+	       regs->ra,  regs->fp,  regs->sp,  regs->gp);
+
+	printk(KERN_NOTICE "ea:  %08lx estatus:  %08lx\n",
+	       regs->ea,  regs->estatus);
+}
+
+
+
+
+/*
+ * Create a kernel thread
+ */
+static ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
+{
+  int i;
+  print_mark(__FILE__, __LINE__);
+  printd("################ KTH arg=%p fn=%p sp=%p\n", arg, fn, &i);
+  do_exit(fn(arg));
+}
+
+int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	struct pt_regs regs;
+        print_mark(__FILE__, __LINE__);
+
+	memset(&regs, 0, sizeof(regs));
+	regs.r4 = (unsigned long)arg;
+	regs.r5 = (unsigned long)fn;
+	regs.ea = (unsigned long)kernel_thread_helper;
+	regs.estatus =  NIOS2_STATUS_PIE_MSK;
+	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+}
+
+void flush_thread(void)
+{
+	/* Now, this task is no longer a kernel thread. */
+	current->thread.flags &= ~NIOS2_FLAG_KTHREAD;
+
+	set_fs(USER_DS);
+}
+
+/*
+ * "nios2_fork()".. By the time we get here, the
+ * non-volatile registers have also been saved on the
+ * stack. We do some ugly pointer stuff here.. (see
+ * also copy_thread)
+ */
+
+asmlinkage int nios2_fork(struct pt_regs *regs)
+{
+   return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
+}
+
+/*
+ * nios2_execve() executes a new program.
+ */
+asmlinkage int nios2_execve(struct pt_regs *regs)
+{
+	int error;
+	char * filename;
+
+	lock_kernel();
+	filename = getname((char *) regs->r4);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = do_execve(filename,
+			  (char **) regs->r5,
+			  (char **) regs->r6,
+			  regs);
+	putname(filename);
+out:
+	unlock_kernel();
+	return error;
+}
+
+asmlinkage int nios2_vfork(struct pt_regs *regs)
+{
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0, NULL, NULL);
+}
+
+
+asmlinkage int nios2_clone(struct pt_regs* regs)
+{
+	unsigned long clone_flags;
+	unsigned long newsp;
+	int __user *parent_tidptr, *child_tidptr;
+
+	clone_flags = regs->r4;
+	newsp = regs->r5;
+	parent_tidptr = (int __user *) regs->r6;
+   child_tidptr = (int __user *) regs->r8;
+
+   if(newsp == 0) {
+      newsp = regs->sp;
+   }
+   
+	return do_fork(clone_flags, newsp, regs, 0, 
+	               parent_tidptr, child_tidptr);
+}
+
+int copy_thread(unsigned long clone_flags,
+		unsigned long usp, unsigned long topstk,
+		struct task_struct * p, struct pt_regs * regs)
+{
+	struct pt_regs * childregs;
+	struct switch_stack * childstack, *stack;
+
+   childregs = task_pt_regs(p);
+
+   /* Save pointer to registers in thread_struct */
+	p->thread.kregs = childregs;
+
+   /* Copy registers */
+	*childregs = *regs;
+
+   /* Copy stacktop and copy the top entrys from parent to child
+    */
+	stack = ((struct switch_stack *) regs) - 1;
+	childstack = ((struct switch_stack *) childregs) - 1;
+	*childstack = *stack;
+
+	childstack->ra = (unsigned long)ret_from_fork;
+
+	if(childregs->estatus & NIOS2_STATUS_U_MSK) {
+	  childregs->sp = usp;
+	}
+	else {
+     childregs->sp = (unsigned long)childstack;
+	}
+   /* Store the kernel stack in thread_struct */
+	p->thread.ksp = (unsigned long)childstack;
+
+   /* Initialize tls register.
+    */
+   if(clone_flags & CLONE_SETTLS) {
+      childstack->r23 = regs->r7;
+   }
+
+	/* Set the return value for the child. */
+	childregs->r2 = 0;
+   childregs->r7 = 0;
+
+	/* Set the return value for the parent. */
+	regs->r2 = p->pid;
+   regs->r7 = 0;  /* No error */
+
+	return 0;
+}
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+void dump(struct pt_regs *fp)
+{
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk(KERN_EMERG "\nCURRENT PROCESS:\n\n");
+	printk(KERN_EMERG "COMM=%s PID=%d\n", current->comm, current->pid);
+
+	if (current->mm) {
+		printk(KERN_EMERG "TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk(KERN_EMERG "USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int)(((unsigned long) current) + THREAD_SIZE));
+	}
+
+	printk(KERN_EMERG "PC: %08lx\n", fp->ea);
+	printk(KERN_EMERG "SR: %08lx    SP: %08lx\n", (long) fp->estatus, (long) fp);
+
+	printk(KERN_EMERG "r1: %08lx    r2: %08lx    r3: %08lx\n",
+		fp->r1, fp->r2, fp->r3);
+
+	printk(KERN_EMERG "r4: %08lx    r5: %08lx    r6: %08lx    r7: %08lx\n",
+		fp->r4, fp->r5, fp->r6, fp->r7);
+	printk(KERN_EMERG "r8: %08lx    r9: %08lx    r10: %08lx    r11: %08lx\n",
+		fp->r8, fp->r9, fp->r10, fp->r11);
+	printk(KERN_EMERG "r12: %08lx  r13: %08lx    r14: %08lx    r15: %08lx\n",
+		fp->r12, fp->r13, fp->r14, fp->r15);
+	printk(KERN_EMERG "or2: %08lx   ra: %08lx     fp: %08lx    sp: %08lx\n",
+		fp->orig_r2, fp->ra, fp->fp, fp->sp);
+	printk(KERN_EMERG "\nUSP: %08x   TRAPFRAME: %08x\n", (unsigned int) fp->sp,
+		(unsigned int) fp);
+
+	printk(KERN_EMERG "\nCODE:");
+	tp = ((unsigned char *) fp->ea) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk(KERN_EMERG "\n%08x: ", (int) (tp + i));
+		printk(KERN_EMERG "%08x ", (int) *sp++);
+	}
+	printk(KERN_EMERG "\n");
+
+	printk(KERN_EMERG "\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk(KERN_EMERG "\n%08x: ", (int) (tp + i));
+		printk(KERN_EMERG "%08x ", (int) *sp++);
+	}
+	printk(KERN_EMERG "\n");
+	printk(KERN_EMERG "\n");
+
+	printk(KERN_EMERG "\nUSER STACK:");
+	tp = (unsigned char *) (fp->sp - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk(KERN_EMERG "\n%08x: ", (int) (tp + i));
+		printk(KERN_EMERG "%08x ", (int) *sp++);
+	}
+	printk(KERN_EMERG "\n\n");
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	unsigned long fp, pc;
+	unsigned long stack_page;
+	int count = 0;
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	stack_page = (unsigned long)p;
+	fp = ((struct switch_stack *)p->thread.ksp)->fp;        //;dgt2
+	do {
+		if (fp < stack_page+sizeof(struct task_struct) ||
+		    fp >= 8184+stack_page)                          //;dgt2;tmp
+			return 0;
+		pc = ((unsigned long *)fp)[1];
+		if (!in_sched_functions(pc))
+			return pc;
+		fp = *(unsigned long *) fp;
+	} while (count++ < 16);                                 //;dgt2;tmp
+	return 0;
+}
+
+/* Return saved PC of a blocked thread. */
+unsigned long thread_saved_pc(struct task_struct *t)
+{
+	return (t->thread.kregs->ea);
+}
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ * Will statup in user mode (status_extension = 0).
+ */
+void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
+{
+	memset((void *) regs, 0, sizeof(struct pt_regs));
+	regs->estatus = NIOS2_STATUS_PIE_MSK|NIOS2_STATUS_U_MSK;
+	regs->ea = pc;
+	regs->sp = sp;
+
+	/* check if debug flag is set */
+	if (current->thread.flags & NIOS2_FLAG_DEBUG ) {
+		if ( *(u32*)pc == NIOS2_OP_NOP ) {
+			*(u32*)pc = NIOS2_OP_BREAK;
+			flush_dcache_range(pc, pc+4);
+			flush_icache_range(pc, pc+4);
+		}
+	}
+}
+
+/* Fill in the fpu structure for a core dump.. */
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
+{
+  return 0;
+}
+
diff --git a/arch/nios2/kernel/ptrace.c b/arch/nios2/kernel/ptrace.c
new file mode 100644
index 0000000..2f5e771
--- /dev/null
+++ b/arch/nios2/kernel/ptrace.c
@@ -0,0 +1,273 @@
+/*
+ *  linux/arch/nios2/kernel/ptrace.c
+ *
+ *  Copyright (C) 1994 by Hamish Macdonald
+ *  Taken from linux/kernel/ptrace.c and modified for M680x0.
+ *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/cacheflush.h>
+
+/* #define DEBUG */
+
+#ifdef DEBUG
+# define PRINTK_DEBUG(str...)   printk(KERN_DEBUG str)
+#else
+# define PRINTK_DEBUG(str...)   do { } while (0)
+#endif
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/* determines which bits in the SR the user has access to. */
+/* 1 = access 0 = no access */
+#define SR_MASK 0x00000000
+
+/* Find the stack offset for a register, relative to thread.ksp. */
+#define PT_REG(reg)	((long)&((struct pt_regs *)0)->reg)
+#define SW_REG(reg)	((long)&((struct switch_stack *)0)->reg \
+			 - sizeof(struct switch_stack))
+
+/* Mapping from PT_xxx to the stack offset at which the register is
+ * saved.
+ */
+static int regoff[] = {
+	         -1, PT_REG( r1), PT_REG( r2), PT_REG( r3),
+	PT_REG( r4), PT_REG( r5), PT_REG( r6), PT_REG( r7),
+	PT_REG( r8), PT_REG( r9), PT_REG(r10), PT_REG(r11),
+	PT_REG(r12), PT_REG(r13), PT_REG(r14), PT_REG(r15),  /* reg 15 */
+	SW_REG(r16), SW_REG(r17), SW_REG(r18), SW_REG(r19),
+	SW_REG(r20), SW_REG(r21), SW_REG(r22), SW_REG(r23),
+	         -1,          -1, PT_REG( gp), PT_REG( sp),
+	PT_REG( fp), PT_REG( ea),          -1, PT_REG( ra),  /* reg 31 */
+	PT_REG( ea),          -1,          -1,          -1,  /* use ea for pc */
+	         -1,          -1,          -1,          -1,
+	         -1,          -1,          -1,          -1   /* reg 43 */
+};
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline long get_reg(struct task_struct *task, int regno)
+{
+	unsigned long *addr;
+
+	if (regno >= ARRAY_SIZE(regoff) || regoff[regno] == -1)
+		return 0;
+
+	addr = (unsigned long *)((char *)task->thread.kregs + regoff[regno]);
+	return *addr;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int put_reg(struct task_struct *task, int regno,
+			  unsigned long data)
+{
+	unsigned long *addr;
+
+	if (regno >= ARRAY_SIZE(regoff) || regoff[regno] == -1)
+		return -1;
+
+	addr = (unsigned long *)((char *)task->thread.kregs + regoff[regno]);
+	*addr = data;
+	return 0;
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Nothing special to do here, no processor debug support.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+}
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+{
+	int ret;
+
+	switch (request) {
+		/* when I and D space are separate, these will need to be fixed. */
+		case PTRACE_PEEKTEXT: /* read word at location addr. */
+		case PTRACE_PEEKDATA:
+			ret = generic_ptrace_peekdata(child, addr, data);
+			break;
+
+		/* read the word at location addr in the USER area. */
+		case PTRACE_PEEKUSR: {
+			unsigned long tmp;
+
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 ||
+			    addr > sizeof(struct user) - 3)
+				break;
+
+			PRINTK_DEBUG("%s PEEKUSR: addr=0x%08x\n", __FUNCTION__, (u32)addr);
+			tmp = 0;  /* Default return condition */
+			addr = addr >> 2; /* temporary hack. */
+			ret = -EIO;
+			if (addr < ARRAY_SIZE(regoff)) {
+				tmp = get_reg(child, addr);
+			} else if (addr == PT_TEXT_ADDR/4) {
+				tmp = child->mm->start_code;
+			} else if (addr == PT_DATA_ADDR/4) {
+				tmp = child->mm->start_data;
+			} else if (addr == PT_TEXT_END_ADDR/4) {
+				tmp = child->mm->end_code;
+			} else
+				break;
+			ret = put_user(tmp,(unsigned long *) data);
+			PRINTK_DEBUG("%s PEEKUSR: rdword=0x%08x\n", __FUNCTION__, (u32)tmp);
+			break;
+		}
+
+		/* when I and D space are separate, this will have to be fixed. */
+		case PTRACE_POKETEXT: /* write the word at location addr. */
+		case PTRACE_POKEDATA:
+			ret = generic_ptrace_pokedata(child, addr, data);
+			break;
+
+		case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+			PRINTK_DEBUG("%s POKEUSR: addr=0x%08x, data=0x%08x\n", __FUNCTION__, (u32)addr, (u32)data);
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 ||
+			    addr > sizeof(struct user) - 3)
+				break;
+
+			addr = addr >> 2; /* temporary hack. */
+
+			if (addr == PTR_ESTATUS) {
+				data &= SR_MASK;
+				data |= get_reg(child, PTR_ESTATUS) & ~(SR_MASK);
+			}
+			if (addr < ARRAY_SIZE(regoff)) {
+				if (put_reg(child, addr, data))
+					break;
+				ret = 0;
+				break;
+			}
+			break;
+
+		case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+		case PTRACE_CONT: { /* restart after signal. */
+
+			PRINTK_DEBUG("%s CONT: addr=0x%08x, data=0x%08x\n", __FUNCTION__, (u32)addr, (u32)data);
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			if (request == PTRACE_SYSCALL) {
+				set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+         }
+			else {
+				clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+         }
+			child->exit_code = data;
+			PRINTK_DEBUG("%s CONT: About to run wake_up_process()\n", __FUNCTION__);
+			wake_up_process(child);
+			ret = 0;
+			break;
+		}
+
+		/*
+		 * make the child exit.  Best I can do is send it a sigkill. 
+		 * perhaps it should be put in the status that it wants to 
+		 * exit.
+		 */
+		case PTRACE_KILL: {
+
+			PRINTK_DEBUG("%s KILL\n", __FUNCTION__);
+			ret = 0;
+			if (child->state == EXIT_ZOMBIE) /* already dead */
+				break;
+			child->exit_code = SIGKILL;
+			wake_up_process(child);
+			break;
+		}
+
+		case PTRACE_GETREGS: { /* Get all gp regs from the child. */
+			int i;
+			unsigned long tmp;
+
+			PRINTK_DEBUG("%s GETREGS\n", __FUNCTION__);
+			for (i = 0; i < ARRAY_SIZE(regoff); i++) {
+			    tmp = get_reg(child, i);
+			    if (put_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				break;
+			    }
+			    data += sizeof(long);
+			}
+			ret = 0;
+			break;
+		}
+
+		case PTRACE_SETREGS: { /* Set all gp regs in the child. */
+			int i;
+			unsigned long tmp;
+
+			PRINTK_DEBUG("%s SETREGS\n", __FUNCTION__);
+			for (i = 0; i < ARRAY_SIZE(regoff); i++) {
+			    if (get_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				break;
+			    }
+			    if (i == PTR_ESTATUS) {
+				tmp &= SR_MASK;
+				tmp |= get_reg(child, PTR_ESTATUS) & ~(SR_MASK);
+			    }
+			    put_reg(child, i, tmp);
+			    data += sizeof(long);
+			}
+			ret = 0;
+			break;
+		}
+
+		default:
+			PRINTK_DEBUG("%s Undefined\n", __FUNCTION__);
+			ret = -EIO;
+			break;
+	}
+	return ret;
+}
+
+asmlinkage void syscall_trace(void)
+{
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		return;
+	if (!(current->ptrace & PT_PTRACED))
+		return;
+	current->exit_code = SIGTRAP;
+	current->state = TASK_STOPPED;
+	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+				 ? 0x80 : 0));
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c
new file mode 100644
index 0000000..15d3a69
--- /dev/null
+++ b/arch/nios2/kernel/setup.c
@@ -0,0 +1,287 @@
+/*
+  21Mar2001    1.1    dgt/microtronix: Altera Excalibur/Nios32 port
+  30Jun2003           kenw/microtronix: Remove cmdline check in flash
+*/
+
+/*
+ *  linux/arch/niosnommu/kernel/setup.c
+ *
+ *  Copyright (C) 2004       Microtronix Datacom Ltd.
+ *  Copyright (C) 2001       Vic Phillips {vic@microtronix.com}
+ *  Copyleft  (C) 2000       James D. Schettine {james@telos-systems.com}
+ *  Copyright (C) 1999       Greg Ungerer (gerg@moreton.com.au)
+ *  Copyright (C) 1998,2000  D. Jeff Dionne <jeff@lineo.ca>
+ *  Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ *  Copyright (C) 1995       Hamish Macdonald
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * This file handles the architecture-dependent parts of system setup
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/genhd.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/major.h>
+#include <linux/bootmem.h>
+#include <linux/initrd.h>
+#include <linux/seq_file.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blkdev.h>
+#endif
+
+#include <asm/irq.h>
+#include <asm/byteorder.h>
+#include <asm/asm-offsets.h>
+#include <asm/pgtable.h>
+#include <asm/setup.h>
+
+/* Sanity check config options for HW supported mul, mulx, div against
+ * the generated header for the specified design.
+ */
+#if defined(CONFIG_NIOS2_HW_MUL_SUPPORT)
+#if HARDWARE_MULTIPLY_PRESENT == 0
+#error Kernel compiled with mul support although not enabled in design
+#endif
+#else
+#if HARDWARE_MULTIPLY_PRESENT != 0
+#warning Kernel compiled without mul support although enabled in design
+#endif
+#endif
+
+#if defined(CONFIG_NIOS2_HW_MULX_SUPPORT)
+#if HARDWARE_MULX_PRESENT == 0
+#error Kernel compiled with mulx support although not enabled in design
+#endif
+#else
+#if HARDWARE_MULX_PRESENT != 0
+#warning Kernel compiled without mulx support although enabled in design
+#endif
+#endif
+
+#if defined(CONFIG_NIOS2_HW_DIV_SUPPORT)
+#if HARDWARE_DIVIDE_PRESENT == 0
+#error Kernel compiled with div support although not enabled in design
+#endif
+#else
+#if HARDWARE_DIVIDE_PRESENT != 0
+#warning Kernel compiled without div support although enabled in design
+#endif
+#endif
+
+#ifdef CONFIG_CONSOLE
+extern struct consw *conswitchp;
+#endif
+
+unsigned long rom_length;
+unsigned long memory_start;
+unsigned long memory_end;
+
+EXPORT_SYMBOL(memory_start);
+EXPORT_SYMBOL(memory_end);
+
+#ifndef CONFIG_PASS_CMDLINE
+static char default_command_line[] = CONFIG_CMDLINE;
+#endif
+static char __initdata command_line[COMMAND_LINE_SIZE] = { 0, };
+
+
+/*				   r1  r2  r3  r4  r5  r6  r7  r8  r9 r10 r11*/
+/*				   r12 r13 r14 r15 or2                      ra  fp  sp  gp es  ste  ea*/
+static struct pt_regs fake_regs = { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\
+				    0,  0,  0,  0,  0, (unsigned long)cpu_idle,  0,  0,  0, 0, 0};
+
+#define CPU "NIOS2"
+
+extern void initMMU(void);
+
+// save args passed from u-boot, called from head.S
+void __init nios2_boot_init(unsigned r4,unsigned r5,unsigned r6,unsigned r7)
+{
+  initMMU();
+
+#if defined(CONFIG_PASS_CMDLINE)
+  if (r4 == 0x534f494e)   // r4 is magic NIOS, to become board info check in the future
+    {
+#if defined(CONFIG_BLK_DEV_INITRD)
+	/*
+	 * If the init RAM disk has been configured in, and there's a valid
+	 * starting address for it, set it up.
+	 */
+	if (r5) {
+		initrd_start = r5;
+		initrd_end = r6;
+	}
+#endif				/* CONFIG_BLK_DEV_INITRD */
+	if (r7)
+		strncpy(command_line, (char *)r7, COMMAND_LINE_SIZE);
+    }
+#endif
+  if (!command_line[0]) {
+    strncpy(command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+  }
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+	int bootmap_size;
+	extern int _stext, _etext;
+	extern int _edata, _end;
+
+#ifdef CONFIG_EARLY_PRINTK
+	extern void setup_early_printk(void);
+	setup_early_printk();
+#endif
+
+	memory_start = PAGE_ALIGN((unsigned long)__pa(&_end));
+	memory_end = (unsigned long) DDR2_TOP_BASE + DDR2_TOP_SPAN;	
+
+#ifndef CONFIG_PASS_CMDLINE
+	memcpy(command_line, default_command_line, sizeof(default_command_line));
+#endif
+
+	printk("\r\n\nLinux/Nios II-MMU\n");
+
+
+	init_mm.start_code = (unsigned long) &_stext;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+	init_mm.brk = (unsigned long) &_end;
+	init_task.thread.kregs = &fake_regs;
+
+	/* Keep a copy of command line */
+	*cmdline_p = &command_line[0];
+
+	memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
+	boot_command_line[COMMAND_LINE_SIZE-1] = 0;
+
+	/*
+	 * give all the memory to the bootmap allocator,  tell it to put the
+	 * boot mem_map at the start of memory
+	 */
+	printk("init_bootmem_node(?,%#lx, %#x, %#lx)\n", 
+	       PFN_UP(memory_start), PFN_DOWN(PHYS_OFFSET), PFN_DOWN(memory_end));
+	bootmap_size = init_bootmem_node(NODE_DATA(0),
+					 PFN_UP(memory_start),
+					 PFN_DOWN(PHYS_OFFSET),
+					 PFN_DOWN(memory_end));
+	
+	/*
+	 * free the usable memory,  we have to make sure we do not free
+	 * the bootmem bitmap so we then reserve it after freeing it :-)
+	 */
+	printk("free_bootmem(%#lx, %#lx)\n", 
+          memory_start, memory_end - memory_start);
+	free_bootmem(memory_start, memory_end - memory_start);
+
+        /*
+         * Reserve the bootmem bitmap itself as well. We do this in two
+         * steps (first step was init_bootmem()) because this catches
+         * the (very unlikely) case of us accidentally initializing the
+         * bootmem allocator with an invalid RAM area.
+	 *
+	 * Arguments are start, size
+         */
+	printk("reserve_bootmem(%#lx, %#x)\n", memory_start, bootmap_size);
+        reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT);
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (initrd_start) {
+	  reserve_bootmem(virt_to_phys((void *)initrd_start), initrd_end - initrd_start, BOOTMEM_DEFAULT);
+	}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 * get kmalloc into gear
+	 */
+	paging_init();
+#ifdef CONFIG_VT
+#if defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;
+#endif
+#endif
+}
+
+/*
+ *	Get CPU information for use by the procfs.
+ */
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+	const char *cpu, *cpu_impl, *fpu;
+	const u_long clockfreq = CPU_FREQ;
+
+	cpu = CPU;
+	cpu_impl = CPU_IMPLEMENTATION;
+	fpu = "none";
+
+	seq_printf(m, "CPU:\t\t%s/%s\n"
+		      "MMU:\t\tways:%d entries:%d\n"
+		      "FPU:\t\t%s\n"
+		      "Clocking:\t%lu.%02lu MHz\n"
+		      "BogoMips:\t%lu.%02lu\n"
+		      "Calibration:\t%lu loops\n",
+		      cpu, cpu_impl,
+		      TLB_NUM_WAYS, TLB_NUM_ENTRIES,
+		      fpu,
+		      clockfreq / 1000000, (clockfreq / 100000) % 10,
+		      (loops_per_jiffy * HZ) / 500000, ((loops_per_jiffy * HZ) / 5000) % 100,
+		      (loops_per_jiffy * HZ));
+
+	return 0;
+}
+
+void arch_gettod(int *year, int *month, int *date, int *hour, int *min, int *sec)
+{
+	*year = *month = *date = *hour = *min = *sec = 0;
+}
+
+static void *cpuinfo_start (struct seq_file *m, loff_t *pos)
+{
+	return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
+}
+
+static void *cpuinfo_next (struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return cpuinfo_start (m, pos);
+}
+
+static void cpuinfo_stop (struct seq_file *m, void *v)
+{
+}
+
+const struct seq_operations cpuinfo_op = {
+	.start	= cpuinfo_start,
+	.next	= cpuinfo_next,
+	.stop	= cpuinfo_stop,
+	.show	= show_cpuinfo
+};
diff --git a/arch/nios2/kernel/signal.c b/arch/nios2/kernel/signal.c
new file mode 100644
index 0000000..9f86ed3
--- /dev/null
+++ b/arch/nios2/kernel/signal.c
@@ -0,0 +1,679 @@
+/*
+ * linux/arch/nios2nommu/kernel/signal.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdnald
+ *
+ * 68060 fixes by Jesper Skov
+ *
+ * 1997-12-01  Modified for POSIX.1b signals by Andreas Schwab
+ *
+ * mathemu support by Roman Zippel
+ *  (Note: fpstate in the signal context is completely ignored for the emulator
+ *         and the internal floating point format is put on stack)
+ *
+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
+ * Atari :-) Current limitation: Only one sigstack can be active at one time.
+ * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
+ * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
+ * signal handlers!
+ *
+ * Jan/20/2004		dgt	    NiosII
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/highuid.h>
+#include <linux/tty.h>
+#include <linux/personality.h>
+#include <linux/binfmts.h>
+#include <linux/fs.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/traps.h>
+#include <asm/ucontext.h>
+#include <asm/cacheflush.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage long sys_wait4(pid_t pid, unsigned int * stat_addr, int options,
+			struct rusage * ru);
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int do_sigsuspend(struct pt_regs *regs)
+{
+	old_sigset_t mask = regs->r4;  // Verify correct syscall reg
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs->r2 = EINTR;
+   regs->r7 = 1;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs, 0))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+do_rt_sigsuspend(struct pt_regs *regs)
+{
+	sigset_t *unewset = (sigset_t *)regs->r4;
+	size_t sigsetsize = (size_t)regs->r5;
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs->r2 = EINTR;
+   regs->r7 = 1;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs, 0))
+			return -EINTR;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+/*
+ * Do a signal return; undo the signal stack.
+ *
+ * Keep the return code on the stack quadword aligned!
+ * That makes the cache flush below easier.
+ */
+
+
+struct sigframe
+{
+	char retcode[12];
+	unsigned long extramask[_NSIG_WORDS-1];
+	struct sigcontext sc;
+};
+
+struct rt_sigframe
+{
+	char retcode[12];
+	struct siginfo info;
+	struct ucontext uc;
+};
+
+#ifdef CONFIG_FPU
+
+static unsigned char fpu_version = 0;	/* version number of fpu, set by setup_frame */
+
+static inline int restore_fpu_state(struct sigcontext *sc)
+{
+	int err = 1;
+
+	if (FPU_IS_EMU) {
+	    /* restore registers */
+	    memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
+	    memcpy(current->thread.fp, sc->sc_fpregs, 24);
+	    return 0;
+	}
+
+	if (sc->sc_fpstate[0]) {
+	    /* Verify the frame format.  */
+	    if (sc->sc_fpstate[0] != fpu_version)
+		goto out;
+
+	    __asm__ volatile ("Nios II FPU"
+			      : /* no outputs */
+			      : );
+	}
+	__asm__ volatile ("Nios II FPU"
+			  : : );
+	err = 0;
+
+out:
+	return err;
+}
+
+#define FPCONTEXT_SIZE	216
+#define uc_fpstate	uc_filler[0]
+#define uc_formatvec	uc_filler[FPCONTEXT_SIZE/4]
+#define uc_extra	uc_filler[FPCONTEXT_SIZE/4+1]
+
+static inline int rt_restore_fpu_state(struct ucontext *uc)
+{
+	unsigned char fpstate[FPCONTEXT_SIZE];
+	int context_size = 0;
+	fpregset_t fpregs;
+	int err = 1;
+
+	if (FPU_IS_EMU) {
+		/* restore fpu control register */
+		if (__copy_from_user(current->thread.fpcntl,
+				&uc->uc_mcontext.fpregs.f_pcr, 12))
+			goto out;
+		/* restore all other fpu register */
+		if (__copy_from_user(current->thread.fp,
+				uc->uc_mcontext.fpregs.f_fpregs, 96))
+			goto out;
+		return 0;
+	}
+
+	if (__get_user(*(long *)fpstate, (long *)&uc->uc_fpstate))
+		goto out;
+	if (fpstate[0]) {
+		context_size = fpstate[1];
+
+		/* Verify the frame format.  */
+		if (fpstate[0] != fpu_version)
+			goto out;
+		if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
+		     sizeof(fpregs)))
+			goto out;
+		__asm__ volatile ("Nios II FPU"
+				  : /* no outputs */
+				  : );
+	}
+	if (context_size &&
+	    __copy_from_user(fpstate + 4, (long *)&uc->uc_fpstate + 1,
+			     context_size))
+		goto out;
+	__asm__ volatile ("Nios II FPU"
+			   : : );
+	err = 0;
+
+out:
+	return err;
+}
+
+#endif
+
+static inline int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp,
+		   int *pr2)
+{
+	int err = 0;
+	int estatus;
+
+	estatus = regs->estatus;
+
+	/* get previous pt_regs */
+	if (copy_from_user(regs, &usc->regs, sizeof(*regs)))
+		goto badframe;
+
+	/* Prevent user from being able to change
+	 * certain processor status bits. Currently nothing.
+	 */
+	regs->estatus = (estatus & 0xffffffff) | (regs->estatus & 0);
+	regs->orig_r2 = -1;		/* disable syscall checks */
+
+	*pr2 = regs->r2;
+
+#ifdef CONFIG_FPU
+	err |= restore_fpu_state(&context);
+#endif
+
+	return err;
+
+badframe:
+	return 1;
+}
+
+static inline int
+rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
+		    struct ucontext *uc, int *pr2)
+{
+	int temp;
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	unsigned long usp;
+	int err;
+
+
+	err = __get_user(temp, &uc->uc_mcontext.version);
+	if (temp != MCONTEXT_VERSION)
+		goto badframe;
+	/* restore passed registers */
+	/* FIXME: What registers should/shoudn't be saved ?
+	 */
+	err |= __get_user(regs->r1, &gregs[0]);
+	err |= __get_user(regs->r2, &gregs[1]);
+	err |= __get_user(regs->r3, &gregs[2]);
+	err |= __get_user(regs->r4, &gregs[3]);
+	err |= __get_user(regs->r5, &gregs[4]);
+	err |= __get_user(regs->r6, &gregs[5]);
+	err |= __get_user(regs->r7, &gregs[6]);
+	err |= __get_user(regs->r8, &gregs[7]);
+	err |= __get_user(regs->r9, &gregs[8]);
+	err |= __get_user(regs->r10, &gregs[9]);
+	err |= __get_user(regs->r11, &gregs[10]);
+	err |= __get_user(regs->r12, &gregs[11]);
+	err |= __get_user(regs->r13, &gregs[12]);
+	err |= __get_user(regs->r14, &gregs[13]);
+	err |= __get_user(regs->r15, &gregs[14]);
+	err |= __get_user(regs->ea, &gregs[27]);
+	err |= __get_user(regs->sp, &gregs[28]);
+	err |= __get_user(sw->r16, &gregs[15]);
+	err |= __get_user(sw->r17, &gregs[16]);
+	err |= __get_user(sw->r18, &gregs[17]);
+	err |= __get_user(sw->r19, &gregs[18]);
+	err |= __get_user(sw->r20, &gregs[19]);
+	err |= __get_user(sw->r21, &gregs[20]);
+	err |= __get_user(sw->r22, &gregs[21]);
+	err |= __get_user(sw->r23, &gregs[22]);
+	err |= __get_user(regs->ra, &gregs[23]);
+	err |= __get_user(sw->fp, &gregs[24]);  // Verify, should this be settable
+	err |= __get_user(sw->gp, &gregs[25]);  // Verify, should this be settable
+
+	err |= __get_user(temp, &gregs[26]);  // Not really necessary no user settable bits
+	regs->estatus = (regs->estatus & 0xffffffff) | (temp & 0x0);
+	regs->orig_r2 = -1;		/* disable syscall checks */
+
+	if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
+		goto badframe;
+
+	*pr2 = regs->r2;
+	return err;
+
+badframe:
+	return 1;
+}
+
+asmlinkage int do_sigreturn(struct pt_regs *regs)
+{
+	struct sigframe *frame = (struct sigframe *) regs->sp;
+	sigset_t set;
+	int rval;
+
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) {
+	        printk("Failed test 1 frame at %p size %ld\n", 
+           frame, sizeof(*frame));
+		goto badframe;
+	}
+	if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
+	    (_NSIG_WORDS > 1 &&
+	     __copy_from_user(&set.sig[1], &frame->extramask,
+			      sizeof(frame->extramask)))) {
+	        printk("Failed test 2\n");
+		goto badframe;
+	}
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+	
+	if (restore_sigcontext(regs, &frame->sc, frame + 1, &rval)) {
+ 	        printk("Failed to restore sigcontext\n");
+		goto badframe;
+	}
+	return rval;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int do_rt_sigreturn(struct switch_stack *sw)
+{
+	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
+	struct rt_sigframe *frame = (struct rt_sigframe *) regs->sp;  // Verify, can we follow the stack back
+	sigset_t set;
+	int rval;
+
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+	
+	if (rt_restore_ucontext(regs, sw, &frame->uc, &rval))
+		goto badframe;
+	return rval;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+static int setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+			     unsigned long mask)
+{
+	int err = 0;
+
+	err |= __put_user(mask, &sc->sc_mask);
+	err |= copy_to_user(&sc->regs, regs, sizeof(*regs));
+	return err;
+}
+
+static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
+{
+	struct switch_stack *sw = (struct switch_stack *)regs - 1;
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	int err = 0;
+
+	err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
+	err |= __put_user(regs->r1, &gregs[0]);
+	err |= __put_user(regs->r2, &gregs[1]);
+	err |= __put_user(regs->r3, &gregs[2]);
+	err |= __put_user(regs->r4, &gregs[3]);
+	err |= __put_user(regs->r5, &gregs[4]);
+	err |= __put_user(regs->r6, &gregs[5]);
+	err |= __put_user(regs->r7, &gregs[6]);
+	err |= __put_user(regs->r8, &gregs[7]);
+	err |= __put_user(regs->r9, &gregs[8]);
+	err |= __put_user(regs->r10, &gregs[9]);
+	err |= __put_user(regs->r11, &gregs[10]);
+	err |= __put_user(regs->r12, &gregs[11]);
+	err |= __put_user(regs->r13, &gregs[12]);
+	err |= __put_user(regs->r14, &gregs[13]);
+	err |= __put_user(regs->r15, &gregs[14]);
+	err |= __put_user(regs->ea, &gregs[27]);
+	err |= __put_user(regs->sp, &gregs[28]);
+	err |= __put_user(sw->r16, &gregs[15]);
+	err |= __put_user(sw->r17, &gregs[16]);
+	err |= __put_user(sw->r18, &gregs[17]);
+	err |= __put_user(sw->r19, &gregs[18]);
+	err |= __put_user(sw->r20, &gregs[19]);
+	err |= __put_user(sw->r21, &gregs[20]);
+	err |= __put_user(sw->r22, &gregs[21]);
+	err |= __put_user(sw->r23, &gregs[22]);
+	err |= __put_user(regs->ra, &gregs[23]);
+	err |= __put_user(sw->fp, &gregs[24]);
+	err |= __put_user(sw->gp, &gregs[25]);
+	return err;
+}
+
+static inline void push_cache (unsigned long vaddr)
+{
+   flush_dcache_range(vaddr, vaddr+12);
+   flush_icache_range(vaddr, vaddr+12);
+}
+
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long usp;
+
+	/* Default to using normal stack.  */
+	usp = regs->sp;
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if ((ka->sa.sa_flags & SA_ONSTACK) && (current->sas_ss_sp != 0)) {
+		if (!on_sig_stack(usp))
+			usp = current->sas_ss_sp + current->sas_ss_size;
+	}
+	return (void *)((usp - frame_size) & -8UL);  // Verify, is it 32 or 64 bit aligned
+}
+
+static void setup_frame (int sig, struct k_sigaction *ka,
+			 sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (_NSIG_WORDS > 1)
+		err |= copy_to_user(frame->extramask, &set->sig[1],
+				    sizeof(frame->extramask));
+
+	err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
+
+	/* Set up to return from userspace.  */
+	regs->ra = (unsigned long) &frame->retcode[0];
+
+	/* movi r2,__NR_sigreturn */
+	err |= __put_user(0x00800004 + (__NR_sigreturn << 6), (long *)(frame->retcode));
+	/* trap */
+	err |= __put_user(0x003b683a, (long *)(frame->retcode + 4));
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	regs->sp = (unsigned long) frame;
+	regs->r4 = (unsigned long) (current_thread_info()->exec_domain
+				    && current_thread_info()->exec_domain->signal_invmap
+				    && sig < 32
+				    ? current_thread_info()->exec_domain->signal_invmap[sig]
+				    : sig);
+	regs->ea = (unsigned long) ka->sa.sa_handler;
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
+			    sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			  &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->sp),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= rt_setup_ucontext(&frame->uc, regs);
+	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Set up to return from userspace.  */
+	regs->ra = (unsigned long) &frame->retcode[0];
+
+	/* movi r2,__NR_rt_sigreturn */
+	err |= __put_user(0x00800004 + (__NR_rt_sigreturn << 6), (long *)(frame->retcode));
+	/* trap */
+	err |= __put_user(0x003b683a, (long *)(frame->retcode + 4));
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	regs->sp = (unsigned long) frame;
+	regs->r4 = (unsigned long) (current_thread_info()->exec_domain
+				    && current_thread_info()->exec_domain->signal_invmap
+				    && sig < 32
+				    ? current_thread_info()->exec_domain->signal_invmap[sig]
+				    : sig);
+	regs->r5 = (unsigned long) &frame->info;
+	regs->r6 = (unsigned long) &frame->uc;
+	regs->ea = (unsigned long) ka->sa.sa_handler;
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+	switch (regs->r2) {
+   case ERESTART_RESTARTBLOCK:
+	case ERESTARTNOHAND:
+		regs->r2 = EINTR;
+      regs->r7 = 1;
+		break;
+
+	case ERESTARTSYS:
+		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+			regs->r2 = EINTR;
+         regs->r7 = 1;
+			break;
+		}
+	/* fallthrough */
+	case ERESTARTNOINTR:
+		regs->r2 = regs->orig_r2;
+		regs->r7 = regs->orig_r7;
+		regs->ea -= 4;
+		break;
+	}
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static void
+handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
+              sigset_t *oldset, struct pt_regs *regs, int syscall)
+{
+	/* are we from a system call? */
+	if (syscall)
+		/* If so, check system call restarting.. */
+		handle_restart(regs, ka, 1);
+
+	/* set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ */
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
+{
+	struct k_sigaction ka;
+	siginfo_t info;
+	int signr;
+
+	/*
+	 * We want the common case to go fast, which
+	 * is why we may in certain cases get here from
+	 * kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return 1;
+
+	/* FIXME - Do we still need to do this ? */
+	current->thread.kregs = regs;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+	if (signr > 0) {
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, &ka, &info, oldset, regs, syscall);
+		return 1;
+	}
+
+	/*
+	 * No signal to deliver to the process - restart the syscall.
+	 */
+	if (syscall){
+      /* Did the syscall return an error code */
+      if(regs->r7 == 1) {
+         if (regs->r2 == ERESTARTNOHAND ||
+             regs->r2 == ERESTARTSYS ||
+             regs->r2 == ERESTARTNOINTR) 
+         {
+            regs->r2 = regs->orig_r2;
+            regs->r7 = regs->orig_r7;
+            regs->ea -= 4;
+         } else if (regs->r2 == ERESTART_RESTARTBLOCK) {
+            regs->r2 = __NR_restart_syscall;
+            regs->ea -= 4;
+         }
+      }
+	}
+	return 0;
+}
diff --git a/arch/nios2/kernel/start.c b/arch/nios2/kernel/start.c
new file mode 100644
index 0000000..194fa84
--- /dev/null
+++ b/arch/nios2/kernel/start.c
@@ -0,0 +1,39 @@
+/*--------------------------------------------------------------------
+ *
+ * arch/nios2nommu/kernel/start.c
+ *
+ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al
+ *
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Jan/20/2004		dgt	    NiosII
+ * May/20/2005		dgt	    Altera NiosII Custom shift instr(s)
+ *                           possibly assumed by memcpy, etc; ensure
+ *                           "correct" core loaded therefore if so.
+ *
+ ---------------------------------------------------------------------*/
+
+
+#include <asm/system.h>
+#include <asm/nios.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/time.h>
+#include <linux/start_kernel.h>
+
+int __init main(void) {
+	start_kernel();
+	return 0;
+}
diff --git a/arch/nios2/kernel/sys_nios2.c b/arch/nios2/kernel/sys_nios2.c
new file mode 100644
index 0000000..d3e27d6
--- /dev/null
+++ b/arch/nios2/kernel/sys_nios2.c
@@ -0,0 +1,266 @@
+/*
+ * linux/arch/nios2nommu/kernel/sys_nios2.c
+ *
+ * Copyright (C) 2004 Microtronix Datacom Ltd.
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/nios2nommu
+ * platform.
+ *
+  * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+*/
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/syscalls.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+#include <linux/uaccess.h>
+#include <linux/ipc.h>
+#include <linux/unistd.h>
+#include <linux/fs.h>
+
+#include <asm/setup.h>
+#include <asm/cachectl.h>
+#include <asm/traps.h>
+#include <asm/cacheflush.h>
+
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+	unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	int error = -EBADF;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+  return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
+                         unsigned long prot, unsigned long flags,
+                         unsigned long fd, unsigned long offset)
+{
+	unsigned long result;
+
+	result = -EINVAL;
+	if (offset & ~PAGE_MASK)
+		goto out;
+
+	result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+
+out:
+	return result;
+}
+
+/*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
+ * handle more than 4 system call parameters, so these system calls
+ * used a memory block for parameter passing..
+ */
+
+struct mmap_arg_struct {
+	unsigned long addr;
+	unsigned long len;
+	unsigned long prot;
+	unsigned long flags;
+	unsigned long fd;
+	unsigned long offset;
+};
+
+struct sel_arg_struct {
+	unsigned long n;
+	fd_set *inp, *outp, *exp;
+	struct timeval *tvp;
+};
+
+asmlinkage int old_select(struct sel_arg_struct *arg)
+{
+	struct sel_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+	/* sys_select() does the appropriate kernel locking */
+	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage int sys_ipc (unsigned int call, int first, int second,
+			unsigned long third, void __user *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+	case SEMOP:
+		return sys_semtimedop (first, (struct sembuf __user *)ptr,
+		                       second, NULL);
+	case SEMTIMEDOP:
+		return sys_semtimedop (first, (struct sembuf __user *)ptr,
+				       second,
+				       (const struct timespec __user *)fifth);
+	case SEMGET:
+		return sys_semget (first, second, third);
+	case SEMCTL: {
+		union semun fourth;
+		if (!ptr)
+			return -EINVAL;
+		if (get_user(fourth.__pad, (void __user *__user *) ptr))
+			return -EFAULT;
+		return sys_semctl (first, second, third, fourth);
+	}
+
+	case MSGSND:
+		return sys_msgsnd (first, (struct msgbuf __user *) ptr,
+				   second, third);
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+			if (!ptr)
+				return -EINVAL;
+
+			if (copy_from_user(&tmp,
+					   (struct ipc_kludge __user *) ptr,
+					   sizeof (tmp)))
+				return -EFAULT;
+			return sys_msgrcv (first, tmp.msgp, second,
+					   tmp.msgtyp, third);
+		}
+		default:
+			return sys_msgrcv (first,
+					   (struct msgbuf __user *) ptr,
+					   second, fifth, third);
+		}
+	case MSGGET:
+		return sys_msgget ((key_t) first, second);
+	case MSGCTL:
+		return sys_msgctl (first, second,
+				   (struct msqid_ds __user *) ptr);
+
+	case SHMAT:
+		switch (version) {
+		default: {
+			unsigned long raddr;
+			ret = do_shmat (first, (char __user *) ptr, second,
+					&raddr);
+			if (ret)
+				return ret;
+			return put_user (raddr, (unsigned long __user *) third);
+		}
+		case 1:	/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				return -EINVAL;
+			return do_shmat (first, (char __user *) ptr, second,
+					 (unsigned long *) third);
+		}
+	case SHMDT:
+		return sys_shmdt ((char __user *)ptr);
+	case SHMGET:
+		return sys_shmget (first, second, third);
+	case SHMCTL:
+		return sys_shmctl (first, second,
+				   (struct shmid_ds __user *) ptr);
+	default:
+		return -ENOSYS;
+	}
+}
+
+/* sys_cacheflush -- flush the processor cache.  
+ */
+asmlinkage int
+sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
+{
+   flush_dcache_range(addr, addr+len);
+   flush_icache_range(addr, addr+len);
+   return(0);
+}
+
+asmlinkage int sys_getpagesize(void)
+{
+	return PAGE_SIZE;
+}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register long __res __asm__ ("r2");
+	register long __sc  __asm__ ("r2") = __NR_execve;
+	register long __a   __asm__ ("r4") = (long) filename;
+	register long __b   __asm__ ("r5") = (long) argv;
+	register long __c   __asm__ ("r6") = (long) envp;
+	__asm__ __volatile__ ("trap" : "=r" (__res)
+			: "0" (__sc), "r" (__a), "r" (__b), "r" (__c)
+			: "memory");
+
+	return __res;
+}
+
+/* Uncomment if you uncomment the syscall printk tracing in entry.S
+ */
+#if 0
+
+void print_syscall(int sc) {
+   printk("Syscall %d\n", sc);
+}
+
+
+void print_syscall_ret(int rv, int err) {
+   printk("  RET %d %d\n", err, rv);
+}
+
+#endif
diff --git a/arch/nios2/kernel/syscall.c b/arch/nios2/kernel/syscall.c
new file mode 100644
index 0000000..fc6901c
--- /dev/null
+++ b/arch/nios2/kernel/syscall.c
@@ -0,0 +1,185 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 2000, 2001, 05 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/capability.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/mman.h>
+#include <linux/ptrace.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/syscalls.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+#include <linux/utsname.h>
+#include <linux/unistd.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+
+#include <asm/cachectl.h>
+#include <asm/cacheflush.h>
+#include <asm/asm-offsets.h>
+#include <asm/signal.h>
+#include <asm/shmparam.h>
+#include <asm/uaccess.h>
+
+unsigned long shm_align_mask = SHMLBA - 1;	/* Sane caches */
+
+EXPORT_SYMBOL(shm_align_mask);
+
+#define COLOUR_ALIGN(addr,pgoff)				\
+	((((addr) + shm_align_mask) & ~shm_align_mask) +	\
+	 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+	unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct vm_area_struct * vmm;
+	int do_color_align;
+	unsigned long task_size;
+
+	task_size = STACK_TOP;
+
+	if (flags & MAP_FIXED) {
+		/*
+		 * We do not accept a shared mapping if it would violate
+		 * cache aliasing constraints.
+		 */
+		if ((flags & MAP_SHARED) && (addr & shm_align_mask))
+			return -EINVAL;
+		return addr;
+	}
+
+	if (len > task_size)
+		return -ENOMEM;
+	do_color_align = 0;
+	if (filp || (flags & MAP_SHARED))
+		do_color_align = 1;
+	if (addr) {
+		if (do_color_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+		else
+			addr = PAGE_ALIGN(addr);
+		vmm = find_vma(current->mm, addr);
+		if (task_size - len >= addr &&
+		    (!vmm || addr + len <= vmm->vm_start))
+			return addr;
+	}
+	addr = TASK_UNMAPPED_BASE;
+	if (do_color_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
+		/* At this point:  (!vmm || addr < vmm->vm_end). */
+		if (task_size - len < addr)
+			return -ENOMEM;
+		if (!vmm || addr + len <= vmm->vm_start)
+			return addr;
+		addr = vmm->vm_end;
+		if (do_color_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+	}
+}
+
+/* common code for old and new mmaps */
+static inline unsigned long
+do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+        unsigned long flags, unsigned long fd, unsigned long pgoff)
+{
+	unsigned long error = -EBADF;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+/*
+ * Compacrapability ...
+ */
+asmlinkage int sys_uname(struct old_utsname __user * name)
+{
+	if (name && !copy_to_user(name, utsname(), sizeof (*name)))
+		return 0;
+	return -EFAULT;
+}
+
+/*
+ * Compacrapability ...
+ */
+asmlinkage int sys_olduname(struct oldold_utsname __user * name)
+{
+	int error;
+
+	if (!name)
+		return -EFAULT;
+	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
+		return -EFAULT;
+
+	error = __copy_to_user(&name->sysname, &utsname()->sysname,
+			       __OLD_UTS_LEN);
+	error -= __put_user(0, name->sysname + __OLD_UTS_LEN);
+	error -= __copy_to_user(&name->nodename, &utsname()->nodename,
+				__OLD_UTS_LEN);
+	error -= __put_user(0, name->nodename + __OLD_UTS_LEN);
+	error -= __copy_to_user(&name->release, &utsname()->release,
+				__OLD_UTS_LEN);
+	error -= __put_user(0, name->release + __OLD_UTS_LEN);
+	error -= __copy_to_user(&name->version, &utsname()->version,
+				__OLD_UTS_LEN);
+	error -= __put_user(0, name->version + __OLD_UTS_LEN);
+	error -= __copy_to_user(&name->machine, &utsname()->machine,
+				__OLD_UTS_LEN);
+	error = __put_user(0, name->machine + __OLD_UTS_LEN);
+	error = error ? -EFAULT : 0;
+
+	return error;
+}
+
+asmlinkage int sys_set_thread_area(unsigned long addr)
+{
+   BUG();
+   return 0;
+}
+
+/*
+ * No implemented yet ...
+ */
+asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
+{
+	return -ENOSYS;
+}
+
+/*
+ * If we ever come here the user sp is bad.  Zap the process right away.
+ * Due to the bad stack signaling wouldn't work.
+ */
+asmlinkage void bad_stack(void)
+{
+	do_exit(SIGSEGV);
+}
diff --git a/arch/nios2/kernel/syscalltable.S b/arch/nios2/kernel/syscalltable.S
new file mode 100644
index 0000000..04324a8
--- /dev/null
+++ b/arch/nios2/kernel/syscalltable.S
@@ -0,0 +1,382 @@
+/*--------------------------------------------------------------------
+ *
+ * arch/nios2/kernel/syscalltable.S
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ * 
+ * Based on:
+ *	
+ * arch/nios2nommu/kernel/syscalltable.S	
+ *
+ * Derived from M68knommu
+ *
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *  Copyright (C) 2002, Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Jan/20/2004		dgt	    NiosII
+ *
+ ---------------------------------------------------------------------*/
+
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/unistd.h>
+#include <asm/asm-macros.h>
+
+.text
+ALIGN
+ENTRY(sys_call_table)
+	.long sys_restart_syscall /* 0 */
+	.long sys_exit
+	.long sys_fork
+	.long sys_read
+	.long sys_write
+	.long sys_open		/* 5 */
+	.long sys_close
+	.long sys_ni_syscall
+	.long sys_creat
+	.long sys_link
+	.long sys_unlink	/* 10 */
+	.long sys_execve
+	.long sys_chdir
+	.long sys_time
+	.long sys_mknod
+	.long sys_chmod		/* 15 */
+	.long sys_chown
+	.long sys_ni_syscall	/* sys_break */
+	.long sys_ni_syscall	/* sys_stat */
+	.long sys_lseek
+	.long sys_getpid	/* 20 */
+	.long sys_mount
+	.long sys_umount
+	.long sys_setuid
+	.long sys_getuid
+	.long sys_stime		/* 25 */
+	.long sys_ptrace
+	.long sys_alarm
+	.long sys_ni_syscall
+	.long sys_pause
+	.long sys_utime		/* 30 */
+	.long sys_ni_syscall	/* old stty syscall holder */
+	.long sys_ni_syscall	/* old gtty syscall holder */
+	.long sys_access
+	.long sys_nice
+	.long sys_ni_syscall	/* 35 */ /* old ftime syscall holder */
+	.long sys_sync
+	.long sys_kill
+	.long sys_rename
+	.long sys_mkdir
+	.long sys_rmdir		/* 40 */
+	.long sys_dup
+	.long sys_pipe
+	.long sys_times
+	.long sys_ni_syscall	/* old prof syscall holder */
+	.long sys_brk		/* 45 */
+	.long sys_setgid
+	.long sys_getgid
+	.long sys_ni_syscall
+	.long sys_geteuid
+	.long sys_getegid	/* 50 */
+	.long sys_acct
+	.long sys_umount	/* recycled never used phys() */
+	.long sys_ni_syscall	/* old lock syscall holder */
+	.long sys_ioctl
+	.long sys_fcntl		/* 55 */
+	.long sys_ni_syscall	/* old mpx syscall holder */
+	.long sys_setpgid
+	.long sys_ni_syscall	/* old ulimit syscall holder */
+	.long sys_ni_syscall
+	.long sys_umask		/* 60 */
+	.long sys_chroot
+	.long sys_ustat
+	.long sys_dup2
+	.long sys_getppid
+	.long sys_getpgrp	/* 65 */
+	.long sys_setsid
+	.long sys_sigaction
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long sys_setreuid	/* 70 */
+	.long sys_setregid
+	.long sys_sigsuspend
+	.long sys_sigpending
+	.long sys_sethostname
+	.long sys_setrlimit	/* 75 */
+	.long sys_ni_syscall
+	.long sys_getrusage
+	.long sys_gettimeofday
+	.long sys_settimeofday
+	.long sys_getgroups	/* 80 */
+	.long sys_setgroups
+	.long sys_select
+	.long sys_symlink
+	.long sys_ni_syscall
+	.long sys_readlink	/* 85 */
+	.long sys_uselib
+	.long sys_swapon
+	.long sys_reboot
+	.long sys_ni_syscall	/* sys_readdir */
+	.long sys_mmap		/* 90 */
+	.long sys_munmap
+	.long sys_truncate
+	.long sys_ftruncate
+	.long sys_fchmod
+	.long sys_fchown	/* 95 */
+	.long sys_getpriority
+	.long sys_setpriority
+	.long sys_ni_syscall	/* sys_profil */
+	.long sys_statfs
+	.long sys_fstatfs	/* 100 */
+	.long sys_ni_syscall	/* sys_ioperm */
+	.long sys_socketcall
+	.long sys_syslog
+	.long sys_setitimer
+	.long sys_getitimer	/* 105 */
+	.long sys_newstat
+	.long sys_newlstat
+	.long sys_newfstat
+	.long sys_ni_syscall	/* sys_uname */
+	.long sys_ni_syscall	/* sys_iopl */
+	.long sys_vhangup
+	.long sys_ni_syscall	/* sys_idle */
+	.long sys_nios2cmpxchg	/* nios2-specific compare and exchange syscall for atomic operations */
+	.long sys_wait4
+	.long sys_swapoff	/* 115 */ /* sys_swapoff */
+	.long sys_sysinfo
+	.long sys_ipc
+	.long sys_fsync
+	.long sys_sigreturn
+	.long sys_clone		/* 120 */
+	.long sys_setdomainname
+	.long sys_newuname
+	.long sys_cacheflush	/* modify_ldt for i386 */
+	.long sys_adjtimex
+	.long sys_mprotect	/* 125 */ /* sys_mprotect */
+	.long sys_sigprocmask
+	.long sys_ni_syscall	/* sys_creat_module */
+	.long sys_init_module
+	.long sys_delete_module
+	.long sys_ni_syscall	/* 130: sys_get_kernel_syms */
+	.long sys_quotactl
+	.long sys_getpgid
+	.long sys_fchdir
+	.long sys_bdflush
+	.long sys_sysfs		/* 135 */
+	.long sys_personality
+	.long sys_ni_syscall	/* sys_afs_syscall */
+	.long sys_setfsuid
+	.long sys_setfsgid
+	.long sys_llseek	/* 140 */
+	.long sys_getdents
+	.long sys_select
+	.long sys_flock
+	.long sys_msync		/* sys_msync */
+	.long sys_readv		/* 145 */
+	.long sys_writev
+	.long sys_getsid
+	.long sys_fdatasync
+	.long sys_sysctl
+	.long sys_mlock		/* 150 */ /* sys_mlock */
+	.long sys_munlock	/* sys_munlock */
+	.long sys_mlockall	/* sys_mlockall */
+	.long sys_munlockall	/* sys_munlockall */
+	.long sys_sched_setparam
+	.long sys_sched_getparam /* 155 */
+	.long sys_sched_setscheduler
+	.long sys_sched_getscheduler
+	.long sys_sched_yield
+	.long sys_sched_get_priority_max
+	.long sys_sched_get_priority_min  /* 160 */
+	.long sys_sched_rr_get_interval
+	.long sys_nanosleep
+	.long sys_mremap
+	.long sys_setresuid
+	.long sys_getresuid	/* 165 */
+	.long sys_getpagesize
+	.long sys_ni_syscall	/* sys_query_module */
+	.long sys_poll
+	.long sys_nfsservctl
+	.long sys_setresgid	/* 170 */
+	.long sys_getresgid
+	.long sys_prctl
+	.long sys_rt_sigreturn
+	.long sys_rt_sigaction
+	.long sys_rt_sigprocmask /* 175 */
+	.long sys_rt_sigpending
+	.long sys_rt_sigtimedwait
+	.long sys_rt_sigqueueinfo
+	.long sys_rt_sigsuspend
+	.long sys_pread64	/* 180 */
+	.long sys_pwrite64
+	.long sys_lchown
+	.long sys_getcwd
+	.long sys_capget
+	.long sys_capset	/* 185 */
+	.long sys_sigaltstack
+	.long sys_sendfile
+	.long sys_ni_syscall	/* streams1 */
+	.long sys_ni_syscall	/* streams2 */
+	.long sys_vfork		/* 190 */
+	.long sys_getrlimit
+	.long sys_ni_syscall
+	.long sys_truncate64
+	.long sys_ftruncate64
+	.long sys_stat64	/* 195 */
+	.long sys_lstat64
+	.long sys_fstat64
+	.long sys_chown
+	.long sys_getuid
+	.long sys_getgid	/* 200 */
+	.long sys_geteuid
+	.long sys_getegid
+	.long sys_setreuid
+	.long sys_setregid
+	.long sys_getgroups	/* 205 */
+	.long sys_setgroups
+	.long sys_fchown
+	.long sys_setresuid
+	.long sys_getresuid
+	.long sys_setresgid	/* 210 */
+	.long sys_getresgid
+	.long sys_lchown
+	.long sys_setuid
+	.long sys_setgid
+	.long sys_setfsuid	/* 215 */
+	.long sys_setfsgid
+	.long sys_pivot_root
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long sys_getdents64	/* 220 */
+	.long sys_gettid
+	.long sys_tkill
+	.long sys_setxattr
+	.long sys_lsetxattr
+	.long sys_fsetxattr	/* 225 */
+	.long sys_getxattr
+	.long sys_lgetxattr
+	.long sys_fgetxattr
+	.long sys_listxattr
+	.long sys_llistxattr	/* 230 */
+	.long sys_flistxattr
+	.long sys_removexattr
+	.long sys_lremovexattr
+	.long sys_fremovexattr
+	.long sys_futex		/* 235 */
+	.long sys_sendfile64
+	.long sys_mincore	/* sys_mincore */
+	.long sys_madvise	/* sys_madvise */
+	.long sys_fcntl64
+	.long sys_readahead	/* 240 */
+	.long sys_io_setup
+	.long sys_io_destroy
+	.long sys_io_getevents
+	.long sys_io_submit
+	.long sys_io_cancel	/* 245 */
+	.long sys_fadvise64
+	.long sys_exit_group
+	.long sys_lookup_dcookie
+	.long sys_epoll_create
+	.long sys_epoll_ctl	/* 250 */
+	.long sys_epoll_wait
+	.long sys_remap_file_pages	/* sys_remap_file_pages */
+	.long sys_set_tid_address
+	.long sys_timer_create
+	.long sys_timer_settime	/* 255 */
+	.long sys_timer_gettime
+	.long sys_timer_getoverrun
+	.long sys_timer_delete
+	.long sys_clock_settime
+	.long sys_clock_gettime	/* 260 */
+	.long sys_clock_getres
+	.long sys_clock_nanosleep
+	.long sys_statfs64
+	.long sys_fstatfs64
+	.long sys_tgkill	/* 265 */
+	.long sys_utimes
+	.long sys_fadvise64_64
+	.long sys_mbind	
+	.long sys_get_mempolicy
+	.long sys_set_mempolicy	/* 270 */
+	.long sys_mq_open
+	.long sys_mq_unlink
+	.long sys_mq_timedsend
+	.long sys_mq_timedreceive
+	.long sys_mq_notify	/* 275 */
+	.long sys_mq_getsetattr
+	.long sys_waitid
+	.long sys_ni_syscall	/* sys_setaltroot */
+	.long sys_ni_syscall	/* sys_add_key */
+	.long sys_ni_syscall	/* 280 */ /* sys_request_key */
+	.long sys_ni_syscall	/* sys_keyctl */
+	.long sys_ioprio_set
+	.long sys_ioprio_get
+	.long sys_inotify_init
+	.long sys_inotify_add_watch	/* 285 */
+	.long sys_inotify_rm_watch
+	.long sys_migrate_pages
+	.long sys_openat
+	.long sys_mkdirat
+	.long sys_mknodat		/* 290 */
+	.long sys_fchownat
+	.long sys_futimesat
+	.long sys_fstatat64
+	.long sys_unlinkat
+	.long sys_renameat		/* 295 */
+	.long sys_linkat
+	.long sys_symlinkat
+	.long sys_readlinkat
+	.long sys_fchmodat
+	.long sys_faccessat		/* 300 */
+	.long sys_pselect6
+	.long sys_ppoll
+	.long sys_unshare
+	.long sys_set_robust_list
+	.long sys_get_robust_list	/* 305 */
+	.long sys_splice
+	.long sys_sync_file_range
+	.long sys_tee
+	.long sys_vmsplice
+	.long sys_move_pages		/* 310 */
+	.long sys_sched_setaffinity
+	.long sys_sched_getaffinity
+	.long sys_kexec_load
+	.long sys_getcpu
+	.long sys_epoll_pwait		/* 315 */
+	.long sys_utimensat
+	.long sys_signalfd
+	.long sys_timerfd_create
+	.long sys_eventfd
+	.long sys_pread64		/* 320 */
+	.long sys_pwrite64
+	.long sys_fallocate
+	.long sys_timerfd_settime
+	.long sys_timerfd_gettime
+	.long sys_signalfd4		/* 325 */
+	.long sys_eventfd2
+	.long sys_epoll_create1
+	.long sys_dup3
+	.long sys_pipe2
+	.long sys_inotify_init1		/* 330 */
+	.long sys_preadv
+	.long sys_pwritev
+	.long sys_rt_sigqueueinfo
+	.long sys_perf_event_open
+
+	.rept NR_syscalls - 335
+		.long sys_ni_syscall
+	.endr
+
diff --git a/arch/nios2/kernel/time.c b/arch/nios2/kernel/time.c
new file mode 100644
index 0000000..2ec3266
--- /dev/null
+++ b/arch/nios2/kernel/time.c
@@ -0,0 +1,165 @@
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/profile.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/clocksource.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+
+#define	TICK_SIZE (tick_nsec / 1000)
+#define NIOS2_TIMER_PERIOD (TIMER_1MS_FREQ/HZ)
+
+#define ALTERA_TIMER_STATUS_REG              0
+#define ALTERA_TIMER_CONTROL_REG             4
+#define ALTERA_TIMER_PERIODL_REG             8
+#define ALTERA_TIMER_PERIODH_REG             12
+#define ALTERA_TIMER_SNAPL_REG               16
+#define ALTERA_TIMER_SNAPH_REG               20
+
+#define ALTERA_TIMER_CONTROL_ITO_MSK         (0x1)
+#define ALTERA_TIMER_CONTROL_CONT_MSK        (0x2)
+#define ALTERA_TIMER_CONTROL_START_MSK       (0x4)
+#define ALTERA_TIMER_CONTROL_STOP_MSK        (0x8)
+
+static unsigned long nios2_timer_count;
+static unsigned long timer_membase;
+
+static inline int set_rtc_mmss(unsigned long nowtime)
+{
+	return 0;
+}
+
+static inline unsigned long read_timersnapshot(void)
+{
+	unsigned long count;
+
+	outw(0, timer_membase + ALTERA_TIMER_SNAPL_REG);
+	count =
+	    inw(timer_membase + ALTERA_TIMER_SNAPH_REG) << 16 |
+	    inw(timer_membase + ALTERA_TIMER_SNAPL_REG);
+
+	return count;
+}
+
+static inline void write_timerperiod(unsigned long period)
+{
+	outw(period, timer_membase + ALTERA_TIMER_PERIODL_REG);
+	outw(period >> 16, timer_membase + ALTERA_TIMER_PERIODH_REG);
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+irqreturn_t timer_interrupt(int irq, void *dummy)
+{
+	/* last time the cmos clock got updated */
+	static long last_rtc_update = 0;
+
+	/* Clear the interrupt condition */
+	outw(0, timer_membase + ALTERA_TIMER_STATUS_REG);
+	nios2_timer_count += NIOS2_TIMER_PERIOD;
+
+	profile_tick(CPU_PROFILING);
+
+	write_seqlock(&xtime_lock);
+
+	do_timer(1);
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if (ntp_synced() &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2 &&
+	    (xtime.tv_nsec / 1000) <= 500000 + ((unsigned)TICK_SIZE) / 2) {
+		if (set_rtc_mmss(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else
+			last_rtc_update = xtime.tv_sec - 600;	/* do it again in 60 s */
+	}
+
+	write_sequnlock(&xtime_lock);
+
+#ifndef CONFIG_SMP
+	update_process_times(user_mode(get_irq_regs()));
+#endif
+
+	return (IRQ_HANDLED);
+}
+
+static cycle_t nios2_timer_read(struct clocksource *cs)
+{
+	unsigned long flags;
+	u32 cycles;
+	u32 tcn;
+
+	local_irq_save(flags);
+	tcn = NIOS2_TIMER_PERIOD - 1 - read_timersnapshot();
+	cycles = nios2_timer_count;
+	local_irq_restore(flags);
+
+	return cycles + tcn;
+}
+
+static struct clocksource nios2_timer = {
+	.name = "timer",
+	.rating = 250,
+	.read = nios2_timer_read,
+	.shift = 20,
+	.mask = CLOCKSOURCE_MASK(32),
+	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static struct irqaction nios2_timer_irq = {
+	.name = "timer",
+	.flags = IRQF_DISABLED | IRQF_TIMER,
+	.handler = timer_interrupt,
+};
+
+void __init nios2_late_time_init(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+	extern void arch_gettod(int *year, int *mon, int *day, int *hour,
+				int *min, int *sec);
+	unsigned ctrl;
+
+	arch_gettod(&year, &mon, &day, &hour, &min, &sec);
+
+	if ((year += 1900) < 1970)
+		year += 100;
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_nsec = 0;
+	wall_to_monotonic.tv_sec = -xtime.tv_sec;
+
+	timer_membase = (unsigned long)ioremap(TIMER_1MS_BASE, TIMER_1MS_SPAN);
+	setup_irq(TIMER_1MS_IRQ, &nios2_timer_irq);
+	write_timerperiod(NIOS2_TIMER_PERIOD - 1);
+
+	/* clocksource initialize */
+	nios2_timer.mult =
+	    clocksource_hz2mult(TIMER_1MS_FREQ, nios2_timer.shift);
+	clocksource_register(&nios2_timer);
+
+	/* interrupt enable + continuous + start */
+	ctrl =
+	    ALTERA_TIMER_CONTROL_ITO_MSK | ALTERA_TIMER_CONTROL_CONT_MSK |
+	    ALTERA_TIMER_CONTROL_START_MSK;
+	outw(ctrl, timer_membase + ALTERA_TIMER_CONTROL_REG);
+}
+
+extern void (*late_time_init)(void);
+void __init time_init(void)
+{
+	late_time_init = nios2_late_time_init;
+}
diff --git a/arch/nios2/kernel/traps.c b/arch/nios2/kernel/traps.c
new file mode 100644
index 0000000..137c71c
--- /dev/null
+++ b/arch/nios2/kernel/traps.c
@@ -0,0 +1,256 @@
+/*
+ * arch/niosnommu/kernel/traps.c
+ *
+ * Copyright 2004 Microtronix Datacom Ltd.
+ * Copyright 2001 Vic Phillips
+ * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * hacked from:
+ *
+ * arch/sparcnommu/kernel/traps.c
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/sched.h>  /* for jiffies */
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+
+#include <asm/delay.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/unistd.h>
+#include <linux/uaccess.h>
+
+#include <asm/nios.h>
+
+/* #define TRAP_DEBUG */
+
+/*
+ * The architecture-independent backtrace generator
+ */
+void dump_stack(void)
+{
+	unsigned long stack;
+
+	show_stack(current, &stack);
+}
+
+EXPORT_SYMBOL(dump_stack);
+
+/*
+ * The show_stack is an external API which we do not use ourselves.
+ * The oops is printed in die_if_kernel.
+ */
+
+int kstack_depth_to_print = 48;
+
+void show_stack(struct task_struct *task, unsigned long *stack)
+{
+	unsigned long *endstack, addr;
+	extern char _start, _etext;
+	int i;
+
+	if (!stack) {
+		if (task)
+			stack = (unsigned long *)task->thread.ksp;
+		else
+			stack = (unsigned long *)&stack;
+	}
+
+	addr = (unsigned long) stack;
+	endstack = (unsigned long *) PAGE_ALIGN(addr);
+
+	printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack);
+	for (i = 0; i < kstack_depth_to_print; i++) {
+		if (stack + 1 > endstack)
+			break;
+		if (i % 8 == 0)
+			printk(KERN_EMERG "\n       ");
+		printk(KERN_EMERG " %08lx", *stack++);
+	}
+
+	printk(KERN_EMERG "\nCall Trace:");
+	i = 0;
+	while (stack + 1 <= endstack) {
+		addr = *stack++;
+		/*
+		 * If the address is either in the text segment of the
+		 * kernel, or in the region which contains vmalloc'ed
+		 * memory, it *may* be the address of a calling
+		 * routine; if so, print it so that someone tracing
+		 * down the cause of the crash will be able to figure
+		 * out the call path that was taken.
+		 */
+		if (((addr >= (unsigned long) &_start) &&
+		     (addr <= (unsigned long) &_etext))) {
+			if (i % 4 == 0)
+				printk(KERN_EMERG "\n       ");
+			printk(KERN_EMERG " [<%08lx>]", addr);
+			i++;
+		}
+	}
+	printk(KERN_EMERG "\n");
+}
+
+void die_if_kernel(char *str, struct pt_regs *pregs)
+{
+	unsigned long pc;
+
+	pc = pregs->ra;
+	printk("0x%08lx\n trapped to die_if_kernel\n",pregs->ra);
+	show_regs(pregs);
+	add_taint(TAINT_DIE);
+	if(!user_mode(pregs))
+		do_exit(SIGKILL);
+	do_exit(SIGSEGV);
+}
+
+void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc)
+{
+	if(type < 0x10) {
+		printk("Unimplemented Nios2 TRAP, type = %02lx\n", type);
+		die_if_kernel("Whee... Hello Mr. Penguin", current->thread.kregs);
+	}	
+}
+
+void trap_init(void)
+{
+#ifdef DEBUG
+	printk("trap_init reached\n");
+#endif
+}
+
+/* Breakpoint handler */
+asmlinkage void breakpoint_c(struct pt_regs *fp)
+{
+	siginfo_t info;
+
+/* 	The breakpoint entry code has moved the PC on by 4 bytes, so we must */
+/* 	move it back.  This could be done on the host but we do it here */
+/* 	because monitor.S of JATG gdbserver does it. */
+	fp->ea -= 4;
+
+	//	printk("Breakpoint detected, instr=0x%08lx ea=0x%08lx ra=0x%08lx sp=0x%08lx\n", *(unsigned long*)fp->ea, fp->ea, fp->ra, fp->sp);
+	
+	info.si_code = TRAP_BRKPT;
+	info.si_signo = SIGTRAP;
+	info.si_errno = 0;
+	info.si_addr = (void *) fp->ea;
+
+	force_sig_info(info.si_signo, &info, current);
+}
+
+
+/* Alignment handler 
+ */
+asmlinkage void handle_unaligned_c(struct pt_regs *fp)
+{
+	siginfo_t info;
+   unsigned long addr = RDCTL(CTL_BADADDR);
+   int cause = RDCTL(CTL_EXCEPTION)/4;
+
+	fp->ea -= 4;
+
+	if (fixup_exception(fp, fp->ea)) {
+		return;
+	}
+
+   if(!user_mode(fp)) {
+      printk("Unaligned access from kernel mode, this might be a hardware\n");
+      printk("problem, dump registers and restart the instruction\n");
+      printk("  BADADDR 0x%08lx\n", addr);
+      printk("  cause   %d\n", cause);
+      printk("  op-code 0x%08lx\n", *(unsigned long*)(fp->ea));
+      show_regs(fp);
+      return;
+   }
+
+   //	printk("Unaligned access instr=0x%08lx addr=%#lx ea=0x%08lx ra=0x%08lx sp=0x%08lx\n", 
+   //   *(unsigned long*)fp->ea, addr, fp->ea, fp->ra, fp->sp);
+	
+	info.si_code = BUS_ADRALN;
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	info.si_addr = (void *) fp->ea;
+
+	force_sig_info(info.si_signo, &info, current);
+}
+
+/* Illegal instruction handler 
+ */
+asmlinkage void handle_illegal_c(struct pt_regs *fp)
+{
+	siginfo_t info;
+
+	fp->ea -= 4;
+
+	//	printk("Illegal instruction instr=0x%08lx ea=0x%08lx ra=0x%08lx sp=0x%08lx\n", 
+	//          *(unsigned long*)fp->ea, fp->ea, fp->ra, fp->sp);
+	
+	info.si_code = ILL_PRVOPC;
+	info.si_signo = SIGILL;
+	info.si_errno = 0;
+	info.si_addr = (void *) fp->ea;
+
+	force_sig_info(info.si_signo, &info, current);
+}
+
+/* Supervisor instruction handler 
+ */
+asmlinkage void handle_supervisor_instr(struct pt_regs *fp)
+{
+	siginfo_t info;
+
+	fp->ea -= 4;
+
+	//	printk("Supervisor instruction instr=0x%08lx ea=0x%08lx ra=0x%08lx sp=0x%08lx\n", 
+	//          *(unsigned long*)fp->ea, fp->ea, fp->ra, fp->sp);
+
+	info.si_code = ILL_PRVOPC;
+	info.si_signo = SIGILL;
+	info.si_errno = 0;
+	info.si_addr = (void *) fp->ea;
+
+	force_sig_info(info.si_signo, &info, current);
+}
+
+
+/* Illegal division error
+ */
+asmlinkage void handle_diverror_c(struct pt_regs *fp)
+{
+	siginfo_t info;
+
+	fp->ea -= 4;
+
+	//	printk("Division error instr=0x%08lx ea=0x%08lx ra=0x%08lx sp=0x%08lx\n", 
+	//          *(unsigned long*)fp->ea, fp->ea, fp->ra, fp->sp);
+	
+	info.si_code = FPE_INTDIV;
+	info.si_signo = SIGFPE;
+	info.si_errno = 0;
+	info.si_addr = (void *) fp->ea;
+
+	force_sig_info(info.si_signo, &info, current);
+}
diff --git a/arch/nios2/kernel/usb.c b/arch/nios2/kernel/usb.c
new file mode 100644
index 0000000..c9d8f25
--- /dev/null
+++ b/arch/nios2/kernel/usb.c
@@ -0,0 +1,341 @@
+/*
+ * arch/nios2nommu/kernel/usb.c -- platform level USB initialization
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#undef	DEBUG
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/nios.h>
+
+#if defined(CONFIG_USB_SL811_HCD) || defined (CONFIG_USB_SL811_HCD_MODULE)
+#if defined(CONFIG_MICROTRONIX_STRATIX) || defined (CONFIG_MICROTRONIX_CYCLONE)
+
+#include <linux/usb/sl811.h>
+#define SL811_ADDR ((unsigned int)na_usb)
+#define SL811_IRQ na_usb_irq
+
+static void sl811_port_power(struct device *dev, int is_on)
+{
+}
+
+static 	void sl811_port_reset(struct device *dev)
+{
+	writeb(0xA, (SL811_ADDR+8));
+	mdelay(10);
+	writeb(4, (SL811_ADDR+8));
+}
+
+static struct resource sl811hs_resources[] = {
+	{
+		.start	= (SL811_ADDR),
+		.end	= (SL811_ADDR + 3),
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= (SL811_ADDR + 4),
+		.end	= (SL811_ADDR + 7),
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= SL811_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct sl811_platform_data sl811_data = {
+	.can_wakeup =	0,
+	.potpg		=	0,
+	.power		=	250,
+	.port_power	=	sl811_port_power,
+	.reset		=	sl811_port_reset,
+};
+
+static struct platform_device sl811hs_device = {
+	.name			= "sl811-hcd",
+	.id			= -1,
+	.dev = {
+		//.release		= usb_release,
+		//.dma_mask		= &ohci_dmamask,
+		.coherent_dma_mask	= 0x0fffffff,
+		.platform_data = &sl811_data,
+	},
+	.num_resources	= ARRAY_SIZE(sl811hs_resources),
+	.resource		= sl811hs_resources,
+};
+
+
+static int __init mtx_kit_usb_init(void)
+{
+	int status;
+
+	status = platform_device_register(&sl811hs_device);
+	if (status) {
+		pr_debug("can't register sl811hs device, %d\n", status);
+		return -1;
+	}
+	
+	writeb(4, (SL811_ADDR+8));
+	return 0;
+}
+
+subsys_initcall(mtx_kit_usb_init);
+#endif /* (CONFIG_MICROTRONIX_STRATIX) || (CONFIG_MICROTRONIX_CYCLONE)*/
+#endif  /*(CONFIG_USB_SL811_HCD) ||(CONFIG_USB_SL811_HCD_MODULE) */
+
+#if defined(CONFIG_USB_ISP116X_HCD) || defined (CONFIG_USB_ISP116X_HCD_MODULE)
+
+#include <linux/usb/isp116x.h>
+
+#define ISP116X_HCD_ADDR ((unsigned int)na_usb)
+#define ISP116X_HCD_IRQ na_usb_irq
+
+static void isp116x_delay(struct device *dev, int delay)
+{
+	ndelay(delay);
+}
+
+static struct resource isp116x_hcd_resources[] = {
+	{
+		.start	= (ISP116X_HCD_ADDR),
+		.end	= (ISP116X_HCD_ADDR + 3),
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= (ISP116X_HCD_ADDR + 4),
+		.end	= (ISP116X_HCD_ADDR + 7),
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= ISP116X_HCD_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct isp116x_platform_data isp116x_data = {
+		// Enable internal resistors on downstream ports
+        .sel15Kres              = 1,
+        // On-chip overcurrent protection
+        .oc_enable              = 1,
+        // INT output polarity
+        .int_act_high           = 0,
+        // INT edge or level triggered
+        .int_edge_triggered     = 0,
+        // Wakeup by devices on usb bus enabled
+        .remote_wakeup_enable   = 0,
+        .delay                  = isp116x_delay,
+};
+
+static struct platform_device isp116x_hcd = {
+	.name			= "isp116x-hcd",
+	.id			= -1,
+	.dev = {
+		//.release		= usb_release,
+		//.dma_mask		= &ohci_dmamask,
+		.coherent_dma_mask	= 0x0fffffff,
+		.platform_data = &isp116x_data,
+	},
+	.num_resources	= ARRAY_SIZE(isp116x_hcd_resources),
+	.resource		= isp116x_hcd_resources,
+};
+
+static int __init usb_hcd_init(void)
+{
+	int status;
+
+	status = platform_device_register(&isp116x_hcd);
+	if (status) {
+		pr_debug("can't register isp116x host controller, %d\n", status);
+		return -1;
+	}
+	
+	return 0;
+}
+subsys_initcall(usb_hcd_init);
+#endif  /*(CONFIG_USB_ISP116X_HCD) ||(CONFIG_USB_ISP116X_HCD_MODULE) */
+
+#if defined(CONFIG_USB_ISP1161X) || defined(CONFIG_USB_ISP1161X_MODULE)
+#include <linux/usb_isp116x_dc.h>
+
+#define ISP116X_UDC_ADDR ((unsigned int)na_usb+8)
+#define ISP116X_UDC_IRQ	 na_int2_usb_irq
+
+static struct resource isp116x_udc_resources[] = {
+	{
+		.start	= (ISP116X_UDC_ADDR),
+		.end	= (ISP116X_UDC_ADDR + 3),
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= (ISP116X_UDC_ADDR + 4),
+		.end	= (ISP116X_UDC_ADDR + 7),
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= ISP116X_UDC_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+static void isp116x_udc_delay()
+{
+	__asm__ __volatile__(
+        "1:  \n\t"
+        "    beq    %0,zero,2f\n\t"
+        "    addi   %0, %0, -1\n\t" 
+        "    br     1b\n\t" 
+        "2:  \n\t" 
+        :
+        :  "r" (nasys_clock_freq_1000 * 180 / 2000000)
+        );
+	
+}
+struct isp116x_dc_platform_data isp116x_udc_data = {
+	.ext_pullup_enable	=0,
+	.no_lazy			=1,
+	.eot_act_high		=0,
+	.remote_wakeup_enable=1,
+	.power_off_enable	=1,
+	.int_edge_triggered	=0,
+	.int_act_high		=0,
+	.clkout_freq		=12,
+	.delay				= isp116x_udc_delay
+};
+
+static struct platform_device isp116x_udc = {
+	.name			= "isp1161a_udc",
+	.id			= -1,
+	.dev = {
+		//.release		= usb_release,
+		//.dma_mask		= &ohci_dmamask,
+		.coherent_dma_mask	= 0x0fffffff,
+		.platform_data = &isp116x_udc_data,
+	},
+	.num_resources	= ARRAY_SIZE(isp116x_udc_resources),
+	.resource		= isp116x_udc_resources,
+};
+
+static int __init usb_udc_init(void)
+{
+	int status;
+	np_pio* pio;
+
+	status = platform_device_register(&isp116x_udc);
+	if (status) {
+		pr_debug("can't register isp116x device controller, %d\n", status);
+		return -1;
+	}
+	
+	/* enable interrupts */
+	pio = (np_pio*)na_int2_usb;
+	//outw(0, &pio->np_piodata);
+	//outw(0, &pio->np_pioedgecapture);
+	outw(1, &pio->np_piointerruptmask);
+	
+	return 0;
+}
+subsys_initcall(usb_udc_init);
+#endif
+
+#if defined(na_ISP1362_avalonS)  // for DE2 dev board, FIX ME otehrwise
+#define na_usb na_ISP1362_avalonS
+#define na_usb_irq na_ISP1362_avalonS_irq
+#endif
+
+#if defined(na_ISP1362_avalon_slave_0)  // for DE2 dev board, FIX ME otehrwise
+#define na_usb na_ISP1362_avalon_slave_0
+#define na_usb_irq na_ISP1362_avalon_slave_0_irq
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) && defined(na_usb)
+
+#include <linux/usb/isp1362.h>
+#define ISP1362_HCD_ADDR ((unsigned int)na_usb)
+#define ISP1362_HCD_IRQ na_usb_irq
+
+static struct resource isp1362_hcd_resources[] = {
+	{
+		.start	= (ISP1362_HCD_ADDR),
+		.end	= (ISP1362_HCD_ADDR + 3),
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= (ISP1362_HCD_ADDR + 4),
+		.end	= (ISP1362_HCD_ADDR + 7),
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= ISP1362_HCD_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct isp1362_platform_data isp1362_data = {
+		// Enable internal resistors on downstream ports
+	.sel15Kres	= 1,
+        // Clock cannot be stopped
+	.clknotstop	= 0,
+        // On-chip overcurrent protection
+	.oc_enable	= 0,
+        // INT output polarity
+	.int_act_high	= 0,
+        // INT edge or level triggered
+	.int_edge_triggered	= 0,
+        // WAKEUP pin connected
+ 	.remote_wakeup_connected	= 0,
+        // Switch or not to switch (keep always powered)
+	.no_power_switching	= 1,
+        // Ganged port power switching (0) or individual port power switching (1)
+	.power_switching_mode	= 0,
+};
+
+static struct platform_device isp1362_hcd = {
+	.name			= "isp1362-hcd",
+	.id			= -1,
+	.dev = {
+		//.release		= usb_release,
+		//.dma_mask		= &ohci_dmamask,
+		.coherent_dma_mask	= 0x0fffffff,
+		.platform_data = &isp1362_data,
+	},
+	.num_resources	= ARRAY_SIZE(isp1362_hcd_resources),
+	.resource		= isp1362_hcd_resources,
+};
+
+static int __init usb_hcd_init(void)
+{
+	int status;
+
+	status = platform_device_register(&isp1362_hcd);
+	if (status) {
+		pr_debug("can't register isp1362 host controller, %d\n", status);
+		return -1;
+	}
+	
+	return 0;
+}
+subsys_initcall(usb_hcd_init);
+#endif
+
diff --git a/arch/nios2/kernel/vmlinux.lds.S b/arch/nios2/kernel/vmlinux.lds.S
new file mode 100644
index 0000000..b1f8204
--- /dev/null
+++ b/arch/nios2/kernel/vmlinux.lds.S
@@ -0,0 +1,50 @@
+#include <asm-generic/vmlinux.lds.h>
+#include <asm/cache.h>
+#include <asm/thread_info.h>
+#include <asm/nios.h>
+
+OUTPUT_FORMAT("elf32-littlenios2", "elf32-littlenios2", "elf32-littlenios2")
+
+OUTPUT_ARCH(nios)
+ENTRY(_start)	/* Defined in head.S */
+
+jiffies = jiffies_64;
+
+SECTIONS
+{
+	. = DDR2_TOP_BASE | KERNEL_REGION_BASE;
+
+	_text = .;
+	_stext = .;
+	HEAD_TEXT_SECTION
+	.text : {
+		TEXT_TEXT
+		SCHED_TEXT
+		LOCK_TEXT
+		IRQENTRY_TEXT
+		KPROBES_TEXT
+	} =0
+	_etext = .;
+
+	EXCEPTION_TABLE(L1_CACHE_BYTES)
+
+	__init_begin = .;
+	INIT_TEXT_SECTION(PAGE_SIZE)
+	INIT_DATA_SECTION(PAGE_SIZE)
+	PERCPU(PAGE_SIZE)
+	__init_end = .;
+
+        _sdata = .;
+	RO_DATA_SECTION(PAGE_SIZE)
+	RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+	_edata = .;
+
+	BSS_SECTION(0, 0, 0)
+	_end = .;
+
+	STABS_DEBUG
+	DWARF_DEBUG
+	NOTES
+
+	DISCARDS
+}
diff --git a/arch/nios2/lib/Makefile b/arch/nios2/lib/Makefile
new file mode 100644
index 0000000..dcc240c
--- /dev/null
+++ b/arch/nios2/lib/Makefile
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2005 Microtronix Datacom Ltd
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Library General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
+# details.
+
+####CSRC := $(wildcard *.c)
+####lib-y  =$(patsubst %.c,%.o, $(CSRC))
+####wapos!
+lib-y  =string.o memcpy.o
+lib-y += libgcc.o
diff --git a/arch/nios2/lib/checksum.c b/arch/nios2/lib/checksum.c
new file mode 100644
index 0000000..0747a98
--- /dev/null
+++ b/arch/nios2/lib/checksum.c
@@ -0,0 +1,73 @@
+/*--------------------------------------------------------------------
+ *
+ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al
+ *
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Jan/20/2004		dgt	    NiosII
+ *
+ ---------------------------------------------------------------------*/
+
+#include <net/checksum.h>
+#include <asm/checksum.h>
+
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+
+__wsum csum_partial(const void * buff, int len, __wsum sum)
+{
+#if 0
+	__asm__ __volatile__ ...//;dgt2;tmp;not (yet) available...
+                         ...//;dgt2;tmp;NiosI didn't offer either...
+#else
+	unsigned int result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	if (sum > result)
+		result += 1;
+	return result;
+#endif
+}
+
+
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+/*
+ * the same as csum_partial, but copies from fs:src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+__wsum csum_partial_copy(const void *src, void *dst, int len, __wsum sum)
+{
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+
+}
diff --git a/arch/nios2/lib/libgcc.c b/arch/nios2/lib/libgcc.c
new file mode 100644
index 0000000..af74c8e
--- /dev/null
+++ b/arch/nios2/lib/libgcc.c
@@ -0,0 +1,574 @@
+
+typedef unsigned int UWtype;
+typedef unsigned int UHWtype;
+typedef unsigned long long UDWtype;
+#define W_TYPE_SIZE 32
+
+typedef unsigned char UQItype;
+typedef long SItype;
+typedef unsigned long USItype;
+typedef long long DItype;
+typedef unsigned long long DSItype;
+
+#include "longlong.h"
+
+
+typedef int word_type;
+typedef long Wtype;
+typedef long long DWtype;
+
+struct DWstruct { Wtype low, high;};
+
+typedef union
+{
+  struct DWstruct s;
+  DWtype ll;
+} DWunion;
+
+#define BITS_PER_UNIT 8
+
+UDWtype
+__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp);
+
+const UQItype __clz_tab[256] =
+{
+  0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
+};
+
+
+DWtype
+__ashldi3 (DWtype u, word_type b)
+{
+  if (b == 0)
+    return u;
+
+  const DWunion uu = {.ll = u};
+  const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
+  DWunion w;
+
+  if (bm <= 0)
+    {
+      w.s.low = 0;
+      w.s.high = (UWtype) uu.s.low << -bm;
+    }
+  else
+    {
+      const UWtype carries = (UWtype) uu.s.low >> bm;
+
+      w.s.low = (UWtype) uu.s.low << b;
+      w.s.high = ((UWtype) uu.s.high << b) | carries;
+    }
+
+  return w.ll;
+}
+
+DWtype
+__ashrdi3 (DWtype u, word_type b)
+{
+  if (b == 0)
+    return u;
+
+  const DWunion uu = {.ll = u};
+  const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
+  DWunion w;
+
+  if (bm <= 0)
+    {
+      /* w.s.high = 1..1 or 0..0 */
+      w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
+      w.s.low = uu.s.high >> -bm;
+    }
+  else
+    {
+      const UWtype carries = (UWtype) uu.s.high << bm;
+
+      w.s.high = uu.s.high >> b;
+      w.s.low = ((UWtype) uu.s.low >> b) | carries;
+    }
+
+  return w.ll;
+}
+
+DWtype
+__lshrdi3 (DWtype u, word_type b)
+{
+  if (b == 0)
+    return u;
+
+  const DWunion uu = {.ll = u};
+  const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
+  DWunion w;
+
+  if (bm <= 0)
+    {
+      w.s.high = 0;
+      w.s.low = (UWtype) uu.s.high >> -bm;
+    }
+  else
+    {
+      const UWtype carries = (UWtype) uu.s.high << bm;
+
+      w.s.high = (UWtype) uu.s.high >> b;
+      w.s.low = ((UWtype) uu.s.low >> b) | carries;
+    }
+
+  return w.ll;
+}
+
+word_type
+__cmpdi2 (DWtype a, DWtype b)
+{
+  const DWunion au = {.ll = a};
+  const DWunion bu = {.ll = b};
+
+  if (au.s.high < bu.s.high)
+    return 0;
+  else if (au.s.high > bu.s.high)
+    return 2;
+  if ((UWtype) au.s.low < (UWtype) bu.s.low)
+    return 0;
+  else if ((UWtype) au.s.low > (UWtype) bu.s.low)
+    return 2;
+  return 1;
+}
+
+UDWtype
+__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
+{
+  const DWunion nn = {.ll = n};
+  const DWunion dd = {.ll = d};
+  DWunion rr;
+  UWtype d0, d1, n0, n1, n2;
+  UWtype q0, q1;
+  UWtype b, bm;
+
+  d0 = dd.s.low;
+  d1 = dd.s.high;
+  n0 = nn.s.low;
+  n1 = nn.s.high;
+
+#if !UDIV_NEEDS_NORMALIZATION
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+	  q1 = 0;
+
+	  /* Remainder in n0.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  udiv_qrnnd (q1, n1, 0, n1, d0);
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0.  */
+	}
+
+      if (rp != 0)
+	{
+	  rr.s.low = n0;
+	  rr.s.high = 0;
+	  *rp = rr.ll;
+	}
+    }
+
+#else /* UDIV_NEEDS_NORMALIZATION */
+
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm != 0)
+	    {
+	      /* Normalize, i.e. make the most significant bit of the
+		 denominator set.  */
+
+	      d0 = d0 << bm;
+	      n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
+	      n0 = n0 << bm;
+	    }
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+	  q1 = 0;
+
+	  /* Remainder in n0 >> bm.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 leading quotient digit q1 = 1).
+
+		 This special case is necessary, not an optimization.
+		 (Shifts counts of W_TYPE_SIZE are undefined.)  */
+
+	      n1 -= d0;
+	      q1 = 1;
+	    }
+	  else
+	    {
+	      /* Normalize.  */
+
+	      b = W_TYPE_SIZE - bm;
+
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd (q1, n1, n2, n1, d0);
+	    }
+
+	  /* n1 != d0...  */
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0 >> bm.  */
+	}
+
+      if (rp != 0)
+	{
+	  rr.s.low = n0 >> bm;
+	  rr.s.high = 0;
+	  *rp = rr.ll;
+	}
+    }
+#endif /* UDIV_NEEDS_NORMALIZATION */
+
+  else
+    {
+      if (d1 > n1)
+	{
+	  /* 00 = nn / DD */
+
+	  q0 = 0;
+	  q1 = 0;
+
+	  /* Remainder in n1n0.  */
+	  if (rp != 0)
+	    {
+	      rr.s.low = n0;
+	      rr.s.high = n1;
+	      *rp = rr.ll;
+	    }
+	}
+      else
+	{
+	  /* 0q = NN / dd */
+
+	  count_leading_zeros (bm, d1);
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 quotient digit q0 = 0 or 1).
+
+		 This special case is necessary, not an optimization.  */
+
+	      /* The condition on the next line takes advantage of that
+		 n1 >= d1 (true due to program flow).  */
+	      if (n1 > d1 || n0 >= d0)
+		{
+		  q0 = 1;
+		  sub_ddmmss (n1, n0, n1, n0, d1, d0);
+		}
+	      else
+		q0 = 0;
+
+	      q1 = 0;
+
+	      if (rp != 0)
+		{
+		  rr.s.low = n0;
+		  rr.s.high = n1;
+		  *rp = rr.ll;
+		}
+	    }
+	  else
+	    {
+	      UWtype m1, m0;
+	      /* Normalize.  */
+
+	      b = W_TYPE_SIZE - bm;
+
+	      d1 = (d1 << bm) | (d0 >> b);
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd (q0, n1, n2, n1, d1);
+	      umul_ppmm (m1, m0, q0, d0);
+
+	      if (m1 > n1 || (m1 == n1 && m0 > n0))
+		{
+		  q0--;
+		  sub_ddmmss (m1, m0, m1, m0, d1, d0);
+		}
+
+	      q1 = 0;
+
+	      /* Remainder in (n1n0 - m1m0) >> bm.  */
+	      if (rp != 0)
+		{
+		  sub_ddmmss (n1, n0, n1, n0, m1, m0);
+		  rr.s.low = (n1 << b) | (n0 >> bm);
+		  rr.s.high = n1 >> bm;
+		  *rp = rr.ll;
+		}
+	    }
+	}
+    }
+
+  const DWunion ww = {{.low = q0, .high = q1}};
+  return ww.ll;
+}
+
+DWtype
+__divdi3 (DWtype u, DWtype v)
+{
+  word_type c = 0;
+  DWunion uu = {.ll = u};
+  DWunion vv = {.ll = v};
+  DWtype w;
+
+  if (uu.s.high < 0)
+    c = ~c,
+    uu.ll = -uu.ll;
+  if (vv.s.high < 0)
+    c = ~c,
+    vv.ll = -vv.ll;
+
+  w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
+  if (c)
+    w = -w;
+
+  return w;
+}
+
+DWtype
+__negdi2 (DWtype u)
+{
+  const DWunion uu = {.ll = u};
+  const DWunion w = { {.low = -uu.s.low,
+		       .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } };
+
+  return w.ll;
+}
+
+
+DWtype
+__muldi3 (DWtype u, DWtype v)
+{
+  const DWunion uu = {.ll = u};
+  const DWunion vv = {.ll = v};
+  DWunion  w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
+  
+  w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
+  + (UWtype) uu.s.high * (UWtype) vv.s.low);
+  
+  return w.ll;
+}
+
+DWtype
+__moddi3 (DWtype u, DWtype v)
+{
+  word_type c = 0;
+  DWunion uu = {.ll = u};
+  DWunion vv = {.ll = v};
+  DWtype w;
+
+  if (uu.s.high < 0)
+    c = ~c,
+    uu.ll = -uu.ll;
+  if (vv.s.high < 0)
+    vv.ll = -vv.ll;
+
+  (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w);
+  if (c)
+    w = -w;
+
+  return w;
+}
+
+word_type
+__ucmpdi2 (DWtype a, DWtype b)
+{
+  const DWunion au = {.ll = a};
+  const DWunion bu = {.ll = b};
+
+  if ((UWtype) au.s.high < (UWtype) bu.s.high)
+    return 0;
+  else if ((UWtype) au.s.high > (UWtype) bu.s.high)
+    return 2;
+  if ((UWtype) au.s.low < (UWtype) bu.s.low)
+    return 0;
+  else if ((UWtype) au.s.low > (UWtype) bu.s.low)
+    return 2;
+  return 1;
+}
+
+
+UDWtype
+__udivdi3 (UDWtype n, UDWtype d)
+{
+  return __udivmoddi4 (n, d, (UDWtype *) 0);
+}
+
+UDWtype
+__umoddi3 (UDWtype u, UDWtype v)
+{
+  UDWtype w;
+  (void) __udivmoddi4 (u, v, &w);
+
+  return w;
+}
+
+static USItype
+udivmodsi4(USItype num, USItype den, word_type modwanted)
+{
+  USItype bit = 1;
+  USItype res = 0;
+
+  while (den < num && bit && !(den & (1L<<31)))
+    {
+      den <<=1;
+      bit <<=1;
+    }
+  while (bit)
+    {
+      if (num >= den)
+	{
+	  num -= den;
+	  res |= bit;
+	}
+      bit >>=1;
+      den >>=1;
+    }
+  if (modwanted) return num;
+  return res;
+}
+
+SItype
+__divsi3 (SItype a, SItype b)
+{
+  word_type neg = 0;
+  SItype res;
+
+  if (a < 0)
+    {
+      a = -a;
+      neg = !neg;
+    }
+
+  if (b < 0)
+    {
+      b = -b;
+      neg = !neg;
+    }
+
+  res = udivmodsi4 (a, b, 0);
+
+  if (neg)
+    res = -res;
+
+  return res;
+}
+
+
+SItype
+__udivsi3 (SItype a, SItype b)
+{
+  return udivmodsi4 (a, b, 0);
+}
+
+
+SItype
+__modsi3 (SItype a, SItype b)
+{
+  word_type neg = 0;
+  SItype res;
+
+  if (a < 0)
+    {
+      a = -a;
+      neg = 1;
+    }
+
+  if (b < 0)
+    b = -b;
+
+  res = udivmodsi4 (a, b, 1);
+
+  if (neg)
+    res = -res;
+
+  return res;
+}
+
+SItype
+__mulsi3 (SItype a, SItype b)
+{
+  SItype res = 0;
+  USItype cnt = a;
+
+  while (cnt)
+    {
+      if (cnt & 1)
+        {
+	  res += b;	  
+	}
+      b <<= 1;
+      cnt >>= 1;
+    }
+    
+  return res;
+}
+
+SItype
+__umodsi3 (SItype a, SItype b)
+
+{  
+  return udivmodsi4 (a, b, 1);
+}
+
+int
+__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, unsigned long size)
+{
+  while (size > 0)
+    {
+      const unsigned char c1 = *s1++, c2 = *s2++;
+      if (c1 != c2)
+	return c1 - c2;
+      size--;
+    }
+  return 0;
+}
diff --git a/arch/nios2/lib/longlong.h b/arch/nios2/lib/longlong.h
new file mode 100644
index 0000000..9c3963e
--- /dev/null
+++ b/arch/nios2/lib/longlong.h
@@ -0,0 +1,1365 @@
+/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
+   Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004,
+   2005  Free Software Foundation, Inc.
+
+   This definition file is free software; you can redistribute it
+   and/or modify it under the terms of the GNU General Public
+   License as published by the Free Software Foundation; either
+   version 2, or (at your option) any later version.
+
+   This definition file is distributed in the hope that it will be
+   useful, but WITHOUT ANY WARRANTY; without even the implied
+   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* You have to define the following before including this file:
+
+   UWtype -- An unsigned type, default type for operations (typically a "word")
+   UHWtype -- An unsigned type, at least half the size of UWtype.
+   UDWtype -- An unsigned type, at least twice as large a UWtype
+   W_TYPE_SIZE -- size in bits of UWtype
+
+   UQItype -- Unsigned 8 bit type.
+   SItype, USItype -- Signed and unsigned 32 bit types.
+   DItype, UDItype -- Signed and unsigned 64 bit types.
+
+   On a 32 bit machine UWtype should typically be USItype;
+   on a 64 bit machine, UWtype should typically be UDItype.  */
+
+#define __BITS4 (W_TYPE_SIZE / 4)
+#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
+
+#ifndef W_TYPE_SIZE
+#define W_TYPE_SIZE	32
+#define UWtype		USItype
+#define UHWtype		USItype
+#define UDWtype		UDItype
+#endif
+
+extern const UQItype __clz_tab[256];
+
+/* Define auxiliary asm macros.
+
+   1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two
+   UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype
+   word product in HIGH_PROD and LOW_PROD.
+
+   2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
+   UDWtype product.  This is just a variant of umul_ppmm.
+
+   3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+   denominator) divides a UDWtype, composed by the UWtype integers
+   HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
+   in QUOTIENT and the remainder in REMAINDER.  HIGH_NUMERATOR must be less
+   than DENOMINATOR for correct operation.  If, in addition, the most
+   significant bit of DENOMINATOR must be 1, then the pre-processor symbol
+   UDIV_NEEDS_NORMALIZATION is defined to 1.
+
+   4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+   denominator).  Like udiv_qrnnd but the numbers are signed.  The quotient
+   is rounded towards 0.
+
+   5) count_leading_zeros(count, x) counts the number of zero-bits from the
+   msb to the first nonzero bit in the UWtype X.  This is the number of
+   steps X needs to be shifted left to set the msb.  Undefined for X == 0,
+   unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
+
+   6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
+   from the least significant end.
+
+   7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+   high_addend_2, low_addend_2) adds two UWtype integers, composed by
+   HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
+   respectively.  The result is placed in HIGH_SUM and LOW_SUM.  Overflow
+   (i.e. carry out) is not stored anywhere, and is lost.
+
+   8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
+   high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
+   composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
+   LOW_SUBTRAHEND_2 respectively.  The result is placed in HIGH_DIFFERENCE
+   and LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
+   and is lost.
+
+   If any of these macros are left undefined for a particular CPU,
+   C macros are used.  */
+
+/* The CPUs come in alphabetical order below.
+
+   Please add support for more CPUs here, or improve the current support
+   for the CPUs below!
+   (E.g. WE32100, IBM360.)  */
+
+#if defined (__GNUC__) && !defined (NO_ASM)
+
+/* We sometimes need to clobber "cc" with gcc2, but that would not be
+   understood by gcc1.  Use cpp to avoid major code duplication.  */
+#if __GNUC__ < 2
+#define __CLOBBER_CC
+#define __AND_CLOBBER_CC
+#else /* __GNUC__ >= 2 */
+#define __CLOBBER_CC : "cc"
+#define __AND_CLOBBER_CC , "cc"
+#endif /* __GNUC__ < 2 */
+
+#if defined (__alpha) && W_TYPE_SIZE == 64
+#define umul_ppmm(ph, pl, m0, m1) \
+  do {									\
+    UDItype __m0 = (m0), __m1 = (m1);					\
+    (ph) = __builtin_alpha_umulh (__m0, __m1);				\
+    (pl) = __m0 * __m1;							\
+  } while (0)
+#define UMUL_TIME 46
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+  do { UDItype __r;							\
+    (q) = __udiv_qrnnd (&__r, (n1), (n0), (d));				\
+    (r) = __r;								\
+  } while (0)
+extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype);
+#define UDIV_TIME 220
+#endif /* LONGLONG_STANDALONE */
+#ifdef __alpha_cix__
+#define count_leading_zeros(COUNT,X)	((COUNT) = __builtin_clzl (X))
+#define count_trailing_zeros(COUNT,X)	((COUNT) = __builtin_ctzl (X))
+#define COUNT_LEADING_ZEROS_0 64
+#else
+#define count_leading_zeros(COUNT,X) \
+  do {									\
+    UDItype __xr = (X), __t, __a;					\
+    __t = __builtin_alpha_cmpbge (0, __xr);				\
+    __a = __clz_tab[__t ^ 0xff] - 1;					\
+    __t = __builtin_alpha_extbl (__xr, __a);				\
+    (COUNT) = 64 - (__clz_tab[__t] + __a*8);				\
+  } while (0)
+#define count_trailing_zeros(COUNT,X) \
+  do {									\
+    UDItype __xr = (X), __t, __a;					\
+    __t = __builtin_alpha_cmpbge (0, __xr);				\
+    __t = ~__t & -~__t;							\
+    __a = ((__t & 0xCC) != 0) * 2;					\
+    __a += ((__t & 0xF0) != 0) * 4;					\
+    __a += ((__t & 0xAA) != 0);						\
+    __t = __builtin_alpha_extbl (__xr, __a);				\
+    __a <<= 3;								\
+    __t &= -__t;							\
+    __a += ((__t & 0xCC) != 0) * 2;					\
+    __a += ((__t & 0xF0) != 0) * 4;					\
+    __a += ((__t & 0xAA) != 0);						\
+    (COUNT) = __a;							\
+  } while (0)
+#endif /* __alpha_cix__ */
+#endif /* __alpha */
+
+#if defined (__arc__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("add.f	%1, %4, %5\n\tadc	%0, %2, %3"		\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "%r" ((USItype) (ah)),					\
+	     "rIJ" ((USItype) (bh)),					\
+	     "%r" ((USItype) (al)),					\
+	     "rIJ" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("sub.f	%1, %4, %5\n\tsbc	%0, %2, %3"		\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "r" ((USItype) (ah)),					\
+	     "rIJ" ((USItype) (bh)),					\
+	     "r" ((USItype) (al)),					\
+	     "rIJ" ((USItype) (bl)))
+/* Call libgcc routine.  */
+#define umul_ppmm(w1, w0, u, v) \
+do {									\
+  DWunion __w;								\
+  __w.ll = __umulsidi3 (u, v);						\
+  w1 = __w.s.high;							\
+  w0 = __w.s.low;							\
+} while (0)
+#define __umulsidi3 __umulsidi3
+UDItype __umulsidi3 (USItype, USItype);
+#endif
+
+#if defined (__arm__) && !defined (__thumb__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("adds	%1, %4, %5\n\tadc	%0, %2, %3"		\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "%r" ((USItype) (ah)),					\
+	     "rI" ((USItype) (bh)),					\
+	     "%r" ((USItype) (al)),					\
+	     "rI" ((USItype) (bl)) __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("subs	%1, %4, %5\n\tsbc	%0, %2, %3"		\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "r" ((USItype) (ah)),					\
+	     "rI" ((USItype) (bh)),					\
+	     "r" ((USItype) (al)),					\
+	     "rI" ((USItype) (bl)) __CLOBBER_CC)
+#define umul_ppmm(xh, xl, a, b) \
+{register USItype __t0, __t1, __t2;					\
+  __asm__ ("%@ Inlined umul_ppmm\n"					\
+	   "	mov	%2, %5, lsr #16\n"				\
+	   "	mov	%0, %6, lsr #16\n"				\
+	   "	bic	%3, %5, %2, lsl #16\n"				\
+	   "	bic	%4, %6, %0, lsl #16\n"				\
+	   "	mul	%1, %3, %4\n"					\
+	   "	mul	%4, %2, %4\n"					\
+	   "	mul	%3, %0, %3\n"					\
+	   "	mul	%0, %2, %0\n"					\
+	   "	adds	%3, %4, %3\n"					\
+	   "	addcs	%0, %0, #65536\n"				\
+	   "	adds	%1, %1, %3, lsl #16\n"				\
+	   "	adc	%0, %0, %3, lsr #16"				\
+	   : "=&r" ((USItype) (xh)),					\
+	     "=r" ((USItype) (xl)),					\
+	     "=&r" (__t0), "=&r" (__t1), "=r" (__t2)			\
+	   : "r" ((USItype) (a)),					\
+	     "r" ((USItype) (b)) __CLOBBER_CC );}
+#define UMUL_TIME 20
+#define UDIV_TIME 100
+#endif /* __arm__ */
+
+#if defined (__hppa) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0"				\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "%rM" ((USItype) (ah)),					\
+	     "rM" ((USItype) (bh)),					\
+	     "%rM" ((USItype) (al)),					\
+	     "rM" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0"				\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "rM" ((USItype) (ah)),					\
+	     "rM" ((USItype) (bh)),					\
+	     "rM" ((USItype) (al)),					\
+	     "rM" ((USItype) (bl)))
+#if defined (_PA_RISC1_1)
+#define umul_ppmm(w1, w0, u, v) \
+  do {									\
+    union								\
+      {									\
+	UDItype __f;							\
+	struct {USItype __w1, __w0;} __w1w0;				\
+      } __t;								\
+    __asm__ ("xmpyu %1,%2,%0"						\
+	     : "=x" (__t.__f)						\
+	     : "x" ((USItype) (u)),					\
+	       "x" ((USItype) (v)));					\
+    (w1) = __t.__w1w0.__w1;						\
+    (w0) = __t.__w1w0.__w0;						\
+     } while (0)
+#define UMUL_TIME 8
+#else
+#define UMUL_TIME 30
+#endif
+#define UDIV_TIME 40
+#define count_leading_zeros(count, x) \
+  do {									\
+    USItype __tmp;							\
+    __asm__ (								\
+       "ldi		1,%0\n"						\
+"	extru,=		%1,15,16,%%r0		; Bits 31..16 zero?\n"	\
+"	extru,tr	%1,15,16,%1		; No.  Shift down, skip add.\n"\
+"	ldo		16(%0),%0		; Yes.  Perform add.\n"	\
+"	extru,=		%1,23,8,%%r0		; Bits 15..8 zero?\n"	\
+"	extru,tr	%1,23,8,%1		; No.  Shift down, skip add.\n"\
+"	ldo		8(%0),%0		; Yes.  Perform add.\n"	\
+"	extru,=		%1,27,4,%%r0		; Bits 7..4 zero?\n"	\
+"	extru,tr	%1,27,4,%1		; No.  Shift down, skip add.\n"\
+"	ldo		4(%0),%0		; Yes.  Perform add.\n"	\
+"	extru,=		%1,29,2,%%r0		; Bits 3..2 zero?\n"	\
+"	extru,tr	%1,29,2,%1		; No.  Shift down, skip add.\n"\
+"	ldo		2(%0),%0		; Yes.  Perform add.\n"	\
+"	extru		%1,30,1,%1		; Extract bit 1.\n"	\
+"	sub		%0,%1,%0		; Subtract it.\n"	\
+	: "=r" (count), "=r" (__tmp) : "1" (x));			\
+  } while (0)
+#endif
+
+#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32
+#define smul_ppmm(xh, xl, m0, m1) \
+  do {									\
+    union {DItype __ll;							\
+	   struct {USItype __h, __l;} __i;				\
+	  } __x;							\
+    __asm__ ("lr %N0,%1\n\tmr %0,%2"					\
+	     : "=&r" (__x.__ll)						\
+	     : "r" (m0), "r" (m1));					\
+    (xh) = __x.__i.__h; (xl) = __x.__i.__l;				\
+  } while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+  do {									\
+    union {DItype __ll;							\
+	   struct {USItype __h, __l;} __i;				\
+	  } __x;							\
+    __x.__i.__h = n1; __x.__i.__l = n0;					\
+    __asm__ ("dr %0,%2"							\
+	     : "=r" (__x.__ll)						\
+	     : "0" (__x.__ll), "r" (d));				\
+    (q) = __x.__i.__l; (r) = __x.__i.__h;				\
+  } while (0)
+#endif
+
+#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("addl %5,%1\n\tadcl %3,%0"					\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "%0" ((USItype) (ah)),					\
+	     "g" ((USItype) (bh)),					\
+	     "%1" ((USItype) (al)),					\
+	     "g" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("subl %5,%1\n\tsbbl %3,%0"					\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "0" ((USItype) (ah)),					\
+	     "g" ((USItype) (bh)),					\
+	     "1" ((USItype) (al)),					\
+	     "g" ((USItype) (bl)))
+#define umul_ppmm(w1, w0, u, v) \
+  __asm__ ("mull %3"							\
+	   : "=a" ((USItype) (w0)),					\
+	     "=d" ((USItype) (w1))					\
+	   : "%0" ((USItype) (u)),					\
+	     "rm" ((USItype) (v)))
+#define udiv_qrnnd(q, r, n1, n0, dv) \
+  __asm__ ("divl %4"							\
+	   : "=a" ((USItype) (q)),					\
+	     "=d" ((USItype) (r))					\
+	   : "0" ((USItype) (n0)),					\
+	     "1" ((USItype) (n1)),					\
+	     "rm" ((USItype) (dv)))
+#define count_leading_zeros(count, x) \
+  do {									\
+    USItype __cbtmp;							\
+    __asm__ ("bsrl %1,%0"						\
+	     : "=r" (__cbtmp) : "rm" ((USItype) (x)));			\
+    (count) = __cbtmp ^ 31;						\
+  } while (0)
+#define count_trailing_zeros(count, x) \
+  __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
+#define UMUL_TIME 40
+#define UDIV_TIME 40
+#endif /* 80x86 */
+
+#if defined (__i960__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+  ({union {UDItype __ll;						\
+	   struct {USItype __l, __h;} __i;				\
+	  } __xx;							\
+  __asm__ ("emul	%2,%1,%0"					\
+	   : "=d" (__xx.__ll)						\
+	   : "%dI" ((USItype) (u)),					\
+	     "dI" ((USItype) (v)));					\
+  (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define __umulsidi3(u, v) \
+  ({UDItype __w;							\
+    __asm__ ("emul	%2,%1,%0"					\
+	     : "=d" (__w)						\
+	     : "%dI" ((USItype) (u)),					\
+	       "dI" ((USItype) (v)));					\
+    __w; })
+#endif /* __i960__ */
+
+#if defined (__M32R__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  /* The cmp clears the condition bit.  */ \
+  __asm__ ("cmp %0,%0\n\taddx %1,%5\n\taddx %0,%3"			\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "0" ((USItype) (ah)),					\
+	     "r" ((USItype) (bh)),					\
+	     "1" ((USItype) (al)),					\
+	     "r" ((USItype) (bl))					\
+	   : "cbit")
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  /* The cmp clears the condition bit.  */ \
+  __asm__ ("cmp %0,%0\n\tsubx %1,%5\n\tsubx %0,%3"			\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "0" ((USItype) (ah)),					\
+	     "r" ((USItype) (bh)),					\
+	     "1" ((USItype) (al)),					\
+	     "r" ((USItype) (bl))					\
+	   : "cbit")
+#endif /* __M32R__ */
+
+#if defined (__mc68000__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0"				\
+	   : "=d" ((USItype) (sh)),					\
+	     "=&d" ((USItype) (sl))					\
+	   : "%0" ((USItype) (ah)),					\
+	     "d" ((USItype) (bh)),					\
+	     "%1" ((USItype) (al)),					\
+	     "g" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0"				\
+	   : "=d" ((USItype) (sh)),					\
+	     "=&d" ((USItype) (sl))					\
+	   : "0" ((USItype) (ah)),					\
+	     "d" ((USItype) (bh)),					\
+	     "1" ((USItype) (al)),					\
+	     "g" ((USItype) (bl)))
+
+/* The '020, '030, '040, '060 and CPU32 have 32x32->64 and 64/32->32q-32r.  */
+#if (defined (__mc68020__) && !defined (__mc68060__))
+#define umul_ppmm(w1, w0, u, v) \
+  __asm__ ("mulu%.l %3,%1:%0"						\
+	   : "=d" ((USItype) (w0)),					\
+	     "=d" ((USItype) (w1))					\
+	   : "%0" ((USItype) (u)),					\
+	     "dmi" ((USItype) (v)))
+#define UMUL_TIME 45
+#define udiv_qrnnd(q, r, n1, n0, d) \
+  __asm__ ("divu%.l %4,%1:%0"						\
+	   : "=d" ((USItype) (q)),					\
+	     "=d" ((USItype) (r))					\
+	   : "0" ((USItype) (n0)),					\
+	     "1" ((USItype) (n1)),					\
+	     "dmi" ((USItype) (d)))
+#define UDIV_TIME 90
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+  __asm__ ("divs%.l %4,%1:%0"						\
+	   : "=d" ((USItype) (q)),					\
+	     "=d" ((USItype) (r))					\
+	   : "0" ((USItype) (n0)),					\
+	     "1" ((USItype) (n1)),					\
+	     "dmi" ((USItype) (d)))
+
+#elif defined (__mcoldfire__) /* not mc68020 */
+
+#define umul_ppmm(xh, xl, a, b) \
+  __asm__ ("| Inlined umul_ppmm\n"					\
+	   "	move%.l	%2,%/d0\n"					\
+	   "	move%.l	%3,%/d1\n"					\
+	   "	move%.l	%/d0,%/d2\n"					\
+	   "	swap	%/d0\n"						\
+	   "	move%.l	%/d1,%/d3\n"					\
+	   "	swap	%/d1\n"						\
+	   "	move%.w	%/d2,%/d4\n"					\
+	   "	mulu	%/d3,%/d4\n"					\
+	   "	mulu	%/d1,%/d2\n"					\
+	   "	mulu	%/d0,%/d3\n"					\
+	   "	mulu	%/d0,%/d1\n"					\
+	   "	move%.l	%/d4,%/d0\n"					\
+	   "	clr%.w	%/d0\n"						\
+	   "	swap	%/d0\n"						\
+	   "	add%.l	%/d0,%/d2\n"					\
+	   "	add%.l	%/d3,%/d2\n"					\
+	   "	jcc	1f\n"						\
+	   "	add%.l	%#65536,%/d1\n"					\
+	   "1:	swap	%/d2\n"						\
+	   "	moveq	%#0,%/d0\n"					\
+	   "	move%.w	%/d2,%/d0\n"					\
+	   "	move%.w	%/d4,%/d2\n"					\
+	   "	move%.l	%/d2,%1\n"					\
+	   "	add%.l	%/d1,%/d0\n"					\
+	   "	move%.l	%/d0,%0"					\
+	   : "=g" ((USItype) (xh)),					\
+	     "=g" ((USItype) (xl))					\
+	   : "g" ((USItype) (a)),					\
+	     "g" ((USItype) (b))					\
+	   : "d0", "d1", "d2", "d3", "d4")
+#define UMUL_TIME 100
+#define UDIV_TIME 400
+#else /* not ColdFire */
+/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX.  */
+#define umul_ppmm(xh, xl, a, b) \
+  __asm__ ("| Inlined umul_ppmm\n"					\
+	   "	move%.l	%2,%/d0\n"					\
+	   "	move%.l	%3,%/d1\n"					\
+	   "	move%.l	%/d0,%/d2\n"					\
+	   "	swap	%/d0\n"						\
+	   "	move%.l	%/d1,%/d3\n"					\
+	   "	swap	%/d1\n"						\
+	   "	move%.w	%/d2,%/d4\n"					\
+	   "	mulu	%/d3,%/d4\n"					\
+	   "	mulu	%/d1,%/d2\n"					\
+	   "	mulu	%/d0,%/d3\n"					\
+	   "	mulu	%/d0,%/d1\n"					\
+	   "	move%.l	%/d4,%/d0\n"					\
+	   "	eor%.w	%/d0,%/d0\n"					\
+	   "	swap	%/d0\n"						\
+	   "	add%.l	%/d0,%/d2\n"					\
+	   "	add%.l	%/d3,%/d2\n"					\
+	   "	jcc	1f\n"						\
+	   "	add%.l	%#65536,%/d1\n"					\
+	   "1:	swap	%/d2\n"						\
+	   "	moveq	%#0,%/d0\n"					\
+	   "	move%.w	%/d2,%/d0\n"					\
+	   "	move%.w	%/d4,%/d2\n"					\
+	   "	move%.l	%/d2,%1\n"					\
+	   "	add%.l	%/d1,%/d0\n"					\
+	   "	move%.l	%/d0,%0"					\
+	   : "=g" ((USItype) (xh)),					\
+	     "=g" ((USItype) (xl))					\
+	   : "g" ((USItype) (a)),					\
+	     "g" ((USItype) (b))					\
+	   : "d0", "d1", "d2", "d3", "d4")
+#define UMUL_TIME 100
+#define UDIV_TIME 400
+
+#endif /* not mc68020 */
+
+/* The '020, '030, '040 and '060 have bitfield insns.
+   cpu32 disguises as a 68020, but lacks them.  */
+#if defined (__mc68020__) && !defined (__mcpu32__)
+#define count_leading_zeros(count, x) \
+  __asm__ ("bfffo %1{%b2:%b2},%0"					\
+	   : "=d" ((USItype) (count))					\
+	   : "od" ((USItype) (x)), "n" (0))
+/* Some ColdFire architectures have a ff1 instruction supported via
+   __builtin_clz. */
+#elif defined (__mcfisaaplus__) || defined (__mcfisac__)
+#define count_leading_zeros(count,x) ((count) = __builtin_clz (x))
+#define COUNT_LEADING_ZEROS_0 32
+#endif
+#endif /* mc68000 */
+
+#if defined (__m88000__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3"			\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "%rJ" ((USItype) (ah)),					\
+	     "rJ" ((USItype) (bh)),					\
+	     "%rJ" ((USItype) (al)),					\
+	     "rJ" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3"			\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "rJ" ((USItype) (ah)),					\
+	     "rJ" ((USItype) (bh)),					\
+	     "rJ" ((USItype) (al)),					\
+	     "rJ" ((USItype) (bl)))
+#define count_leading_zeros(count, x) \
+  do {									\
+    USItype __cbtmp;							\
+    __asm__ ("ff1 %0,%1"						\
+	     : "=r" (__cbtmp)						\
+	     : "r" ((USItype) (x)));					\
+    (count) = __cbtmp ^ 31;						\
+  } while (0)
+#define COUNT_LEADING_ZEROS_0 63 /* sic */
+#if defined (__mc88110__)
+#define umul_ppmm(wh, wl, u, v) \
+  do {									\
+    union {UDItype __ll;						\
+	   struct {USItype __h, __l;} __i;				\
+	  } __xx;							\
+    __asm__ ("mulu.d	%0,%1,%2"					\
+	     : "=r" (__xx.__ll)						\
+	     : "r" ((USItype) (u)),					\
+	       "r" ((USItype) (v)));					\
+    (wh) = __xx.__i.__h;						\
+    (wl) = __xx.__i.__l;						\
+  } while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+  ({union {UDItype __ll;						\
+	   struct {USItype __h, __l;} __i;				\
+	  } __xx;							\
+  USItype __q;								\
+  __xx.__i.__h = (n1); __xx.__i.__l = (n0);				\
+  __asm__ ("divu.d %0,%1,%2"						\
+	   : "=r" (__q)							\
+	   : "r" (__xx.__ll),						\
+	     "r" ((USItype) (d)));					\
+  (r) = (n0) - __q * (d); (q) = __q; })
+#define UMUL_TIME 5
+#define UDIV_TIME 25
+#else
+#define UMUL_TIME 17
+#define UDIV_TIME 150
+#endif /* __mc88110__ */
+#endif /* __m88000__ */
+
+#if defined (__mips__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+  __asm__ ("multu %2,%3"						\
+	   : "=l" ((USItype) (w0)),					\
+	     "=h" ((USItype) (w1))					\
+	   : "d" ((USItype) (u)),					\
+	     "d" ((USItype) (v)))
+#define UMUL_TIME 10
+#define UDIV_TIME 100
+#endif /* __mips__ */
+
+#if defined (__ns32000__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+  ({union {UDItype __ll;						\
+	   struct {USItype __l, __h;} __i;				\
+	  } __xx;							\
+  __asm__ ("meid %2,%0"							\
+	   : "=g" (__xx.__ll)						\
+	   : "%0" ((USItype) (u)),					\
+	     "g" ((USItype) (v)));					\
+  (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define __umulsidi3(u, v) \
+  ({UDItype __w;							\
+    __asm__ ("meid %2,%0"						\
+	     : "=g" (__w)						\
+	     : "%0" ((USItype) (u)),					\
+	       "g" ((USItype) (v)));					\
+    __w; })
+#define udiv_qrnnd(q, r, n1, n0, d) \
+  ({union {UDItype __ll;						\
+	   struct {USItype __l, __h;} __i;				\
+	  } __xx;							\
+  __xx.__i.__h = (n1); __xx.__i.__l = (n0);				\
+  __asm__ ("deid %2,%0"							\
+	   : "=g" (__xx.__ll)						\
+	   : "0" (__xx.__ll),						\
+	     "g" ((USItype) (d)));					\
+  (r) = __xx.__i.__l; (q) = __xx.__i.__h; })
+#define count_trailing_zeros(count,x) \
+  do {									\
+    __asm__ ("ffsd     %2,%0"						\
+            : "=r" ((USItype) (count))					\
+            : "0" ((USItype) 0),					\
+              "r" ((USItype) (x)));					\
+  } while (0)
+#endif /* __ns32000__ */
+
+/* FIXME: We should test _IBMR2 here when we add assembly support for the
+   system vendor compilers.
+   FIXME: What's needed for gcc PowerPC VxWorks?  __vxworks__ is not good
+   enough, since that hits ARM and m68k too.  */
+#if (defined (_ARCH_PPC)	/* AIX */				\
+     || defined (_ARCH_PWR)	/* AIX */				\
+     || defined (_ARCH_COM)	/* AIX */				\
+     || defined (__powerpc__)	/* gcc */				\
+     || defined (__POWERPC__)	/* BEOS */				\
+     || defined (__ppc__)	/* Darwin */				\
+     || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */    \
+     || (defined (PPC) && defined (CPU_FAMILY)    /* VxWorks */               \
+         && CPU_FAMILY == PPC)                                                \
+     ) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  do {									\
+    if (__builtin_constant_p (bh) && (bh) == 0)				\
+      __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2"		\
+	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+    else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0)		\
+      __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2"		\
+	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+    else								\
+      __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3"		\
+	     : "=r" (sh), "=&r" (sl)					\
+	     : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl));		\
+  } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  do {									\
+    if (__builtin_constant_p (ah) && (ah) == 0)				\
+      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2"	\
+	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+    else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0)		\
+      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2"	\
+	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+    else if (__builtin_constant_p (bh) && (bh) == 0)			\
+      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2"		\
+	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+    else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0)		\
+      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2"		\
+	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+    else								\
+      __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2"	\
+	       : "=r" (sh), "=&r" (sl)					\
+	       : "r" (ah), "r" (bh), "rI" (al), "r" (bl));		\
+  } while (0)
+#define count_leading_zeros(count, x) \
+  __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x))
+#define COUNT_LEADING_ZEROS_0 32
+#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \
+  || defined (__ppc__)                                                    \
+  || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */       \
+  || (defined (PPC) && defined (CPU_FAMILY)    /* VxWorks */                  \
+         && CPU_FAMILY == PPC)
+#define umul_ppmm(ph, pl, m0, m1) \
+  do {									\
+    USItype __m0 = (m0), __m1 = (m1);					\
+    __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));	\
+    (pl) = __m0 * __m1;							\
+  } while (0)
+#define UMUL_TIME 15
+#define smul_ppmm(ph, pl, m0, m1) \
+  do {									\
+    SItype __m0 = (m0), __m1 = (m1);					\
+    __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));	\
+    (pl) = __m0 * __m1;							\
+  } while (0)
+#define SMUL_TIME 14
+#define UDIV_TIME 120
+#elif defined (_ARCH_PWR)
+#define UMUL_TIME 8
+#define smul_ppmm(xh, xl, m0, m1) \
+  __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1))
+#define SMUL_TIME 4
+#define sdiv_qrnnd(q, r, nh, nl, d) \
+  __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d))
+#define UDIV_TIME 100
+#endif
+#endif /* 32-bit POWER architecture variants.  */
+
+/* We should test _IBMR2 here when we add assembly support for the system
+   vendor compilers.  */
+#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  do {									\
+    if (__builtin_constant_p (bh) && (bh) == 0)				\
+      __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2"		\
+	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+    else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0)		\
+      __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2"		\
+	     : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+    else								\
+      __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3"		\
+	     : "=r" (sh), "=&r" (sl)					\
+	     : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl));		\
+  } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  do {									\
+    if (__builtin_constant_p (ah) && (ah) == 0)				\
+      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2"	\
+	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+    else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0)		\
+      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2"	\
+	       : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+    else if (__builtin_constant_p (bh) && (bh) == 0)			\
+      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2"		\
+	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+    else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0)		\
+      __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2"		\
+	       : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+    else								\
+      __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2"	\
+	       : "=r" (sh), "=&r" (sl)					\
+	       : "r" (ah), "r" (bh), "rI" (al), "r" (bl));		\
+  } while (0)
+#define count_leading_zeros(count, x) \
+  __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x))
+#define COUNT_LEADING_ZEROS_0 64
+#define umul_ppmm(ph, pl, m0, m1) \
+  do {									\
+    UDItype __m0 = (m0), __m1 = (m1);					\
+    __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));	\
+    (pl) = __m0 * __m1;							\
+  } while (0)
+#define UMUL_TIME 15
+#define smul_ppmm(ph, pl, m0, m1) \
+  do {									\
+    DItype __m0 = (m0), __m1 = (m1);					\
+    __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));	\
+    (pl) = __m0 * __m1;							\
+  } while (0)
+#define SMUL_TIME 14  /* ??? */
+#define UDIV_TIME 120 /* ??? */
+#endif /* 64-bit PowerPC.  */
+
+#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("a %1,%5\n\tae %0,%3"					\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "%0" ((USItype) (ah)),					\
+	     "r" ((USItype) (bh)),					\
+	     "%1" ((USItype) (al)),					\
+	     "r" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("s %1,%5\n\tse %0,%3"					\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "0" ((USItype) (ah)),					\
+	     "r" ((USItype) (bh)),					\
+	     "1" ((USItype) (al)),					\
+	     "r" ((USItype) (bl)))
+#define umul_ppmm(ph, pl, m0, m1) \
+  do {									\
+    USItype __m0 = (m0), __m1 = (m1);					\
+    __asm__ (								\
+       "s	r2,r2\n"						\
+"	mts	r10,%2\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	m	r2,%3\n"						\
+"	cas	%0,r2,r0\n"						\
+"	mfs	r10,%1"							\
+	     : "=r" ((USItype) (ph)),					\
+	       "=r" ((USItype) (pl))					\
+	     : "%r" (__m0),						\
+		"r" (__m1)						\
+	     : "r2");							\
+    (ph) += ((((SItype) __m0 >> 31) & __m1)				\
+	     + (((SItype) __m1 >> 31) & __m0));				\
+  } while (0)
+#define UMUL_TIME 20
+#define UDIV_TIME 200
+#define count_leading_zeros(count, x) \
+  do {									\
+    if ((x) >= 0x10000)							\
+      __asm__ ("clz	%0,%1"						\
+	       : "=r" ((USItype) (count))				\
+	       : "r" ((USItype) (x) >> 16));				\
+    else								\
+      {									\
+	__asm__ ("clz	%0,%1"						\
+		 : "=r" ((USItype) (count))				\
+		 : "r" ((USItype) (x)));					\
+	(count) += 16;							\
+      }									\
+  } while (0)
+#endif
+
+#if defined (__sh2__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+  __asm__ (								\
+       "dmulu.l	%2,%3\n\tsts	macl,%1\n\tsts	mach,%0"		\
+	   : "=r" ((USItype)(w1)),					\
+	     "=r" ((USItype)(w0))					\
+	   : "r" ((USItype)(u)),					\
+	     "r" ((USItype)(v))						\
+	   : "macl", "mach")
+#define UMUL_TIME 5
+#endif
+
+#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32
+#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v)
+#define count_leading_zeros(count, x) \
+  do									\
+    {									\
+      UDItype x_ = (USItype)(x);					\
+      SItype c_;							\
+									\
+      __asm__ ("nsb %1, %0" : "=r" (c_) : "r" (x_));			\
+      (count) = c_ - 31;						\
+    }									\
+  while (0)
+#define COUNT_LEADING_ZEROS_0 32
+#endif
+
+#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \
+    && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0"				\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "%rJ" ((USItype) (ah)),					\
+	     "rI" ((USItype) (bh)),					\
+	     "%rJ" ((USItype) (al)),					\
+	     "rI" ((USItype) (bl))					\
+	   __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0"				\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "rJ" ((USItype) (ah)),					\
+	     "rI" ((USItype) (bh)),					\
+	     "rJ" ((USItype) (al)),					\
+	     "rI" ((USItype) (bl))					\
+	   __CLOBBER_CC)
+#if defined (__sparc_v8__)
+#define umul_ppmm(w1, w0, u, v) \
+  __asm__ ("umul %2,%3,%1;rd %%y,%0"					\
+	   : "=r" ((USItype) (w1)),					\
+	     "=r" ((USItype) (w0))					\
+	   : "r" ((USItype) (u)),					\
+	     "r" ((USItype) (v)))
+#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \
+  __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\
+	   : "=&r" ((USItype) (__q)),					\
+	     "=&r" ((USItype) (__r))					\
+	   : "r" ((USItype) (__n1)),					\
+	     "r" ((USItype) (__n0)),					\
+	     "r" ((USItype) (__d)))
+#else
+#if defined (__sparclite__)
+/* This has hardware multiply but not divide.  It also has two additional
+   instructions scan (ffs from high bit) and divscc.  */
+#define umul_ppmm(w1, w0, u, v) \
+  __asm__ ("umul %2,%3,%1;rd %%y,%0"					\
+	   : "=r" ((USItype) (w1)),					\
+	     "=r" ((USItype) (w0))					\
+	   : "r" ((USItype) (u)),					\
+	     "r" ((USItype) (v)))
+#define udiv_qrnnd(q, r, n1, n0, d) \
+  __asm__ ("! Inlined udiv_qrnnd\n"					\
+"	wr	%%g0,%2,%%y	! Not a delayed write for sparclite\n"	\
+"	tst	%%g0\n"							\
+"	divscc	%3,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%%g1\n"						\
+"	divscc	%%g1,%4,%0\n"						\
+"	rd	%%y,%1\n"						\
+"	bl,a 1f\n"							\
+"	add	%1,%4,%1\n"						\
+"1:	! End of inline udiv_qrnnd"					\
+	   : "=r" ((USItype) (q)),					\
+	     "=r" ((USItype) (r))					\
+	   : "r" ((USItype) (n1)),					\
+	     "r" ((USItype) (n0)),					\
+	     "rI" ((USItype) (d))					\
+	   : "g1" __AND_CLOBBER_CC)
+#define UDIV_TIME 37
+#define count_leading_zeros(count, x) \
+  do {                                                                  \
+  __asm__ ("scan %1,1,%0"                                               \
+           : "=r" ((USItype) (count))                                   \
+           : "r" ((USItype) (x)));					\
+  } while (0)
+/* Early sparclites return 63 for an argument of 0, but they warn that future
+   implementations might change this.  Therefore, leave COUNT_LEADING_ZEROS_0
+   undefined.  */
+#else
+/* SPARC without integer multiplication and divide instructions.
+   (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */
+#define umul_ppmm(w1, w0, u, v) \
+  __asm__ ("! Inlined umul_ppmm\n"					\
+"	wr	%%g0,%2,%%y	! SPARC has 0-3 delay insn after a wr\n"\
+"	sra	%3,31,%%o5	! Don't move this insn\n"		\
+"	and	%2,%%o5,%%o5	! Don't move this insn\n"		\
+"	andcc	%%g0,0,%%g1	! Don't move this insn\n"		\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,%3,%%g1\n"						\
+"	mulscc	%%g1,0,%%g1\n"						\
+"	add	%%g1,%%o5,%0\n"						\
+"	rd	%%y,%1"							\
+	   : "=r" ((USItype) (w1)),					\
+	     "=r" ((USItype) (w0))					\
+	   : "%rI" ((USItype) (u)),					\
+	     "r" ((USItype) (v))						\
+	   : "g1", "o5" __AND_CLOBBER_CC)
+#define UMUL_TIME 39		/* 39 instructions */
+/* It's quite necessary to add this much assembler for the sparc.
+   The default udiv_qrnnd (in C) is more than 10 times slower!  */
+#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \
+  __asm__ ("! Inlined udiv_qrnnd\n"					\
+"	mov	32,%%g1\n"						\
+"	subcc	%1,%2,%%g0\n"						\
+"1:	bcs	5f\n"							\
+"	 addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb\n"	\
+"	sub	%1,%2,%1	! this kills msb of n\n"		\
+"	addx	%1,%1,%1	! so this can't give carry\n"		\
+"	subcc	%%g1,1,%%g1\n"						\
+"2:	bne	1b\n"							\
+"	 subcc	%1,%2,%%g0\n"						\
+"	bcs	3f\n"							\
+"	 addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb\n"	\
+"	b	3f\n"							\
+"	 sub	%1,%2,%1	! this kills msb of n\n"		\
+"4:	sub	%1,%2,%1\n"						\
+"5:	addxcc	%1,%1,%1\n"						\
+"	bcc	2b\n"							\
+"	 subcc	%%g1,1,%%g1\n"						\
+"! Got carry from n.  Subtract next step to cancel this carry.\n"	\
+"	bne	4b\n"							\
+"	 addcc	%0,%0,%0	! shift n1n0 and a 0-bit in lsb\n"	\
+"	sub	%1,%2,%1\n"						\
+"3:	xnor	%0,0,%0\n"						\
+"	! End of inline udiv_qrnnd"					\
+	   : "=&r" ((USItype) (__q)),					\
+	     "=&r" ((USItype) (__r))					\
+	   : "r" ((USItype) (__d)),					\
+	     "1" ((USItype) (__n1)),					\
+	     "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC)
+#define UDIV_TIME (3+7*32)	/* 7 instructions/iteration. 32 iterations.  */
+#endif /* __sparclite__ */
+#endif /* __sparc_v8__ */
+#endif /* sparc32 */
+
+#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \
+    && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl)				\
+  __asm__ ("addcc %r4,%5,%1\n\t"					\
+   	   "add %r2,%3,%0\n\t"						\
+   	   "bcs,a,pn %%xcc, 1f\n\t"					\
+   	   "add %0, 1, %0\n"						\
+	   "1:"								\
+	   : "=r" ((UDItype)(sh)),				      	\
+	     "=&r" ((UDItype)(sl))				      	\
+	   : "%rJ" ((UDItype)(ah)),				     	\
+	     "rI" ((UDItype)(bh)),				      	\
+	     "%rJ" ((UDItype)(al)),				     	\
+	     "rI" ((UDItype)(bl))				       	\
+	   __CLOBBER_CC)
+
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) 				\
+  __asm__ ("subcc %r4,%5,%1\n\t"					\
+   	   "sub %r2,%3,%0\n\t"						\
+   	   "bcs,a,pn %%xcc, 1f\n\t"					\
+   	   "sub %0, 1, %0\n\t"						\
+	   "1:"								\
+	   : "=r" ((UDItype)(sh)),				      	\
+	     "=&r" ((UDItype)(sl))				      	\
+	   : "rJ" ((UDItype)(ah)),				     	\
+	     "rI" ((UDItype)(bh)),				      	\
+	     "rJ" ((UDItype)(al)),				     	\
+	     "rI" ((UDItype)(bl))				       	\
+	   __CLOBBER_CC)
+
+#define umul_ppmm(wh, wl, u, v)						\
+  do {									\
+	  UDItype tmp1, tmp2, tmp3, tmp4;				\
+	  __asm__ __volatile__ (					\
+		   "srl %7,0,%3\n\t"					\
+		   "mulx %3,%6,%1\n\t"					\
+		   "srlx %6,32,%2\n\t"					\
+		   "mulx %2,%3,%4\n\t"					\
+		   "sllx %4,32,%5\n\t"					\
+		   "srl %6,0,%3\n\t"					\
+		   "sub %1,%5,%5\n\t"					\
+		   "srlx %5,32,%5\n\t"					\
+		   "addcc %4,%5,%4\n\t"					\
+		   "srlx %7,32,%5\n\t"					\
+		   "mulx %3,%5,%3\n\t"					\
+		   "mulx %2,%5,%5\n\t"					\
+		   "sethi %%hi(0x80000000),%2\n\t"			\
+		   "addcc %4,%3,%4\n\t"					\
+		   "srlx %4,32,%4\n\t"					\
+		   "add %2,%2,%2\n\t"					\
+		   "movcc %%xcc,%%g0,%2\n\t"				\
+		   "addcc %5,%4,%5\n\t"					\
+		   "sllx %3,32,%3\n\t"					\
+		   "add %1,%3,%1\n\t"					\
+		   "add %5,%2,%0"					\
+	   : "=r" ((UDItype)(wh)),					\
+	     "=&r" ((UDItype)(wl)),					\
+	     "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4)	\
+	   : "r" ((UDItype)(u)),					\
+	     "r" ((UDItype)(v))						\
+	   __CLOBBER_CC);						\
+  } while (0)
+#define UMUL_TIME 96
+#define UDIV_TIME 230
+#endif /* sparc64 */
+
+#if defined (__vax__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("addl2 %5,%1\n\tadwc %3,%0"					\
+	   : "=g" ((USItype) (sh)),					\
+	     "=&g" ((USItype) (sl))					\
+	   : "%0" ((USItype) (ah)),					\
+	     "g" ((USItype) (bh)),					\
+	     "%1" ((USItype) (al)),					\
+	     "g" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("subl2 %5,%1\n\tsbwc %3,%0"					\
+	   : "=g" ((USItype) (sh)),					\
+	     "=&g" ((USItype) (sl))					\
+	   : "0" ((USItype) (ah)),					\
+	     "g" ((USItype) (bh)),					\
+	     "1" ((USItype) (al)),					\
+	     "g" ((USItype) (bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+  do {									\
+    union {								\
+	UDItype __ll;							\
+	struct {USItype __l, __h;} __i;					\
+      } __xx;								\
+    USItype __m0 = (m0), __m1 = (m1);					\
+    __asm__ ("emul %1,%2,$0,%0"						\
+	     : "=r" (__xx.__ll)						\
+	     : "g" (__m0),						\
+	       "g" (__m1));						\
+    (xh) = __xx.__i.__h;						\
+    (xl) = __xx.__i.__l;						\
+    (xh) += ((((SItype) __m0 >> 31) & __m1)				\
+	     + (((SItype) __m1 >> 31) & __m0));				\
+  } while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+  do {									\
+    union {DItype __ll;							\
+	   struct {SItype __l, __h;} __i;				\
+	  } __xx;							\
+    __xx.__i.__h = n1; __xx.__i.__l = n0;				\
+    __asm__ ("ediv %3,%2,%0,%1"						\
+	     : "=g" (q), "=g" (r)					\
+	     : "g" (__xx.__ll), "g" (d));				\
+  } while (0)
+#endif /* __vax__ */
+
+#if defined (__z8000__) && W_TYPE_SIZE == 16
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("add	%H1,%H5\n\tadc	%H0,%H3"				\
+	   : "=r" ((unsigned int)(sh)),					\
+	     "=&r" ((unsigned int)(sl))					\
+	   : "%0" ((unsigned int)(ah)),					\
+	     "r" ((unsigned int)(bh)),					\
+	     "%1" ((unsigned int)(al)),					\
+	     "rQR" ((unsigned int)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("sub	%H1,%H5\n\tsbc	%H0,%H3"				\
+	   : "=r" ((unsigned int)(sh)),					\
+	     "=&r" ((unsigned int)(sl))					\
+	   : "0" ((unsigned int)(ah)),					\
+	     "r" ((unsigned int)(bh)),					\
+	     "1" ((unsigned int)(al)),					\
+	     "rQR" ((unsigned int)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+  do {									\
+    union {long int __ll;						\
+	   struct {unsigned int __h, __l;} __i;				\
+	  } __xx;							\
+    unsigned int __m0 = (m0), __m1 = (m1);				\
+    __asm__ ("mult	%S0,%H3"					\
+	     : "=r" (__xx.__i.__h),					\
+	       "=r" (__xx.__i.__l)					\
+	     : "%1" (__m0),						\
+	       "rQR" (__m1));						\
+    (xh) = __xx.__i.__h; (xl) = __xx.__i.__l;				\
+    (xh) += ((((signed int) __m0 >> 15) & __m1)				\
+	     + (((signed int) __m1 >> 15) & __m0));			\
+  } while (0)
+#endif /* __z8000__ */
+
+#endif /* __GNUC__ */
+
+/* If this machine has no inline assembler, use C macros.  */
+
+#if !defined (add_ssaaaa)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  do {									\
+    UWtype __x;								\
+    __x = (al) + (bl);							\
+    (sh) = (ah) + (bh) + (__x < (al));					\
+    (sl) = __x;								\
+  } while (0)
+#endif
+
+#if !defined (sub_ddmmss)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  do {									\
+    UWtype __x;								\
+    __x = (al) - (bl);							\
+    (sh) = (ah) - (bh) - (__x > (al));					\
+    (sl) = __x;								\
+  } while (0)
+#endif
+
+/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of
+   smul_ppmm.  */
+#if !defined (umul_ppmm) && defined (smul_ppmm)
+#define umul_ppmm(w1, w0, u, v)						\
+  do {									\
+    UWtype __w1;							\
+    UWtype __xm0 = (u), __xm1 = (v);					\
+    smul_ppmm (__w1, w0, __xm0, __xm1);					\
+    (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1)		\
+		+ (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0);		\
+  } while (0)
+#endif
+
+/* If we still don't have umul_ppmm, define it using plain C.  */
+#if !defined (umul_ppmm)
+#warning "Default c-implementation of umul_ppm"
+#define umul_ppmm(w1, w0, u, v)						\
+  do {									\
+    UWtype __x0, __x1, __x2, __x3;					\
+    UHWtype __ul, __vl, __uh, __vh;					\
+									\
+    __ul = __ll_lowpart (u);						\
+    __uh = __ll_highpart (u);						\
+    __vl = __ll_lowpart (v);						\
+    __vh = __ll_highpart (v);						\
+									\
+    __x0 = (UWtype) __ul * __vl;					\
+    __x1 = (UWtype) __ul * __vh;					\
+    __x2 = (UWtype) __uh * __vl;					\
+    __x3 = (UWtype) __uh * __vh;					\
+									\
+    __x1 += __ll_highpart (__x0);/* this can't give carry */		\
+    __x1 += __x2;		/* but this indeed can */		\
+    if (__x1 < __x2)		/* did we get it? */			\
+      __x3 += __ll_B;		/* yes, add it in the proper pos.  */	\
+									\
+    (w1) = __x3 + __ll_highpart (__x1);					\
+    (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);		\
+  } while (0)
+#endif
+
+#if !defined (__umulsidi3)
+#warning "Default c-implementation of __umulsidi3"
+#define __umulsidi3(u, v) \
+  ({DWunion __w;							\
+    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
+    __w.ll; })
+#endif
+
+/* Define this unconditionally, so it can be used for debugging.  */
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+  do {									\
+    UWtype __d1, __d0, __q1, __q0;					\
+    UWtype __r1, __r0, __m;						\
+    __d1 = __ll_highpart (d);						\
+    __d0 = __ll_lowpart (d);						\
+									\
+    __r1 = (n1) % __d1;							\
+    __q1 = (n1) / __d1;							\
+    __m = (UWtype) __q1 * __d0;						\
+    __r1 = __r1 * __ll_B | __ll_highpart (n0);				\
+    if (__r1 < __m)							\
+      {									\
+	__q1--, __r1 += (d);						\
+	if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+	  if (__r1 < __m)						\
+	    __q1--, __r1 += (d);					\
+      }									\
+    __r1 -= __m;							\
+									\
+    __r0 = __r1 % __d1;							\
+    __q0 = __r1 / __d1;							\
+    __m = (UWtype) __q0 * __d0;						\
+    __r0 = __r0 * __ll_B | __ll_lowpart (n0);				\
+    if (__r0 < __m)							\
+      {									\
+	__q0--, __r0 += (d);						\
+	if (__r0 >= (d))						\
+	  if (__r0 < __m)						\
+	    __q0--, __r0 += (d);					\
+      }									\
+    __r0 -= __m;							\
+									\
+    (q) = (UWtype) __q1 * __ll_B | __q0;				\
+    (r) = __r0;								\
+  } while (0)
+
+/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
+   __udiv_w_sdiv (defined in libgcc or elsewhere).  */
+#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
+#define udiv_qrnnd(q, r, nh, nl, d) \
+  do {									\
+    USItype __r;							\
+    (q) = __udiv_w_sdiv (&__r, nh, nl, d);				\
+    (r) = __r;								\
+  } while (0)
+#endif
+
+/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c.  */
+#if !defined (udiv_qrnnd)
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
+#endif
+
+#if !defined (count_leading_zeros)
+#warning "Using count_leading_zeroes in C"
+#define count_leading_zeros(count, x) \
+  do {									\
+    UWtype __xr = (x);							\
+    UWtype __a;								\
+									\
+    if (W_TYPE_SIZE <= 32)						\
+      {									\
+	__a = __xr < ((UWtype)1<<2*__BITS4)				\
+	  ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4)			\
+	  : (__xr < ((UWtype)1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);	\
+      }									\
+    else								\
+      {									\
+	for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8)			\
+	  if (((__xr >> __a) & 0xff) != 0)				\
+	    break;							\
+      }									\
+									\
+    (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);		\
+  } while (0)
+#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
+#endif
+
+#if !defined (count_trailing_zeros)
+/* Define count_trailing_zeros using count_leading_zeros.  The latter might be
+   defined in asm, but if it is not, the C version above is good enough.  */
+#define count_trailing_zeros(count, x) \
+  do {									\
+    UWtype __ctz_x = (x);						\
+    UWtype __ctz_c;							\
+    count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x);			\
+    (count) = W_TYPE_SIZE - 1 - __ctz_c;				\
+  } while (0)
+#endif
+
+#ifndef UDIV_NEEDS_NORMALIZATION
+#define UDIV_NEEDS_NORMALIZATION 0
+#endif
diff --git a/arch/nios2/lib/memcpy.c b/arch/nios2/lib/memcpy.c
new file mode 100644
index 0000000..9349379
--- /dev/null
+++ b/arch/nios2/lib/memcpy.c
@@ -0,0 +1,199 @@
+/* Copy memory to memory until the specified number of bytes
+   has been copied.  Overlap is NOT handled correctly.
+   Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   stream-lined memory access
+*/
+
+#include <linux/types.h>
+#include <linux/autoconf.h>
+#include <asm/string.h>
+
+#ifdef __HAVE_ARCH_MEMCPY
+
+/* Type to use for aligned memory operations.
+   This should normally be the biggest type supported by a single load
+   and store.  */
+#define	op_t	unsigned long int
+#define OPSIZ	(sizeof(op_t))
+
+/* Type to use for unaligned operations.  */
+typedef unsigned char byte;
+
+/* Optimal type for storing bytes in registers.  */
+#define	reg_char	char
+
+#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
+
+/* Copy exactly NBYTES bytes from SRC_BP to DST_BP,
+   without any assumptions about alignment of the pointers.  */
+#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes)				      \
+  do									      \
+    {									      \
+      size_t __nbytes = (nbytes);					      \
+      while (__nbytes > 0)						      \
+	{								      \
+	  byte __x = ((byte *) src_bp)[0];				      \
+	  src_bp += 1;							      \
+	  __nbytes -= 1;						      \
+	  ((byte *) dst_bp)[0] = __x;					      \
+	  dst_bp += 1;							      \
+	}								      \
+    } while (0)
+
+/* Copy *up to* NBYTES bytes from SRC_BP to DST_BP, with
+   the assumption that DST_BP is aligned on an OPSIZ multiple.  If
+   not all bytes could be easily copied, store remaining number of bytes
+   in NBYTES_LEFT, otherwise store 0.  */
+/* extern void _wordcopy_fwd_aligned __P ((long int, long int, size_t)); */
+/* extern void _wordcopy_fwd_dest_aligned __P ((long int, long int, size_t)); */
+#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes)		      \
+  do									      \
+    {									      \
+      if (src_bp % OPSIZ == 0)						      \
+	_wordcopy_fwd_aligned (dst_bp, src_bp, (nbytes) / OPSIZ);	      \
+      else								      \
+	_wordcopy_fwd_dest_aligned (dst_bp, src_bp, (nbytes) / OPSIZ);	      \
+      src_bp += (nbytes) & -OPSIZ;					      \
+      dst_bp += (nbytes) & -OPSIZ;					      \
+      (nbytes_left) = (nbytes) % OPSIZ;					      \
+    } while (0)
+
+
+/* Threshold value for when to enter the unrolled loops.  */
+#define	OP_T_THRES	16
+
+/* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
+   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
+   Both SRCP and DSTP should be aligned for memory operations on `op_t's.  */
+/* stream-lined (read x8 + write x8) */
+static void _wordcopy_fwd_aligned (long int dstp, long int srcp, size_t len)
+{
+  while (len > 7) {
+    register op_t a0,a1,a2,a3,a4,a5,a6,a7;
+    a0 = ((op_t *) srcp)[0];
+    a1 = ((op_t *) srcp)[1];
+    a2 = ((op_t *) srcp)[2];
+    a3 = ((op_t *) srcp)[3];
+    a4 = ((op_t *) srcp)[4];
+    a5 = ((op_t *) srcp)[5];
+    a6 = ((op_t *) srcp)[6];
+    a7 = ((op_t *) srcp)[7];
+    ((op_t *) dstp)[0] = a0;
+    ((op_t *) dstp)[1] = a1;
+    ((op_t *) dstp)[2] = a2;
+    ((op_t *) dstp)[3] = a3;
+    ((op_t *) dstp)[4] = a4;
+    ((op_t *) dstp)[5] = a5;
+    ((op_t *) dstp)[6] = a6;
+    ((op_t *) dstp)[7] = a7;
+
+    srcp += 8 * OPSIZ;
+    dstp += 8 * OPSIZ;
+    len -= 8;
+  }
+  while (len > 0) {
+    *(op_t *)dstp=*(op_t *)srcp;
+
+    srcp += OPSIZ;
+    dstp += OPSIZ;
+    len -= 1;
+  }
+}
+
+/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
+   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
+   DSTP should be aligned for memory operations on `op_t's, but SRCP must
+   *not* be aligned.  */
+/* stream-lined (read x4 + write x4) */
+static void _wordcopy_fwd_dest_aligned (long int dstp, long int srcp, size_t len)
+{
+  op_t ap;
+  int sh_1, sh_2;
+
+  /* Calculate how to shift a word read at the memory operation
+     aligned srcp to make it aligned for copy.  */
+
+  sh_1 = 8 * (srcp % OPSIZ);
+  sh_2 = 8 * OPSIZ - sh_1;
+
+  /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
+     it points in the middle of.  */
+  srcp &= -OPSIZ;
+  ap = ((op_t *) srcp)[0];
+  srcp += OPSIZ;
+
+  while (len > 3) {
+    op_t a0,a1,a2,a3;
+    a0 = ((op_t *) srcp)[0];
+    a1 = ((op_t *) srcp)[1];
+    a2 = ((op_t *) srcp)[2];
+    a3 = ((op_t *) srcp)[3];
+    ((op_t *) dstp)[0] = MERGE (ap, sh_1, a0, sh_2);
+    ((op_t *) dstp)[1] = MERGE (a0, sh_1, a1, sh_2);
+    ((op_t *) dstp)[2] = MERGE (a1, sh_1, a2, sh_2);
+    ((op_t *) dstp)[3] = MERGE (a2, sh_1, a3, sh_2);
+
+    ap = a3;
+    srcp += 4 * OPSIZ;
+    dstp += 4 * OPSIZ;
+    len -= 4;
+  }
+  while (len > 0) {
+    register op_t a0;
+    a0 = ((op_t *) srcp)[0];
+    ((op_t *) dstp)[0] = MERGE (ap, sh_1, a0, sh_2);
+
+    ap = a0;
+    srcp += OPSIZ;
+    dstp += OPSIZ;
+    len -= 1;
+  }
+}
+
+void *memcpy (void *dstpp, const void *srcpp, size_t len)
+{
+  unsigned long int dstp = (long int) dstpp;
+  unsigned long int srcp = (long int) srcpp;
+
+  /* Copy from the beginning to the end.  */
+
+  /* If there not too few bytes to copy, use word copy.  */
+  if (len >= OP_T_THRES)
+    {
+      /* Copy just a few bytes to make DSTP aligned.  */
+      len -= (-dstp) % OPSIZ;
+      BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
+
+      /* Copy whole pages from SRCP to DSTP by virtual address manipulation,
+	 as much as possible.  */
+
+      /* PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len); */
+
+      /* Copy from SRCP to DSTP taking advantage of the known alignment of
+	 DSTP.  Number of bytes remaining is put in the third argument,
+	 i.e. in LEN.  This number may vary from machine to machine.  */
+
+      WORD_COPY_FWD (dstp, srcp, len, len);
+
+      /* Fall out and copy the tail.  */
+    }
+
+  /* There are just a few bytes to copy.  Use byte memory operations.  */
+  BYTE_COPY_FWD (dstp, srcp, len);
+
+  return dstpp;
+}
+
+void *memcpyb (void *dstpp, const void *srcpp, unsigned len)
+{
+  unsigned long int dstp = (long int) dstpp;
+  unsigned long int srcp = (long int) srcpp;
+
+  BYTE_COPY_FWD (dstp, srcp, len);
+
+  return dstpp;
+}
+#endif
diff --git a/arch/nios2/lib/string.c b/arch/nios2/lib/string.c
new file mode 100644
index 0000000..49365d7
--- /dev/null
+++ b/arch/nios2/lib/string.c
@@ -0,0 +1,179 @@
+/*--------------------------------------------------------------------
+ *
+ * arch/nios2nommu/lib/string.c
+ *
+ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al
+ *
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Jan/20/2004		dgt	    NiosII
+ * Jun/09/2004		dgt	    Split out memcpy into separate source file
+ *
+ ---------------------------------------------------------------------*/
+
+#include <linux/types.h>
+#include <asm/nios.h>
+#include <asm/string.h>
+
+#ifdef __HAVE_ARCH_MEMSET
+void * memset(void * s,int c,size_t count)
+{
+
+    if (count > 8) {
+        int destptr, charcnt, dwordcnt, fill8reg, wrkrega;
+        __asm__ __volatile__ (
+                 // fill8 %3, %5 (c & 0xff)\n\t"
+		 //
+            "    slli    %4,    %5,   8\n\t"
+            "    or      %4,    %4,   %5\n\t"
+            "    slli    %3,    %4,   16\n\t"
+            "    or      %3,    %3,   %4\n\t"
+                 //
+                 // Word-align %0 (s) if necessary
+                 //
+            "    andi    %4,    %0,   0x01\n\t"
+            "    beq     %4,    zero, 1f\n\t"
+            "    addi    %1,    %1,   -1\n\t"
+            "    stb     %3,  0(%0)\n\t"
+            "    addi    %0,    %0,   1\n\t"
+            "1:  \n\t"
+            "    mov     %2,    %1\n\t"
+                 //
+                 // Dword-align %0 (s) if necessary
+                 //
+            "    andi    %4,    %0,   0x02\n\t"
+            "    beq     %4,    zero, 2f\n\t"
+            "    addi    %1,    %1,   -2\n\t"
+            "    sth     %3,  0(%0)\n\t"
+            "    addi    %0,    %0,   2\n\t"
+            "    mov     %2,    %1\n\t"
+            "2:  \n\t"
+                 // %1 and %2 are how many more bytes to set
+                 //
+            "    srli    %2,    %2,   2\n\t"
+	         //
+                 // %2 is how many dwords to set
+	         //
+            "3:  ;\n\t"
+            "    stw     %3,  0(%0)\n\t"
+            "    addi    %0,    %0,   4\n\t"
+            "    addi    %2,    %2,   -1\n\t"
+            "    bne     %2,    zero, 3b\n\t"
+	         //
+                 // store residual word and/or byte if necessary
+                 //
+            "    andi    %4,    %1,   0x02\n\t"
+            "    beq     %4,    zero, 4f\n\t"
+            "    sth     %3,  0(%0)\n\t"
+            "    addi    %0,    %0,   2\n\t"
+            "4:  \n\t"
+                 // store residual byte if necessary
+                 //
+            "    andi    %4,    %1,   0x01\n\t"
+            "    beq     %4,    zero, 5f\n\t"
+            "    stb     %3,  0(%0)\n\t"
+            "5:  \n\t"
+
+            : "=r" (destptr),               /* %0  Output               */
+              "=r" (charcnt),               /* %1  Output               */
+              "=r" (dwordcnt),              /* %2  Output               */
+              "=r" (fill8reg),              /* %3  Output               */
+              "=r" (wrkrega)                /* %4  Output               */
+
+            : "r" (c & 0xff),               /* %5  Input                */
+              "0" (s),                      /* %0  Input/Output         */
+              "1" (count)                   /* %1  Input/Output         */
+
+            : "memory"                      /* clobbered                */
+            );
+	}
+	else {
+	char* xs=(char*)s;
+	while (count--)
+		*xs++ = c;
+	}
+	return s;
+}
+#endif
+
+#ifdef __HAVE_ARCH_MEMMOVE
+void * memmove(void * d, const void * s, size_t count)
+{
+    unsigned long dst, src;
+
+    if (d < s) {
+	dst = (unsigned long) d;
+	src = (unsigned long) s;
+
+	if ((count < 8) || ((dst ^ src) & 3))
+	    goto restup;
+
+	if (dst & 1) {
+		*(char*)dst++=*(char*)src++;
+	    count--;
+	}
+	if (dst & 2) {
+		*(short*)dst=*(short*)src;
+	    src += 2;
+	    dst += 2;
+	    count -= 2;
+	}
+	while (count > 3) {
+		*(long*)dst=*(long*)src;
+	    src += 4;
+	    dst += 4;
+	    count -= 4;
+	}
+
+    restup:
+	while (count--)
+		*(char*)dst++=*(char*)src++;
+    } else {
+	dst = (unsigned long) d + count;
+	src = (unsigned long) s + count;
+
+	if ((count < 8) || ((dst ^ src) & 3))
+	    goto restdown;
+
+	if (dst & 1) {
+	    src--;
+	    dst--;
+	    count--;
+		*(char*)dst=*(char*)src;
+	}
+	if (dst & 2) {
+	    src -= 2;
+	    dst -= 2;
+	    count -= 2;
+		*(short*)dst=*(short*)src;
+	}
+	while (count > 3) {
+	    src -= 4;
+	    dst -= 4;
+	    count -= 4;
+		*(long*)dst=*(long*)src;
+	}
+
+    restdown:
+	while (count--) {
+	    src--;
+	    dst--;
+		*(char*)dst=*(char*)src;
+	}
+    }
+
+    return d;	
+
+}
+#endif
diff --git a/arch/nios2/mm/Makefile b/arch/nios2/mm/Makefile
new file mode 100644
index 0000000..745e041
--- /dev/null
+++ b/arch/nios2/mm/Makefile
@@ -0,0 +1,15 @@
+# $Id: Makefile,v 1.1 2006/07/05 06:23:18 gerg Exp $
+# Makefile for the linux nios2-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+obj-y	:= init.o ioremap.o memory.o pgtable.o tlb.o pg.o uaccess.o fault.o 
+obj-y	+= dma-noncoherent.o
+obj-y   += pgalloc.o
+obj-y   += mmu_context.o
+obj-y	+= mmdump.o extable.o cacheflush.o
+
diff --git a/arch/nios2/mm/bak/Makefile b/arch/nios2/mm/bak/Makefile
new file mode 100644
index 0000000..67494c9
--- /dev/null
+++ b/arch/nios2/mm/bak/Makefile
@@ -0,0 +1 @@
+obj-y := init.o dma-noncoherent.o
\ No newline at end of file
diff --git a/arch/nios2/mm/bak/dma-noncoherent.c b/arch/nios2/mm/bak/dma-noncoherent.c
new file mode 100644
index 0000000..5649940
--- /dev/null
+++ b/arch/nios2/mm/bak/dma-noncoherent.c
@@ -0,0 +1,373 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+
+#define UNCAC_ADDR(addr) ((void *)((unsigned long)(addr) | 0x80000000))
+#define   CAC_ADDR(addr) ((void *)((unsigned long)(addr) & ~0x80000000))
+
+/*
+ * Warning on the terminology - Linux calls an uncached area coherent;
+ * MIPS terminology calls memory areas with hardware maintained coherency
+ * coherent.
+ */
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, gfp_t gfp)
+{
+	void *ret;
+	/* ignore region specifiers */
+	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
+		gfp |= GFP_DMA;
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_phys(ret);
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_noncoherent);
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, gfp_t gfp)
+{
+	void *ret;
+
+	ret = dma_alloc_noncoherent(dev, size, dma_handle, gfp);
+	if (ret) {
+		dma_cache_wback_inv((unsigned long) ret, size);
+		ret = UNCAC_ADDR(ret);
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	free_pages((unsigned long) vaddr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_noncoherent);
+
+void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	unsigned long addr = (unsigned long) vaddr;
+
+	addr = (unsigned long) CAC_ADDR(addr);
+	free_pages(addr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_coherent);
+
+static inline void __dma_sync(unsigned long addr, size_t size,
+	enum dma_data_direction direction)
+{
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		dma_cache_wback(addr, size);
+		break;
+
+	case DMA_FROM_DEVICE:
+		dma_cache_inv(addr, size);
+		break;
+
+	case DMA_BIDIRECTIONAL:
+		dma_cache_wback_inv(addr, size);
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+	enum dma_data_direction direction)
+{
+	unsigned long addr = (unsigned long) ptr;
+
+	__dma_sync(addr, size, direction);
+
+	return virt_to_phys(ptr);
+}
+
+EXPORT_SYMBOL(dma_map_single);
+
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+	enum dma_data_direction direction)
+{
+	unsigned long addr;
+	addr = dma_addr + PAGE_OFFSET;
+
+	//__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_unmap_single);
+
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	for (i = 0; i < nents; i++, sg++) {
+		unsigned long addr;
+
+		addr = (unsigned long) page_address(sg->page);
+		if (addr) {
+			__dma_sync(addr + sg->offset, sg->length, direction);
+			sg->dma_address = (dma_addr_t)page_to_phys(sg->page)
+					  + sg->offset;
+		}
+	}
+
+	return nents;
+}
+
+EXPORT_SYMBOL(dma_map_sg);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = (unsigned long) page_address(page) + offset;
+	dma_cache_wback_inv(addr, size);
+
+	return page_to_phys(page) + offset;
+}
+
+EXPORT_SYMBOL(dma_map_page);
+
+void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+	enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+
+	if (direction != DMA_TO_DEVICE) {
+		unsigned long addr;
+
+		addr = dma_address + PAGE_OFFSET;
+		dma_cache_wback_inv(addr, size);
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_page);
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	enum dma_data_direction direction)
+{
+	unsigned long addr;
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	if (direction == DMA_TO_DEVICE)
+		return;
+
+	for (i = 0; i < nhwentries; i++, sg++) {
+		addr = (unsigned long) page_address(sg->page);
+		if (addr)
+			__dma_sync(addr + sg->offset, sg->length, direction);
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_sg);
+
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = dma_handle + PAGE_OFFSET;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_cpu);
+
+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = dma_handle + PAGE_OFFSET;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_device);
+
+void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = dma_handle + offset + PAGE_OFFSET;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
+
+void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = dma_handle + offset + PAGE_OFFSET;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_device);
+
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nelems; i++, sg++)
+		__dma_sync((unsigned long)page_address(sg->page),
+		           sg->length, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nelems; i++, sg++)
+		__dma_sync((unsigned long)page_address(sg->page),
+		           sg->length, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+int dma_mapping_error(dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_mapping_error);
+
+int dma_supported(struct device *dev, u64 mask)
+{
+	/*
+	 * we fall back to GFP_DMA when the mask isn't all 1s,
+	 * so we can't guarantee allocations that must be
+	 * within a tighter range than GFP_DMA..
+	 */
+	if (mask < 0x00ffffff)
+		return 0;
+
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_supported);
+
+int dma_is_consistent(dma_addr_t dma_addr)
+{
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_is_consistent);
+
+void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction)
+{
+	if (direction == DMA_NONE)
+		return;
+
+	dma_cache_wback_inv((unsigned long)vaddr, size);
+}
+
+EXPORT_SYMBOL(dma_cache_sync);
+
+/* The DAC routines are a PCIism.. */
+
+#ifdef CONFIG_PCI
+
+#include <linux/pci.h>
+
+dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev,
+	struct page *page, unsigned long offset, int direction)
+{
+	return (dma64_addr_t)page_to_phys(page) + offset;
+}
+
+EXPORT_SYMBOL(pci_dac_page_to_dma);
+
+struct page *pci_dac_dma_to_page(struct pci_dev *pdev,
+	dma64_addr_t dma_addr)
+{
+	return mem_map + (dma_addr >> PAGE_SHIFT);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_to_page);
+
+unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
+	dma64_addr_t dma_addr)
+{
+	return dma_addr & ~PAGE_MASK;
+}
+
+EXPORT_SYMBOL(pci_dac_dma_to_offset);
+
+void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
+	dma64_addr_t dma_addr, size_t len, int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu);
+
+void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
+	dma64_addr_t dma_addr, size_t len, int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device);
+
+#endif /* CONFIG_PCI */
diff --git a/arch/nios2/mm/bak/init.c b/arch/nios2/mm/bak/init.c
new file mode 100644
index 0000000..9a9a0c7
--- /dev/null
+++ b/arch/nios2/mm/bak/init.c
@@ -0,0 +1,14 @@
+void mem_init(void)
+{
+   #warning "Implement mem_init"
+}
+
+void free_initmem(void)
+{
+   #warning "Implement free_initmem"
+}
+
+void show_mem(void) 
+{
+   #warning "Implement free_initmem"
+}
diff --git a/arch/nios2/mm/cacheflush.c b/arch/nios2/mm/cacheflush.c
new file mode 100644
index 0000000..f0aa1db
--- /dev/null
+++ b/arch/nios2/mm/cacheflush.c
@@ -0,0 +1,210 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ */
+
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <asm/cacheflush.h>
+
+
+static void __flush_dcache(unsigned long start, unsigned long end) {
+   unsigned long addr;
+
+   start &= ~(DCACHE_LINE_SIZE - 1);
+   end += (DCACHE_LINE_SIZE - 1);
+   end &= ~(DCACHE_LINE_SIZE - 1);
+
+   if(end > start + DCACHE_SIZE) {
+      end = start + DCACHE_SIZE;
+   }
+
+   for(addr = start; addr < end; addr += DCACHE_LINE_SIZE) {
+      __asm__ __volatile__ ("   flushd 0(%0)\n" 
+                            : /* Outputs */
+                            : /* Inputs  */ "r"(addr) 
+                            /* : No clobber */);
+   }   
+   //__asm__ __volatile(" flushp\n");
+}
+
+static void __flush_icache(unsigned long start, unsigned long end) {
+   unsigned long addr;
+
+   start &= ~(ICACHE_LINE_SIZE - 1);
+   end += (ICACHE_LINE_SIZE - 1);
+   end &= ~(ICACHE_LINE_SIZE - 1);
+
+   if(end > start + ICACHE_SIZE) {
+      end = start + ICACHE_SIZE;
+   }
+
+   for(addr = start; addr < end; addr += ICACHE_LINE_SIZE) {
+      __asm__ __volatile__ ("   flushi %0\n" 
+                            : /* Outputs */
+                            : /* Inputs  */ "r"(addr) 
+                            /* : No clobber */);
+   }
+   __asm__ __volatile(" flushp\n");
+}
+
+static void flush_aliases(struct address_space *mapping, struct page* page) {
+   struct mm_struct *mm = current->active_mm;
+   struct vm_area_struct *mpnt;
+   struct prio_tree_iter iter;
+   pgoff_t pgoff;
+   
+   pgoff = page->index;
+   
+   flush_dcache_mmap_lock(mapping);
+   vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) {
+      unsigned long offset;
+      
+      if (mpnt->vm_mm != mm)
+         continue;
+      if (!(mpnt->vm_flags & VM_MAYSHARE))
+            continue;
+      
+      offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
+      flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page));
+   }
+   flush_dcache_mmap_unlock(mapping);
+}
+
+extern void flush_cache_all()  {
+   __flush_dcache(0, DCACHE_SIZE);
+   __flush_icache(0, ICACHE_SIZE);
+}
+
+extern void flush_cache_mm(struct mm_struct *mm) {
+   flush_cache_all();
+}
+
+extern void flush_cache_dup_mm(struct mm_struct *mm) {
+   flush_cache_all();
+}
+
+extern void flush_icache_range(unsigned long start,unsigned long end) {
+   __flush_icache(start, end);
+}
+
+extern void flush_dcache_range(unsigned long start, unsigned long end) {
+   __flush_dcache(start, end);
+   /* FIXME: Maybe we should remove __flush_icache ? 
+    */
+   __flush_icache(start, end);
+}
+
+extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) {
+   __flush_dcache(start, end);
+   if(vma == NULL || (vma->vm_flags & VM_EXEC)) {
+      __flush_icache(start, end);
+   }
+}
+
+extern void flush_icache_page(struct vm_area_struct *vma, struct page* page) {
+   unsigned long start = (unsigned long) page_address(page);
+	unsigned long end = start + PAGE_SIZE;
+
+   __flush_icache(start, end);
+}
+
+extern void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) {
+   unsigned long start = vmaddr;
+	unsigned long end = start + PAGE_SIZE;
+
+   __flush_dcache(start, end);
+   if(vma->vm_flags & VM_EXEC) {
+      __flush_icache(start, end);
+   }
+}
+
+extern void flush_dcache_page(struct page* page) {
+   struct address_space *mapping = page_mapping(page);
+
+   /* Flush this page if there are aliases.
+    */
+   if(mapping) {
+      if (!mapping_mapped(mapping)) {
+         clear_bit(PG_arch_1, &page->flags);
+      }
+      else if(mapping) {
+         unsigned long start = (unsigned long) page_address(page);
+         __flush_dcache(start, start + PAGE_SIZE);
+         flush_aliases(mapping,  page);
+      }
+   }
+}
+EXPORT_SYMBOL(flush_dcache_page);
+
+void update_mmu_cache(struct vm_area_struct *vma,
+				          unsigned long address, pte_t pte)
+{
+	unsigned long pfn = pte_pfn(pte);
+	struct page *page;
+
+
+   if (!pfn_valid(pfn)) {
+		return;
+   }
+
+	page = pfn_to_page(pfn);
+
+   if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) {
+      unsigned long start = page_to_virt(page);
+      struct address_space *mapping;
+
+      __flush_dcache(start, start + PAGE_SIZE);
+
+      mapping = page_mapping(page);
+      if (mapping) {
+         flush_aliases(mapping, page);
+      }
+      set_bit(PG_arch_1, &page->flags);
+   }
+}
+
+extern void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+                			   struct page *to)
+{
+   flush_dcache_range(vaddr, vaddr + PAGE_SIZE);
+   flush_icache_range(vaddr, vaddr + PAGE_SIZE);
+   memcpy(vto, vfrom, PAGE_SIZE);
+   flush_dcache_range((unsigned long)vto, (unsigned long)vto + PAGE_SIZE);
+}
+
+extern void clear_user_page(void *addr, unsigned long vaddr, struct page* page)
+{
+   flush_dcache_range(vaddr, vaddr + PAGE_SIZE);
+   flush_icache_range(vaddr, vaddr + PAGE_SIZE);
+   memset(addr, 0, PAGE_SIZE);
+   flush_dcache_range((unsigned long)addr, (unsigned long)addr + PAGE_SIZE);
+}
+
+void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
+                         unsigned long user_vaddr,
+                         void *dst, void *src, int len)
+{
+   flush_cache_page(vma, user_vaddr, page_to_pfn(page));
+	memcpy(dst, src, len);
+   flush_dcache_range((unsigned long)src, (unsigned long)src+len);
+   if(vma->vm_flags & VM_EXEC) {
+      flush_icache_range((unsigned long)src, (unsigned long)src+len);
+   }
+}
+
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+                       unsigned long user_vaddr,
+                       void *dst, void *src, int len)
+{
+   flush_cache_page(vma, user_vaddr, page_to_pfn(page));
+	memcpy(dst, src, len);
+   flush_dcache_range((unsigned long)dst, (unsigned long)dst+len);
+   if(vma->vm_flags & VM_EXEC) {
+      flush_icache_range((unsigned long)dst, (unsigned long)dst+len);
+   }
+}
diff --git a/arch/nios2/mm/dma-noncoherent.c b/arch/nios2/mm/dma-noncoherent.c
new file mode 100644
index 0000000..2ff4cd6
--- /dev/null
+++ b/arch/nios2/mm/dma-noncoherent.c
@@ -0,0 +1,378 @@
+/* This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ *  linux/arch/nios2/mm/dma-noncoherent.c 
+ * 
+ *  Copyright (C) 2009, Wind River Systems Inc
+ *  Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ *
+ * Based on:
+ *
+ *  linux/arch/nios2nommu/mm/dma-noncoherent.c 
+ *
+ *
+ * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
+ * 
+ * Swiped from MIPS and cloned for nios2 by fredrik.markstrom@gmail.com 
+ * and  ivarholmqvist@gmail.com
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+
+
+/*
+ * Warning on the terminology - Linux calls an uncached area coherent;
+ * MIPS terminology calls memory areas with hardware maintained coherency
+ * coherent.
+ */
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, gfp_t gfp)
+{
+	void *ret;
+	/* ignore region specifiers */
+	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
+		gfp |= GFP_DMA;
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_phys(ret);
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_noncoherent);
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, gfp_t gfp)
+{
+	void *ret;
+
+	ret = dma_alloc_noncoherent(dev, size, dma_handle, gfp);
+	if (ret) {
+		flush_dcache_range((unsigned long) ret, (unsigned long) ret + size);
+		ret = UNCAC_ADDR(ret);
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	free_pages((unsigned long) vaddr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_noncoherent);
+
+void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	unsigned long addr = (unsigned long) vaddr;
+
+	addr = (unsigned long) CAC_ADDR(addr);
+	free_pages(addr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_coherent);
+
+static inline void __dma_sync(unsigned long addr, size_t size,
+	enum dma_data_direction direction)
+{
+	switch (direction) {
+	case DMA_TO_DEVICE:
+	case DMA_FROM_DEVICE:
+	case DMA_BIDIRECTIONAL:
+		flush_dcache_range((unsigned long) addr, (unsigned long) addr + size);
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+	enum dma_data_direction direction)
+{
+	unsigned long addr = (unsigned long) ptr;
+
+	__dma_sync(addr, size, direction);
+
+	return virt_to_phys(ptr);
+}
+
+EXPORT_SYMBOL(dma_map_single);
+
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+	enum dma_data_direction direction)
+{
+	unsigned long addr;
+	addr = dma_addr + PAGE_OFFSET;
+
+	//__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_unmap_single);
+
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	for_each_sg (sg, sg, nents, i) {
+		unsigned long addr;
+
+		addr = (unsigned long) sg_virt(sg);
+		if (addr) {
+			__dma_sync(addr, sg->length, direction);
+			sg->dma_address = sg_phys(sg);
+		}
+	}
+
+	return nents;
+}
+
+EXPORT_SYMBOL(dma_map_sg);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = (unsigned long) page_address(page) + offset;
+	__dma_sync(addr, size, direction);
+
+	return page_to_phys(page) + offset;
+}
+
+EXPORT_SYMBOL(dma_map_page);
+
+void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+	enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+
+	if (direction != DMA_TO_DEVICE) {
+		unsigned long addr;
+
+		addr = dma_address + PAGE_OFFSET;
+		__dma_sync(addr, size, direction);
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_page);
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	enum dma_data_direction direction)
+{
+	unsigned long addr;
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	if (direction == DMA_TO_DEVICE)
+		return;
+
+	for_each_sg (sg, sg, nhwentries, i) {
+		addr = (unsigned long) sg_virt(sg);
+		if (addr)
+			__dma_sync(addr, sg->length, direction);
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_sg);
+
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = dma_handle + PAGE_OFFSET;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_cpu);
+
+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = dma_handle + PAGE_OFFSET;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_device);
+
+void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = dma_handle + offset + PAGE_OFFSET;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
+
+void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = dma_handle + offset + PAGE_OFFSET;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_device);
+
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for_each_sg (sg, sg, nelems, i) {
+		__dma_sync((unsigned long)sg_virt(sg),
+		           sg->length, direction);
+	}
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for_each_sg (sg, sg, nelems, i) {
+		__dma_sync((unsigned long)sg_virt(sg),
+		           sg->length, direction);
+	}
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_mapping_error);
+
+int dma_supported(struct device *dev, u64 mask)
+{
+	/*
+	 * we fall back to GFP_DMA when the mask isn't all 1s,
+	 * so we can't guarantee allocations that must be
+	 * within a tighter range than GFP_DMA..
+	 */
+	if (mask < 0x00ffffff)
+		return 0;
+
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_supported);
+
+int dma_is_consistent(dma_addr_t dma_addr)
+{
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_is_consistent);
+
+void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction)
+{
+	if (direction == DMA_NONE)
+		return;
+
+	__dma_sync((unsigned long)vaddr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_cache_sync);
+
+/* The DAC routines are a PCIism.. */
+
+#ifdef CONFIG_PCI
+
+#include <linux/pci.h>
+
+dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev,
+	struct page *page, unsigned long offset, int direction)
+{
+	return (dma64_addr_t)page_to_phys(page) + offset;
+}
+
+EXPORT_SYMBOL(pci_dac_page_to_dma);
+
+struct page *pci_dac_dma_to_page(struct pci_dev *pdev,
+	dma64_addr_t dma_addr)
+{
+	return mem_map + (dma_addr >> PAGE_SHIFT);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_to_page);
+
+unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
+	dma64_addr_t dma_addr)
+{
+	return dma_addr & ~PAGE_MASK;
+}
+
+EXPORT_SYMBOL(pci_dac_dma_to_offset);
+
+void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
+	dma64_addr_t dma_addr, size_t len, int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	__dma_sync(dma_addr + PAGE_OFFSET, len, DMA_BIDIRECTIONAL);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu);
+
+void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
+	dma64_addr_t dma_addr, size_t len, int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	__dma_sync(dma_addr + PAGE_OFFSET, len, DMA_BIDIRECTIONAL);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device);
+
+#endif /* CONFIG_PCI */
diff --git a/arch/nios2/mm/extable.c b/arch/nios2/mm/extable.c
new file mode 100644
index 0000000..ee41cd3
--- /dev/null
+++ b/arch/nios2/mm/extable.c
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ */
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+
+int fixup_exception(struct pt_regs *regs, unsigned long address)
+{
+	const struct exception_table_entry *fixup;
+
+	fixup = search_exception_tables(regs->ea);
+	if (fixup) {
+		regs->ea = fixup->nextinsn;
+
+		return 1;
+	}
+
+	return 0;
+}
diff --git a/arch/nios2/mm/fault.c b/arch/nios2/mm/fault.c
new file mode 100644
index 0000000..7d6501e
--- /dev/null
+++ b/arch/nios2/mm/fault.c
@@ -0,0 +1,288 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * linux/nios2/mm/fault.c
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ *
+ * Based on:
+ *
+ * linux/nios2nommu/mm/fault.c
+ *
+ * Copyright (C) 1995 - 2000 by Ralf Baechle
+ */
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/vt_kern.h>		/* For unblank_screen() */
+#include <linux/module.h>
+
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/ptrace.h>
+
+#include <asm/tlbstats.h>
+
+extern struct tlb_stat statistics;
+
+/*
+ * This routine handles page faults.  It determines the address,
+ * and the problem, and then passes it off to one of the appropriate
+ * routines.
+ */
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
+                              unsigned long address)
+{
+	struct vm_area_struct * vma = NULL;
+	struct task_struct *tsk = current;
+	struct mm_struct *mm = tsk->mm;
+	const int field = sizeof(unsigned long) * 2;
+	siginfo_t info;
+	int fault;
+   int write = 0;
+
+	statistics.do_page_fault++;
+	info.si_code = SEGV_MAPERR;
+
+	/*
+	 * We fault-in kernel-space virtual memory on-demand. The
+	 * 'reference' page table is init_mm.pgd.
+	 *
+	 * NOTE! We MUST NOT take any locks for this case. We may
+	 * be in an interrupt or a critical region, and should
+	 * only copy the information from the master page table,
+	 * nothing more.
+	 */
+	if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END)) {
+	  if (user_mode(regs)) {
+	    goto bad_area_nosemaphore;
+	  }
+	  else {
+        goto vmalloc_fault;
+	  }
+   }
+#ifdef MODULE_START
+	if (unlikely(address >= MODULE_START && address < MODULE_END))
+               goto vmalloc_fault;
+#endif
+	if(unlikely(address >= TASK_SIZE)) {
+		goto bad_area_nosemaphore;
+	}
+	/*
+	 * If we're in an interrupt or have no user
+	 * context, we must not take the fault..
+	 */
+	if (in_atomic() || !mm)
+		goto bad_area_nosemaphore;
+
+	down_read(&mm->mmap_sem);
+	vma = find_vma(mm, address);
+	if (!vma)
+		goto bad_area;
+	if (vma->vm_start <= address)
+		goto good_area;
+	if (!(vma->vm_flags & VM_GROWSDOWN))
+		goto bad_area;
+	if (expand_stack(vma, address))
+		goto bad_area;
+/*
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+good_area:
+	info.si_code = SEGV_ACCERR;
+
+   switch(cause) {
+      case EXC_SUPERV_INSN_ACCESS:
+         goto bad_area;
+
+      case EXC_SUPERV_DATA_ACCESS:
+         goto bad_area;
+
+      case EXC_X_PROTECTION_FAULT:
+         if (!(vma->vm_flags & VM_EXEC)) {
+            goto bad_area;
+         }
+         break;
+      case EXC_R_PROTECTION_FAULT:
+         if (!(vma->vm_flags & VM_READ)) {
+            goto bad_area;
+         }
+         break;
+      case EXC_W_PROT_FAULT:
+         write = 1;
+         if (!(vma->vm_flags & VM_WRITE)) {
+            goto bad_area;
+         }
+         break;
+	}
+
+survive:
+	/*
+	 * If for any reason at all we couldn't handle the fault,
+	 * make sure we exit gracefully rather than endlessly redo
+	 * the fault.
+	 */
+	fault = handle_mm_fault(mm, vma, address, write);
+	if (unlikely(fault & VM_FAULT_ERROR)) {
+		if (fault & VM_FAULT_OOM)
+			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGBUS)
+			goto do_sigbus;
+		BUG();
+	}
+	if (fault & VM_FAULT_MAJOR)
+		current->maj_flt++;
+	else
+		current->min_flt++;
+
+	up_read(&mm->mmap_sem);
+	return;
+
+/*
+ * Something tried to access memory that isn't in our memory map..
+ * Fix it, but check if it's kernel or user first..
+ */
+bad_area:
+	up_read(&mm->mmap_sem);
+
+bad_area_nosemaphore:
+	/* User mode accesses just cause a SIGSEGV */
+	if (user_mode(regs)) {
+#if 0
+		printk("do_page_fault() #2: sending SIGSEGV to %s for "
+		       "invalid %s\n%0*lx (ea == %0*lx)(ra == %0*lx)\n",
+		       tsk->comm,
+		       write ? "write access to" : "read access from",
+		       field, address,
+		       field, (unsigned long) regs->ea, 
+		       field, (unsigned long) regs->ra);
+#endif
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		/* info.si_code has been set above */
+		info.si_addr = (void __user *) address;
+		force_sig_info(SIGSEGV, &info, tsk);
+		return;
+	}
+
+no_context:
+	/* Are we prepared to handle this kernel fault?  */
+	if (fixup_exception(regs, address)) {
+		return;
+	}
+
+	/*
+	 * Oops. The kernel tried to access some bad page. We'll have to
+	 * terminate things with extreme prejudice.
+	 */
+	bust_spinlocks(1);
+
+	printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at "
+	       "virtual address %0*lx, epc == %0*lx, ra == %0*lx\n",
+	       raw_smp_processor_id(), field, address, field, regs->ea,
+	       field,  regs->ra);
+	panic("Oops");
+
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+out_of_memory:
+	up_read(&mm->mmap_sem);
+	if (is_global_init(tsk)) {
+		yield();
+		down_read(&mm->mmap_sem);
+		goto survive;
+	}
+	printk(KERN_INFO "VM: killing process %s\n", tsk->comm);
+	if (user_mode(regs))
+		do_group_exit(SIGKILL);
+	goto no_context;
+
+do_sigbus:
+	up_read(&mm->mmap_sem);
+
+	/* Kernel mode? Handle exceptions or die */
+	if (!user_mode(regs))
+		goto no_context;
+	else
+	/*
+	 * Send a sigbus, regardless of whether we were in kernel
+	 * or user mode.
+	 */
+#if 0
+		printk("do_page_fault() #3: sending SIGBUS to %s for "
+		       "invalid %s\n%0*lx (epc == %0*lx, ra == %0*lx)\n",
+		       tsk->comm,
+		       write ? "write access to" : "read access from",
+		       field, address,
+		       field, (unsigned long) regs->ea,
+		       field, (unsigned long) regs->ra);
+#endif
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	info.si_code = BUS_ADRERR;
+	info.si_addr = (void __user *) address;
+	force_sig_info(SIGBUS, &info, tsk);
+
+	return;
+vmalloc_fault:
+	{
+		/*
+		 * Synchronize this task's top level page-table
+		 * with the 'reference' page table.
+		 *
+		 * Do _not_ use "tsk" here. We might be inside
+		 * an interrupt in the middle of a task switch..
+		 */
+#define pgd_index(address)	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+#define __pgd_offset(address)	pgd_index(address)
+		int offset = __pgd_offset(address);
+		pgd_t *pgd, *pgd_k;
+		pud_t *pud, *pud_k;
+		pmd_t *pmd, *pmd_k;
+		pte_t *pte_k;
+
+#if 1
+      /* FIXME: Is this entierly correct ?
+       */
+		pgd = (pgd_t *) pgd_current[raw_smp_processor_id()] + offset;
+#else
+		pgd = &current->mm->pgd[offset];
+#endif
+		pgd_k = init_mm.pgd + offset;
+
+		if (!pgd_present(*pgd_k))
+			goto no_context;
+		set_pgd(pgd, *pgd_k);
+
+		pud = pud_offset(pgd, address);
+		pud_k = pud_offset(pgd_k, address);
+		if (!pud_present(*pud_k))
+			goto no_context;
+		pmd = pmd_offset(pud, address);
+		pmd_k = pmd_offset(pud_k, address);
+		if (!pmd_present(*pmd_k))
+			goto no_context;
+		set_pmd(pmd, *pmd_k);
+
+		pte_k = pte_offset_kernel(pmd_k, address);
+		if (!pte_present(*pte_k)) {
+			goto no_context;
+      }
+		return;
+	}
+}
diff --git a/arch/nios2/mm/init.c b/arch/nios2/mm/init.c
new file mode 100644
index 0000000..28bba60
--- /dev/null
+++ b/arch/nios2/mm/init.c
@@ -0,0 +1,256 @@
+/*
+ *  linux/arch/nios2/mm/init.c
+ *
+ *  Copyright (C) 2009 Wind River Systems Inc trough
+ *  Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ *
+ *  Based on:
+ * 
+ *  linux/arch/nios2nommu/mm/init.c
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
+ * Copyright (C) 2004   Microtronix Datacom Ltd
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/init.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *
+ *  JAN/1999 -- hacked to support ColdFire (gerg@snapgear.com)
+ *  DEC/2000 -- linux 2.4 support <davidm@snapgear.com>
+ * Jan/20/2004		dgt	    NiosII
+ *
+ */
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/init.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/bootmem.h>
+#include <linux/slab.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/percpu.h>
+#include <asm/tlb.h>
+#include <asm/mmu_context.h>
+
+//;dgt2;#include <asm/machdep.h>
+//;dgt2;#include <asm/shglcore.h>
+
+#define DEBUG
+
+extern void die_if_kernel(char *,struct pt_regs *,long);
+extern void free_initmem(void);
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+static unsigned long empty_bad_page_table;
+
+static unsigned long empty_bad_page;
+
+unsigned long empty_zero_page;
+
+unsigned long empty_zero_page, zero_page_mask;
+
+extern unsigned long rom_length;
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses of available kernel virtual memory.
+ */
+void __init paging_init(void)
+{
+	/*
+	 * Make sure start_mem is page aligned, otherwise bootmem and
+	 * page_alloc get different views of the world.
+	 */
+	unsigned long start_mem = PHYS_OFFSET;
+	unsigned long end_mem   = memory_end;
+
+   pagetable_init();
+   pgd_current[0] = (unsigned long)swapper_pg_dir;
+
+	/*
+	 * Initialize the bad page table and bad page to point
+	 * to a couple of allocated pages.
+	 */
+	empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_zero_page = (unsigned long)alloc_bootmem_pages(DCACHE_SIZE);
+	memset((void *)empty_zero_page, 0, DCACHE_SIZE);
+   flush_dcache_range(empty_zero_page, empty_zero_page + DCACHE_SIZE);
+
+	/*
+	 * Set up SFC/DFC registers (user data space).
+	 */
+#if 0
+	set_fs (USER_DS);
+#endif
+
+	{
+		unsigned long zones_size[MAX_NR_ZONES] = {0, };
+
+		zones_size[ZONE_DMA] = ((end_mem - start_mem) >> PAGE_SHIFT);
+		zones_size[ZONE_NORMAL] = 0;
+#ifdef CONFIG_HIGHMEM
+		zones_size[ZONE_HIGHMEM] = 0;
+#endif
+		free_area_init(zones_size);
+	}
+}
+
+void __init mem_init(void)
+{
+	int codek = 0, datak = 0, initk = 0;
+	unsigned long tmp;
+	extern char _etext, _stext, __init_begin, __init_end, _end;
+	unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */
+	unsigned long end_mem   = memory_end; /* DAVIDM - this must not include kernel stack at top */
+
+#ifdef DEBUG
+	printk(KERN_DEBUG "Mem_init: start=%lx, end=%lx\n", start_mem, end_mem);
+#endif
+
+	end_mem &= PAGE_MASK;
+	high_memory = __va(end_mem);
+
+	start_mem = PAGE_ALIGN(start_mem);
+	max_mapnr = ((unsigned long)end_mem) >> PAGE_SHIFT;
+	num_physpages = max_mapnr;
+	printk("We have %ld pages of RAM\n", num_physpages);
+
+	/* this will put all memory onto the freelists */
+	totalram_pages = free_all_bootmem();
+
+	codek = (&_etext - &_stext) >> 10;
+	datak = (&_end - &_etext) >> 10;
+	initk = (&__init_begin - &__init_end) >> 10;
+
+	tmp = nr_free_pages() << PAGE_SHIFT;
+	printk(KERN_INFO "Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n",
+	       tmp >> 10,
+	       (&_end - &_stext) >> 10,
+	       (rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
+	       rom_length >> 10,
+	       codek,
+	       datak
+	       );
+}
+
+
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void __init free_initrd_mem(unsigned long start, unsigned long end)
+{
+	int pages = 0;
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(start));
+		init_page_count(virt_to_page(start));
+		free_page(start);
+		totalram_pages++;
+		pages++;
+	}
+	printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
+}
+#endif
+
+void free_initmem(void)
+{
+#ifdef CONFIG_RAMKERNEL
+	unsigned long addr;
+	extern char __init_begin, __init_end;
+	/*
+	 * The following code should be cool even if these sections
+	 * are not page aligned.
+	 */
+	addr = PAGE_ALIGN((unsigned long)(&__init_begin));
+	/* next to check that the page we free is not a partial page */
+	for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(addr));
+		init_page_count(virt_to_page(addr));
+		free_page(addr);
+		totalram_pages++;
+	}
+	printk(KERN_NOTICE "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n",
+			(addr - PAGE_ALIGN((long) &__init_begin)) >> 10,
+			(int)(PAGE_ALIGN((unsigned long)(&__init_begin))),
+			(int)(addr - PAGE_SIZE));
+#endif
+}
+
+void __init fixrange_init(unsigned long start, unsigned long end,
+	pgd_t *pgd_base)
+{
+#if defined(CONFIG_HIGHMEM)
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+	int i, j, k;
+	unsigned long vaddr;
+
+	vaddr = start;
+	i = __pgd_offset(vaddr);
+	j = __pud_offset(vaddr);
+	k = __pmd_offset(vaddr);
+	pgd = pgd_base + i;
+
+	for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+		pud = (pud_t *)pgd;
+		for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
+			pmd = (pmd_t *)pud;
+			for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
+				if (pmd_none(*pmd)) {
+					pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+					set_pmd(pmd, __pmd((unsigned long)pte));
+					if (pte != pte_offset_kernel(pmd, 0))
+						BUG();
+				}
+				vaddr += PMD_SIZE;
+			}
+			k = 0;
+		}
+		j = 0;
+	}
+#endif
+}
+
+
+#define __page_aligned(order) __attribute__((__aligned__(PAGE_SIZE<<order)))
+unsigned long pgd_current[NR_CPUS];
+pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned(PGD_ORDER);
+pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER);
diff --git a/arch/nios2/mm/ioremap.c b/arch/nios2/mm/ioremap.c
new file mode 100644
index 0000000..0964368
--- /dev/null
+++ b/arch/nios2/mm/ioremap.c
@@ -0,0 +1,217 @@
+/*
+ *  linux/arch/nios2/mm/ioremap.c
+ *
+ *   Copyright (C) 2009, Wind River Systems Inc
+ *   Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ *
+ *  linux/arch/nios2nommu/mm/ioremap.c, based on:
+ *
+ *  linux/arch/m68knommu/mm/kmap.c
+ *
+ *  Copyright (C) 2004 Microtronix Datacom Ltd.
+ *  Copyright (C) 2000 Lineo, <davidm@lineo.com>
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/tlbflush.h>
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address,
+                                  unsigned long size, 
+                                  unsigned long phys_addr, unsigned long flags)
+{
+	unsigned long end;
+	unsigned long pfn;
+	pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | _PAGE_READ
+	                           | _PAGE_WRITE | flags);
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	if (address >= end)
+		BUG();
+	pfn = phys_addr >> PAGE_SHIFT;
+	do {
+		if (!pte_none(*pte)) {
+			printk("remap_area_pte: page already exists\n");
+			BUG();
+		}
+		set_pte(pte, pfn_pte(pfn, pgprot));
+		address += PAGE_SIZE;
+		pfn++;
+		pte++;
+	} while (address && (address < end));
+}
+
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
+                                 unsigned long size, unsigned long phys_addr, 
+                                 unsigned long flags)
+{
+	unsigned long end;
+
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	phys_addr -= address;
+	if (address >= end)
+		BUG();
+	do {
+		pte_t * pte = pte_alloc_kernel(pmd, address);
+		if (!pte)
+			return -ENOMEM;
+		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+	return 0;
+}
+
+static int remap_area_pages(unsigned long address, 
+                            unsigned long phys_addr,
+                            unsigned long size, unsigned long flags)
+{
+	int error;
+	pgd_t * dir;
+	unsigned long end = address + size;
+
+	phys_addr -= address;
+	dir = pgd_offset(&init_mm, address);
+	flush_cache_all();
+	if (address >= end)
+		BUG();
+	do {
+		pud_t *pud;
+		pmd_t *pmd;
+
+		error = -ENOMEM;
+		pud = pud_alloc(&init_mm, dir, address);
+		if (!pud)
+			break;
+		pmd = pmd_alloc(&init_mm, pud, address);
+		if (!pmd)
+			break;
+		if (remap_area_pmd(pmd, address, end - address,
+					 phys_addr + address, flags))
+			break;
+		error = 0;
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	} while (address && (address < end));
+	flush_tlb_all();
+	return error;
+}
+
+#define IS_MAPPABLE_UNCACHEABLE(addr) (addr < 0x20000000UL)
+
+/*
+ * Map some physical address range into the kernel address space.
+ */
+void *__ioremap(unsigned long phys_addr, unsigned long size, int cacheflag)
+{
+	struct vm_struct * area;
+	unsigned long offset;
+	unsigned long last_addr;
+	void * addr;
+
+	/* Don't allow wraparound or zero size 
+    */
+	last_addr = phys_addr + size - 1;
+
+	if (!size || last_addr < phys_addr)
+		return NULL;
+
+	/* Don't allow anybody to remap normal RAM that we're using..
+	 */
+	if (phys_addr > PHYS_OFFSET && phys_addr < virt_to_phys(high_memory)) {
+		char *t_addr, *t_end;
+		struct page *page;
+
+		t_addr = __va(phys_addr);
+		t_end = t_addr + (size - 1);
+		for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
+			if(!PageReserved(page)) {
+				return NULL;
+         }
+	}
+
+	/*
+	 * Map uncached objects in the low part of address space to 0xe0000000UL
+	 */
+	if (IS_MAPPABLE_UNCACHEABLE(phys_addr) && 
+       IS_MAPPABLE_UNCACHEABLE(last_addr) &&
+       !(cacheflag & _PAGE_CACHED))
+   {
+		return (void __iomem *)(0xe0000000UL + phys_addr);
+   }
+
+
+	/*
+	 * Mappings have to be page-aligned
+	 */
+	offset = phys_addr & ~PAGE_MASK;
+	phys_addr &= PAGE_MASK;
+	size = PAGE_ALIGN(last_addr + 1) - phys_addr;
+
+	/*
+	 * Ok, go for it..
+	 */
+	area = get_vm_area(size, VM_IOREMAP);
+	if (!area)
+		return NULL;
+	addr = area->addr;
+	if (remap_area_pages((unsigned long) addr, phys_addr, size, cacheflag)) {
+		vunmap(addr);
+		return NULL;
+	}
+	return (void __iomem *) (offset + (char *)addr);
+}
+
+/*
+ * __iounmap unmaps nearly everything, so be careful
+ * it doesn't free currently pointer/page tables anymore but it
+ * wasn't used anyway and might be added later.
+ */
+void __iounmap(void *addr)
+{
+	struct vm_struct *p;
+
+	if (addr > (void*)0xe0000000UL)     /* FIXME */
+		return;
+
+	p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
+	if (!p)
+		printk(KERN_ERR "iounmap: bad address %p\n", addr);
+   kfree(p);
+}
+
diff --git a/arch/nios2/mm/memory.c b/arch/nios2/mm/memory.c
new file mode 100644
index 0000000..806acc6
--- /dev/null
+++ b/arch/nios2/mm/memory.c
@@ -0,0 +1,58 @@
+/*
+ *  linux/arch/nios2/mm/memory.c
+ * 
+ *  Copyright (C) 2009, Wind River Systems Inc
+ *  Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ *
+ *  Based on:
+ *
+ *  linux/arch/nio2nommu/mm/memory.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *  Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 2004  Microtronix Datacom Ltd.
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/memory.c
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+
+unsigned long kernel_map(unsigned long paddr, unsigned long size,
+			 int nocacheflag, unsigned long *memavailp )
+{
+	return paddr;
+}
diff --git a/arch/nios2/mm/mmdump.c b/arch/nios2/mm/mmdump.c
new file mode 100644
index 0000000..80caf31
--- /dev/null
+++ b/arch/nios2/mm/mmdump.c
@@ -0,0 +1,80 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ */
+
+#include <asm/pgtable.h>
+#include <linux/mm.h>
+
+void dump_pte(unsigned long baseaddr, pte_t* pte) {
+  int i;
+  printk("\n==========================================================\n");
+  printk("PTE @0x%p dump\n", pte);
+  printk("==========================================================\n");
+  for(i = 0; i < PTRS_PER_PTE; i++) {
+    unsigned long v = pte_val(pte[i]);
+    if(pte_present(*pte) || v != 0) {
+      printk("%#10lx val=%#10lx (pfn=%ld prot=%#lx\n", 
+	     baseaddr + i*PAGE_SIZE, v, v & 0xfffffUL, v >> 20);
+    }
+    else {
+      if(v != 0) {
+	/* Oooops, present but not 0... it's probably ok but unimplemented
+	 */
+	BUG();
+      }
+    }
+  }
+}
+
+void dump_pgd(void) {
+  int i;
+  printk("\n==========================================================\n");
+  printk("PGD dump\n");
+  printk("==========================================================\n");
+  printk("current->mm = %p\n", current->mm);
+  if(current->mm == NULL) { return; }
+  printk("current->mm->pgd = %p\n", current->mm->pgd);
+  
+  for(i = 0; i < PTRS_PER_PGD; i++) {
+    if(pgd_val(current->mm->pgd[i]) == (unsigned long)invalid_pte_table) {
+      continue;
+    }
+    if(pgd_val(current->mm->pgd[i]) == 0) {
+      continue;
+    }
+    printk("pgd[%d] VA@%#10x = %#10lx\n", i, i << PGDIR_SHIFT,
+	   pgd_val(current->mm->pgd[i]));
+
+    {
+      pgd_t* pgd = &current->mm->pgd[i];
+      pud_t* pud = pud_offset(pgd, i << PGDIR_SHIFT);
+      pmd_t* pmd = pmd_offset(pud, i << PGDIR_SHIFT);
+      pte_t* pte = pte_offset_map(pmd, i << PGDIR_SHIFT);
+      
+      dump_pte(i << PGDIR_SHIFT, pte);
+    }
+  }
+}
+
+void dump_page_array(void) {
+  int i;
+  printk("Page array\n");
+  printk("==========================================================\n");
+  for(i = 0; i < num_physpages; i++) {
+    struct page* page = &mem_map[i];
+    printk("Page %4d flags=%#10lx _count=%-2d _mapcount=%-2d index=%ld virtual=%#lx\n",
+	   i,
+	   page->flags, page_count(page), page_mapcount(page), page->index, 
+	   /*(unsigned long)page->virtual*/ 0xdeadbabeUL);
+  }
+}
+
+void dump_all(void) {
+  dump_pgd();
+  dump_page_array();
+}
diff --git a/arch/nios2/mm/mmu_context.c b/arch/nios2/mm/mmu_context.c
new file mode 100644
index 0000000..70e22e0
--- /dev/null
+++ b/arch/nios2/mm/mmu_context.c
@@ -0,0 +1,144 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ */
+
+#include <asm/nios.h>
+#include <asm/mmu_context.h>
+
+/* The pids position and mask in context.
+ */
+#define PID_SHIFT       0                     
+#define PID_BITS        PROCESS_ID_NUM_BITS
+#define PID_MASK        ((1UL << PID_BITS) - 1)
+
+/* The versions position and mask in context
+ */
+#define VERSION_BITS  (32-PID_BITS)
+#define VERSION_SHIFT (PID_SHIFT + PID_BITS)
+#define VERSION_MASK  ((1UL << VERSION_BITS) - 1)
+
+/* Return the version part of a context
+ */
+#define CTX_VERSION(c) (((c) >> VERSION_SHIFT) & VERSION_MASK)
+
+/* Return the pid part of a context
+ */
+#define CTX_PID(c)     (((c) >> PID_SHIFT) & PID_MASK)
+
+
+/* Value of the first context (version 1, pid 0)
+ */
+#define FIRST_CTX      ((1UL << VERSION_SHIFT)|(0 << PID_SHIFT))
+
+static unsigned long ctx = FIRST_CTX;
+
+/* For the fast tlb miss handlers, we keep a per cpu array of pointers
+ * to the current pgd for each processor. Also, the proc. id is stuffed
+ * into the context register.
+ */
+extern unsigned long pgd_current[];
+
+
+void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+/* Set new context (pid), keep way
+ */
+static void set_context(mm_context_t context)
+{
+   extern void set_mmu_pid(unsigned long pid);
+   set_mmu_pid(CTX_PID(context[0]));
+}
+
+static unsigned long get_new_context(void)
+{
+
+   /* Return the next pid
+    */
+   ctx += (1UL << PID_SHIFT);
+
+   /* If the pid field wraps around we increase the version and
+    * flush the tlb.
+    */
+   if (unlikely(CTX_PID(ctx) == 0)) {
+      /* Version is incremented since the pid increment above
+       * overflows info version.
+       */
+      flush_cache_all();
+      local_flush_tlb_all();    
+   }
+
+   /* If the version wraps we start over with the first 
+    * generation, we do not need to flush the tlb here
+    * since it's always done in the if above
+    */
+   if (unlikely(CTX_VERSION(ctx) == 0)) {
+      ctx = FIRST_CTX;    
+   }
+
+   return ctx;
+}
+
+/* Set all new contexts to 0, that way the generation will never match
+ * the currently running generation when this context is switched in.
+ */
+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+  mm->context[0] = 0;
+  return 0;
+}
+
+void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+	       struct task_struct *tsk)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+   /* If the process context we are swapping in has a 
+    * different context generation then we have it should
+    * get a new generation/pid.
+    */
+	if (unlikely(CTX_VERSION(next->context[0]) != CTX_VERSION(ctx))) {
+      next->context[0] = get_new_context();
+	}
+   /* Save the current pgd so the fast tlb handler can find it
+    */
+	pgd_current[smp_processor_id()] = (unsigned long)next->pgd;
+
+   /* Set the current context
+    */
+	set_context(next->context);
+   
+	local_irq_restore(flags);
+}
+
+void deactivate_mm(struct task_struct *tsk, struct mm_struct *mm)
+{
+
+}
+
+/* Destroy context related info for an mm_struct that is about
+ * to be put to rest.
+ */
+void destroy_context(struct mm_struct *mm){
+}
+
+/* After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+void activate_mm(struct mm_struct *prev, struct mm_struct *next) {
+  next->context[0] = get_new_context();
+  set_context(next->context);
+  pgd_current[smp_processor_id()] = (unsigned long)next->pgd;
+}
+
+unsigned long get_pid_from_context(mm_context_t* context) {
+   return CTX_PID((*context)[0]);
+}
diff --git a/arch/nios2/mm/pg.c b/arch/nios2/mm/pg.c
new file mode 100644
index 0000000..cfcaa96
--- /dev/null
+++ b/arch/nios2/mm/pg.c
@@ -0,0 +1,22 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+
diff --git a/arch/nios2/mm/pgalloc.c b/arch/nios2/mm/pgalloc.c
new file mode 100644
index 0000000..8dae434
--- /dev/null
+++ b/arch/nios2/mm/pgalloc.c
@@ -0,0 +1,24 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ */
+
+#include <asm/pgalloc.h>
+
+pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+	pgd_t *ret, *init;	
+	ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER);
+	if (ret) {
+		init = pgd_offset(&init_mm, 0UL);
+		pgd_init((unsigned long)ret);
+		memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+		       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+	}
+
+	return ret;
+}
diff --git a/arch/nios2/mm/pgtable.c b/arch/nios2/mm/pgtable.c
new file mode 100644
index 0000000..ddbd333
--- /dev/null
+++ b/arch/nios2/mm/pgtable.c
@@ -0,0 +1,349 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <asm/fixmap.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+
+#define DEBUG 0
+#define dprintk(fmt,args...) if(DEBUG) { printk(__FILE__   fmt, ##args); }
+
+/* pteaddr: 
+ *   ptbase | vpn* | zero
+ *   31-22  | 21-2 | 1-0
+ *   
+ *   *vpn is preserved on double fault
+ *   
+ * tlbacc:
+ *   IG   |*flags| pfn
+ *   31-25|24-20 | 19-0
+ *   
+ *   *crwxg
+ *   
+ * tlbmisc:
+ *   resv  |way   |rd | we|pid |dbl|bad|perm|d
+ *   31-24 |23-20 |19 | 20|17-4|3  |2  |1   |0
+ *  
+ */
+
+#define CALLED()
+
+void pgd_init(unsigned long page)
+{
+  unsigned long *p = (unsigned long *) page;
+  int i;
+  CALLED();
+  
+  for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+    p[i + 0] = (unsigned long) invalid_pte_table;
+    p[i + 1] = (unsigned long) invalid_pte_table;
+    p[i + 2] = (unsigned long) invalid_pte_table;
+    p[i + 3] = (unsigned long) invalid_pte_table;
+    p[i + 4] = (unsigned long) invalid_pte_table;
+    p[i + 5] = (unsigned long) invalid_pte_table;
+    p[i + 6] = (unsigned long) invalid_pte_table;
+    p[i + 7] = (unsigned long) invalid_pte_table;
+  }
+}
+
+void __init pagetable_init(void)
+{
+	pgd_t *pgd_base;
+#ifdef CONFIG_HIGHMEM
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+#endif
+	dprintk("check impl\n");
+
+	/* Initialize the entire pgd.  */
+	pgd_init((unsigned long)swapper_pg_dir);
+	pgd_init((unsigned long)swapper_pg_dir
+		 + sizeof(pgd_t) * USER_PTRS_PER_PGD);
+
+	pgd_base = swapper_pg_dir;
+
+#ifdef CONFIG_HIGHMEM
+	/*
+	 * Permanent kmaps:
+	 */
+	vaddr = PKMAP_BASE;
+	fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+
+	pgd = swapper_pg_dir + __pgd_offset(vaddr);
+	pud = pud_offset(pgd, vaddr);
+	pmd = pmd_offset(pud, vaddr);
+	pte = pte_offset_kernel(pmd, vaddr);
+	pkmap_page_table = pte;
+#endif
+}
+
+#define pgd_index(address)	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+
+
+/* FIXME: Avoiding cache alias for the zero-page is kind of stupid
+ *        but we need to do it to avoid alias-warnings in the iss.
+ */
+extern unsigned long empty_zero_page;
+struct page * ZERO_PAGE(unsigned long vaddr)
+{
+  struct page* page;
+  unsigned long poffset;
+
+  poffset = vaddr & ((DCACHE_SIZE - 1) & ~(PAGE_SIZE - 1));
+
+  page = virt_to_page(empty_zero_page + poffset);
+
+  return page;
+}
+
+
+/*
+ * (pmds are folded into puds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+void set_pmd(pmd_t *pmdptr, pmd_t pmdval)
+{
+  CALLED();
+
+  pmdptr->pud.pgd.pgd = pmdval.pud.pgd.pgd;
+}
+
+pgd_t *pgd_offset(struct mm_struct *mm, unsigned long addr)
+{
+  return mm->pgd + pgd_index(addr);
+}
+
+void pgtable_cache_init(void)
+{
+}
+
+/* ivho: set back to "static inline" when correct in pgtable.c
+ */
+int pte_write(pte_t pte){
+  return (pte_val(pte) & (_PAGE_WRITE << 20)) != 0;
+}
+int pte_dirty(pte_t pte){
+  return (pte_val(pte) & (_PAGE_MODIFIED << 20)) != 0;
+
+}
+int pte_young(pte_t pte){
+  return (pte_val(pte) & (_PAGE_ACCESSED << 20)) != 0;
+}
+int pte_file(pte_t pte){BUG();}
+
+/* Swap not implemented
+ */
+swp_entry_t   __pte_to_swp_entry(pte_t pte){BUG();}
+pte_t         __swp_entry_to_pte(swp_entry_t swp){BUG();}
+unsigned long __swp_type(swp_entry_t swp){BUG();}
+pgoff_t       __swp_offset(swp_entry_t swp){BUG();}
+swp_entry_t   __swp_entry(unsigned long type, pgoff_t offset){BUG();}
+
+/* FIXME: Today unmapped pages are mapped to the low physical addresses
+ * and not 0 (to avoid to trigger the false alias detection in the iss)
+ * Also check pte_clear.
+ */
+int pte_none(pte_t pte){
+#if 0
+   return (!((pte_val(pte) >> 20) & ~_PAGE_GLOBAL));
+#else
+   return (!((pte_val(pte) >> 20) & ~(_PAGE_GLOBAL|0xf)));
+#endif
+}
+
+int pte_present(pte_t pte){
+  return ((pte_val(pte) >> 20) & _PAGE_PRESENT) != 0;
+}
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+pte_t pte_wrprotect(pte_t pte)
+{
+  pte_t p;
+  pte_val(p) = pte_val(pte) & ~(_PAGE_WRITE<<20);
+  return p;
+}
+pte_t pte_mkclean(pte_t pte){
+   return pte;
+}
+
+pte_t pte_mkold(pte_t pte)
+{
+  pte_val(pte) |= (_PAGE_OLD << 20);
+  return pte;
+}
+
+pte_t pte_mkwrite(pte_t pte){ 
+  pte_val(pte) |= (_PAGE_WRITE << 20);
+  return pte;
+}
+
+pte_t pte_mkdirty(pte_t pte){
+   pte_val(pte) |= (_PAGE_MODIFIED << 20);
+  return pte;
+}
+
+pte_t pte_mkyoung(pte_t pte){ 
+   pte_val(pte) |= (_PAGE_ACCESSED << 20);
+   return pte;
+}
+
+pte_t pte_modify(pte_t pte, pgprot_t newprot){
+	const unsigned long mask = (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC) << 20;
+	pte_val(pte) = (pte_val(pte) & ~mask) | ((pgprot_val(newprot) << 20) & mask);
+	return pte;
+}
+
+
+int   pmd_present(pmd_t pmd) {
+  return (pmd_val(pmd) !=  (unsigned long) invalid_pte_table) && (pmd_val(pmd) != 0UL);
+}
+
+void  pmd_clear(pmd_t *pmdp) {
+  pmd_val(*pmdp) = (unsigned long)invalid_pte_table;
+}
+
+/*
+ * Certain architectures need to do special things when pte's
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+void set_pte(pte_t *ptep, pte_t pteval){
+  *ptep = pteval;
+}
+
+void set_pte_at(struct mm_struct *mm, unsigned long addr,
+		pte_t *ptep, pte_t pteval)
+{
+   unsigned long paddr = page_to_virt(pte_page(pteval));
+   flush_dcache_range(paddr, paddr + PAGE_SIZE);
+   set_pte(ptep, pteval);
+}
+
+int pmd_none(pmd_t pmd){
+  int rv;
+
+  rv  = (pmd_val(pmd) == (unsigned long)invalid_pte_table);
+  rv |= (pmd_val(pmd) == 0UL);
+  dprintk("pmd_none returns %#x (pmd=%#lx)\n", rv, pmd_val(pmd));
+  return rv;
+}
+
+int pmd_bad(pmd_t pmd){
+  dprintk("pmd_bad returns %#lx\n", pmd_val(pmd) & ~PAGE_MASK);
+  return pmd_val(pmd) & ~PAGE_MASK;
+}
+
+
+void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep){
+  pte_t null;
+  /* FIXME: check FIXME at pte_none
+   */
+#if 0
+  pte_val(null) = 0;
+#else
+  pte_val(null) = (addr >> PAGE_SHIFT) & 0xf;
+#endif
+  set_pte_at(mm, addr, ptep, null);
+  flush_tlb_one(addr);
+}
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+pte_t mk_pte(struct page *page, pgprot_t pgprot){
+  pte_t rv;
+
+  CALLED();
+
+  pte_val(rv) = (pgprot_val(pgprot) << 20) | page_to_pfn(page);
+
+  return rv;
+}
+
+void pte_unmap(pte_t *pte){
+  (void)pte;
+}
+
+void pte_unmap_nested(pte_t *pte)
+{
+  (void)pte;
+}
+
+pte_t pgoff_to_pte(pgoff_t off){BUG();}
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+unsigned long pte_pfn(pte_t pte){
+  return pte_val(pte) & 0xfffff;
+}
+
+pte_t * pte_offset_map(pmd_t *dir, unsigned long address){
+  pte_t* rv;
+  CALLED();
+  rv = (pte_t *)page_address(pmd_page(*dir)) + 
+    ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
+  return rv;
+}
+
+pte_t * pte_offset_map_nested(pmd_t *dir, unsigned long address)
+{
+  return pte_offset_map(dir,address);
+}
+
+/* to find an entry in a kernel page-table-directory */
+pgd_t * pgd_offset_k(unsigned long address) 
+{
+  return pgd_offset(&init_mm, address);
+}
+
+/* Get the address to the PTE for a vaddr in specfic directory 
+ */
+pte_t * pte_offset_kernel(pmd_t * dir, unsigned long address){
+  pte_t* rv;
+  CALLED();
+  dprintk("pte_offset_kernel for address %#lx pmd=%#lx\n", 
+	 address, pmd_val(*dir) );
+  rv = (pte_t *)pmd_page_vaddr(*(dir)) + 
+    ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
+  return rv;
+}
+
+pte_t pfn_pte(unsigned long  pfn, pgprot_t prot)
+{
+   pte_t pte;
+   pte_val(pte) = pfn | (pgprot_val(prot) << 20);
+   return pte;
+}
+
+pgoff_t pte_to_pgoff(pte_t pte){
+   BUG();
+}
+
+void pgd_ERROR(pgd_t e){
+   BUG();
+}
+
+
+struct page * pte_page(pte_t pte){
+   return pfn_to_page(pte_pfn(pte));
+}
+
+int kern_addr_valid(unsigned long addr){BUG();}
diff --git a/arch/nios2/mm/tlb.c b/arch/nios2/mm/tlb.c
new file mode 100644
index 0000000..466144b
--- /dev/null
+++ b/arch/nios2/mm/tlb.c
@@ -0,0 +1,451 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/tlb.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+#include <asm/tlbstats.h>
+#include <asm/nios.h>
+
+#if TLB_NUM_WAYS == 8
+#define TLB_WAY_BITS 3
+#elif TLB_NUM_WAYS == 16
+#define TLB_WAY_BITS 4
+#else
+#error Please add support for TLB_WAY_BITS in tlb.c (TLB_NUM_WAYS != 8/16)
+#endif
+
+#define TLB_INDEX_MASK ((((1UL << (TLB_PTR_SZ - TLB_WAY_BITS))) - 1) << PAGE_SHIFT)
+
+struct tlb_stat statistics;
+
+#define TLB_NUM_LINES (TLB_NUM_ENTRIES/TLB_NUM_WAYS)
+
+#define DEBUG 0
+#define dprintk(fmt,args...) if(DEBUG) { printk(__FILE__   fmt, ##args); }
+#define nios_iss_set_trace(d)
+
+/* Used as illegal PHYS_ADDR for TLB mappings
+ */
+/* FIXME: ((1UL << DATA_ADDR_WIDTH) - 1)
+ */
+#define MAX_PHYS_ADDR 0
+
+#define CTL_STATUS    0
+#define CTL_ESTATUS   1
+#define CTL_BSTATUS   2
+#define CTL_IENABLE   3
+#define CTL_IPENDING  4
+#define CTL_CPUID     5
+#define CTL_RSVo1      6
+#define CTL_EXCEPTION 7
+#define CTL_PTEADDR   8
+#define CTL_TLBACC    9
+#define CTL_TLBMISC   10
+#define CTL_RSV2      11
+#define CTL_BADADDR   12
+#define CTL_CONFIG    13
+#define CTL_MPUBASE   14
+#define CTL_MPUACC    15 
+#define CTL_SIM    6
+
+/* bit definitions for TLBMISC register
+ */ 
+#define PID_SHIFT     4
+#define PID_MASK 0x3fff
+
+#define WAY_SHIFT 20
+#define WAY_MASK  0xf
+
+/* Allow access from user space to special virtual address
+ * for debugging purposes
+ */
+#define NIOS_DEBUG_REG 1
+
+#if NIOS_DEBUG_REG
+#define DEBUG_ADDR	0xdffff000
+#define KD_CURRENT	0 
+#define KD_PGD		1
+#define KD_MMU		2
+#define KD_TRACEON	3
+#define KD_TRACEOFF	4
+#define KD_DEBUG	5
+#define KD_PT_ESTATUS   6
+#define KD_START_STAT	7
+
+void dump_pgd(void);
+void dump_tlb_line(unsigned long line);
+
+static void start_new_stats(struct tlb_stat *stat)
+{
+   printk("tlb.c: stats->local_flush_tlb_mm = %d\r\n",
+	  stat->local_flush_tlb_mm);
+   printk("tlb.c: stats->local_flush_tlb_one_pid = %d\r\n",
+	  stat->local_flush_tlb_one_pid);
+   printk("tlb.c: stats->local_flush_tlb_range = %d\r\n",
+	  stat->local_flush_tlb_range);
+   printk("tlb.c: stats->local_flush_tlb_page = %d\r\n",
+	  stat->local_flush_tlb_page);
+   printk("tlb.c: stats->local_flush_tlb_kernel_range = %d\r\n",
+	  stat->local_flush_tlb_kernel_range);
+   printk("tlb.c: stats->local_flush_tlb_one = %d\r\n",
+	  stat->local_flush_tlb_one);
+   printk("tlb.c: stats->flush_tlb_pid = %d\r\n",
+	  stat->flush_tlb_pid);
+   printk("tlb.c: stats->local_flush_tlb_all = %d\r\n",
+	  stat->local_flush_tlb_all);
+   printk("tlb.c: stats->tlb_flush = %d\r\n",
+	  stat->tlb_flush);
+   printk("tlb.c: stats->tlb_c_handler = %d\r\n",
+	  stat->tlb_c_handler);
+   printk("tlb.c: stats->tlb_fast_handler = %d\r\n",
+	  stat->tlb_fast_handler);
+   printk("tlb.c: stats->do_page_fault_prot = %d\r\n",
+	  stat->do_page_fault_prot);
+   printk("tlb.c: stats->do_page_fault = %d\r\n",
+	  stat->do_page_fault);
+   memset(stat, 0, sizeof(*stat));
+}
+
+static void nios_debug(struct pt_regs *pt,  unsigned long addr)
+{
+  int reg = addr & ~PAGE_MASK;
+  printk("debug detected %#lx (reg=%d)\n", addr, reg );  
+  switch (reg) {
+  case KD_CURRENT:
+    printk("current->comm <%s>\n",current->comm);    
+    break;
+
+  case KD_TRACEON:
+    nios_iss_set_trace(1);	
+    break;
+
+  case KD_TRACEOFF:
+    nios_iss_set_trace(0);
+    break;
+
+  case KD_PT_ESTATUS:
+    printk("estatus=%#lx\n", pt->estatus);
+    break;
+    
+  case KD_START_STAT:
+    start_new_stats(&statistics);
+    break;
+    
+  default:
+    printk("unknown reg\n");
+    break;
+  }
+}
+#endif
+
+/* All entries common to a mm share an asid.  To effectively flush
+   these entries, we just bump the asid. */
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+   mm_context_t *context = &mm->context;
+
+   statistics.local_flush_tlb_mm++;
+   
+   if(current->mm == mm) {
+      local_flush_tlb_all();      
+   }
+   else {
+      memset(&context[0], 0, sizeof(mm_context_t));
+   }
+}
+
+/*
+ * This one is only used for pages with the global bit set so we don't care
+ * much about the ASID.
+ *
+ * FIXME: This is proken, to prove it mmap a read/write-page, mprotect it to 
+ *        read only then write to it, the tlb-entry will not be flushed.
+ *
+ */
+void local_flush_tlb_one_pid(unsigned long addr, unsigned long mmu_pid)
+{
+  int way;
+  unsigned long org_misc;
+
+  statistics.local_flush_tlb_one_pid++;
+  
+  dprintk("Flush tlb-entry for vaddr=%#lx\n", addr);
+  /* remember pid/way until we return. 
+   * CHECKME: is there a race here when writing org_misc back?
+   */
+  org_misc = (RDCTL(CTL_TLBMISC) & ((PID_MASK << PID_SHIFT) | (WAY_MASK << WAY_SHIFT)));
+
+  WRCTL(CTL_PTEADDR, (addr >> PAGE_SHIFT) << 2);
+  for(way = 0; way < TLB_NUM_WAYS; way++)  {
+    unsigned long pteaddr;
+    unsigned long tlbmisc;
+    unsigned long pid;
+    WRCTL(CTL_TLBMISC, (1UL << 19) | (way << 20));
+    pteaddr = RDCTL(CTL_PTEADDR);
+    tlbmisc = RDCTL(CTL_TLBMISC);
+    pid = (tlbmisc >> PID_SHIFT) & PID_MASK;
+    if(((((pteaddr >> 2) & 0xfffff)) == (addr >> PAGE_SHIFT)) &&
+       pid == mmu_pid) {
+      unsigned long vaddr = IO_REGION_BASE + (PAGE_SIZE * TLB_NUM_ENTRIES/TLB_NUM_WAYS)*way + (addr & TLB_INDEX_MASK);
+      dprintk("Flush entry by writing %#lx way=%dl pid=%ld\n", vaddr, way, pid);
+      
+      WRCTL(CTL_PTEADDR, (vaddr >> 12) << 2);
+      WRCTL(CTL_TLBMISC, (1UL << 18) | (way << 20) | pid << PID_SHIFT);
+      WRCTL(CTL_TLBACC, (MAX_PHYS_ADDR >> PAGE_SHIFT));
+    }
+  } 
+	      
+  WRCTL(CTL_TLBMISC, org_misc);
+}  
+
+void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+			   unsigned long end)
+{
+   /* Implemented in mmu_context.c
+    */
+   extern unsigned long get_pid_from_context(mm_context_t* ctx);
+   unsigned long mmu_pid = get_pid_from_context(&vma->vm_mm->context);
+
+   statistics.local_flush_tlb_range++;
+
+   while (start < end) {
+      local_flush_tlb_one_pid(start, mmu_pid);
+      start += PAGE_SIZE;
+   }
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
+{
+  statistics.local_flush_tlb_page++;
+  local_flush_tlb_one(address);
+}
+
+void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+  statistics.local_flush_tlb_kernel_range++;
+   while (start < end) {
+      local_flush_tlb_one(start);
+      start += PAGE_SIZE;
+   }
+}
+
+
+/*
+ * This one is only used for pages with the global bit set so we don't care
+ * much about the ASID.
+ */
+void local_flush_tlb_one(unsigned long addr)
+{
+  int way;
+  unsigned long pid, org_misc;
+  statistics.local_flush_tlb_one++;
+  dprintk("Flush tlb-entry for vaddr=%#lx\n", addr);
+  /* remember pid/way until we return. 
+   * CHECKME: is there a race here when writing org_misc back?
+   */
+  org_misc = (RDCTL(CTL_TLBMISC) & ((PID_MASK << PID_SHIFT) | (WAY_MASK << WAY_SHIFT)));
+
+  WRCTL(CTL_PTEADDR, (addr >> PAGE_SHIFT) << 2);
+  for(way = 0; way < TLB_NUM_WAYS; way++)  {
+    unsigned long pteaddr;
+    unsigned long tlbmisc;
+    WRCTL(CTL_TLBMISC, (1UL << 19) | (way << 20));
+    pteaddr = RDCTL(CTL_PTEADDR);
+    tlbmisc = RDCTL(CTL_TLBMISC);
+    if((((pteaddr >> 2) & 0xfffff)) == (addr >> PAGE_SHIFT)) {
+      unsigned long vaddr = IO_REGION_BASE + (PAGE_SIZE * TLB_NUM_ENTRIES/TLB_NUM_WAYS)*way + (addr & TLB_INDEX_MASK);
+      pid = (tlbmisc >> PID_SHIFT) & PID_MASK;
+      dprintk("Flush entry by writing %#lx way=%dl pid=%ld\n", vaddr, way, pid);
+      
+      WRCTL(CTL_PTEADDR, (vaddr >> 12) << 2);
+      WRCTL(CTL_TLBMISC, (1UL << 18) | (way << 20) | pid << PID_SHIFT);
+      WRCTL(CTL_TLBACC, (MAX_PHYS_ADDR >> PAGE_SHIFT));
+    }
+  } 
+	      
+  WRCTL(CTL_TLBMISC, org_misc);
+}  
+
+void dump_tlb(void) {
+   int i;
+   for(i = 0; i < TLB_NUM_LINES; i++) {
+      dump_tlb_line(i);
+   }
+}
+
+void dump_tlb_line(unsigned long line)
+{
+  int way;
+  unsigned long org_misc;
+  printk("dump tlb-entries for line=%#lx (addr %08lx)\n", line, line<<(PAGE_SHIFT + TLB_WAY_BITS));
+
+  /* remember pid/way until we return.
+   */
+  org_misc = (RDCTL(CTL_TLBMISC) & ((PID_MASK << PID_SHIFT) | (WAY_MASK << WAY_SHIFT)));
+
+  WRCTL(CTL_PTEADDR, line << 2);
+
+  for(way = 0; way < TLB_NUM_WAYS; way++)  {
+    unsigned long pteaddr;
+    unsigned long tlbmisc;
+    unsigned long tlbacc;
+    WRCTL(CTL_TLBMISC, (1UL << 19) | (way << 20));
+    pteaddr = RDCTL(CTL_PTEADDR);
+    tlbmisc = RDCTL(CTL_TLBMISC);
+    tlbacc = RDCTL(CTL_TLBACC);
+    if((tlbacc << PAGE_SHIFT) != (MAX_PHYS_ADDR & PAGE_MASK)) {
+       printk("-- way:%02x vpn:0x%08lx phys:0x%08lx pid:0x%02lx flags:%c%c%c%c%c\n", 
+       way, 
+       (pteaddr<<(PAGE_SHIFT-2)),
+       (tlbacc<<PAGE_SHIFT),
+       (tlbmisc>>PID_SHIFT)&PID_MASK,
+       ((tlbacc>>20)&_PAGE_READ?'r':'-'),
+       ((tlbacc>>20)&_PAGE_WRITE?'w':'-'),
+       ((tlbacc>>20)&_PAGE_EXEC?'x':'-'),
+       ((tlbacc>>20)&_PAGE_GLOBAL?'g':'-'),
+       ((tlbacc>>20)&_PAGE_CACHED?'c':'-'));
+    }
+  } 
+  
+  WRCTL(CTL_TLBMISC, org_misc);
+}  
+		
+void flush_tlb_pid(unsigned long pid)
+{
+  unsigned long line;
+  int way;
+  unsigned long org_misc;
+  statistics.flush_tlb_pid++;
+
+  /* remember pid/way until we return.
+   */
+  org_misc = (RDCTL(CTL_TLBMISC) & ((PID_MASK << PID_SHIFT) | (WAY_MASK << WAY_SHIFT)));
+
+  for(line = 0; line < TLB_NUM_LINES; line++) {
+   /* FIXME: << TLB_WAY_BITS should probably not be here
+    */
+    WRCTL(CTL_PTEADDR, line << 2);
+  
+    for(way = 0; way < TLB_NUM_WAYS; way++)  {
+      unsigned long pteaddr;
+      unsigned long tlbmisc;
+      unsigned long tlbacc;
+      WRCTL(CTL_TLBMISC, (1UL << 19) | (way << 20));
+      pteaddr = RDCTL(CTL_PTEADDR);
+      tlbmisc = RDCTL(CTL_TLBMISC);
+      tlbacc = RDCTL(CTL_TLBACC);
+      
+      if (((tlbmisc>>PID_SHIFT)&PID_MASK) == pid) {
+         WRCTL(CTL_TLBACC, (MAX_PHYS_ADDR >> PAGE_SHIFT));
+      }
+    } 
+    
+    WRCTL(CTL_TLBMISC, org_misc);
+  }  
+}
+
+void local_flush_tlb_all(void)
+{
+   int i;
+   unsigned long vaddr = IO_REGION_BASE;
+   unsigned int way;
+   statistics.local_flush_tlb_all++;
+
+   /* Map each TLB entry to physcal address 0 
+    * with no-access and a bad ptbase
+    */
+   for (way = 0; way < TLB_NUM_WAYS; way++) {
+      for (i = 0; i < TLB_NUM_ENTRIES/TLB_NUM_WAYS; i++) {
+
+         WRCTL(CTL_PTEADDR, ((vaddr) >> PAGE_SHIFT) << 2);
+	 // ivho: 1<<18 ?
+         WRCTL(CTL_TLBMISC, (1<<18) | (way << 20));
+         WRCTL(CTL_TLBACC, (MAX_PHYS_ADDR >> PAGE_SHIFT));
+         vaddr += 1UL << 12;
+      }
+   }
+}
+
+void tlb_flush(struct mmu_gather *tlb)
+{
+  statistics.tlb_flush++;
+  flush_tlb_mm(tlb->mm);
+}
+
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+#include <asm/nios.h>
+
+void initMMU(void)
+{
+   local_flush_tlb_all();
+}
+
+void unhandled_exception(struct pt_regs *fp, int cause)
+{
+   cause /= 4;
+   /* print "safe" output first
+    */
+   printk("Unhandled exception #%d , fp 0x%p\n", cause, fp);
+
+   /* Now dereference fp
+    */
+   fp->ea -= 4;   
+   show_regs(fp);
+
+   /* Halt the ISS
+    */
+   WRCTL(6,1);
+   for(;;);
+}
+
+extern asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
+                                     unsigned long address);
+
+
+static int maybe_debug_register_access(struct pt_regs* regs, unsigned long addr) {
+    if (DEBUG_ADDR == (addr & PAGE_MASK)) {
+      nios_debug(regs, addr);
+      return 1;
+    }
+    return 0;
+}
+
+/* FIXME: This function should probably be eliminated, we
+ *        should do this directly in fault.c
+ */
+void protection_exception_c(struct pt_regs *regs, int cause, 
+                            unsigned long addr) 
+{
+   cause /= 4;
+
+   /* Restart the instruction
+    */
+   regs->ea -= 4;
+
+   /* Handle debug addresses
+    */
+   if(maybe_debug_register_access(regs, addr)) {
+      /* Don't restart the instruction.
+       */
+      regs->ea += 4;
+   }
+   else {
+      do_page_fault(regs, cause, addr);      
+   }
+} 
+
+void set_mmu_pid(unsigned long pid) {
+   WRCTL(CTL_TLBMISC, (RDCTL(CTL_TLBMISC) & (WAY_MASK << WAY_SHIFT)) | ((pid & PID_MASK) << PID_SHIFT));
+}
diff --git a/arch/nios2/mm/uaccess.c b/arch/nios2/mm/uaccess.c
new file mode 100644
index 0000000..149663a
--- /dev/null
+++ b/arch/nios2/mm/uaccess.c
@@ -0,0 +1,235 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ */
+
+#include <linux/module.h>
+
+#include <asm/uaccess.h>
+
+extern long __copy_from_user(void* to, const void __user *from, int n);
+asm("   .global	__copy_from_user              \n"
+    "   .type __copy_from_user, @function       \n"
+    "__copy_from_user:                          \n"
+    "   movi r2,7                               \n"
+    "   mov  r3,r4                              \n"
+    "   bge	r2,r6,1f                            \n"
+    "   xor	r2,r4,r5                    			\n"
+    "   andi	r2,r2,3                          \n"
+    "   movi	r7,3                             \n"
+    "   beq	r2,zero,4f                          \n"
+    "1: addi r6,r6,-1                           \n"
+    "   movi	r2,-1                            \n"
+    "   beq	r6,r2,3f                            \n"
+    "   mov	r7,r2                               \n"
+    "2: ldbu r2,0(r5)                           \n"
+    "   addi	r6,r6,-1                         \n"
+    "   addi	r5,r5,1                          \n"
+    "   stb	r2,0(r3)                            \n"
+    "   addi	r3,r3,1                          \n"
+    "   bne	r6,r7,2b                            \n"
+    "3:                                         \n"
+    "   addi     r2,r6,1                        \n"
+    "   ret                                     \n"
+    "13:mov      r2,r6                          \n"
+    "   ret                                     \n" 
+    "4: andi r2,r4,1                            \n"
+    "   cmpeq	r2,r2,zero                       \n"
+    "   beq	r2,zero,7f                          \n"
+    "5: andi r2,r3,2                            \n"
+    "   beq	r2,zero,6f                          \n"
+    "9: ldhu	r2,0(r5)                         \n"
+    "   addi	r6,r6,-2                         \n"
+    "   addi	r5,r5,2                          \n"
+    "   sth	r2,0(r3)                            \n"
+    "   addi	r3,r3,2                          \n"
+    "6: bge r7,r6,1b                            \n"
+    "10:ldw	r2,0(r5)                            \n"
+    "   addi	r6,r6,-4                         \n"
+    "   addi	r5,r5,4                          \n"
+    "   stw	r2,0(r3)                            \n"
+    "   addi	r3,r3,4                          \n"
+    "   br	6b                                  \n"
+    "7: ldbu r2,0(r5)                           \n"
+    "   addi	r6,r6,-1                         \n"
+    "   addi	r5,r5,1                          \n"
+    "   addi	r3,r4,1                          \n"
+    "   stb	r2,0(r4)                            \n"
+    "   br	5b                                  \n"
+    ".section __ex_table,\"a\"                  \n"
+    ".word 2b,3b                                \n"
+    ".word 9b,13b                               \n"
+    ".word 10b,13b                              \n"
+    ".word 7b,13b                               \n"
+    ".previous                                  \n"
+   );
+
+
+extern long __copy_to_user(void __user *to, const void *from, long n);
+
+asm(
+   "   .global	__copy_to_user           \n"
+   "   .type __copy_to_user, @function  \n"
+   "__copy_to_user:                     \n"
+   "   movi r2,7                        \n"
+   "   mov  r3,r4                       \n"
+   "   bge	r2,r6,1f                    \n"
+   "   xor	r2,r4,r5                    \n"
+   "   andi	r2,r2,3                     \n"
+   "   movi	r7,3                        \n"
+   "   beq	r2,zero,4f                  \n"
+/* Bail if we try to copy zero bytes  */
+   "1: addi r6,r6,-1                    \n"
+   "   movi	r2,-1                       \n"
+   "   beq	r6,r2,3f                    \n"
+/* Copy byte by byte for small copies and if src^dst != 0 */
+   "   mov	r7,r2                       \n"
+   "2: ldbu r2,0(r5)                    \n"
+   "   addi	r5,r5,1                     \n"
+   "9: stb	r2,0(r3)			\n"
+   "   addi	r6,r6,-1			\n"
+   "   addi	r3,r3,1				\n"
+   "   bne	r6,r7,2b			\n"
+   "3: addi     r2,r6,1			\n"
+   "   ret                                     \n" 
+   "13:mov      r2,r6                          \n"
+   "   ret                                     \n" 
+/*  If 'to' is an odd address byte copy   */
+   "4: andi r2,r4,1				\n"
+   "   cmpeq	r2,r2,zero			\n"
+   "   beq	r2,zero,7f			\n"
+/* If 'to' is not divideable by four copy halfwords */
+   "5: andi r2,r3,2				\n"
+   "   beq	r2,zero,6f			\n"
+   "   ldhu	r2,0(r5)			\n"
+   "   addi	r5,r5,2				\n"
+   "10:sth	r2,0(r3)			\n"
+   "   addi	r6,r6,-2			\n"
+   "   addi	r3,r3,2				\n"
+/* Copy words */
+   "6: bge r7,r6,1b				\n"
+   "   ldw	r2,0(r5)			\n"
+   "   addi	r5,r5,4				\n"
+   "11:stw	r2,0(r3)			\n"
+   "   addi	r6,r6,-4			\n"
+   "   addi	r3,r3,4				\n"
+   "   br	6b				\n"
+/* Copy remaining bytes */
+   "7: ldbu r2,0(r5)				\n"
+   "   addi	r5,r5,1				\n"
+   "   addi	r3,r4,1				\n"
+   "12: stb	r2,0(r4)			\n"
+   "   addi	r6,r6,-1			\n"
+   "   br	5b				\n"
+   ".section __ex_table,\"a\"                \n"
+   ".word 9b,3b	                        \n"
+   ".word 10b,13b	                        \n"
+   ".word 11b,13b	                        \n"
+   ".word 12b,13b	                        \n"
+   ".previous                                \n");
+
+extern long __copy_from_user_inatomic(void* to, const void __user *from, int n)
+{
+  return __copy_from_user(to, from, n);
+}
+
+extern long copy_from_user(void* to, const void __user *from, int n)
+{
+  if(!access_ok(VERIFY_READ, from, n)) {
+    return n;
+  }
+  return __copy_from_user(to, from, n);
+}
+
+
+extern long __copy_to_user_inatomic(void __user *to, const void *from, long n) {
+  return __copy_to_user(to, from, n);
+}
+
+extern long copy_to_user(void __user *to, const void *from, long n)
+{
+  if(!access_ok(VERIFY_WRITE, to, n)) {
+    return n;
+  }
+  return __copy_to_user(to, from, n);
+}
+
+extern long strncpy_from_user(char *__to, const char __user *__from, long __len) {
+  int l = strnlen_user(__from, __len);
+  int is_zt = 1;
+  
+  if(l > __len) {
+    is_zt = 0;
+    l = __len;
+  }
+  
+  if(l == 0 || copy_from_user(__to, __from, l)) {
+    return -EFAULT;
+  }
+  if(is_zt) {
+    l--;
+  }
+  return l;
+}
+
+extern long strnlen_user(const char __user *s, long n) {
+  int i;
+  char c;
+  for (i = 0; i < n; i++) {
+     if (get_user(c, s+i) == -EFAULT){
+      return 0;
+    }
+    if (c == 0) {
+      return i+1;
+    }
+  }
+  return n + 1;
+}
+
+__kernel_size_t __clear_user(void __user *addr, __kernel_size_t size) {
+  while(size > 0)
+  {
+     if(__put_user(0, (char*)addr) == -EFAULT) {
+        break;
+     }
+     addr++;
+     size--;
+  }
+  return size;
+}
+
+size_t clear_user(void __user *addr, __kernel_size_t size) {
+   if(!access_ok(VERIFY_WRITE, addr, size)) {
+      return size;
+   }
+   return __clear_user(addr, size);
+}
+
+extern int segment_eq(mm_segment_t a, mm_segment_t b) {
+  return a.seg == b.seg;
+}
+
+extern mm_segment_t get_ds(void) {
+  return KERNEL_DS;
+}
+
+extern void set_fs(mm_segment_t seg) {
+   current_thread_info()->addr_limit = seg;
+}
+
+extern mm_segment_t get_fs(void) {
+  return current_thread_info()->addr_limit;
+}
+
+
+EXPORT_SYMBOL(__copy_from_user);
+EXPORT_SYMBOL(copy_from_user);
+EXPORT_SYMBOL(__copy_to_user);
+EXPORT_SYMBOL(copy_to_user);
+EXPORT_SYMBOL(get_ds);
+EXPORT_SYMBOL(get_fs);
+EXPORT_SYMBOL(set_fs);
diff --git a/arch/nios2/scripts/PTF/PTFParser.pm b/arch/nios2/scripts/PTF/PTFParser.pm
new file mode 100644
index 0000000..c243c7b
--- /dev/null
+++ b/arch/nios2/scripts/PTF/PTFParser.pm
@@ -0,0 +1,873 @@
+####################################################################
+#
+#    This file was generated using Parse::Yapp version 1.05.
+#
+#        Don't edit this file, use source file instead.
+#
+#             ANY CHANGE MADE HERE WILL BE LOST !
+#
+####################################################################
+package PTFParser;
+use vars qw ( @ISA );
+use strict;
+
+@ISA= qw ( Parse::Yapp::Driver );
+#Included Parse/Yapp/Driver.pm file----------------------------------------
+{
+#
+# Module Parse::Yapp::Driver
+#
+# This module is part of the Parse::Yapp package available on your
+# nearest CPAN
+#
+# Any use of this module in a standalone parser make the included
+# text under the same copyright as the Parse::Yapp module itself.
+#
+# This notice should remain unchanged.
+#
+# (c) Copyright 1998-2001 Francois Desarmenien, all rights reserved.
+# (see the pod text in Parse::Yapp module for use and distribution rights)
+#
+
+package Parse::Yapp::Driver;
+
+require 5.004;
+
+use strict;
+
+use vars qw ( $VERSION $COMPATIBLE $FILENAME );
+
+$VERSION = '1.05';
+$COMPATIBLE = '0.07';
+$FILENAME=__FILE__;
+
+use Carp;
+
+#Known parameters, all starting with YY (leading YY will be discarded)
+my(%params)=(YYLEX => 'CODE', 'YYERROR' => 'CODE', YYVERSION => '',
+			 YYRULES => 'ARRAY', YYSTATES => 'ARRAY', YYDEBUG => '');
+#Mandatory parameters
+my(@params)=('LEX','RULES','STATES');
+
+sub new {
+    my($class)=shift;
+	my($errst,$nberr,$token,$value,$check,$dotpos);
+    my($self)={ ERROR => \&_Error,
+				ERRST => \$errst,
+                NBERR => \$nberr,
+				TOKEN => \$token,
+				VALUE => \$value,
+				DOTPOS => \$dotpos,
+				STACK => [],
+				DEBUG => 0,
+				CHECK => \$check };
+
+	_CheckParams( [], \%params, \@_, $self );
+
+		exists($$self{VERSION})
+	and	$$self{VERSION} < $COMPATIBLE
+	and	croak "Yapp driver version $VERSION ".
+			  "incompatible with version $$self{VERSION}:\n".
+			  "Please recompile parser module.";
+
+        ref($class)
+    and $class=ref($class);
+
+    bless($self,$class);
+}
+
+sub YYParse {
+    my($self)=shift;
+    my($retval);
+
+	_CheckParams( \@params, \%params, \@_, $self );
+
+	if($$self{DEBUG}) {
+		_DBLoad();
+		$retval = eval '$self->_DBParse()';#Do not create stab entry on compile
+        $@ and die $@;
+	}
+	else {
+		$retval = $self->_Parse();
+	}
+    $retval
+}
+
+sub YYData {
+	my($self)=shift;
+
+		exists($$self{USER})
+	or	$$self{USER}={};
+
+	$$self{USER};
+	
+}
+
+sub YYErrok {
+	my($self)=shift;
+
+	${$$self{ERRST}}=0;
+    undef;
+}
+
+sub YYNberr {
+	my($self)=shift;
+
+	${$$self{NBERR}};
+}
+
+sub YYRecovering {
+	my($self)=shift;
+
+	${$$self{ERRST}} != 0;
+}
+
+sub YYAbort {
+	my($self)=shift;
+
+	${$$self{CHECK}}='ABORT';
+    undef;
+}
+
+sub YYAccept {
+	my($self)=shift;
+
+	${$$self{CHECK}}='ACCEPT';
+    undef;
+}
+
+sub YYError {
+	my($self)=shift;
+
+	${$$self{CHECK}}='ERROR';
+    undef;
+}
+
+sub YYSemval {
+	my($self)=shift;
+	my($index)= $_[0] - ${$$self{DOTPOS}} - 1;
+
+		$index < 0
+	and	-$index <= @{$$self{STACK}}
+	and	return $$self{STACK}[$index][1];
+
+	undef;	#Invalid index
+}
+
+sub YYCurtok {
+	my($self)=shift;
+
+        @_
+    and ${$$self{TOKEN}}=$_[0];
+    ${$$self{TOKEN}};
+}
+
+sub YYCurval {
+	my($self)=shift;
+
+        @_
+    and ${$$self{VALUE}}=$_[0];
+    ${$$self{VALUE}};
+}
+
+sub YYExpect {
+    my($self)=shift;
+
+    keys %{$self->{STATES}[$self->{STACK}[-1][0]]{ACTIONS}}
+}
+
+sub YYLexer {
+    my($self)=shift;
+
+	$$self{LEX};
+}
+
+
+#################
+# Private stuff #
+#################
+
+
+sub _CheckParams {
+	my($mandatory,$checklist,$inarray,$outhash)=@_;
+	my($prm,$value);
+	my($prmlst)={};
+
+	while(($prm,$value)=splice(@$inarray,0,2)) {
+        $prm=uc($prm);
+			exists($$checklist{$prm})
+		or	croak("Unknow parameter '$prm'");
+			ref($value) eq $$checklist{$prm}
+		or	croak("Invalid value for parameter '$prm'");
+        $prm=unpack('@2A*',$prm);
+		$$outhash{$prm}=$value;
+	}
+	for (@$mandatory) {
+			exists($$outhash{$_})
+		or	croak("Missing mandatory parameter '".lc($_)."'");
+	}
+}
+
+sub _Error {
+	print "Parse error.\n";
+}
+
+sub _DBLoad {
+	{
+		no strict 'refs';
+
+			exists(${__PACKAGE__.'::'}{_DBParse})#Already loaded ?
+		and	return;
+	}
+	my($fname)=__FILE__;
+	my(@drv);
+	open(DRV,"<$fname") or die "Report this as a BUG: Cannot open $fname";
+	while(<DRV>) {
+                	/^\s*sub\s+_Parse\s*{\s*$/ .. /^\s*}\s*#\s*_Parse\s*$/
+        	and     do {
+                	s/^#DBG>//;
+                	push(@drv,$_);
+        	}
+	}
+	close(DRV);
+
+	$drv[0]=~s/_P/_DBP/;
+	eval join('',@drv);
+}
+
+#Note that for loading debugging version of the driver,
+#this file will be parsed from 'sub _Parse' up to '}#_Parse' inclusive.
+#So, DO NOT remove comment at end of sub !!!
+sub _Parse {
+    my($self)=shift;
+
+	my($rules,$states,$lex,$error)
+     = @$self{ 'RULES', 'STATES', 'LEX', 'ERROR' };
+	my($errstatus,$nberror,$token,$value,$stack,$check,$dotpos)
+     = @$self{ 'ERRST', 'NBERR', 'TOKEN', 'VALUE', 'STACK', 'CHECK', 'DOTPOS' };
+
+#DBG>	my($debug)=$$self{DEBUG};
+#DBG>	my($dbgerror)=0;
+
+#DBG>	my($ShowCurToken) = sub {
+#DBG>		my($tok)='>';
+#DBG>		for (split('',$$token)) {
+#DBG>			$tok.=		(ord($_) < 32 or ord($_) > 126)
+#DBG>					?	sprintf('<%02X>',ord($_))
+#DBG>					:	$_;
+#DBG>		}
+#DBG>		$tok.='<';
+#DBG>	};
+
+	$$errstatus=0;
+	$$nberror=0;
+	($$token,$$value)=(undef,undef);
+	@$stack=( [ 0, undef ] );
+	$$check='';
+
+    while(1) {
+        my($actions,$act,$stateno);
+
+        $stateno=$$stack[-1][0];
+        $actions=$$states[$stateno];
+
+#DBG>	print STDERR ('-' x 40),"\n";
+#DBG>		$debug & 0x2
+#DBG>	and	print STDERR "In state $stateno:\n";
+#DBG>		$debug & 0x08
+#DBG>	and	print STDERR "Stack:[".
+#DBG>					 join(',',map { $$_[0] } @$stack).
+#DBG>					 "]\n";
+
+
+        if  (exists($$actions{ACTIONS})) {
+
+				defined($$token)
+            or	do {
+				($$token,$$value)=&$lex($self);
+#DBG>				$debug & 0x01
+#DBG>			and	print STDERR "Need token. Got ".&$ShowCurToken."\n";
+			};
+
+            $act=   exists($$actions{ACTIONS}{$$token})
+                    ?   $$actions{ACTIONS}{$$token}
+                    :   exists($$actions{DEFAULT})
+                        ?   $$actions{DEFAULT}
+                        :   undef;
+        }
+        else {
+            $act=$$actions{DEFAULT};
+#DBG>			$debug & 0x01
+#DBG>		and	print STDERR "Don't need token.\n";
+        }
+
+            defined($act)
+        and do {
+
+                $act > 0
+            and do {        #shift
+
+#DBG>				$debug & 0x04
+#DBG>			and	print STDERR "Shift and go to state $act.\n";
+
+					$$errstatus
+				and	do {
+					--$$errstatus;
+
+#DBG>					$debug & 0x10
+#DBG>				and	$dbgerror
+#DBG>				and	$$errstatus == 0
+#DBG>				and	do {
+#DBG>					print STDERR "**End of Error recovery.\n";
+#DBG>					$dbgerror=0;
+#DBG>				};
+				};
+
+
+                push(@$stack,[ $act, $$value ]);
+
+					$$token ne ''	#Don't eat the eof
+				and	$$token=$$value=undef;
+                next;
+            };
+
+            #reduce
+            my($lhs,$len,$code,@sempar,$semval);
+            ($lhs,$len,$code)=@{$$rules[-$act]};
+
+#DBG>			$debug & 0x04
+#DBG>		and	$act
+#DBG>		and	print STDERR "Reduce using rule ".-$act." ($lhs,$len): ";
+
+                $act
+            or  $self->YYAccept();
+
+            $$dotpos=$len;
+
+                unpack('A1',$lhs) eq '@'    #In line rule
+            and do {
+                    $lhs =~ /^\@[0-9]+\-([0-9]+)$/
+                or  die "In line rule name '$lhs' ill formed: ".
+                        "report it as a BUG.\n";
+                $$dotpos = $1;
+            };
+
+            @sempar =       $$dotpos
+                        ?   map { $$_[1] } @$stack[ -$$dotpos .. -1 ]
+                        :   ();
+
+            $semval = $code ? &$code( $self, @sempar )
+                            : @sempar ? $sempar[0] : undef;
+
+            splice(@$stack,-$len,$len);
+
+                $$check eq 'ACCEPT'
+            and do {
+
+#DBG>			$debug & 0x04
+#DBG>		and	print STDERR "Accept.\n";
+
+				return($semval);
+			};
+
+                $$check eq 'ABORT'
+            and	do {
+
+#DBG>			$debug & 0x04
+#DBG>		and	print STDERR "Abort.\n";
+
+				return(undef);
+
+			};
+
+#DBG>			$debug & 0x04
+#DBG>		and	print STDERR "Back to state $$stack[-1][0], then ";
+
+                $$check eq 'ERROR'
+            or  do {
+#DBG>				$debug & 0x04
+#DBG>			and	print STDERR 
+#DBG>				    "go to state $$states[$$stack[-1][0]]{GOTOS}{$lhs}.\n";
+
+#DBG>				$debug & 0x10
+#DBG>			and	$dbgerror
+#DBG>			and	$$errstatus == 0
+#DBG>			and	do {
+#DBG>				print STDERR "**End of Error recovery.\n";
+#DBG>				$dbgerror=0;
+#DBG>			};
+
+			    push(@$stack,
+                     [ $$states[$$stack[-1][0]]{GOTOS}{$lhs}, $semval ]);
+                $$check='';
+                next;
+            };
+
+#DBG>			$debug & 0x04
+#DBG>		and	print STDERR "Forced Error recovery.\n";
+
+            $$check='';
+
+        };
+
+        #Error
+            $$errstatus
+        or   do {
+
+            $$errstatus = 1;
+            &$error($self);
+                $$errstatus # if 0, then YYErrok has been called
+            or  next;       # so continue parsing
+
+#DBG>			$debug & 0x10
+#DBG>		and	do {
+#DBG>			print STDERR "**Entering Error recovery.\n";
+#DBG>			++$dbgerror;
+#DBG>		};
+
+            ++$$nberror;
+
+        };
+
+			$$errstatus == 3	#The next token is not valid: discard it
+		and	do {
+				$$token eq ''	# End of input: no hope
+			and	do {
+#DBG>				$debug & 0x10
+#DBG>			and	print STDERR "**At eof: aborting.\n";
+				return(undef);
+			};
+
+#DBG>			$debug & 0x10
+#DBG>		and	print STDERR "**Dicard invalid token ".&$ShowCurToken.".\n";
+
+			$$token=$$value=undef;
+		};
+
+        $$errstatus=3;
+
+		while(	  @$stack
+			  and (		not exists($$states[$$stack[-1][0]]{ACTIONS})
+			        or  not exists($$states[$$stack[-1][0]]{ACTIONS}{error})
+					or	$$states[$$stack[-1][0]]{ACTIONS}{error} <= 0)) {
+
+#DBG>			$debug & 0x10
+#DBG>		and	print STDERR "**Pop state $$stack[-1][0].\n";
+
+			pop(@$stack);
+		}
+
+			@$stack
+		or	do {
+
+#DBG>			$debug & 0x10
+#DBG>		and	print STDERR "**No state left on stack: aborting.\n";
+
+			return(undef);
+		};
+
+		#shift the error token
+
+#DBG>			$debug & 0x10
+#DBG>		and	print STDERR "**Shift \$error token and go to state ".
+#DBG>						 $$states[$$stack[-1][0]]{ACTIONS}{error}.
+#DBG>						 ".\n";
+
+		push(@$stack, [ $$states[$$stack[-1][0]]{ACTIONS}{error}, undef ]);
+
+    }
+
+    #never reached
+	croak("Error in driver logic. Please, report it as a BUG");
+
+}#_Parse
+#DO NOT remove comment
+
+1;
+
+}
+#End of include--------------------------------------------------
+
+
+#line 1 "PTFParser.yp"
+#
+# Altera PTF file parser
+#
+# Copyright (c) 2004 Microtronix Datacom Ltd.
+#
+
+package PTFParser;
+
+use PTF::PTFSection;
+
+#global variables should go here.
+
+#my $line = 0;		# for error messages
+#my @sectionStack = ();	# used to keep track of ptf sections
+#my $root;
+
+my $fh;
+
+sub new {
+        my($class)=shift;
+        ref($class)
+    and $class=ref($class);
+
+    my($self)=$class->SUPER::new( yyversion => '1.05',
+                                  yystates =>
+[
+	{#State 0
+		ACTIONS => {
+			'IDENTIFIER' => 1
+		},
+		GOTOS => {
+			'section' => 2,
+			'section_title' => 3
+		}
+	},
+	{#State 1
+		ACTIONS => {
+			'IDENTIFIER' => 4,
+			'STRING_LITERAL' => 6,
+			'NUMBER' => 7
+		},
+		DEFAULT => -3,
+		GOTOS => {
+			'section_name' => 5
+		}
+	},
+	{#State 2
+		ACTIONS => {
+			'' => 8
+		}
+	},
+	{#State 3
+		ACTIONS => {
+			"{" => 9
+		}
+	},
+	{#State 4
+		DEFAULT => -4
+	},
+	{#State 5
+		DEFAULT => -2
+	},
+	{#State 6
+		DEFAULT => -6
+	},
+	{#State 7
+		DEFAULT => -5
+	},
+	{#State 8
+		DEFAULT => 0
+	},
+	{#State 9
+		ACTIONS => {
+			'IDENTIFIER' => 11,
+			'HIERARCHICAL_NAME' => 13
+		},
+		DEFAULT => -7,
+		GOTOS => {
+			'assignment_name' => 10,
+			'assignment' => 12,
+			'section_element' => 14,
+			'section' => 15,
+			'section_title' => 3
+		}
+	},
+	{#State 10
+		ACTIONS => {
+			"=" => 16
+		}
+	},
+	{#State 11
+		ACTIONS => {
+			'IDENTIFIER' => 4,
+			'STRING_LITERAL' => 6,
+			'NUMBER' => 7,
+			"=" => -11
+		},
+		DEFAULT => -3,
+		GOTOS => {
+			'section_name' => 5
+		}
+	},
+	{#State 12
+		ACTIONS => {
+			'IDENTIFIER' => 11,
+			'HIERARCHICAL_NAME' => 13
+		},
+		DEFAULT => -7,
+		GOTOS => {
+			'assignment_name' => 10,
+			'assignment' => 12,
+			'section_element' => 17,
+			'section' => 15,
+			'section_title' => 3
+		}
+	},
+	{#State 13
+		DEFAULT => -12
+	},
+	{#State 14
+		ACTIONS => {
+			"}" => 18
+		}
+	},
+	{#State 15
+		ACTIONS => {
+			'IDENTIFIER' => 11,
+			'HIERARCHICAL_NAME' => 13
+		},
+		DEFAULT => -7,
+		GOTOS => {
+			'assignment_name' => 10,
+			'assignment' => 12,
+			'section_element' => 19,
+			'section' => 15,
+			'section_title' => 3
+		}
+	},
+	{#State 16
+		ACTIONS => {
+			'STRING_LITERAL' => 20,
+			'NUMBER' => 22
+		},
+		GOTOS => {
+			'assignment_value' => 21
+		}
+	},
+	{#State 17
+		DEFAULT => -8
+	},
+	{#State 18
+		DEFAULT => -1
+	},
+	{#State 19
+		DEFAULT => -9
+	},
+	{#State 20
+		DEFAULT => -13
+	},
+	{#State 21
+		ACTIONS => {
+			";" => 23
+		}
+	},
+	{#State 22
+		DEFAULT => -14
+	},
+	{#State 23
+		DEFAULT => -10
+	}
+],
+                                  yyrules  =>
+[
+	[#Rule 0
+		 '$start', 2, undef
+	],
+	[#Rule 1
+		 'section', 4,
+sub
+#line 20 "PTFParser.yp"
+{ 
+			my $sectionStack = $_[0]->YYData->{sectionStack};
+			pop @{$sectionStack}; 
+		}
+	],
+	[#Rule 2
+		 'section_title', 2,
+sub
+#line 26 "PTFParser.yp"
+{ 
+			my $section = PTFSection->new (type => $_[1], name => $_[2]); 
+			my $sectionStack = $_[0]->YYData->{sectionStack};
+			
+			if (scalar(@{$sectionStack}) == 0) {
+				$_[0]->YYData->{root} = $section;
+			} else {
+				my $parent = $sectionStack->[$#{$sectionStack}];
+				$parent->addSection ($section);
+			}
+
+			push @{$sectionStack}, $section;
+		}
+	],
+	[#Rule 3
+		 'section_name', 0, undef
+	],
+	[#Rule 4
+		 'section_name', 1, undef
+	],
+	[#Rule 5
+		 'section_name', 1, undef
+	],
+	[#Rule 6
+		 'section_name', 1, undef
+	],
+	[#Rule 7
+		 'section_element', 0, undef
+	],
+	[#Rule 8
+		 'section_element', 2, undef
+	],
+	[#Rule 9
+		 'section_element', 2, undef
+	],
+	[#Rule 10
+		 'assignment', 4,
+sub
+#line 52 "PTFParser.yp"
+{ 
+			my $sectionStack = $_[0]->YYData->{sectionStack};
+			my $parent= $sectionStack->[$#{$sectionStack}]; 
+			$parent->addAssignment ($_[1], $_[3]); 
+		}
+	],
+	[#Rule 11
+		 'assignment_name', 1, undef
+	],
+	[#Rule 12
+		 'assignment_name', 1, undef
+	],
+	[#Rule 13
+		 'assignment_value', 1, undef
+	],
+	[#Rule 14
+		 'assignment_value', 1, undef
+	]
+],
+                                  @_);
+    bless($self,$class);
+}
+
+#line 67 "PTFParser.yp"
+
+
+sub _Error {
+# TODO: update this error function to be more useful
+        exists $_[0]->YYData->{ERRMSG}
+    and do {
+        print $_[0]->YYData->{ERRMSG};
+        delete $_[0]->YYData->{ERRMSG};
+        return;
+    };
+    print "Syntax error on line $_[0]->YYData->{line}.\n";
+}
+
+sub _Lexer {
+	my($parser)=shift;
+
+	if (! $parser->YYData->{INPUT}) {
+		if ($parser->YYData->{INPUT} = <$fh>) {
+			$parser->YYData->{line} += 1;
+		} else {
+			return ('', undef);
+		}
+	}
+
+	$parser->YYData->{INPUT} and
+		$parser->YYData->{INPUT} =~ s/^\s*//;
+
+	while (1) {
+		
+		# skip blank lines
+		if ($parser->YYData->{INPUT} =~ s/^[ \t\r\n]*$//) {
+			if ($parser->YYData->{INPUT} = <$fh>) {
+				$parser->YYData->{line} += 1;
+			} else {
+				return ('', undef);
+			}
+			$parser->YYData->{INPUT} and
+				$parser->YYData->{INPUT} =~ s/^\s*//;
+			next;
+		}	
+		
+		# Skip comments
+		if ($parser->YYData->{INPUT} =~ s/^#.*//) {
+			if ($parser->YYData->{INPUT} = <$fh>) {
+				$parser->YYData->{line} += 1;
+			} else {
+				return ('', undef);
+			}
+			$parser->YYData->{INPUT} and
+				$parser->YYData->{INPUT} =~ s/^\s*//;
+			next;
+		}	
+
+		# Don't continue if the line length is 0;
+		if (length $parser->YYData->{INPUT} == 0) {
+			if ($parser->YYData->{INPUT} = <$fh>) {
+				$parser->YYData->{line} += 1;
+			} else {
+				return ('', undef);
+			}
+			$parser->YYData->{INPUT} and
+				$parser->YYData->{INPUT} =~ s/^\s*//;
+			next;
+		}
+
+		# tokenize input
+    		$parser->YYData->{INPUT} =~ s/^([a-zA-Z_][a-zA-Z_0-9\/]*)//
+			and return('IDENTIFIER',$1);
+		$parser->YYData->{INPUT} =~ s/^"([^"\\]*(\\.[^"\\]*)*)"//
+			and return('STRING_LITERAL',$1);
+		$parser->YYData->{INPUT} =~ s/^"([^"\\]*(\\.[^"\\]*)*)//
+			and do {
+				my $literal = $1;
+
+				do {
+					if ($parser->YYData->{INPUT} = <$fh>) {
+						$parser->YYData->{line} += 1;
+					} else {
+						return ('', undef);
+					}
+
+					$parser->YYData->{INPUT} =~ s/([^"\\]*(\\.[^"\\]*)*)"//
+						and do {
+							$literal .= $1;
+							return ('STRING_LITERAL', $literal);
+						};
+
+					$parser->YYData->{INPUT} =~ s/([^"\\]*(\\.[^"\\]*)*)// 
+						and $literal .= $1;
+				} while (1);
+			};
+		$parser->YYData->{INPUT} =~ s/^([0-9]+)//
+			and return('NUMBER',$1);
+		$parser->YYData->{INPUT} =~ s/^([\$]{1,2}[a-zA-Z0-9 \/_]+)//
+			and return('HIERARCHICAL_NAME',$1);
+		$parser->YYData->{INPUT} =~ s/^(.)//
+			and return($1,$1);
+	}
+}
+
+sub readPTF {
+	my $self = shift;
+	my $filename = shift;
+
+	# store information for later use
+	$self->YYData->{line} = 0;
+	$self->YYData->{sectionStack} = [];
+	undef $self->YYData->{root};
+	
+	if (-e $filename) {
+		open (PTFFILE, $filename);
+		$fh = \*PTFFILE;
+	} else {
+		$fh = \*STDIN;
+	}
+	
+	$self->YYParse (
+		yylex => \&_Lexer,
+		yyerror => \&_Error,
+		);
+		
+	if (-e $filename) {
+		close PTFFILE;
+	}
+
+	return $self->YYData->{root};
+}
+
+1;
diff --git a/arch/nios2/scripts/PTF/PTFParser.yp b/arch/nios2/scripts/PTF/PTFParser.yp
new file mode 100644
index 0000000..e105e6a
--- /dev/null
+++ b/arch/nios2/scripts/PTF/PTFParser.yp
@@ -0,0 +1,178 @@
+%{#
+# Altera PTF file parser
+#
+# Copyright (c) 2004 Microtronix Datacom Ltd.
+#
+
+package PTFParser;
+
+use PTF::PTFSection;
+
+%}
+
+%%
+section: section_title '{' section_element '}' { 
+			my $sectionStack = $_[0]->YYData->{sectionStack};
+			pop @{$sectionStack}; 
+		}
+;
+
+section_title: IDENTIFIER section_name { 
+			my $section = PTFSection->new (type => $_[1], name => $_[2]); 
+			my $sectionStack = $_[0]->YYData->{sectionStack};
+			
+			if (scalar(@{$sectionStack}) == 0) {
+				$_[0]->YYData->{root} = $section;
+			} else {
+				my $parent = $sectionStack->[$#{$sectionStack}];
+				$parent->addSection ($section);
+			}
+
+			push @{$sectionStack}, $section;
+		}
+;
+
+section_name: # empty string
+	| IDENTIFIER 
+	| NUMBER 
+	| STRING_LITERAL 
+;
+
+section_element: # empty element
+	| assignment section_element
+	| section section_element
+;
+
+assignment: assignment_name '=' assignment_value ';' { 
+			my $sectionStack = $_[0]->YYData->{sectionStack};
+			my $parent= $sectionStack->[$#{$sectionStack}]; 
+			$parent->addAssignment ($_[1], $_[3]); 
+		}
+;
+
+assignment_name: IDENTIFIER
+	| HIERARCHICAL_NAME 
+;
+
+assignment_value: STRING_LITERAL
+	| NUMBER 
+;
+
+%%
+
+sub _Error {
+# TODO: update this error function to be more useful
+        exists $_[0]->YYData->{ERRMSG}
+    and do {
+        print $_[0]->YYData->{ERRMSG};
+        delete $_[0]->YYData->{ERRMSG};
+        return;
+    };
+    print "Syntax error on line $_[0]->YYData->{line}.\n";
+}
+
+sub _Lexer {
+	my($parser)=shift;
+
+	if (! $parser->YYData->{INPUT}) {
+		if ($parser->YYData->{INPUT} = <PTFFILE>) {
+			$parser->YYData->{line} += 1;
+		} else {
+			return ('', undef);
+		}
+	}
+
+	$parser->YYData->{INPUT} and
+		$parser->YYData->{INPUT} =~ s/^\s*//;
+
+	while (1) {
+		
+		# skip blank lines
+		if ($parser->YYData->{INPUT} =~ s/^[ \t\r\n]*$//) {
+			if ($parser->YYData->{INPUT} = <PTFFILE>) {
+				$parser->YYData->{line} += 1;
+			} else {
+				return ('', undef);
+			}
+			$parser->YYData->{INPUT} and
+				$parser->YYData->{INPUT} =~ s/^\s*//;
+			next;
+		}	
+		
+		# Skip comments
+		if ($parser->YYData->{INPUT} =~ s/^#.*//) {
+			if ($parser->YYData->{INPUT} = <PTFFILE>) {
+				$parser->YYData->{line} += 1;
+			} else {
+				return ('', undef);
+			}
+			$parser->YYData->{INPUT} and
+				$parser->YYData->{INPUT} =~ s/^\s*//;
+			next;
+		}	
+
+		# Don't continue if the line length is 0;
+		if (length $parser->YYData->{INPUT} == 0) {
+			if ($parser->YYData->{INPUT} = <PTFFILE>) {
+				$parser->YYData->{line} += 1;
+			} else {
+				return ('', undef);
+			}
+			$parser->YYData->{INPUT} and
+				$parser->YYData->{INPUT} =~ s/^\s*//;
+			next;
+		}
+
+		# tokenize input
+    		$parser->YYData->{INPUT} =~ s/^([a-zA-Z_][a-zA-Z_0-9\/]*)//
+			and return('IDENTIFIER',$1);
+		$parser->YYData->{INPUT} =~ s/^"([^"\\]*(\\.[^"\\]*)*)"//
+			and return('STRING_LITERAL',$1);
+		$parser->YYData->{INPUT} =~ s/^"([^"\\]*(\\.[^"\\]*)*)//
+			and do {
+				my $literal = $1;
+
+				do {
+					if ($parser->YYData->{INPUT} = <PTFFILE>) {
+						$parser->YYData->{line} += 1;
+					} else {
+						return ('', undef);
+					}
+
+					$parser->YYData->{INPUT} =~ s/([^"\\]*(\\.[^"\\]*)*)"//
+						and do {
+							$literal .= $1;
+							return ('STRING_LITERAL', $literal);
+						};
+
+					$parser->YYData->{INPUT} =~ s/([^"\\]*(\\.[^"\\]*)*)// 
+						and $literal .= $1;
+				} while (1);
+			};
+		$parser->YYData->{INPUT} =~ s/^([0-9]+)//
+			and return('NUMBER',$1);
+		$parser->YYData->{INPUT} =~ s/^([\$]{1,2}[a-zA-Z0-9 \/_]+)//
+			and return('HIERARCHICAL_NAME',$1);
+		$parser->YYData->{INPUT} =~ s/^(.)//
+			and return($1,$1);
+	}
+}
+
+sub readPTF {
+	my $self = shift;
+	my $filename = shift;
+
+	# store information for later use
+	$self->YYData->{line} = 0;
+	$self->YYData->{sectionStack} = [];
+	undef $self->YYData->{root};
+	
+	open (PTFFILE, $filename) or return undef;
+	$self->YYParse (
+		yylex => \&_Lexer,
+		yyerror => \&_Error,
+		);
+	close PTFFILE;
+
+	return $self->YYData->{root};
+}
diff --git a/arch/nios2/scripts/PTF/PTFSection.pm b/arch/nios2/scripts/PTF/PTFSection.pm
new file mode 100644
index 0000000..a88d340
--- /dev/null
+++ b/arch/nios2/scripts/PTF/PTFSection.pm
@@ -0,0 +1,81 @@
+package PTFSection;
+
+use strict;
+
+# Fields:
+#  type = type of PTF Section
+#  name = name of PTF Section (can be blank)
+#  sections = array of section references
+#  assignments = hash of assignments
+
+sub new {
+	my $invocant = shift;
+	my $class = ref($invocant) || $invocant;
+	my $self = {
+		@_,
+		sections => [],
+		assignments => {},
+	};
+	bless ($self, $class);
+	return $self;
+}
+
+sub addSection {
+	my ($self, $section) = @_;
+	push @{$self->{sections}}, $section;
+}
+
+sub getSections {
+	my ($self, $type) = @_;
+	
+	if (! $type) {
+		return @{$self->{sections}};
+	}
+	
+	my @matchedSections;
+	foreach my $section (@{$self->{sections}}) {
+		if ($section->type eq $type) {
+			push @matchedSections, $section;
+		}
+	}
+	
+	return @matchedSections;
+}
+
+sub getSection {
+	my ($self, $type, $name) = @_;
+	
+	if (! $name) {
+		$name = "";
+	}
+	
+	foreach my $section (@{$self->{sections}}) {
+		if ($section->type eq $type and $section->name eq $name) {
+			return $section;
+		}
+	}
+
+}
+
+sub addAssignment {
+	my ($self, $name, $value) = @_;
+	$self->{assignments}{$name} = $value;
+}
+
+sub getAssignment {
+	my ($self, $name) = @_;
+	return $self->{assignments}{$name};
+}
+
+sub type {
+	my $self = shift;
+	return $self->{type};
+}
+
+sub name {
+	my $self = shift;
+	return $self->{name};
+}
+
+
+1;
diff --git a/arch/nios2/scripts/PTF/SystemPTF.pm b/arch/nios2/scripts/PTF/SystemPTF.pm
new file mode 100644
index 0000000..4ca77df
--- /dev/null
+++ b/arch/nios2/scripts/PTF/SystemPTF.pm
@@ -0,0 +1,159 @@
+package SystemPTF;
+
+use strict;
+
+use PTF::PTFParser;
+use PTF::PTFSection;
+use PTF::SystemPTF::CPU;
+use PTF::SystemPTF::Board;
+use PTF::SystemPTF::Module;
+
+# Fields:
+
+my %module_order;
+
+sub new {
+	my $invocant = shift;
+	my $class = ref($invocant) || $invocant;
+	my $self = {
+		filename => "",
+		@_,
+	};
+	
+	my $parser = PTFParser->new;
+	$self->{root} = $parser->readPTF($self->{filename});
+
+	# if the specified PTF file could not be read properly, return undef;
+	$self->{root} or return;
+	
+	# if the specified PTF file is not a SYSTEM, return undef.
+	if ($self->{root}->type ne 'SYSTEM') {
+		return;
+	}
+	
+	# initialize the modulemap
+	my @modules = $self->{root}->getSections ("MODULE");
+	my $index = 0;
+	foreach my $module (@modules) {
+		# if the module is not enabled then do not add
+		my $SBI = $module->getSection ('SYSTEM_BUILDER_INFO', '');
+		if ($SBI->getAssignment ('Is_Enabled') eq "1") {
+			$self->{modules}->{$module->name} = $module;
+			$module_order{$module->name} = $index;
+			$index += 1;
+		}
+	}
+
+	bless ($self, $class);
+	return $self;
+}
+
+sub getName {
+	my ($self) = @_;
+	return $self->{root}->name;
+}
+
+sub getCPUList {
+	my ($self, @classes) = @_;
+	my @cpulist = ();
+	
+	foreach my $module_name (keys (%{$self->{modules}})) {
+		my $module = $self->{modules}->{$module_name};
+		my $module_class = $module->getAssignment ('class');
+		foreach my $class (@classes) {
+			if ($module_class eq $class) {
+				push @cpulist, $module->name;
+			}
+		}
+	}
+	
+	return @cpulist;
+}
+
+sub getCPU {
+	my ($self, $name) = @_;
+	
+	my $cpu = CPU->new (ptf => $self->{modules}->{$name});
+}
+
+sub getModule {
+	my ($self, $name) = @_;
+	
+	my $module = Module->new (ptf => $self->{modules}->{$name});
+}
+
+sub getSlaveModules {
+	my ($self, $master, $type) = @_;
+	
+	# create %connected set with just the master
+	# value of hash key is inconsequential
+	my %connected;
+	$connected{$master} = ( );
+	
+	# create %pool set with all modules
+	# value of hash key is inconsequential
+	my %pool;
+	@pool{keys (%{$self->{modules}})} = ( );
+	
+	my $dirty = 1;
+	while ($dirty) {
+		# %pool = difference (%pool, %connected)
+		delete @pool{ keys %connected };
+		
+		$dirty = 0;
+		
+		foreach my $name (keys %pool) {
+			my $mod = $self->getModule ($name);
+			my %mod_masters;
+			@mod_masters{ $mod->getMasters ($type) } = ( );
+			
+			# if intersection (%masters, %connected) is not empty
+			delete @mod_masters{
+				grep ( ! exists $connected{ $_ },
+					keys %mod_masters) };
+			
+			if (scalar(keys(%mod_masters)) > 0) {
+				$connected{$name} = ( );
+				$dirty = 1;
+			}
+		}
+	}
+	
+	delete $connected{$master};
+
+	return sort module_comparison keys (%connected); 
+}
+
+# get the clock frequency of a module
+sub getClockFreq () {
+	my ($self, $name) = @_;
+	
+	my $module = $self->{root}->getSection ('MODULE', $name);
+	$module or return;
+	my $sbi = $module->getSection ('SYSTEM_BUILDER_INFO', '');
+	$sbi or return;
+	my $clk_src = $sbi->getAssignment ('Clock_Source');
+	$clk_src or return;
+	my $wsa = $self->{root}->getSection ('WIZARD_SCRIPT_ARGUMENTS', '');
+	$wsa or return;
+	my $clocks = $wsa->getSection ('CLOCKS', '');
+	$clocks or return;
+	my $clock = $clocks->getSection ('CLOCK', $clk_src);
+	$clock or return;
+	my $result = $clock->getAssignment ('frequency');
+	return $result;
+}
+
+# This is not really a class method... more of a helper function really...
+sub module_comparison {
+	if ($module_order{$a} > $module_order{$b}) {
+		return 1;
+	} elsif ($module_order{$a} < $module_order{$b}) {
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+
+1;
diff --git a/arch/nios2/scripts/PTF/SystemPTF/Board.pm b/arch/nios2/scripts/PTF/SystemPTF/Board.pm
new file mode 100644
index 0000000..fe2bbc8
--- /dev/null
+++ b/arch/nios2/scripts/PTF/SystemPTF/Board.pm
@@ -0,0 +1,2 @@
+1;
+
diff --git a/arch/nios2/scripts/PTF/SystemPTF/CPU.pm b/arch/nios2/scripts/PTF/SystemPTF/CPU.pm
new file mode 100644
index 0000000..810886d
--- /dev/null
+++ b/arch/nios2/scripts/PTF/SystemPTF/CPU.pm
@@ -0,0 +1,101 @@
+package CPU;
+
+use PTF::PTFSection;
+
+sub new {
+    my $invocant = shift;
+    my $class = ref($invocant) || $invocant;
+    my $self = {
+		@_,
+    };
+	
+    # if no ptf section was passed in, then return undef
+    $self->{ptf} or return;
+
+    bless ($self, $class);
+    return $self;
+}
+
+sub getClass {
+	my ($self) = @_;
+	
+	return $self->{ptf}->getAssignment ('class');
+}
+
+sub getVersion {
+	my ($self) = @_;
+	
+	return $self->{ptf}->getAssignment ('class_version');
+}
+
+sub getConstant {
+	my ($self, $name) = @_;
+	
+	# get WSA
+	$wsa = $self->{ptf}->getSection('WIZARD_SCRIPT_ARGUMENTS', '');
+	$wsa or return;
+	
+	# get constants section
+	$constants = $wsa->getSection('CONSTANTS', '');
+	$constants or return;
+	
+	# get section for specific constant
+	$constant = $constants->getSection ('CONSTANT', $name);
+	$constant or return;
+	
+	# get value of constant
+	$value = $constant->getAssignment ('value');
+	return $value;
+}
+
+sub getWSAAssignment {
+	my ($self, $name) = @_;
+
+	# get WSA
+	$wsa = $self->{ptf}->getSection('WIZARD_SCRIPT_ARGUMENTS', '');
+	$wsa or return;
+
+	# get value of WSA Assignment
+	$value = $wsa->getAssignment ($name);
+	return $value;
+}
+
+sub getResetLocationOffset {
+	my ($self) = @_;
+	
+	$wsa = $self->{ptf}->getSection('WIZARD_SCRIPT_ARGUMENTS', '');
+	$wsa or return;
+	
+	my $location = $wsa->getAssignment ('reset_slave');
+	my $offset = $wsa->getAssignment ('reset_offset');
+	
+	return ($location, $offset);
+}
+
+sub getExceptLocationOffset {
+	my ($self) = @_;
+	
+	$wsa = $self->{ptf}->getSection('WIZARD_SCRIPT_ARGUMENTS', '');
+	$wsa or return;
+	
+	my $location = $wsa->getAssignment ('exc_slave');
+	my $offset = $wsa->getAssignment ('exc_offset');
+	
+	return ($location, $offset);
+}
+
+sub isEnabled {
+	my ($self) = @_;
+	
+	$sbi = $self->{ptf}->getSection('SYSTEM_BUILDER_INFO', '');
+	$sbi or return;
+	
+	my $enabled = $sbi->getAssignment ('Is_Enabled');
+	if ($enabled eq "1") {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+1;
diff --git a/arch/nios2/scripts/PTF/SystemPTF/Module.pm b/arch/nios2/scripts/PTF/SystemPTF/Module.pm
new file mode 100644
index 0000000..dce0783
--- /dev/null
+++ b/arch/nios2/scripts/PTF/SystemPTF/Module.pm
@@ -0,0 +1,283 @@
+package Module;
+
+use PTF::PTFSection;
+
+sub new {
+    my $invocant = shift;
+    my $class = ref($invocant) || $invocant;
+    my $self = {
+	@_,
+    };
+    
+    # if no ptf section was passed in, then return undef
+    $self->{ptf} or return;
+
+    bless ($self, $class);
+    return $self;
+}
+
+sub getClass {
+	my ($self) = @_;
+	
+	return $self->{ptf}->getAssignment ('class');
+}
+
+sub getGtfClass {
+  my ($self) = @_;
+  
+  return $self->{ptf}->getAssignment ('gtf_class_name');
+}
+sub getPorts {
+	my ($self) = @_;
+	
+	my @port_names;
+	
+	my @ports = $self->{ptf}->getSections ('SLAVE');
+	foreach $port (@ports) {
+		push @port_names, $port->name;
+	}
+
+	return @port_names;
+}
+
+sub getPort {
+	my ($self, $port_name) = @_;
+	
+	my $port;
+
+	if (! $port_name) {
+		# use first port found
+		my @port_names = $self->getPorts ();
+		$port = $self->{ptf}->getSection ('SLAVE', $port_names[0]);
+	} else {
+		$port = $self->{ptf}->getSection ('SLAVE', $port_name);
+		if (! $port) {
+			# return undef if the PTF section doesn't exist
+			return;
+		}
+	}
+	
+	return $port;
+}
+
+sub getWSAAssignment {
+	my ($self, $assignment) = @_;
+	
+	my $WSA = $self->{ptf}->getSection ('WIZARD_SCRIPT_ARGUMENTS', '');
+	if (! $WSA) {
+		# return undef if the WSA section doesn't exist.
+		return;
+	}
+	
+	my $result = $WSA->getAssignment ($assignment);
+	
+	return $result;
+	
+}
+
+sub getWSAConstant {
+	my ($self, $name) = @_;
+	
+	my $WSA = $self->{ptf}->getSection ('WIZARD_SCRIPT_ARGUMENTS', '');
+	if (! $WSA) {
+		# return undef if the WSA section doesn't exist.
+		return;
+	}
+	
+	my $constants = $WSA->getSection ('CONSTANTS', '');
+	if (! $constants) {
+		# return undef if the CONSTANTS section doesn't exist.
+		return;
+	}
+	
+	my $constant = $constants->getSection ('CONSTANT', $name);
+	if (! $constant) {
+		# return undef if the CONSTANT $name section doesn't exist.
+		return;
+	}
+	
+	my $result = $constant->getAssignment ('value');
+	return $result;
+	
+}
+
+sub isMemoryDevice {
+	my ($self, $port_name) = @_;
+	
+	my $port = $self->getPort ($port_name);
+	if (! $port) {
+		# return undef if the PTF section doesn't exist
+		return;
+	}
+	
+	my $SBI = $port->getSection('SYSTEM_BUILDER_INFO', '');
+	if (! $SBI) {
+		# return undef if the PTF section doesn't exist
+		return;
+	}
+	
+	my $result = $SBI->getAssignment('Is_Memory_Device');
+	
+	return $result;
+}
+
+sub isNonvolatileStorage {
+	my ($self, $port_name) = @_;
+	
+	my $port = $self->getPort ($port_name);
+	if (! $port) {
+		# return undef if the PTF section doesn't exist
+		return;
+	}
+	
+	my $SBI = $port->getSection('SYSTEM_BUILDER_INFO', '');
+	if (! $SBI) {
+		# return undef if the PTF section doesn't exist
+		return;
+	}
+	
+	my $result = $SBI->getAssignment('Is_Nonvolatile_Storage');
+	
+	return $result;
+}
+
+sub isCustomInstruction {
+	my ($self, $port_name) = @_;
+	
+	my $port = $self->getPort ($port_name);
+	if (! $port) {
+		# return undef if the PTF section doesn't exist
+		return;
+	}
+	
+	my $SBI = $port->getSection('SYSTEM_BUILDER_INFO', '');
+	if (! $SBI) {
+		# return undef if the PTF section doesn't exist
+		return;
+	}
+	
+	my $result = $SBI->getAssignment('Is_Custom_Instruction');
+	
+	return $result;
+}
+
+sub getBaseAddress {
+	my ($self, $port_name) = @_;
+	
+	my $port = $self->getPort ($port_name);
+	if (! $port) {
+		# return undef if the PTF section doesn't exist
+		return;
+	}
+	
+	my $SBI = $port->getSection('SYSTEM_BUILDER_INFO', '');
+	if (! $SBI) {
+		# return undef if the PTF section doesn't exist
+		return;
+	}
+	
+	my $result = $SBI->getAssignment('Base_Address');
+	if ($result eq 'N/A') {
+		return;
+	}
+	return $result;
+}
+
+sub getSize {
+	my ($self, $port_name) = @_;
+	
+	my $port = $self->getPort ($port_name);
+	$port or return;  #return undef if the ptf section doesn't exist
+	
+	my $SBI = $port->getSection ('SYSTEM_BUILDER_INFO', '');
+	my $data_width = $SBI->getAssignment ('Data_Width');
+	my $addr_width = $SBI->getAssignment ('Address_Width');
+	
+	my $size = (1 << $addr_width) * ($data_width / 8);
+	my $size_text = sprintf ("%#010x", $size);
+	return $size_text;
+}
+
+sub getIRQ {
+	my ($self, $port_name) = @_;
+	
+	my $port = $self->getPort ($port_name);
+	if (! $port) {
+		# return undef if the PTF section doesn't exist
+		return;
+	}
+	
+	my $SBI = $port->getSection('SYSTEM_BUILDER_INFO', '');
+	if (! $SBI) {
+		# return undef if the PTF section doesn't exist
+		return;
+	}
+	
+	my $result = $SBI->getAssignment('Has_IRQ');
+	if ($result ne "1") {
+		# this device has no associated IRQ
+		return;
+	}
+	
+	my @irq_masters = $SBI->getSections('IRQ_MASTER');
+	if (! @irq_masters) {
+		# this device has no associated IRQ_MASTER
+		return;
+	}
+	return $irq_masters[0]->getAssignment('IRQ_Number');
+}
+
+sub getMasters {
+	my ($self, $type) = @_;
+	my %masters = ();
+	
+	# get list of all slave for device
+	my @slaves = $self->{ptf}->getSections ('SLAVE');
+	
+	# get list of masters of relevant type for all slaves
+	foreach my $slave (@slaves) {
+		# get SBI for slave
+		my $SBI = $slave->getSection ('SYSTEM_BUILDER_INFO', '');
+		
+		# get list of all MASTERED_BY and IRQ_MASTER sections
+		my @mastered_bys = $SBI->getSections ('MASTERED_BY');
+		my @irq_masters = $SBI->getSections ('IRQ_MASTER');
+		
+		# start adding masters to the list
+		foreach my $master (@mastered_bys, @irq_masters) {
+			my $section_name = $master->name;
+			$section_name =~ /(.*)\/(.*)/;
+			my $master_name = $1;
+			my $master_type = $2;
+
+			if (! $type) {
+				$masters{$master_name} = ();
+			} else {
+				if ($master_type eq $type) {
+					$masters{$master_name} = ();
+				}
+			}
+			
+		}
+		
+	}
+	
+	return keys (%masters);
+}
+
+sub isEnabled {
+	my ($self) = @_;
+	
+	$sbi = $self->{ptf}->getSection('SYSTEM_BUILDER_INFO', '');
+	$sbi or return;
+	
+	my $enabled = $sbi->getAssignment ('Is_Enabled');
+	if ($enabled eq "1") {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+1;
+
diff --git a/arch/nios2/scripts/gen_nios2.h.pl b/arch/nios2/scripts/gen_nios2.h.pl
new file mode 100644
index 0000000..f32ad66
--- /dev/null
+++ b/arch/nios2/scripts/gen_nios2.h.pl
@@ -0,0 +1,275 @@
+# This script generates an appropriate hardware.h file for Nios II Linux based
+# on information within the target hardware's system.ptf file.  This script
+# outputs everything to stdout.
+#
+# usage:
+#
+#  [SOPC Builder]$ perl gen_hardware.h.pl <target cpu> <exec location>
+
+use PTF::SystemPTF;
+use strict;
+use integer;
+
+my $target_cpu;
+my $exec_location;
+
+if (scalar (@ARGV) < 2) {
+	print STDERR "ERROR: Invalid number of parameters.\n";
+	print ("#error Invalid number of parameters.\n");
+	exit;
+} else {
+	$target_cpu = $ARGV[0];
+	$exec_location = $ARGV[1];
+}
+
+#
+# startup the parser.
+#
+my $system = SystemPTF->new;
+if (!$system) {
+	print STDERR "ERROR: Specified file is not a SYSTEM ptf file.\n";
+	print ("#error Specified file is not a SYSTEM ptf file.\n");
+	exit;
+}
+
+#
+# print header for nios2.h
+#
+print <<ENDOFHEADER;
+#ifndef __NIOS2_H__
+#define __NIOS2_H__
+
+/*
+ * This file contains hardware information about the target platform.
+ *
+ * This file is automatically generated.  Do not modify.
+ */
+   
+ENDOFHEADER
+
+#
+# generate contents for nios2.h
+#
+my $result; # dummy variable
+my $cpu = $system->getCPU ($target_cpu);
+if (! $cpu) {
+	print STDERR "ERROR: $target_cpu is not a valid CPU in system: " . $system->getName () . ".\n";
+	print "#error $target_cpu is not a valid CPU in system: " . $system->getName () . ".\n";
+	exit 1;
+}
+
+my $exec_module = $system->getModule ($exec_location);
+if (! $exec_module) {
+	print STDERR "ERROR: $exec_location is not a valid module in the system: " . $system->getName() . ".\n";
+	print "#error $exec_location is not a valid module in system: " . $system->getName () . ".\n";
+	exit 1;
+}
+
+my %found_classes;
+my @found_classes_order;
+
+# the SYSPTF environment variable is set by kernel build process.
+if ($ENV{SYSPTF} ne "") {
+	print "/* Input System: " . $ENV{SYSPTF} .  ":" . $system->getName () . " */\n";
+} else {
+	print "/* Input System: " . $system->getName () . " */\n";
+}
+print "/* Target CPU: " . $target_cpu . " */\n";
+
+print "\n";
+
+print <<ENDOFCONSTANTS;
+/* Nios II Constants */
+#define NIOS2_STATUS_PIE_MSK  0x1
+#define NIOS2_STATUS_PIE_OFST 0
+#define NIOS2_STATUS_U_MSK    0x2
+#define NIOS2_STATUS_U_OFST   1
+ENDOFCONSTANTS
+
+print "\n";
+
+print "/*\n";
+print " * Outputting basic values from system.ptf.\n";
+print " */\n\n";
+
+#
+# Start outputing information about each module.
+#
+my @module_names = $system->getSlaveModules ($target_cpu);
+foreach my $module_name (@module_names) {
+	my $module = $system->getModule ($module_name);
+	my $module_class = $module->getClass ();
+	my @module_ports = $module->getPorts ();
+	my $mask = 0;
+	my $text_printed = 0;
+	my $output = "";
+
+	# $output .= "/* $module_name (of type $module_class) */\n";
+
+	if (! exists $found_classes{$module_class}) {
+		push @found_classes_order, $module_class;
+	}
+	push @{$found_classes{$module_class}}, $module_name;
+	
+	if (scalar (@module_ports) > 0) {
+		my $base_address;
+		my $mem_size;
+		my $mem_end;
+		
+		# base address information 
+		$base_address = $module->getBaseAddress ();
+		if ($base_address) {
+			$output .= sprintf ("#define na_%-50s %#010x\n", 
+				($module_name, hex ($base_address) | $mask));
+			$text_printed = 1;
+		}
+		if ($module->isMemoryDevice()) {
+			# output size and end address
+			$mem_size = $module->getSize();
+			$output .= sprintf ("#define na_%-50s %#010x\n",
+				($module_name . "_size", hex ($mem_size)));
+			$mem_end = hex ($mem_size) + hex($base_address);
+			$output .= sprintf ("#define na_%-50s %#010x\n",
+				($module_name . "_end", $mem_end));
+
+			$text_printed = 1;
+		}
+
+		# irq information 
+		$result = $module->getIRQ ();
+		if (defined ($result)) {
+			$output .= sprintf ("#define na_%-30s %30s\n", 
+				($module_name . "_irq", $result));
+			$text_printed = 1;
+		}
+
+		# clock information 
+		$result = $system->getClockFreq($module_name);
+		if (defined ($result)) {
+			$output .= sprintf ("#define na_%-30s %30s\n", 
+				($module_name . "_clock_freq", $result));
+			$text_printed = 1;
+		}
+
+	}
+	if (scalar (@module_ports) > 1) {
+		# if device has multiple ports
+		foreach my $port_name (@module_ports) {
+			# base address information
+			$result = $module->getBaseAddress ($port_name);
+			if ($result) {
+			$output .= sprintf ("#define na_%-50s %#010x\n", 
+				($module_name . "_" . $port_name, hex ($result) | $mask));
+				$text_printed = 1;
+			}
+
+			# irq information
+			$result = $module->getIRQ ($port_name);
+			if (defined ($result)) {
+			$output .= sprintf ("#define na_%-30s %30s\n", 
+				($module_name . "_" . $port_name . "_irq", $result));
+				$text_printed = 1;
+			}
+		}
+	}
+
+	if ($text_printed == 1) {
+		# $output .= "\n";
+		print $output;
+	}
+}
+
+print "\n";
+
+#
+# Handle special cases through customized perl scripts
+#
+foreach my $class_name (@found_classes_order) {
+	my $code = "";
+	
+	foreach my $dir (@INC) {
+		if (-e "$dir/nios2.h/$class_name.pm") {
+			print "/* Executing ...scripts/nios2.h/$class_name.pm */\n";
+			$code .= "require \"$dir/nios2.h/BasicModule.pm\";";
+			$code .= "require \"$dir/nios2.h/$class_name.pm\";";
+			$code .= $class_name . "::run(\$system, \@{\$found_classes{\$class_name}});";
+			eval $code;
+			if ($@) {
+				print "#warning Could not execute ...scripts/nios2.h/$class_name.pm\n";
+				print "#warning Error message is stored in nios2.h:\n";
+				print "/*\n";
+				print "$@";
+				print "*/\n";
+				print STDERR "Could not execute ...scripts/nios2.h/$class_name.pm\n";
+				print STDERR "Error message follows:\n";
+				print STDERR "$@";
+			} 
+			last;
+		}
+	}
+}
+
+#
+# Write out system information
+#
+print "/*\n";
+print " * Basic System Information\n";
+print " */\n";
+
+$result = $cpu->getWSAAssignment ('cache_icache_size');
+printf ("#define %-53s %10d\n", ("nasys_icache_size", $result));
+
+$result = $cpu->getConstant ('nasys_icache_line_size');
+printf ("#define %-53s %10d\n", ("nasys_icache_line_size", $result));
+
+$result = $cpu->getWSAAssignment ('cache_dcache_size');
+printf ("#define %-53s %10d\n", ("nasys_dcache_size", $result));
+
+$result = $cpu->getConstant ('nasys_dcache_line_size');
+printf ("#define %-53s %10d\n", ("nasys_dcache_line_size", $result));
+
+print "\n";
+
+printf ("#define %-33s %30s\n", 
+	("nasys_program_mem", "na_${exec_location}"));
+printf ("#define %-33s %30s\n", 
+	("nasys_program_mem_size", "na_${exec_location}_size"));
+printf ("#define %-33s %30s\n", 
+	("nasys_program_mem_end", "na_${exec_location}_end"));
+	
+print "\n";
+
+print "\n";
+printf ("#define %-33s %30s\n", 
+	("na_cpu_clock_freq", $system->getClockFreq($target_cpu)));
+	
+{	
+	my ($reset_location, $reset_offset) = $cpu->getResetLocationOffset();
+	my ($reset_module_name, $reset_port_name) = ($reset_location =~ /(.*)\/(.*)/);
+	my $reset_module = $system->getModule ($reset_module_name);
+	my $reset_address = $reset_module->getBaseAddress ($reset_port_name);
+	
+	$reset_address = hex ($reset_address) + hex ($reset_offset);
+	printf ("#define %-53s %#010x\n", 
+		("CPU_RESET_ADDRESS", $reset_address));
+}
+
+{	
+	my ($except_location, $except_offset) = $cpu->getExceptLocationOffset();
+	my ($except_module_name, $except_port_name) = ($except_location =~ /(.*)\/(.*)/);
+	my $except_module = $system->getModule ($except_module_name);
+	my $except_address = $except_module->getBaseAddress ($except_port_name);
+	
+	$except_address = hex ($except_address) + hex ($except_offset);
+	printf ("#define %-53s %#010x\n", 
+		("CPU_EXCEPT_ADDRESS", $except_address));
+}
+
+print "\n";
+
+#
+# print footer for nios2.h
+#
+print <<ENDOFFOOTER;
+#endif /* __NIOS2_H__ */
+ENDOFFOOTER
diff --git a/arch/nios2/scripts/hwselect.pl b/arch/nios2/scripts/hwselect.pl
new file mode 100644
index 0000000..d96a0ff
--- /dev/null
+++ b/arch/nios2/scripts/hwselect.pl
@@ -0,0 +1,141 @@
+# This script generates arch/nios2/hardware.mk based on user input
+
+# usage:
+#
+#  [SOPC Builder]$ perl hwselect.pl <ptf file path> <target file path>
+#
+
+use PTF::SystemPTF;
+use strict;
+use integer;
+
+my $ptf_filename;
+my $target_filename;
+my $index;
+my $system;
+
+#
+# Subroutine: Prompt user for an answer
+#
+
+sub request_answer {
+	my ($min, $max) = @_;
+	my $answer;
+
+	do {
+		print "Selection: ";
+		$answer = <STDIN>;
+		if (! ($answer >= $min && $answer <= $max)) {
+			print "Invalid response, please try again.\n";
+		}
+	} until $answer >= $min && $answer <= $max;
+
+	return $answer;
+}
+
+#
+# Check for correct number of args
+#
+
+if (scalar (@ARGV) != 2) {
+	print STDERR "ERROR: Invalid number of parameters.\n";
+	exit;
+} else {
+	$ptf_filename = $ARGV[0];
+	$target_filename = $ARGV[1];
+}
+
+#
+# Check to see if the specified file exists
+#
+
+if (! -e $ptf_filename) {
+	print STDERR "ERROR: Could not open SYSTEM ptf file.\n";
+	exit;
+}
+
+#
+# startup the parser.
+#
+$system = SystemPTF->new (filename => $ptf_filename);
+if (!$system) {
+	print STDERR "ERROR: Specified file is not a SYSTEM ptf file.\n";
+	exit;
+}
+
+#
+# Grab listing of Nios II processors and force user to select one:
+# 
+
+print "\n--- Please select which CPU you wish to build the kernel against:\n\n";
+
+my @cpulist = $system->getCPUList ('altera_nios2');
+my %cpuinfo;
+
+$index = 1;
+foreach my $cpu (@cpulist) {
+	my $cpu_module = $system->getCPU ($cpu);
+	if ($cpu_module->isEnabled ()) {
+		my $class = $cpu_module->getClass();
+		my $type = $cpu_module->getWSAAssignment('cpu_selection');
+		my $version = $cpu_module->getVersion();
+
+		print "($index) $cpu - Class: $class Type: $type Version: $version\n";
+	}
+	$index += 1;
+}
+
+print "\n";
+
+my $cpu_selection = $cpulist[request_answer (1, $index - 1) - 1];
+
+#
+# Grab list of memory devices that $cpu_selection is hooked up to:
+#
+my @modulelist = $system->getSlaveModules ($cpu_selection);
+my %meminfo;
+foreach my $module_name (@modulelist) {
+	my $module = $system->getModule ($module_name);
+	my $class = $module->getClass ();
+
+	if ($module->isEnabled ()) {	
+		if ($module->isMemoryDevice()) {
+			$meminfo{$module_name}{class} = $class;
+			$meminfo{$module_name}{size} = $module->getSize();
+		}
+	}
+}
+
+#
+# Select program memory to execute kernel from:
+# 
+print "\n--- Please select a device to execute kernel from:\n\n";
+
+$index = 1;
+foreach my $name (keys (%meminfo)) {
+	my $size = hex ($meminfo{$name}{size});
+	print "($index) $name\n\tClass: $meminfo{$name}{class}\n\tSize: $size bytes\n\n";
+	$index += 1;
+}
+
+my @memlist = keys (%meminfo);
+my $mem_selected = $memlist[request_answer (1, $index - 1) - 1];
+
+print "\n--- Summary using\n\n";
+print "PTF: $ptf_filename\n";
+print "CPU:                            $cpu_selection\n";
+print "Program memory to execute from: $mem_selected\n";
+
+#
+# Write settings out to Makefile fragment
+#
+open (HWMK, ">$target_filename") ||
+	die "Could not write to $target_filename";
+
+print HWMK "SYSPTF = $ptf_filename\n";
+print HWMK "CPU = $cpu_selection\n";
+print HWMK "EXEMEM = $mem_selected\n";
+
+close (HWMK);
+
+print "\n--- Settings written to $target_filename\n\n";
diff --git a/arch/nios2/scripts/nios2.h/BasicModule.pm b/arch/nios2/scripts/nios2.h/BasicModule.pm
new file mode 100644
index 0000000..7038a68
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/BasicModule.pm
@@ -0,0 +1,267 @@
+package BasicModule;
+
+require PTF::SystemPTF;
+require PTF::SystemPTF::Module;
+use strict;
+
+# Description: Prints an error message to stdout.  This should prefix each line
+#              with "#error " so that it can be properly read by the C 
+#              pre-processor.
+# Args: $module_name: name of module that was is required by driver
+#       $class_name: name of device class that module belongs to.
+sub print_error_name_used {
+	my ($class, $module_name, $class_name) = @_;
+
+	print "#error The kernel requires that the $class->required_class_name device be named as $module_name.\n";
+	print "#error The current hardware has $module_name defined as a(n) $class_name device.\n";
+	print "#error This will cause the kernel to fail.\n";
+	print "#error Please rename the current $module_name device to something else in SOPC Builder.\n";
+}
+
+# Description: This casts the base address to a specific data type
+#              By default, it does not cast the base address to
+#              anything.
+sub base_address_cast {
+	my ($class, $port_name) = @_;
+	return;
+}
+
+# Description: This sub-routine prints out a prefix that is shown only once
+#              before any translations take place.
+sub print_prefix {
+	my ($class, $system) = @_;
+	printf ("\n");
+}
+
+# Description: Prints a set of lines to stdout that re-defines all symbols
+#              related to $module_name to the symbols required by the driver.
+#              Typically starts off with "#undefine ..." statements followed
+#              by one or more "#define statements".
+# Args: $required_module_name: the module name that's expected by the kernel.
+#       $module_name: the name of the module that was found in the PTF file.
+sub translate {
+	my ($class, $system, $required_module_name, $module_name) = @_;
+	
+	# get the necessary info about the module
+	my $module = $system->getModule ($module_name);
+	my @port_names = $module->getPorts ();
+	
+	my $boolean_base_address_cast = 0;
+	if (scalar (@port_names) > 1) {
+		foreach my $port_name (@port_names) {
+			my $cast = $class->base_address_cast ($port_name);
+			if (defined ($cast)) {
+				$boolean_base_address_cast = 1;
+				last;
+			}
+		}
+	} else {
+		my $cast = $class->base_address_cast;
+		if (defined ($cast)) {
+			$boolean_base_address_cast = 1;
+		}
+	}
+
+	if ($module_name eq $required_module_name && 
+			!$boolean_base_address_cast) {
+		printf ("/* No translation necessary for $module_name */\n\n");
+		return;
+	}
+
+	# undefine the original entries
+	print "/* Redefining $module_name -> $required_module_name */\n";
+	if (scalar (@port_names) == 1) {
+		my $irq = $module->getIRQ ();
+		print "#undef na_" . $module_name . "\n";
+		if (defined ($irq)) {
+			print "#undef na_" . $module_name . "_irq\n";
+		}
+		print "\n";
+	} else {
+		foreach my $port_name (@port_names) {
+			print "#undef na_" . $module_name . "_" . 
+				$port_name . "\n";
+			my $irq = $module->getIRQ ($port_name);
+			if (defined ($irq)) {
+				print "#undef na_" . $module_name . "_" .
+					$port_name . "_irq\n";
+			}
+			print "\n";
+		}
+	}
+	
+	if (scalar (@port_names) == 1) {
+		# set up a string to pass to printf that will output the correct
+		# #define base address statement.
+
+		# turn on the high bit for the base address to bypass cache.
+		my $base_address = $module->getBaseAddress ();
+		$base_address = hex ($base_address);
+	
+		my $cast = $class->base_address_cast;
+		$class->print_define_line ($required_module_name, 
+			undef, "addr", $cast, $base_address);
+	
+		# print out an IRQ define statement if necessary
+		my $irq = $module->getIRQ ();
+		if (defined ($irq)) {
+			$class->print_define_line ($required_module_name, 
+				undef, "irq", undef, $irq);
+		}
+		printf ("\n");
+	} else {
+		foreach my $port_name (@port_names) {
+			my $cast = $class->base_address_cast ($port_name);
+			my $base_address = $module->getBaseAddress ($port_name);
+			$base_address = hex ($base_address);
+			$class->print_define_line ($required_module_name, 
+				$port_name, "addr", $cast, $base_address);
+
+			my $irq = $module->getIRQ ($port_name);
+			if (defined ($irq)) {
+				$class->print_define_line (
+					$required_module_name, $port_name,
+					"irq", undef, $irq);
+			}
+			
+			print "\n";
+		}
+	}
+}
+
+# Description: The following sub-routine prints out "undef" or "define"
+#              statements based on the arguments received.
+# Args: $name: "define" or "undef"
+#       $port: name of port (if applicable)
+#       $type: "addr" or "irq"
+#       $cast: data type to cast base address to (if applicable)
+#       $value: value of symbol to be defined (if applicable)
+sub print_define_line {
+	my ($class, $name, $port, $type, $cast, $value) = @_;
+
+	# construct the symbol that is being used
+	my $symbol .= "na_";
+	$symbol .= $name;
+
+	$symbol .= defined ($port) ? "_" . $port : "";
+	$symbol .= $type eq "irq" ? "_irq" : "";
+	
+	my $string_value;
+	if ($type eq "addr") {
+		$string_value = sprintf ("%#010x", $value);
+		if (defined $cast) {
+			$string_value = "(($cast*) $string_value)";
+		}
+	} else {
+		$string_value = $value;
+	}
+	printf ("%-41s %30s\n", "#define $symbol", $string_value);
+}	
+
+# Description: This sub-routine prints out a prefix that is shown only once
+#              after any translations take place.
+sub print_suffix {
+	my ($class, $system) = @_;
+	# intentionally left empty
+}
+	
+# Description: The following function allows the class to further determine if
+#              the module is valid.  For instance, the timer class requires
+#              that the selected module does not have a fixed period.
+#              This function returns true by default which basically means
+#              that all modules belonging to class are valid.
+sub is_module_valid {
+	my ($class, $system, $module_name) = @_;
+	return 1;
+}
+
+# Description: This sub-routine is required.  It is executed by the
+#              "../gen_nios2_system_h.pl" script whenever any devices of type
+#              $class->required_class_name are found in the PTF file.
+#
+#              It looks for any conflicting module names first.  If any are
+#              found, "print_error_name_used" is called and this perl module
+#              exits.
+#
+#              It then goes through the list of module names found in the PTF
+#              file that are of type $class->required_class_name and maps them to the
+#              list of unused names in $class->required_module_names.
+#
+#              Finally, it will call the "translate" sub-routine to output the
+#              symbols required by the driver.
+# Args: $system: a variable containing a reference to the system.ptf file that
+#                provides full access to any information in the file.
+#       @found_module_names: a list of module names that are of type
+#                            $class->required_class_name
+sub run2 {
+	my ($class, $system, @found_module_names) = @_;
+
+	# initialize a mapping of required module names to actual module names
+	my %module_map;
+	foreach my $module_name ($class->required_module_names) {
+		$module_map{$module_name} = "";
+	}
+
+	# if the required module name is already in use in the PTF file for a
+	# different device class, flag it as an error. 
+	my $error_found = 0;
+	foreach my $module_name ($class->required_module_names) {
+		my $module = $system->getModule ($module_name);
+
+		if (!defined ($module)) {
+			next;
+		}
+		
+		my $class_name = $module->getClass ();
+		if ($class_name ne $class->required_class_name) {
+			$class->print_error_name_used ($class, $module_name, $class_name);
+			$error_found = 1;
+		}
+	}
+
+	# if errors were found, then there's no point in continuing.
+	if ($error_found == 1) {
+		return;
+	}
+
+	# Run through list of modules that belong to the class and start
+	# mapping each module name to the first unused required module name
+	# as defined above
+	FOUND_MOD_LOOP: foreach my $module_name (@found_module_names) {
+
+		# If the module name has already been used, then continue
+		# to the next one.
+		foreach my $required_module_name ($class->required_module_names) {
+			if ($module_map{$required_module_name} eq $module_name) {
+				next FOUND_MOD_LOOP;
+			}
+		}
+
+		# assertion: $module_name is not mapped yet.
+		foreach my $required_module_name ($class->required_module_names) {
+			if ($module_map{$required_module_name} ne "") {
+				next;
+			}
+
+			if ($class->is_module_valid ($system, $module_name)) {
+				$module_map{$required_module_name} = $module_name;
+			}
+			last;
+		}
+	}
+
+	$class->print_prefix ($system);
+
+	# Now that everything's been mapped (or as close as we're going to get
+	# to it being mapped), start printing out the literal translation.
+	foreach my $required_module_name ($class->required_module_names) {
+		my $module_name = $module_map{$required_module_name};
+		if (length ($module_name) > 0) {
+			$class->translate ($system, $required_module_name, $module_name);
+		}
+	}
+
+	$class->print_suffix ($system);
+}
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/altera_avalon_jtag_uart.pm b/arch/nios2/scripts/nios2.h/altera_avalon_jtag_uart.pm
new file mode 100644
index 0000000..22bb9c9
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/altera_avalon_jtag_uart.pm
@@ -0,0 +1,18 @@
+package altera_avalon_jtag_uart;
+
+use base qw(BasicModule);
+use strict;
+
+sub required_module_names {
+	("jtag_uart")
+}
+
+sub required_class_name {
+	"altera_avalon_jtag_uart";
+}
+
+sub run {
+	altera_avalon_jtag_uart->run2 (@_);
+}
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/altera_avalon_lan91c111.pm b/arch/nios2/scripts/nios2.h/altera_avalon_lan91c111.pm
new file mode 100644
index 0000000..5a29b7e
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/altera_avalon_lan91c111.pm
@@ -0,0 +1,38 @@
+package altera_avalon_lan91c111;
+
+require PTF::SystemPTF;
+require PTF::SystemPTF::Module;
+use base qw(BasicModule);
+use strict;
+
+sub required_module_names {
+	"enet"
+}
+
+sub required_class_name {
+	"altera_avalon_lan91c111"
+}
+
+sub translate {
+	my $class = shift;
+	my ($system, $required_module_name, $module_name) = @_;
+	$class->SUPER::translate (@_);
+
+	my $module = $system->getModule ($module_name);
+
+	my $offset_keyword = "LAN91C111_REGISTERS_OFFSET";
+	my $offset = $module->getWSAConstant ($offset_keyword);
+	printf ("%-41s %30s\n", "#define $offset_keyword", $offset);
+
+	my $width_keyword = "LAN91C111_DATA_BUS_WIDTH";
+	my $width = $module->getWSAConstant ($width_keyword);
+	printf ("%-41s %30s\n", "#define $width_keyword", $width);
+
+	print "\n";
+}
+
+sub run {
+	altera_avalon_lan91c111->run2 (@_);
+}
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/altera_avalon_pio.pm b/arch/nios2/scripts/nios2.h/altera_avalon_pio.pm
new file mode 100644
index 0000000..bd1736f
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/altera_avalon_pio.pm
@@ -0,0 +1,46 @@
+package altera_avalon_pio;
+
+require PTF::SystemPTF;
+require PTF::SystemPTF::Module;
+use strict;
+
+sub run {
+	my ($system, @pio_names) = @_;
+
+	print "#ifndef __ASSEMBLY__\n";
+	print "#include <asm/pio_struct.h>\n";
+	print "#endif\n\n";
+	
+	foreach my $pio_name (@pio_names) {
+		my $module = $system->getModule ($pio_name);
+
+		# get all the relevant information
+		my $base_address = $module->getBaseAddress ();
+		$base_address = hex ($base_address);
+		my $irq = $module->getIRQ ();
+
+		print "/* Casting base addresses to the appropriate structure */\n";
+
+		# undefine all the old symbols first
+		print "#undef na_${pio_name}\n";
+		if (defined ($irq)) {
+			print "#undef na_${pio_name}_irq\n";
+			print "\n";
+		}
+
+		# define base address
+		$base_address = sprintf ("%#010x", $base_address);
+		printf ("%-41s %30s\n", "#define na_${pio_name}", 
+			"((np_pio*) ${base_address})");
+
+		# define irq
+		if (defined ($irq)) {
+			printf ("%-41s %30s\n", "#define na_${pio_name}_irq", 
+				$irq);
+		}
+
+		print "\n";
+	}
+}
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/altera_avalon_sysid.pm b/arch/nios2/scripts/nios2.h/altera_avalon_sysid.pm
new file mode 100644
index 0000000..deb9826
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/altera_avalon_sysid.pm
@@ -0,0 +1,18 @@
+package altera_avalon_sysid;
+
+use base qw(BasicModule);
+use strict;
+
+sub required_class_name {
+	"altera_avalon_sysid"
+}
+
+sub required_module_names {
+	"sysid"
+}
+
+sub run {
+	altera_avalon_sysid->run2 (@_);
+}
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/altera_avalon_timer.pm b/arch/nios2/scripts/nios2.h/altera_avalon_timer.pm
new file mode 100644
index 0000000..bda996f
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/altera_avalon_timer.pm
@@ -0,0 +1,42 @@
+package altera_avalon_timer;
+
+use base qw(BasicModule);
+use strict;
+
+sub required_class_name {
+	"altera_avalon_timer";
+}
+
+sub required_module_names {
+	"timer0"
+}
+
+sub base_address_cast {
+	"void "
+}
+
+# only timers with a non-fixed-period are valid
+sub is_module_valid {
+	my ($class, $system, $module_name) = @_;
+	
+	my $module = $system->getModule ($module_name);
+	my $fixed_period = $module->getWSAAssignment ('fixed_period');	
+
+	if ($fixed_period eq '0') {
+	    printf ("\n");
+	    printf ("/* system timer input clock frequency */\n");
+	    printf ("#define %-33s %30s\n", 
+		    ("nasys_clock_freq", $system->getClockFreq($module_name)));
+	    printf ("#define %-33s %30s\n", 
+		    ("nasys_clock_freq_1000", int ($system->getClockFreq($module_name)) / 1000));
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+sub run {
+	altera_avalon_timer->run2 (@_);
+}
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/altera_avalon_uart.pm b/arch/nios2/scripts/nios2.h/altera_avalon_uart.pm
new file mode 100644
index 0000000..ada44d4
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/altera_avalon_uart.pm
@@ -0,0 +1,36 @@
+package altera_avalon_uart;
+
+use base qw(BasicModule);
+use strict;
+
+sub required_module_names {
+	("uart0", "uart1", "uart2", "uart3")
+}
+
+sub required_class_name {
+	"altera_avalon_uart";
+}
+
+sub base_address_cast {
+	"void *"
+}
+
+sub translate {
+	my $class = shift;
+	my ($system, $required_module_name, $module_name) = @_;
+
+	$class->SUPER::translate (@_);
+
+	if (!defined ($altera_avalon_uart::default_uart)) {
+		print "/* The default uart is always the first one found in the PTF file */\n";
+		print "#define nasys_printf_uart na_$required_module_name\n\n";
+		$altera_avalon_uart::default_uart = $required_module_name;
+	}
+
+}
+
+sub run {
+	altera_avalon_uart->run2 (@_);
+}
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/fifoed_avalon_uart.pm b/arch/nios2/scripts/nios2.h/fifoed_avalon_uart.pm
new file mode 100644
index 0000000..1931a31
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/fifoed_avalon_uart.pm
@@ -0,0 +1,36 @@
+package fifoed_avalon_uart;
+
+use base qw(BasicModule);
+use strict;
+
+sub required_module_names {
+	("uart0", "uart1", "uart2", "uart3")
+}
+
+sub required_class_name {
+        "fifoed_avalon_uart";
+}
+
+sub base_address_cast {
+	"void "
+}
+
+sub translate {
+	my $class = shift;
+	my ($system, $required_module_name, $module_name) = @_;
+
+	$class->SUPER::translate (@_);
+
+        if (!defined ($fifoed_avalon_uart::default_uart)) {
+                print "/* The default uart is always the first one found in the PTF file */\n";
+                print "#define nasys_printf_uart na_$required_module_name\n\n";
+                $fifoed_avalon_uart::default_uart = $required_module_name;
+        }
+
+}
+
+sub run {
+        fifoed_avalon_uart->run2 (@_);
+}
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/gtf/altera_avalon_remote_update_cycloneiii.pm b/arch/nios2/scripts/nios2.h/gtf/altera_avalon_remote_update_cycloneiii.pm
new file mode 100644
index 0000000..64febd1
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/gtf/altera_avalon_remote_update_cycloneiii.pm
@@ -0,0 +1,21 @@
+package altera_avalon_remote_update_cycloneiii;
+
+require PTF::SystemPTF;
+require PTF::SystemPTF::Module;
+use strict;
+
+sub run {
+  my ($system, $altremote_name) = @_;
+  my $module = $system->getModule ($altremote_name);
+  my $base_address = $module->getBaseAddress ();
+  $base_address = hex ($base_address) | 0x80000000;
+# undefine all the old symbols first
+    print "#undef na_${altremote_name}\n";
+
+# define base address
+    $base_address = sprintf ("%#010x", $base_address);
+    printf ("%-41s %30s\n", "#define na_altremote", "${base_address}");
+    print "\n";
+}
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/mtip_avalon_10_100_mac.pm b/arch/nios2/scripts/nios2.h/mtip_avalon_10_100_mac.pm
new file mode 100644
index 0000000..fdd727b
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/mtip_avalon_10_100_mac.pm
@@ -0,0 +1,18 @@
+package mtip_avalon_10_100_mac;
+
+use base qw(BasicModule);
+use strict;
+
+sub required_class_name {
+	"mtip_avalon_10_100_mac";
+}
+
+sub required_module_names {
+	"mtip_mac"
+}
+
+sub run {
+	mtip_avalon_10_100_mac->run2 (@_);
+}
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/mtx_avalon_dm9000.pm b/arch/nios2/scripts/nios2.h/mtx_avalon_dm9000.pm
new file mode 100644
index 0000000..5985c2f
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/mtx_avalon_dm9000.pm
@@ -0,0 +1,18 @@
+package mtx_avalon_dm9000;
+
+use base qw(BasicModule);
+use strict;
+
+sub required_module_names {
+	"dm9000"
+}
+
+sub required_class_name {
+	"mtx_avalon_dm9000"
+}
+
+sub run {
+	mtx_avalon_dm9000->run2(@_);
+}
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/mtx_avalon_isp1161a1.pm b/arch/nios2/scripts/nios2.h/mtx_avalon_isp1161a1.pm
new file mode 100644
index 0000000..e70ffa3
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/mtx_avalon_isp1161a1.pm
@@ -0,0 +1,18 @@
+package mtx_avalon_isp1161a1;
+
+use base qw(BasicModule);
+use strict;
+
+sub required_module_names {
+	"usb"
+}
+
+sub required_class_name {
+	"mtx_avalon_isp1161a1";
+}
+
+sub run {
+	mtx_avalon_isp1161a1->run2(@_);
+}
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/no_legacy_module.pm b/arch/nios2/scripts/nios2.h/no_legacy_module.pm
new file mode 100644
index 0000000..940e923
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/no_legacy_module.pm
@@ -0,0 +1,44 @@
+package no_legacy_module;
+
+use base qw(BasicModule);
+use strict;
+
+sub required_class_name {
+  "no_legacy_module";
+}
+
+sub run {
+  my ($system, @no_legacy_module_names) = @_;
+
+  foreach my $no_legacy_module_name (@no_legacy_module_names) {
+    my $module = $system->getModule ($no_legacy_module_name);
+    my $gtf_class_name = $module->getGtfClass ();
+
+    foreach my $dir (@INC) {
+    if (-e "$dir/nios2.h/gtf/$gtf_class_name.pm") {
+      my $code = "";
+      print "/* Executing ...scripts/nios2.h/gtf/$gtf_class_name.pm */\n";
+      $code .= "require \"$dir/nios2.h/BasicModule.pm\";";
+      $code .= "require \"$dir/nios2.h/gtf/$gtf_class_name.pm\";";
+      $code .= $gtf_class_name . "::run(\$system, \$no_legacy_module_name);";
+      eval $code;
+      if ($@) {
+        print "#warning Could not execute ...scripts/nios2_system.h/gtf/$gtf_class_name.pm\n";
+        print "#warning Error message is stored in nios2_system.h:\n";
+        print "/*\n";
+        print "$@";
+        print "*/\n";
+        print STDERR "Could not execute ...scripts/nios2_system.h/gtf/$gtf_class_name.pm\n";
+        print STDERR "Error message follows:\n";
+        print STDERR "$@";
+} 
+      last;
+}   
+}
+
+}
+
+}
+
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/opencores_ethernet_mac.pm b/arch/nios2/scripts/nios2.h/opencores_ethernet_mac.pm
new file mode 100644
index 0000000..7b580b5
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/opencores_ethernet_mac.pm
@@ -0,0 +1,18 @@
+package opencores_ethernet_mac;
+
+use base qw(BasicModule);
+use strict;
+
+sub required_module_names {
+	"igor_mac"
+}
+
+sub required_class_name {
+	"opencores_ethernet_mac"
+}
+
+sub run {
+	opencores_ethernet_mac->run2 (@_);
+}
+
+1;
diff --git a/arch/nios2/scripts/nios2.h/opencores_i2c.pm b/arch/nios2/scripts/nios2.h/opencores_i2c.pm
new file mode 100644
index 0000000..512d12c
--- /dev/null
+++ b/arch/nios2/scripts/nios2.h/opencores_i2c.pm
@@ -0,0 +1,18 @@
+package opencores_i2c;
+
+use base qw(BasicModule);
+use strict;
+
+sub required_module_names {
+	("i2c_0", "i2c_1")
+}
+
+sub required_class_name {
+	"opencores_i2c";
+}
+
+sub run {
+	opencores_i2c->run2 (@_);
+}
+
+1;
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index f2df6e2..3fade4d 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -781,5 +781,16 @@ config PATA_BF54X
 
 	  If unsure, say N.
 
+config PATA_ALTERA_CF
+	tristate "Altera SOPC Builder CompactFlash support (Experimental)"
+	depends on NIOS2 && EXPERIMENTAL
+	help
+	  This option enables support for the CompactFlash core in an
+	  Altera SOPC Builder system.  It supports insertion and removal
+	  of CompactFlash cards.  It can be used instead of the generic
+	  PATA platform device support if this functionality is desired.
+
+	  If unsure, say N.
+
 endif # ATA_SFF
 endif # ATA
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 01e126f..9be42c2 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_PATA_PLATFORM)	+= pata_platform.o
 obj-$(CONFIG_PATA_AT91)	+= pata_at91.o
 obj-$(CONFIG_PATA_OF_PLATFORM)	+= pata_of_platform.o
 obj-$(CONFIG_PATA_ICSIDE)	+= pata_icside.o
+obj-$(CONFIG_PATA_ALTERA_CF)	+= pata_altera_cf.o
 # Should be last but two libata driver
 obj-$(CONFIG_PATA_ACPI)		+= pata_acpi.o
 # Should be last but one libata driver
diff --git a/drivers/ata/pata_altera_cf.c b/drivers/ata/pata_altera_cf.c
new file mode 100644
index 0000000..cb6a852
--- /dev/null
+++ b/drivers/ata/pata_altera_cf.c
@@ -0,0 +1,586 @@
+/*
+ *  pata_altera_cf.c - PATA driver for Altera SOPC Builder CompactFlash core.
+ *
+ *  Copyright (C) 2009 MEV Limited <http://www.mev.co.uk>
+ *  Author: Ian Abbott <abbotti@mev.co.uk>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  This file was based on/inspired by:
+ *    drivers/ata/pata_platform.c
+ *    drivers/ata/pata_pcmcia.c
+ *    drivers/ata/pata_ixp4xx_cf.c
+ *    altcf.c from the Microtronix Nios II Linux distribution.
+ *
+ *  This is a platform device driver and expects two memory resources and
+ *  two IRQ resources per platform device in the following:
+ *
+ *    IDE memory resource -- 64 byte memory area consisting of IDE registers
+ *                           on 4-byte boundaries.
+ *    IDE IRQ resource    -- IRQ resource consisting of IRQ number and desired
+ *                           IRQ flags for the IDE interface.  The IRQ number
+ *                           can be set to 0 to avoid setting up the IRQ.
+ *    CF CONTROL memory resource -- 16 byte resource consisting of the CF
+ *                           CONTROL registers on 4-byte boundaries.
+ *    CF CONTROL IRQ resource -- IRQ resource consisting of IRQ number and
+ *                           desired IRQ flags for the CF CONTROL interface.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <scsi/scsi_host.h>
+#include <linux/ata.h>
+#include <linux/libata.h>
+#include <linux/platform_device.h>
+#include <linux/kthread.h>
+
+#define DRV_NAME "pata_altera_cf"
+#define DRV_VERSION "0.01"
+
+
+#define ALTCF_SHIFT		2
+
+/* IDE registers */
+#define ALTCF_IDE_LEN		(16 << ALTCF_SHIFT)
+#define ALTCF_IDE_REG_DATA	(ATA_REG_DATA << ALTCF_SHIFT)
+#define ALTCF_IDE_REG_ERR	(ATA_REG_ERR << ALTCF_SHIFT)
+#define ALTCF_IDE_REG_NSECT	(ATA_REG_NSECT << ALTCF_SHIFT)
+#define ALTCF_IDE_REG_LBAL	(ATA_REG_LBAL << ALTCF_SHIFT)
+#define ALTCF_IDE_REG_LBAM	(ATA_REG_LBAM << ALTCF_SHIFT)
+#define ALTCF_IDE_REG_LBAH	(ATA_REG_LBAH << ALTCF_SHIFT)
+#define ALTCF_IDE_REG_DEVICE	(ATA_REG_DEVICE << ALTCF_SHIFT)
+#define ALTCF_IDE_REG_STATUS	(ATA_REG_STATUS << ALTCF_SHIFT)
+#define ALTCF_IDE_REG_FEATURE	(ATA_REG_FEATURE << ALTCF_SHIFT)
+#define ALTCF_IDE_REG_CMD	(ATA_REG_CMD << ALTCF_SHIFT)
+#define ALTCF_IDE_REG_CTL	(14 << ALTCF_SHIFT)
+
+/* CF CONTROL registers */
+#define ALTCF_CFC_LEN		(4 << ALTCF_SHIFT)
+#define ALTCF_CFC_REG_CFCTL	(0 << ALTCF_SHIFT)
+#define ALTCF_CFC_REG_IDECTL	(1 << ALTCF_SHIFT)
+
+/* CFCTL register bitmasks */
+#define ALTCF_CFCTL_DET		0x01	/* CF detected */
+#define ALTCF_CFCTL_PWR		0x02	/* power */
+#define ALTCF_CFCTL_RST		0x04	/* reset */
+#define ALTCF_CFCTL_IDET	0x08	/* "CF detect change" intr enable */
+
+/* IDECTL register bitmasks */
+#define ALTCF_IDECTL_IIDE	0x01	/* IDE interrupt enable */
+
+/* Macros to read/write CF CONTROL registers. */
+#define READ_CFCTL(altcf)	readl((altcf)->cfc_base + ALTCF_CFC_REG_CFCTL)
+#define WRITE_CFCTL(altcf, d)	\
+	writel((d), (altcf)->cfc_base + ALTCF_CFC_REG_CFCTL)
+#define READ_IDECTL(altcf)	readl((altcf)->cfc_base + ALTCF_CFC_REG_IDECTL)
+#define WRITE_IDECTL(altcf, d)	\
+	writel((d), (altcf)->cfc_base + ALTCF_CFC_REG_IDECTL)
+
+typedef unsigned char __iomem *ptr_iomem;
+
+/*
+ * This is the driver's private data for the device.  The struct device's
+ * private data pointer is used by the libata core so we can't use it ourselves.
+ * Instead, we use the devres functions to access it.  This is a lot slower
+ * than using the device's private data pointer but we shouldn't have to do it
+ * very often.
+ */
+struct altcf_private {
+	struct device *dev;		/* point back to device */
+	resource_size_t ide_raw_base;	/* unmapped IDE registers */
+	ptr_iomem ide_base;		/* mapped IDE registers */
+	ptr_iomem cfc_base;		/* mapped CF CONTROL registers */
+	struct task_struct *cf_thread;	/* kthread to handle CF events */
+	int cfc_irq;			/* IRQ for CF CONTROL */
+	int ide_irq;			/* IRQ for IDE */
+	unsigned long ide_irqflags;	/* IRQ flags for IDE */
+	unsigned long event;		/* event/state bits */
+	spinlock_t cfctl_lock;		/* spinlock to change CFCTL */
+	unsigned char cfctl;		/* CFCTL register */
+	void *ata_group_id;		/* devres group ID of ATA resources */
+};
+
+/* Event/state bits. */
+enum altcf_event {
+	EV_CHANGE,
+	EV_HOLD,
+	EV_DEAD
+};
+
+/* Update the CFCTL register. */
+static void update_cfctl(struct altcf_private *altcf,
+		unsigned char mask, unsigned char set)
+{
+	unsigned long flags;
+
+	set &= mask;
+	spin_lock_irqsave(&altcf->cfctl_lock, flags);
+	altcf->cfctl = (altcf->cfctl & ~mask) | set;
+	WRITE_CFCTL(altcf, altcf->cfctl);
+	spin_unlock_irqrestore(&altcf->cfctl_lock, flags);
+}
+
+/* IRQ handler to handle CF detection state changes. */
+static irqreturn_t altcf_cf_interrupt(int irq, void *context)
+{
+	struct altcf_private *altcf = context;
+
+	READ_CFCTL(altcf);	/* Clear interrupt */
+	/* Record the fact that something changed. */
+	set_bit(EV_CHANGE, &altcf->event);
+	smp_mb();
+	/* Wake up the kthread to deal with it. */
+	wake_up_process(altcf->cf_thread);
+	return IRQ_HANDLED;
+}
+
+/* Provide our own set_mode(). */
+static int altcf_set_mode(struct ata_link *link, struct ata_device **error)
+{
+	struct ata_device *dev;
+
+	ata_for_each_dev(dev, link, ENABLED) {
+		ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n");
+		dev->pio_mode = XFER_PIO_0;
+		dev->xfer_mode = XFER_PIO_0;
+		dev->xfer_shift = ATA_SHIFT_PIO;
+		dev->flags |= ATA_DFLAG_PIO;
+	}
+	return 0;
+}
+
+static struct scsi_host_template altcf_sht = {
+	ATA_PIO_SHT(DRV_NAME),
+};
+
+static struct ata_port_operations altcf_port_ops = {
+	.inherits		= &ata_sff_port_ops,
+	.sff_data_xfer		= ata_sff_data_xfer_noirq,
+	.cable_detect		= ata_cable_40wire,
+	.set_mode		= altcf_set_mode,
+	.port_start		= ATA_OP_NULL,
+};
+
+/* Checks if CF present and sets up ATA host. */
+static void altcf_detect_cf(struct altcf_private *altcf)
+{
+	struct ata_host *host;
+	struct ata_port *ap;
+	void *group_id;
+
+	if ((READ_CFCTL(altcf) & ALTCF_CFCTL_DET) == 0)
+		return;
+
+	dev_dbg(altcf->dev, "CF detected\n");
+	/* Hold in reset powered down for 0.5 seconds. */
+	update_cfctl(altcf, ALTCF_CFCTL_RST | ALTCF_CFCTL_PWR, ALTCF_CFCTL_RST);
+	msleep(500);
+	if (test_bit(EV_CHANGE, &altcf->event)
+			|| test_bit(EV_DEAD, &altcf->event)) {
+		goto fail_reset_sleep;
+	}
+	/* Remove reset, power up and wait 0.5 seconds. */
+	update_cfctl(altcf, ALTCF_CFCTL_RST | ALTCF_CFCTL_PWR, ALTCF_CFCTL_PWR);
+	msleep(500);
+	if (test_bit(EV_CHANGE, &altcf->event)
+			|| test_bit(EV_DEAD, &altcf->event)) {
+		goto fail_power_sleep;
+	}
+
+	/* Create devres group to manage ATA host resources. */
+	group_id = devres_open_group(altcf->dev, NULL, GFP_KERNEL);
+	if (group_id == NULL) {
+		dev_warn(altcf->dev, "failed to allocate ATA group\n");
+		goto fail_open_group;
+	}
+
+	/* Allocate ATA host with single port. */
+	host = ata_host_alloc(altcf->dev, 1);
+	if (host == NULL) {
+		dev_warn(altcf->dev, "failed to allocate ATA host\n");
+		goto fail_ata_host_alloc;
+	}
+
+	ap = host->ports[0];
+	ap->ops = &altcf_port_ops;
+	ap->pio_mask = 0x1f;	/* PIO4 */
+	ap->flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO;
+
+	/* Use polling mode if there's no IRQ. */
+	if (!altcf->ide_irq) {
+		ap->flags |= ATA_FLAG_PIO_POLLING;
+		ata_port_desc(ap, "no IRQ, using PIO polling");
+	}
+
+	/* Set up register addresses. */
+	/* command section */
+	ap->ioaddr.cmd_addr = altcf->ide_base;
+	ap->ioaddr.data_addr = ap->ioaddr.cmd_addr + ALTCF_IDE_REG_DATA;
+	ap->ioaddr.error_addr = ap->ioaddr.cmd_addr + ALTCF_IDE_REG_ERR;
+	ap->ioaddr.feature_addr = ap->ioaddr.cmd_addr + ALTCF_IDE_REG_FEATURE;
+	ap->ioaddr.nsect_addr = ap->ioaddr.cmd_addr + ALTCF_IDE_REG_NSECT;
+	ap->ioaddr.lbal_addr = ap->ioaddr.cmd_addr + ALTCF_IDE_REG_LBAL;
+	ap->ioaddr.lbam_addr = ap->ioaddr.cmd_addr + ALTCF_IDE_REG_LBAM;
+	ap->ioaddr.lbah_addr = ap->ioaddr.cmd_addr + ALTCF_IDE_REG_LBAH;
+	ap->ioaddr.device_addr = ap->ioaddr.cmd_addr + ALTCF_IDE_REG_DEVICE;
+	ap->ioaddr.status_addr = ap->ioaddr.cmd_addr + ALTCF_IDE_REG_STATUS;
+	ap->ioaddr.command_addr = ap->ioaddr.cmd_addr + ALTCF_IDE_REG_CMD;
+	/* control section */
+	ap->ioaddr.ctl_addr = altcf->ide_base + ALTCF_IDE_REG_CTL;
+	ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
+	ata_port_desc(ap, "mmio cmd 0x%llx ctl 0x%llx",
+			(unsigned long long)altcf->ide_raw_base,
+			(unsigned long long)altcf->ide_raw_base
+			+ ALTCF_IDE_REG_CTL);
+
+	/* Enable the IDE IRQ if using it. */
+	if (altcf->ide_irq)
+		WRITE_IDECTL(altcf, ALTCF_IDECTL_IIDE);
+
+	/* Activate the ATA host. */
+	if (ata_host_activate(host, altcf->ide_irq,
+				altcf->ide_irq ? ata_sff_interrupt : NULL,
+				altcf->ide_irqflags, &altcf_sht)) {
+		dev_warn(altcf->dev, "failed to activate ATA host\n");
+		goto fail_ata_host_activate;
+	}
+
+	/* Success! */
+	altcf->ata_group_id = group_id;
+	devres_close_group(altcf->dev, group_id);
+	return;
+
+fail_ata_host_activate:
+
+	/* Disable IDE IRQ. */
+	WRITE_IDECTL(altcf, 0);
+fail_ata_host_alloc:
+
+	devres_release_group(altcf->dev, group_id);
+fail_open_group:
+fail_power_sleep:
+
+	/* Hold in reset powered down. */
+	update_cfctl(altcf, ALTCF_CFCTL_RST | ALTCF_CFCTL_PWR, ALTCF_CFCTL_RST);
+fail_reset_sleep:
+
+	dev_dbg(altcf->dev, "CF detection cancelled\n");
+}
+
+/* Get rid of old ATA host, if any. */
+static void altcf_remove_ata(struct altcf_private *altcf)
+{
+	void *group_id;
+	struct ata_host *host;
+
+	/* Disable IDE IRQ. */
+	WRITE_IDECTL(altcf, 0);
+	/* Look for ATA resources. */
+	group_id = altcf->ata_group_id;
+	altcf->ata_group_id = NULL;
+	if (group_id) {
+		dev_dbg(altcf->dev, "removing old CF\n");
+		/* Look for ATA host and detach it. */
+		host = dev_get_drvdata(altcf->dev);
+		if (host) {
+			ata_host_detach(host);
+		}
+		/* Release ATA resources. */
+		devres_release_group(altcf->dev, group_id);
+	}
+	/* Hold CF in reset powered down. */
+	update_cfctl(altcf, ALTCF_CFCTL_RST | ALTCF_CFCTL_PWR, ALTCF_CFCTL_RST);
+}
+
+/*
+ * Kthread function to handle CF detection state changes.
+ * It is responsible for adding and removing the ATA host.
+ */
+static int altcf_thread(void *context)
+{
+	struct altcf_private *altcf = context;
+
+	for (;;) {
+		dev_dbg(altcf->dev, "altcf_thread loop\n");
+		set_current_state(TASK_INTERRUPTIBLE);
+		while (!kthread_should_stop()
+				&& (test_bit(EV_HOLD, &altcf->event)
+					|| (!test_and_clear_bit(EV_CHANGE,
+							&altcf->event)
+						&& !test_bit(EV_DEAD,
+							&altcf->event)))) {
+			dev_dbg(altcf->dev, "altcf_thread sleeping\n");
+			schedule();
+			dev_dbg(altcf->dev, "altcf_thread woken\n");
+			set_current_state(TASK_INTERRUPTIBLE);
+		}
+		__set_current_state(TASK_RUNNING);
+		if (kthread_should_stop()) {
+			dev_dbg(altcf->dev, "altcf_thread stopping\n");
+			break;
+		}
+		/* State changed, so remove ATA host if previously set up. */
+		altcf_remove_ata(altcf);
+		if (!test_bit(EV_DEAD, &altcf->event)) {
+			/* Check if CF is present and set it up. */
+			altcf_detect_cf(altcf);
+		}
+	}
+	/* Finally, remove ATA host if set up. */
+	altcf_remove_ata(altcf);
+	dev_dbg(altcf->dev, "altcf_thread exit\n");
+	return 0;
+}
+
+/* This is the devres release function for our private data. */
+static void altcf_private_release(struct device *dev, void *res)
+{
+	/* no op */
+}
+
+/* Add a device. */
+static int __devinit altcf_probe(struct device *dev,
+		struct resource *ide_mem_res, struct resource *ide_irq_res,
+		struct resource *cfc_mem_res, struct resource *cfc_irq_res)
+{
+	struct altcf_private *altcf;
+	int rc = -ENXIO;
+
+	/* Check resources */
+	if (resource_type(ide_mem_res) != IORESOURCE_MEM) {
+		dev_err(dev, "IDE region wrong type\n");
+		return rc;
+	}
+	if (resource_size(ide_mem_res) < ALTCF_IDE_LEN) {
+		dev_err(dev, "IDE region too small");
+		return rc;
+	}
+	if (resource_type(ide_irq_res) != IORESOURCE_IRQ) {
+		dev_err(dev, "IDE IRQ wrong type\n");
+		return rc;
+	}
+	if (resource_type(cfc_mem_res) != IORESOURCE_MEM) {
+		dev_err(dev, "CF CONTROL region wrong type\n");
+		return rc;
+	}
+	if (resource_size(cfc_mem_res) < ALTCF_CFC_LEN) {
+		dev_err(dev, "CF CONTROL region too small");
+		return rc;
+	}
+
+	/* Allocate private data and add it to the device. */
+	rc = -ENOMEM;
+	altcf = devres_alloc(altcf_private_release,
+			sizeof(struct altcf_private), GFP_KERNEL);
+	if (!altcf) {
+		dev_err(dev, "failed to alloc private data\n");
+		return rc;
+	}
+	altcf->dev = dev;	/* point back to device */
+	devres_add(dev, altcf);
+	/* Some more initialization. */
+	altcf->ide_irq = (int)ide_irq_res->start;
+	altcf->ide_irqflags = ide_irq_res->flags & IORESOURCE_BITS;
+	altcf->cfc_irq = (int)cfc_irq_res->start;
+	spin_lock_init(&altcf->cfctl_lock);
+
+	/* Map registers. */
+	altcf->ide_raw_base = ide_mem_res->start;
+	altcf->ide_base = devm_ioremap_nocache(dev, ide_mem_res->start,
+			ALTCF_IDE_LEN);
+	if (!altcf->ide_base) {
+		dev_err(dev, "failed to remap IDE registers\n");
+		return rc;
+	}
+	altcf->cfc_base = devm_ioremap_nocache(dev, cfc_mem_res->start,
+			ALTCF_CFC_LEN);
+	if (!altcf->cfc_base) {
+		dev_err(dev, "failed to remap CF CONTROL registers\n");
+		return rc;
+	}
+
+	/* Initialize CF CONTROL registers. */
+	altcf->cfctl = ALTCF_CFCTL_RST;
+	WRITE_CFCTL(altcf, altcf->cfctl);
+	WRITE_IDECTL(altcf, 0);
+	READ_CFCTL(altcf);	/* Clear "CF detect change" interrupt. */
+
+	/* Set event to hold off processing of CF state changes. */
+	set_bit(EV_HOLD, &altcf->event);
+	smp_mb();
+
+	/* Create kthread to handle CF state changes. */
+	altcf->cf_thread = kthread_create(altcf_thread, altcf,
+			DRV_NAME "/%s", dev_name(dev));
+	if (IS_ERR(altcf->cf_thread)) {
+		rc = PTR_ERR(altcf->cf_thread);
+		altcf->cf_thread = NULL;
+		dev_err(dev, "failed to create thread (%d)\n", rc);
+		return rc;
+	}
+
+	/* Request IRQ handler to handle "CF detect change" interrupt. */
+	rc = request_irq(altcf->cfc_irq, altcf_cf_interrupt,
+			(cfc_irq_res->flags & IORESOURCE_BITS),
+			DRV_NAME, altcf);
+	if (rc) {
+		dev_err(dev, "failed to request CF CONTROL IRQ %d flags 0x%lx"
+				" (%d)\n",
+				altcf->cfc_irq,
+				(cfc_irq_res->flags & IORESOURCE_BITS), rc);
+		goto fail_request_irq_cf;
+	}
+
+	/* Enable the "CF detect change" interrupt. */
+	update_cfctl(altcf, ALTCF_CFCTL_IDET, ALTCF_CFCTL_IDET);
+
+	/* Generate initial CF state change event. */
+	set_bit(EV_CHANGE, &altcf->event);
+	smp_mb__before_clear_bit();
+	clear_bit(EV_HOLD, &altcf->event);
+	smp_mb__after_clear_bit();
+	wake_up_process(altcf->cf_thread);
+
+	return 0;
+
+#ifdef unused
+	/* Disable the "CF detect change" interrupt and free the IRQ. */
+	update_cfctl(altcf, ALTCF_CFCTL_IDET, 0);
+	free_irq(altcf->cfc_irq, altcf);
+#endif
+fail_request_irq_cf:
+
+	/* Stop the thread. */
+	kthread_stop(altcf->cf_thread);
+	/* Reinitialize CF CONTROL registers. */
+	altcf->cfctl = ALTCF_CFCTL_RST;
+	WRITE_CFCTL(altcf, altcf->cfctl);
+	WRITE_IDECTL(altcf, 0);
+	/* Everything else is removed by devres. */
+	return rc;
+}
+
+/* Remove a device. */
+static int __devexit altcf_remove(struct device *dev)
+{
+	struct altcf_private *altcf;
+
+	/* Get pointer to our private data resource. */
+	altcf = devres_find(dev, altcf_private_release, NULL, NULL);
+	if (altcf == NULL) {
+		return -ENXIO;
+	}
+	/* Hold off CF detect thread processing and mark device as dead. */
+	set_bit(EV_HOLD, &altcf->event);
+	set_bit(EV_DEAD, &altcf->event);
+	smp_mb();
+	/* Disable the "CF detect change" interrupt and free the IRQ. */
+	update_cfctl(altcf, ALTCF_CFCTL_IDET, 0);
+	free_irq(altcf->cfc_irq, altcf);
+	/* Stop the thread. */
+	if (altcf->cf_thread) {
+		kthread_stop(altcf->cf_thread);
+		altcf->cf_thread = NULL;
+	}
+	/* Reinitialize CF CONTROL registers. */
+	altcf->cfctl = ALTCF_CFCTL_RST;
+	WRITE_CFCTL(altcf, altcf->cfctl);
+	WRITE_IDECTL(altcf, 0);
+	/* Everything else is removed by devres. */
+	return 0;
+}
+
+/* Add a platform device. */
+static int __devinit altcf_platform_probe(struct platform_device *pdev)
+{
+	struct resource *ide_mem_res;
+	struct resource *ide_irq_res;
+	struct resource *cfc_mem_res;
+	struct resource *cfc_irq_res;
+
+	if (pdev->num_resources != 4) {
+		dev_err(&pdev->dev, "invalid number of resources\n");
+		return -EINVAL;
+	}
+
+	/* Get the IDE MMIO resource. */
+	ide_mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (unlikely(ide_mem_res == NULL)) {
+		dev_err(&pdev->dev, "no IDE mem resource\n");
+		return -EINVAL;
+	}
+
+	/* Get the IDE IRQ resource. */
+	ide_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if ((unlikely(ide_irq_res == NULL))) {
+		dev_err(&pdev->dev, "no IDE IRQ resource\n");
+		return -EINVAL;
+	}
+
+	/* Get the CF CONTROL MMIO resource. */
+	cfc_mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (unlikely(ide_mem_res == NULL)) {
+		dev_err(&pdev->dev, "no CF CONTROL mem resource\n");
+		return -EINVAL;
+	}
+
+	/* Get the CF CONTROL IRQ resource. */
+	cfc_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+	if ((unlikely(cfc_irq_res == NULL))) {
+		dev_err(&pdev->dev, "no CF CONTROL IRQ resource\n");
+		return -EINVAL;
+	}
+	
+	return altcf_probe(&pdev->dev, ide_mem_res, ide_irq_res,
+			cfc_mem_res, cfc_irq_res);
+}
+
+/* Remove a platform device. */
+static int __devexit altcf_platform_remove(struct platform_device *pdev)
+{
+	return altcf_remove(&pdev->dev);
+}
+
+/* We are a platform device driver. */
+static struct platform_driver altcf_platform_driver = {
+	.probe		= altcf_platform_probe,
+	.remove		= __devexit_p(altcf_platform_remove),
+	.driver = {
+		.name		= DRV_NAME,
+		.owner		= THIS_MODULE,
+	},
+};
+
+/* module_init function */
+static int __init altcf_init(void)
+{
+	return platform_driver_register(&altcf_platform_driver);
+}
+
+/* module_exit function */
+static void __exit altcf_exit(void)
+{
+	platform_driver_unregister(&altcf_platform_driver);
+}
+
+MODULE_AUTHOR("Ian Abbott");
+MODULE_DESCRIPTION("low-level driver for Altera SOPC Builder CompactFlash ATA");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+MODULE_ALIAS("platform:" DRV_NAME);
+
+module_init(altcf_init);
+module_exit(altcf_exit);
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 08a6f50..7c2195d 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -127,6 +127,24 @@ config SERIAL_NONSTANDARD
 
 	  Most people can say N here.
 
+config NIOS_LCD_16207
+	tristate "Nios LCD 16207 device support"
+	depends on NIOS || NIOS2
+	help
+	  This driver supports the Nios LCD 16207 device.
+
+config NIOS_BUTTON
+	bool "Nios PIO buttons support"
+	depends on NIOS || NIOS2
+	---help---
+	This driver takes the 4 user buttons on Altera's Nios Development Kit
+	as a source of input: users can input '1','2','4' or '8' by pressing
+	one of the 4 buttons. The device node is a character device with a
+	major of 62 and minor of 0. Users can view input using the following
+	command:
+		$ cat /dev/btn
+	where /dev/btn is the device node file.
+
 config COMPUTONE
 	tristate "Computone IntelliPort Plus serial support"
 	depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 19a79dd..1275a91 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -90,6 +90,8 @@ obj-$(CONFIG_I8K)		+= i8k.o
 obj-$(CONFIG_DS1620)		+= ds1620.o
 obj-$(CONFIG_HW_RANDOM)		+= hw_random/
 obj-$(CONFIG_PPDEV)		+= ppdev.o
+obj-$(CONFIG_NIOS_LCD_16207)	+= lcd_16207.o
+obj-$(CONFIG_NIOS_BUTTON)	+= altera_pio_button.o
 obj-$(CONFIG_NWBUTTON)		+= nwbutton.o
 obj-$(CONFIG_NWFLASH)		+= nwflash.o
 obj-$(CONFIG_SCx200_GPIO)	+= scx200_gpio.o
diff --git a/drivers/char/altera_pio_button.c b/drivers/char/altera_pio_button.c
new file mode 100644
index 0000000..36373af
--- /dev/null
+++ b/drivers/char/altera_pio_button.c
@@ -0,0 +1,280 @@
+/*
+ *  linux/drivers/char/altera_pio_button.c
+ *  A simple character driver that takes buttons on Nios Development
+ *  Kit as an input device (major 62)
+ *  
+ *  The characters input can be  '1', '2', '4' or '8'
+ *  
+ *  Copyright (C) 2004 Microtronix Datacom Ltd
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ * 
+ *  Written by Wentao Xu <wentao@microtronix.com>
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/major.h>
+#include <linux/module.h>
+#include <linux/capability.h>
+#include <linux/uio.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cdev.h>
+#include <linux/poll.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#define BUTTON_MAJOR	62
+int button_major = BUTTON_MAJOR;
+int button_minor = 0;
+
+#define PIO_BUTTON_BASE	na_button_pio
+#define PIO_BUTTON_IRQ	na_button_pio_irq
+#define PIO_BUTTON_SIZE sizeof(np_pio)
+
+#define BUTTON_BUF_SIZE 	100
+struct button_dev {
+	int count;
+	int head;
+	int tail;
+	char	buf[BUTTON_BUF_SIZE];
+
+	int started;
+	struct cdev cdev;
+	wait_queue_head_t rxq;
+	struct semaphore mutex;
+} _button_dev;
+
+
+static void button_handle_event(void *dev_id)
+{
+	static int old = 0;
+	int status, key;
+	struct button_dev * dev=(struct button_dev*)dev_id;
+	np_pio* pio = (np_pio *)(PIO_BUTTON_BASE);
+
+	outl(0, &pio->np_pioedgecapture);
+	/* read input, check 4 buttons */
+	status = (~inl(&pio->np_piodata)) & 0xF;
+	key = status - old;
+	old = status;
+	
+	if (key > 0) {
+		down(&dev->mutex);
+		/* we simply discard new inputs if buffer overflows */
+		if (dev->count < BUTTON_BUF_SIZE) {
+			dev->buf[dev->tail] = key + '0';
+			dev->tail = (dev->tail+1) % BUTTON_BUF_SIZE;
+			dev->count++; 
+		}
+		up(&dev->mutex);
+		
+		/* wake up any waiting reader */
+		if (waitqueue_active(&dev->rxq)) {
+			wake_up(&dev->rxq);
+		}
+	}
+
+	/* re-enable interrupts */
+	outl(-1, &pio->np_piointerruptmask);
+}
+
+static DECLARE_WORK(button_work, button_handle_event);
+static irqreturn_t pio_button_isr(int irq, void *dev_id)
+{
+	np_pio* pio = (np_pio *)PIO_BUTTON_BASE;
+	
+	if (!pio) 
+		return IRQ_NONE;
+
+	
+	/* disable interrupt */
+	outl(0, &pio->np_pioedgecapture);
+	outl(0, &pio->np_piointerruptmask);
+
+	/* activate the bottom half */
+	schedule_work(&button_work);
+	
+	return IRQ_HANDLED;
+}
+static int button_start(struct button_dev *dev)
+{
+	np_pio *pio=(np_pio *)(PIO_BUTTON_BASE);
+	
+	outl(0, &pio->np_pioedgecapture);
+	outl(0, &pio->np_piodirection); 
+
+	/* register interrupt */
+	if (request_irq(PIO_BUTTON_IRQ, pio_button_isr, SA_INTERRUPT, "pio_button", 
+					(void*)(dev))) {
+		printk("pio_button: unable to register interrupt %d\n", PIO_BUTTON_IRQ); 
+		return -1;
+	}
+	outl(-1, &pio->np_piointerruptmask);
+
+	return 0;
+}
+/*
+ * Open/close .
+ */
+static int button_open(struct inode *inode, struct file *filp)
+{
+	struct button_dev *dev;
+	
+	dev = container_of(inode->i_cdev, struct button_dev, cdev);
+	filp->private_data = dev;
+
+	preempt_disable();
+	dev->started++;
+	if (dev->started!=1) {
+		preempt_enable();
+		return 0;
+	}
+		
+	/* init buffon info */
+	dev->count=0;
+	dev->head=0;
+	dev->tail=0;
+	init_waitqueue_head(&dev->rxq);
+	init_MUTEX(&dev->mutex);
+	/* init buttons */	
+	button_start(dev);
+	preempt_enable();
+	
+	return 0;
+}
+
+/*
+ */
+static int button_release(struct inode *inode, struct file *filp)
+{
+	np_pio *pio=(np_pio *)(PIO_BUTTON_BASE);
+	struct button_dev *dev = (struct button_dev*)filp->private_data;
+	
+	preempt_disable();
+	dev->started--;
+	if (dev->started != 0) {
+		preempt_enable();
+		return 0;
+	}
+	preempt_enable();
+	
+	/*disable this interrupts */
+	outl(0, &pio->np_piointerruptmask);
+	free_irq(PIO_BUTTON_IRQ, (void*)(dev));
+	return 0;
+}
+
+/*
+ */
+static int
+button_ioctl(struct inode *inode, struct file *filp,
+		  unsigned int command, unsigned long arg)
+{
+	return -EINVAL;
+}
+
+static ssize_t button_read(struct file *filp, char *buf,
+			 size_t count, loff_t * ppos)
+{
+	int i, total;
+	struct button_dev *dev = (struct button_dev*)filp->private_data;
+	
+	if (dev->count==0) {
+		DEFINE_WAIT(wait);
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+			
+		while (!signal_pending(current) && (dev->count == 0)) {
+			prepare_to_wait(&dev->rxq, &wait, TASK_INTERRUPTIBLE);
+			if (!signal_pending(current) && (dev->count == 0))
+				schedule();
+			finish_wait(&dev->rxq, &wait);
+		}
+		if (signal_pending(current) && (dev->count == 0))
+			return -ERESTARTSYS;
+	}
+
+	if (down_interruptible(&dev->mutex))
+		return -ERESTARTSYS;
+		
+	/* return data */
+	total = (count < dev->count) ? count : dev->count;
+	for (i=0; i < total; i++) {
+		put_user(dev->buf[dev->head], buf+i);
+		dev->head = (dev->head + 1) % BUTTON_BUF_SIZE;
+		dev->count--;
+	}	
+	up(&dev->mutex);
+	
+	return total;
+}
+
+static unsigned int button_poll(struct file *filp, poll_table *wait)
+{
+	struct button_dev *dev = (struct button_dev*)filp->private_data;
+	unsigned int mask = 0;
+
+	poll_wait(filp, &dev->rxq, wait);
+	
+	if (dev->count > 0)
+	mask |= POLLIN | POLLRDNORM; /* readable */
+	return mask;
+}
+
+static struct file_operations button_fops = {
+	.read	=	button_read,
+	.open	=	button_open,
+	.release=	button_release,
+	.ioctl	=	button_ioctl,
+	.poll	=	button_poll,
+	.owner	=	THIS_MODULE,
+};
+
+
+static int __init button_init(void)
+{
+	int i;
+	dev_t devno;
+	
+	if (!(request_mem_region((unsigned long)PIO_BUTTON_BASE, PIO_BUTTON_SIZE, "pio_button")))
+		return -1;
+		
+	devno = MKDEV(button_major, button_minor);
+	cdev_init(&_button_dev.cdev, &button_fops);
+	_button_dev.cdev.owner = THIS_MODULE;
+	_button_dev.started = 0;
+	
+	i = register_chrdev_region(devno, 1, "pio_button");
+	if (i) {
+		printk(KERN_NOTICE "Can't get major %d for PIO buttons", button_major);
+		goto error1;
+	}
+	i = cdev_add(&_button_dev.cdev, devno, 1);
+	if (i) {
+		printk(KERN_NOTICE "Error %d adding PIO buttons", i);
+		goto error2;
+	}
+error2:
+	unregister_chrdev_region(devno, 1);
+error1:
+	release_mem_region((unsigned long)PIO_BUTTON_BASE, PIO_BUTTON_SIZE);
+	
+	return i;
+}
+
+static void __exit button_exit(void)
+{
+	cdev_del(&_button_dev.cdev);
+	unregister_chrdev_region(MKDEV(button_major, button_minor), 1);
+	release_mem_region((unsigned long)PIO_BUTTON_BASE, PIO_BUTTON_SIZE);
+}
+
+module_init(button_init);
+module_exit(button_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/lcd_16207.c b/drivers/char/lcd_16207.c
new file mode 100644
index 0000000..259b8a0
--- /dev/null
+++ b/drivers/char/lcd_16207.c
@@ -0,0 +1,473 @@
+/*
+ *  lcd16207.c - Device driver for reading and writing characters
+ *  to the 2x16 LCD display on DE2 Board using the 
+ *  altera lcd16207 core
+ */
+
+/*
+ * shell commands to compile the module in "drivers/char/"
+ *
+ * make ARCH=nios2 CROSS_COMPILE=nios2-linux-uclibc- -C ~/uClinux-dist/linux-2.6.x M=`pwd` modules 
+ * nios2-linux-uclibc-strip -R .comment -R .note -g --strip-unneeded hello.ko
+*/
+#include <linux/kernel.h>	/* We're doing kernel work */
+#include <linux/module.h>	/* Specifically, a module */
+#include <linux/fs.h>
+#include <asm/uaccess.h>	/* for get_user and put_user */
+#include <linux/delay.h>
+
+#include <linux/lcd_16207.h>
+
+#define SUCCESS 0
+//#define DEBUG 1
+
+/* 
+ * Is the device open right now? Used to prevent
+ * concurent access into the same device 
+ */
+static int Device_Open = 0;
+
+/* 
+ * Waiting time for writing the next
+ * characters of the buffer to the display 
+ */
+static unsigned long Display_Wait = 1500000;
+
+/* 
+ * The message the device will give when asked 
+ */
+static char Message[BUF_LCD_CHARS];
+
+/* 
+ * How far did the process reading the message get?
+ * Useful if the message is larger than the size of the
+ * buffer we get to fill in device_read. 
+ */
+static char *Message_Ptr;
+
+/* 
+ * Pointer to the Lines of the Display
+ */
+static char *Message_Ptr_Line1 = Message;
+static char *Message_Ptr_Line2 = Message + BUF_LCD_LINE;
+static char *Message_Ptr_Write;
+
+/* 
+ * This is called whenever a process attempts to open the device file 
+ */
+static int device_open(struct inode *inode, struct file *file)
+{
+#ifdef DEBUG
+        printk(KERN_INFO "device_open(%p)\n", file);
+#endif
+  
+        /* 
+         * We don't want to talk to two processes at the same time 
+         */
+        if (Device_Open)
+                return -EBUSY;
+
+        Device_Open++;
+        /*
+         * Initialize the message 
+         */
+        memset(Message,32,BUF_LCD_CHARS);	
+  
+        try_module_get(THIS_MODULE);
+        return SUCCESS;
+}
+
+static int device_release(struct inode *inode, struct file *file)
+{
+#ifdef DEBUG
+        printk(KERN_INFO "device_release(%p,%p)\n", inode, file);
+#endif
+  
+        /* 
+         * We're now ready for our next caller 
+         */
+        Device_Open--;
+  
+        module_put(THIS_MODULE);
+        return SUCCESS;
+}
+
+/* 
+ * This function is called whenever a process which has already opened the
+ * device file attempts to read from it.
+ */
+//not implemented yet
+static ssize_t device_read(struct file *file,	/* see include/linux/fs.h   */
+			   char __user * buffer,	/* buffer to be
+							 * filled with data */
+			   size_t length,	/* length of the buffer     */
+			   loff_t * offset)
+{
+        /* 
+         * Number of bytes actually written to the buffer 
+         */
+        int bytes_read = 0;
+        Message_Ptr = Message;
+        LcdReadLines();
+
+#ifdef DEBUG
+        printk(KERN_INFO "device_read(%p,%p,%d)\n", file, buffer, length);
+        printk(KERN_INFO "Message:%s:End\n",Message);
+#endif
+  
+        /* 
+         * Actually put the data into the buffer 
+         */
+        while (length>0 && bytes_read<BUF_LCD_CHARS) {
+    
+                /* 
+                 * Because the buffer is in the user data segment,
+                 * not the kernel data segment, assignment wouldn't
+                 * work. Instead, we have to use put_user which
+                 * copies data from the kernel data segment to the
+                 * user data segment. 
+                 */
+                put_user(*(Message_Ptr++), buffer++);
+                length--;
+                bytes_read++;
+        }
+
+#ifdef DEBUG
+        printk(KERN_INFO "Read %d bytes, %d left\n", bytes_read, length);
+#endif
+
+        if (length>0) {
+                /* 
+                 * Put a zero at the end of the buffer, so it will be 
+                 * properly terminated 
+                 */ 
+                put_user('\0', buffer++);
+                bytes_read++;
+                length--;
+        }
+
+        /* 
+         * Read functions are supposed to return the number
+         * of bytes actually inserted into the buffer 
+         */
+        return bytes_read;
+}
+
+/* 
+ * This function is called when somebody tries to
+ * write into our device file. 
+ */
+static ssize_t device_write(struct file *file,
+			    const char __user * buffer, size_t length, loff_t * offset)
+{
+        int ii;
+
+#ifdef DEBUG
+        printk(KERN_INFO "device_write(%p,%s,%d);\n", file, buffer, length);
+#endif
+
+        ii=0;
+        while(ii<length){
+                strncpy(Message_Ptr_Line1, Message_Ptr_Line2, BUF_LCD_LINE);
+                Message_Ptr=Message;
+                
+                if ( (length-ii) > BUF_LCD_LINE){
+                        copy_from_user(Message_Ptr_Line2, buffer+ii, BUF_LCD_LINE);
+                        ii=ii+BUF_LCD_LINE;
+                } else {
+                        copy_from_user(Message_Ptr_Line2, buffer+ii, length-ii);
+                        memset(Message_Ptr_Line2+(length-ii),32,BUF_LCD_LINE-(length-ii));  
+                        ii=length;
+                }                
+                WaitNios(Display_Wait);
+                LcdWriteLines();
+        }
+#ifdef DEBUG
+        printk(KERN_INFO "Message:%s:End\n",Message);
+#endif
+        /* 
+         * Again, return the number of input characters used 
+         */
+        return length;
+}
+
+/* 
+ * This function is called whenever a process tries to do an ioctl on our
+ * device file. We get two extra parameters (additional to the inode and file
+ * structures, which all device functions get): the number of the ioctl called
+ * and the parameter given to the ioctl function.
+ *
+ * If the ioctl is write or read/write (meaning output is returned to the
+ * calling process), the ioctl call returns the output of this function.
+ *
+ */
+static int device_ioctl(struct inode *inode,	/* see include/linux/fs.h */
+                        struct file *file,	/* ditto */
+                        unsigned int ioctl_num,	/* number and param for ioctl */
+                        unsigned long ioctl_param)
+{
+        int i;
+        char *temp;
+        char ch;
+
+        /* 
+         * Switch according to the ioctl called 
+         */
+        switch (ioctl_num) {
+        case IOCTL_SET_MSG:
+                /* 
+                 * Receive a pointer to a message (in user space) and set that
+                 * to be the device's message.  Get the parameter given to 
+                 * ioctl by the process. 
+                 */
+                temp = (char *)ioctl_param;
+    
+                /* 
+                 * Find the length of the message 
+                 */
+                get_user(ch, temp);
+                if (ch=='\0')
+                        break;
+                for (i = 0; ch!='\0' ; i++, temp++)
+                        get_user(ch, temp);
+    
+                device_write(file, (char *)ioctl_param, i-1, 0);
+                break;
+
+        case IOCTL_SET_DISP_WAIT:
+                /* 
+                 * Set the time of the Display to wait before
+                 * printing the next 2x16 chars to the display.
+                 * 
+                 */
+                Display_Wait=(unsigned long)ioctl_param;
+#ifdef DEBUG
+                printk(KERN_INFO "Display wait set to hex %08X\n", (unsigned int) Display_Wait);
+#endif
+                break;
+
+        case IOCTL_GET_MSG:
+                /* 
+                 * Give the current message to the calling process - 
+                 * the parameter we got is a pointer, fill it. 
+                 */
+                i = device_read(file, (char *)ioctl_param, BUF_LCD_CHARS+1, 0);
+                break;
+    
+                //not tested - still todo
+        case IOCTL_GET_NTH_BYTE:
+                /* 
+                 * This ioctl is both input (ioctl_param) and 
+                 * output (the return value of this function) 
+                 */
+                return Message[ioctl_param];
+                break;
+        }
+        return SUCCESS;
+}
+
+/* Module Declarations */
+
+/* 
+ * This structure will hold the functions to be called
+ * when a process does something to the device we
+ * created. Since a pointer to this structure is kept in
+ * the devices table, it can't be local to
+ * init_module. NULL is for unimplemented functions. 
+ */
+struct file_operations Fops = {
+        .read = device_read,
+        .write = device_write,
+        .ioctl = device_ioctl,
+        .open = device_open,
+        .release = device_release,	/* a.k.a. close */
+};
+
+/* 
+ * Initialize the module - Register the character device 
+ */
+static int __init lcd16207_module_init(void)
+{
+        int ret_val;
+        /* 
+         * Register the character device (atleast try) 
+         */
+        ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &Fops);
+
+        /* 
+         * Negative values signify an error 
+         */
+        if (ret_val < 0) {
+                printk(KERN_ALERT "%s failed with %d\n",
+                       "Sorry, registering the character device ", ret_val);
+                return ret_val;
+        }
+        printk(KERN_INFO "Device %s registered\n", DEVICE_FILE_NAME);
+        /*  
+            printk(KERN_INFO "%s The lcd16207 major device number is %d.\n",
+            "Registeration is a success", MAJOR_NUM);
+            printk(KERN_INFO "If you want to talk to the device driver,\n");
+            printk(KERN_INFO "you'll have to create a device file. \n");
+            printk(KERN_INFO "We suggest you use:\n");
+            printk(KERN_INFO "mknod %s c %d 0\n", DEVICE_FILE_NAME, MAJOR_NUM);
+            printk(KERN_INFO "The device file name is important, because\n");
+            printk(KERN_INFO "the ioctl program assumes that's the\n");
+            printk(KERN_INFO "file you'll use.\n");
+        */  
+        mdelay(20);
+        WriteNios(ADR_LCD_COMMAND,LCD_COM_RESET);
+        mdelay(5);
+        WriteNios(ADR_LCD_COMMAND,LCD_COM_RESET);
+        udelay(200);
+        WriteNios(ADR_LCD_COMMAND,LCD_COM_RESET);
+        udelay(200);
+        WriteNios(ADR_LCD_COMMAND,LCD_NUMROWS | LCD_INTERFACE | LCD_CMD_FUNC);
+        udelay(50);
+        WriteNios(ADR_LCD_COMMAND,LCD_CMD_ONOFF);
+        udelay(50);
+        WriteNios(ADR_LCD_COMMAND,LCD_CMD_CLEAR);
+        mdelay(2);
+        WriteNios(ADR_LCD_COMMAND,LCD_CMD_ONOFF | LCD_CMD_ENABLE_DISP | LCD_CMD_ENABLE_CURSOR); // | LCD_CMD_ENABLE_BLINK);
+        udelay(50);
+        //write " Hello uClinux! " to the display
+        WriteNios(ADR_LCD_DATA,0x20);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x48);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x65);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x6C);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x6C);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x6F);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x20);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x75);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x43);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x6C);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x69);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x6E);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x75);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x78);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x21);
+        udelay(50);
+        WriteNios(ADR_LCD_DATA,0x20);
+        udelay(50);
+
+        return 0;
+}
+
+/* 
+ * Cleanup - unregister the appropriate file from /proc 
+ */
+static void __exit lcd16207_module_exit(void)
+{
+        //int ret;
+  
+        /* 
+         * Unregister the device 
+         */
+        unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
+  
+        /*
+         * If there's an error, report it 
+         */
+        //if (ret < 0)
+        //printk(KERN_ALERT "Error: unregister_chrdev: %d\n", ret);
+}
+
+/*
+ * write all chars to the LCD
+ */
+static void LcdWriteLines(void)
+{
+        int i;
+        WriteNios(ADR_LCD_COMMAND,0x80);
+        udelay(50);
+        Message_Ptr_Write = Message_Ptr_Line1;
+        for (i = 0; i < BUF_LCD_LINE; i++){
+                WriteNios(ADR_LCD_DATA, (unsigned long)*(Message_Ptr_Write+i) );
+                udelay(50);
+        }
+        WriteNios(ADR_LCD_COMMAND,0x80 + 0x40);
+        udelay(50);
+        Message_Ptr_Write = Message_Ptr_Line2;
+        for (i = 0; i < BUF_LCD_LINE; i++){
+                WriteNios(ADR_LCD_DATA, (unsigned long)*(Message_Ptr_Write+i) );
+                udelay(50);
+        }
+}
+
+/*
+ * read all chars from the LCD
+ */
+static void LcdReadLines(void)
+{
+        int i;
+        WriteNios(ADR_LCD_COMMAND,0x80);
+        udelay(50);
+        Message_Ptr_Write = Message_Ptr_Line1;
+        for (i = 0; i < BUF_LCD_LINE; i++){
+                *(Message_Ptr_Write+i)=ReadNios(ADR_LCD_READ);
+                udelay(50);
+        }
+        WriteNios(ADR_LCD_COMMAND,0x80 + 0x40);
+        udelay(50);
+        Message_Ptr_Write = Message_Ptr_Line2;
+        for (i = 0; i < BUF_LCD_LINE; i++){
+                *(Message_Ptr_Write+i)=ReadNios(ADR_LCD_READ);
+                udelay(50);
+        }
+}
+
+/*
+ * write 32bit value to avalon bus address
+ */
+static void WriteNios(unsigned long addr, unsigned long value)
+{
+        (* (volatile unsigned long *)(addr))=value;
+}
+  
+/*
+ * read 32bit value from avalon bus address
+ */
+static unsigned long ReadNios(unsigned long addr)
+{
+        return (unsigned long)(* (volatile unsigned long *)(addr));
+}
+
+/*
+ * wait for us
+ */
+static void WaitNios(unsigned long us)
+{
+        unsigned long usLoop,i;
+        if (us > 2000){
+                usLoop=us/2000;
+                us = us % usLoop;
+                for (i=0;i<usLoop;i++){
+                        udelay(2000);
+                }
+        }   
+        udelay(us);
+}
+
+module_init(lcd16207_module_init);
+module_exit(lcd16207_module_exit);
+
+
+//#define author "The kernel programming guide, NIOS wiki users and mamba"
+//#define description "A driver for lcd16207 device of the DE2 board and the lcd16207 core of altera."
+//MODULE_AUTHOR(author);
+//MODULE_DESCRIPTION(description);
+MODULE_SUPPORTED_DEVICE(DEVICE_NAME);
+MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index 0dabe64..556b670 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -95,6 +95,7 @@ static void ocores_process(struct ocores_i2c *i2c)
 	if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) {
 		i2c->state =
 			(msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE;
+		oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
 
 		if (stat & OCI2C_STAT_NACK) {
 			i2c->state = STATE_ERROR;
@@ -129,6 +130,7 @@ static void ocores_process(struct ocores_i2c *i2c)
 					? STATE_READ : STATE_WRITE;
 		} else {
 			i2c->state = STATE_DONE;
+			oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
 			oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP);
 			return;
 		}
@@ -266,12 +268,21 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev)
 	i2c->adap.dev.parent = &pdev->dev;
 
 	/* add i2c adapter to i2c tree */
-	ret = i2c_add_adapter(&i2c->adap);
+#ifdef CONFIG_I2C_BOARDINFO
+	i2c->adap.nr = pdev->id;
+	ret = i2c_add_numbered_adapter(&i2c->adap);
+#else
+	res = i2c_add_adapter(&i2c->adap);
+#endif
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to add adapter\n");
 		goto add_adapter_failed;
 	}
 
+	printk(KERN_INFO "i2c-%d: I2C OpenCores Bus Adapter, MMIO = 0x%X, irq = %d\n",
+			i2c_adapter_id(&i2c->adap), (int) res->start, (int) res2->start);
+	printk(KERN_INFO "i2c-%d: Using %dkHz clock source\n", i2c_adapter_id(&i2c->adap),
+			i2c->clock_khz);
 	/* add in known devices to the bus */
 	for (i = 0; i < pdata->num_devices; i++)
 		i2c_new_device(&i2c->adap, pdata->devices + i);
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index c4b3fbd..3d22093 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -166,6 +166,15 @@ config SERIO_MACEPS2
 	  To compile this driver as a module, choose M here: the
 	  module will be called maceps2.
 
+config SERIO_ALTPS2
+	tristate "Altera UP PS2 controller"
+	depends on EMBEDDED
+	help
+	  Say Y here if you have Altera UP PS/2 ports.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called altps2.
+
 config SERIO_LIBPS2
 	tristate "PS/2 driver library" if EMBEDDED
 	help
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
index 9b6c813..57f867b 100644
--- a/drivers/input/serio/Makefile
+++ b/drivers/input/serio/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_HP_SDC)		+= hp_sdc.o
 obj-$(CONFIG_HIL_MLC)		+= hp_sdc_mlc.o hil_mlc.o
 obj-$(CONFIG_SERIO_PCIPS2)	+= pcips2.o
 obj-$(CONFIG_SERIO_MACEPS2)	+= maceps2.o
+obj-$(CONFIG_SERIO_ALTPS2)	+= altps2.o
 obj-$(CONFIG_SERIO_LIBPS2)	+= libps2.o
 obj-$(CONFIG_SERIO_RAW)		+= serio_raw.o
 obj-$(CONFIG_SERIO_XILINX_XPS_PS2)	+= xilinx_ps2.o
diff --git a/drivers/input/serio/altps2.c b/drivers/input/serio/altps2.c
new file mode 100644
index 0000000..43dc1c9
--- /dev/null
+++ b/drivers/input/serio/altps2.c
@@ -0,0 +1,180 @@
+/*
+ *  Altera University Program PS2 controller driver
+ *
+ *  Based on sa1111ps2.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#define DRV_NAME "altps2"
+
+struct ps2if {
+	struct serio		*io;
+	struct platform_device	*dev;
+	unsigned base;
+	unsigned irq;
+};
+
+/*
+ * Read all bytes waiting in the PS2 port.  There should be
+ * at the most one, but we loop for safety.
+ */
+static irqreturn_t ps2_rxint(int irq, void *dev_id)
+{
+	struct ps2if *ps2if = dev_id;
+	unsigned int status;
+	int handled = IRQ_NONE;
+
+	while ((status = inl(ps2if->base)) & 0xffff0000) {
+		serio_interrupt(ps2if->io, status & 0xff, 0);
+		handled = IRQ_HANDLED;
+	}
+	return handled;
+}
+
+/*
+ * Write a byte to the PS2 port.
+ */
+static int ps2_write(struct serio *io, unsigned char val)
+{
+	struct ps2if *ps2if = io->port_data;
+
+	outl(val, ps2if->base);
+	return 0;
+}
+
+static int ps2_open(struct serio *io)
+{
+	struct ps2if *ps2if = io->port_data;
+	int ret;
+
+	ret = request_irq(ps2if->irq, ps2_rxint, 0,
+			  DRV_NAME, ps2if);
+	if (ret) {
+		printk(KERN_ERR DRV_NAME ": could not allocate IRQ%d: %d\n",
+			ps2if->irq, ret);
+		return ret;
+	}
+	outl(1, ps2if->base + 4);	/* enable rx irq */
+	return 0;
+}
+
+static void ps2_close(struct serio *io)
+{
+	struct ps2if *ps2if = io->port_data;
+
+	outl(0, ps2if->base);  /* disable rx irq */
+	free_irq(ps2if->irq, ps2if);
+}
+
+/*
+ * Add one device to this driver.
+ */
+static int ps2_probe(struct platform_device *dev)
+{
+	struct ps2if *ps2if;
+	struct serio *serio;
+	struct resource *res;
+	int ret;
+
+	ps2if = kzalloc(sizeof(struct ps2if), GFP_KERNEL);
+	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!ps2if || !serio) {
+		ret = -ENOMEM;
+		goto free;
+	}
+
+	serio->id.type		= SERIO_8042;
+	serio->write		= ps2_write;
+	serio->open		= ps2_open;
+	serio->close		= ps2_close;
+	strlcpy(serio->name, dev_name(&dev->dev), sizeof(serio->name));
+	strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
+	serio->port_data	= ps2if;
+	serio->dev.parent	= &dev->dev;
+	ps2if->io		= serio;
+	ps2if->dev		= dev;
+	platform_set_drvdata(dev, ps2if);
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		ret = -ENOENT;
+		goto free;
+	}
+	ps2if->irq  = platform_get_irq(dev, 0);
+	if (ps2if->irq < 0) {
+		ret = -ENXIO;
+		goto free;
+	}
+	ps2if->base = (unsigned) ioremap(res->start,
+					 (res->end - res->start) + 1);
+	if (!ps2if->base) {
+		ret = -ENOMEM;
+		goto free;
+	}
+	printk(KERN_INFO DRV_NAME ": base %08x irq %d\n",
+	       ps2if->base, ps2if->irq);
+	/* clear fifo */
+	while (inl(ps2if->base) & 0xffff0000)
+		;
+	serio_register_port(ps2if->io);
+	return 0;
+
+ free:
+	platform_set_drvdata(dev, NULL);
+	kfree(ps2if);
+	kfree(serio);
+	return ret;
+}
+
+/*
+ * Remove one device from this driver.
+ */
+static int ps2_remove(struct platform_device *dev)
+{
+	struct ps2if *ps2if = platform_get_drvdata(dev);
+
+	platform_set_drvdata(dev, NULL);
+	serio_unregister_port(ps2if->io);
+	iounmap((void *)ps2if->base);
+	kfree(ps2if);
+
+	return 0;
+}
+
+/*
+ * Our device driver structure
+ */
+static struct platform_driver ps2_driver = {
+	.probe		= ps2_probe,
+	.remove		= ps2_remove,
+	.driver	= {
+		.name	= DRV_NAME,
+	},
+};
+
+static int __init ps2_init(void)
+{
+	return platform_driver_register(&ps2_driver);
+}
+
+static void __exit ps2_exit(void)
+{
+	platform_driver_unregister(&ps2_driver);
+}
+
+module_init(ps2_init);
+module_exit(ps2_exit);
+
+MODULE_DESCRIPTION("Altera University Program PS2 controller driver");
+MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 7cb057f..eec3061 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -316,3 +316,9 @@ config MMC_VIA_SDMMC
 	  If you have a controller with this interface, say Y or M here.
 
 	  If unsure, say N.
+
+config MMC_NIOS
+	tristate "NIOS SD/SDIO/MMC Host"
+	depends on NIOS2
+	help
+		Device driver for the FPS-Tech SD/SDIO/MMC Host for Altera NIOS systems
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index abcb040..bdad959 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_MMC_SDRICOH_CS)	+= sdricoh_cs.o
 obj-$(CONFIG_MMC_TMIO)		+= tmio_mmc.o
 obj-$(CONFIG_MMC_CB710)	+= cb710-mmc.o
 obj-$(CONFIG_MMC_VIA_SDMMC)	+= via-sdmmc.o
+obj-$(CONFIG_MMC_NIOS)		+= nios_mmc.o
 
 ifeq ($(CONFIG_CB710_DEBUG),y)
 	CFLAGS-cb710-mmc	+= -DDEBUG
diff --git a/drivers/mmc/host/nios_mmc.c b/drivers/mmc/host/nios_mmc.c
new file mode 100644
index 0000000..535f815
--- /dev/null
+++ b/drivers/mmc/host/nios_mmc.c
@@ -0,0 +1,618 @@
+/*
+ *  linux/drivers/mmc/nios_mmc.c - FPS-Tech NIOS_MMC Driver
+ *
+ *  Copyright (C) 2008 Jai Dhar / FPS-Tech, All Rights Reserved.
+ *  Credits: This driver is partially derived from pxamci.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/core.h>
+#include <linux/pagemap.h>
+
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
+
+#include <linux/nios_mmc.h>
+
+#define DRIVER_NAME	"nios_mmc"
+#define NR_SG 1
+#define debug_level 0
+
+#if defined(CONFIG_MMC_DEBUG)
+#define MMC_DEBUG(l,x...) {\
+	if (l <= debug_level)\
+	{\
+       		printk("%s(): ",__func__); printk(x);\
+	}\
+}
+#else
+#define MMC_DEBUG(l,x...) {}
+#endif /* CONFIG_MMC_DEBUG */
+
+#define MMC_CRIT_ERR(x...) {\
+	printk("Crit. error in %s(): %s. Halting\n",__func__,x);\
+	while(1);\
+}
+#define SD_MAX_FREQ 25000000	/* Set the max frequency to 25MHz (std. speed) */
+#define SD_MIN_FREQ 375000	/* Set the minimum frequency to 375Khz */
+
+/********** Function prototypes ************/
+static void nios_mmc_start_cmd(NIOS_MMC_HOST * host, struct mmc_command *cmd);
+static void nios_mmc_end_request(struct mmc_host *mmc, struct mmc_request *mrq);
+static int nios_mmc_procinit(NIOS_MMC_HOST * host);
+static void nios_mmc_procclose(void);
+unsigned int max_blk_count = 128;
+unsigned int max_req_size = 512 * 128;
+unsigned int max_seg_size = 512 * 128;
+unsigned int dat_width = 1;
+unsigned int blk_prefetch = 1;
+unsigned int fmax = SD_MAX_FREQ;
+static unsigned int irq_count;
+/**************************** Low-level register access ******************************/
+static void nios_mmc_writel(unsigned int val, NIOS_MMC_HOST *host, unsigned char off)
+{
+	writel(val, host->base + off);
+}
+static unsigned int nios_mmc_readl(NIOS_MMC_HOST *host, unsigned char off)
+{
+	return readl(host->base + off);
+}
+/***************************** Start of main functions ********************************/
+
+static void nios_mmc_end_cmd(NIOS_MMC_HOST * host, unsigned int stat)
+{
+	unsigned int ret;
+	struct mmc_command *cmd = host->cmd;
+	struct mmc_data *data = cmd->data;
+	struct mmc_command *stop = data->stop;
+
+	/* assign stop only if data is assigned */
+	if (data)
+		stop = data->stop;
+	else
+		stop = NULL;
+	/* Check MRQ first */
+	if (cmd == NULL) {
+		MMC_CRIT_ERR("CMD is null when it shouldn't be!");
+	}
+	/* Interrupt flags will be cleared in ISR routine, so we don't have to touch them */
+	if (stat & NIOS_MMC_CTLSTAT_TIMEOUTERR_IF) {
+		MMC_DEBUG(1, "Timeout error\n");
+		ret = -ETIMEDOUT;
+	} else if (stat & NIOS_MMC_CTLSTAT_FRMERR_IF) {
+		MMC_DEBUG(1, "Framing error\n");
+		ret = -EILSEQ;
+	} else if (stat & NIOS_MMC_CTLSTAT_CRCERR_IF) {
+		MMC_DEBUG(1, "CRC Error\n");
+		ret = -EILSEQ;
+	} else if (stat & NIOS_MMC_CTLSTAT_FIFO_UNDERRUN_IF) {
+		MMC_DEBUG(1, "FIFO Underrun error\n");
+		ret = -EINVAL;
+	} else if (stat & NIOS_MMC_CTLSTAT_FIFO_OVERRUN_IF) {
+		MMC_DEBUG(1, "FIFO Overrun error\n");
+		ret = -EINVAL;
+	} else {
+		/* Response is good! */
+		ret = 0;
+	}
+	if (ret) {
+		MMC_DEBUG(1, "Error executing CMD%d\n", cmd->opcode);
+		MMC_DEBUG(2, "Response argument: 0x%X\n",
+			  nios_mmc_readl(host, NIOS_MMC_REG_CMD_ARG0));
+	}
+	/* Load response into command structure */
+	cmd->error = ret;
+	if (mmc_resp_type(cmd) == MMC_RSP_R2) {
+		cmd->resp[0] = nios_mmc_readl(host, NIOS_MMC_REG_CMD_ARG3);
+		cmd->resp[1] = nios_mmc_readl(host, NIOS_MMC_REG_CMD_ARG2);
+		cmd->resp[2] = nios_mmc_readl(host, NIOS_MMC_REG_CMD_ARG1);
+		cmd->resp[3] = nios_mmc_readl(host, NIOS_MMC_REG_CMD_ARG0);
+	} else
+		cmd->resp[0] = nios_mmc_readl(host, NIOS_MMC_REG_CMD_ARG0);
+	/* Check if this was a data transaction */
+	if (data) {
+		if (cmd->error == 0)
+			data->bytes_xfered = data->blksz * data->blocks;
+		else
+			data->bytes_xfered = 0;
+	}
+	if (stop) {
+		/* Schedule the stop command */
+		/* We will need to reassign the pointer in the structure since we are 
+		 * switching commands now */
+		host->cmd = stop;
+		nios_mmc_start_cmd(host, stop);
+	} else {
+		/* No other commands needed, finish off transaction */
+		nios_mmc_end_request(host->mmc, cmd->mrq);
+	}
+}
+
+/* nios_mmc_execute_cmd(): Key function that interacts with MMC Host to carry out command */
+static void nios_mmc_execute_cmd(NIOS_MMC_HOST * host, unsigned char cmd,
+				 unsigned int arg_in, unsigned char resp_type,
+				 unsigned char nocrc, unsigned int bytes,
+				 unsigned int blocks, unsigned char rwn,
+				 unsigned int buf)
+{
+	unsigned int xfer_ctl = 0;
+	u_char cmdidx;
+
+	/* Do a sanity check that the core isn't busy... why should it be since we haven't started a cmd?? */
+	if (nios_mmc_readl(host, NIOS_MMC_REG_CTLSTAT) & NIOS_MMC_CTLSTAT_BUSY) {
+		MMC_CRIT_ERR("Core is busy when it shouldn't be!");
+	}
+	xfer_ctl = (cmd & 0x3F) << NIOS_MMC_XFER_CTL_CMD_IDX_SHIFT;
+	nios_mmc_writel(arg_in, host, NIOS_MMC_REG_CMD_ARG0);
+	xfer_ctl |= (resp_type & 0x3) << NIOS_MMC_XFER_CTL_RESP_CODE_SHIFT;
+	if (nocrc)
+		xfer_ctl |= NIOS_MMC_XFER_CTL_RESP_NOCRC;
+	if (rwn)
+		xfer_ctl |= NIOS_MMC_XFER_CTL_DAT_RWn;
+	xfer_ctl |= (bytes & 0x3FF) << NIOS_MMC_XFER_CTL_BYTE_COUNT_SHIFT;
+	xfer_ctl |= (blocks & 0x3FF) << NIOS_MMC_XFER_CTL_BLOCK_COUNT_SHIFT;
+	xfer_ctl |= NIOS_MMC_XFER_CTL_XFER_START;
+	if (host->dat_width)
+		xfer_ctl |= NIOS_MMC_XFER_CTL_DAT_WIDTH;
+	cmdidx = (xfer_ctl >> NIOS_MMC_XFER_CTL_CMD_IDX_SHIFT) & 0x3F;
+	/* Setup DMA base */
+	flush_dcache_range(buf, buf + bytes * blocks);
+	nios_mmc_writel(buf, host, NIOS_MMC_REG_DMA_BASE);
+	if (bytes) {
+		MMC_DEBUG(1,
+			  "XFER_CTL: 0x%X (CMD%d), DMA_BASE(%c): 0x%X, ARG_IN: 0x%X, %d/%db\n",
+			  xfer_ctl, cmdidx,
+			  (xfer_ctl & NIOS_MMC_XFER_CTL_DAT_RWn) ? 'R' : 'W',
+			  buf, arg_in, blocks, bytes);
+	} else {
+		MMC_DEBUG(1, "XFER_CTL: 0x%X (CMD%d), ARG_IN: 0x%X\n",
+			  xfer_ctl, cmdidx, arg_in);
+	}
+	/* Execute command */
+	nios_mmc_writel(xfer_ctl, host, NIOS_MMC_REG_XFER_CTL);
+}
+static irqreturn_t nios_mmc_irq(int irq, void *dev_id)
+{
+	NIOS_MMC_HOST *host = dev_id;
+	unsigned int stat;
+
+	stat = nios_mmc_readl(host, NIOS_MMC_REG_CTLSTAT);
+	/* Clear the interrupt */
+	nios_mmc_writel(stat, host, NIOS_MMC_REG_CTLSTAT);
+	MMC_DEBUG(2, "IRQ, ctlstat: 0x%X\n", stat);
+
+	if (stat & NIOS_MMC_CTLSTAT_CD_IF) {
+		/* Card-detect interrupt */
+		if (stat & NIOS_MMC_CTLSTAT_CD) {
+			MMC_DEBUG(1, "HOT-PLUG: Card inserted\n");
+		} else {
+			MMC_DEBUG(1, "HOT-PLUG: Card removed\n");
+		}
+		mmc_detect_change(host->mmc, 100);
+	}
+	if (stat & NIOS_MMC_CTLSTAT_XFER_IF) {
+		MMC_DEBUG(3, "Detected XFER Interrupt\n");
+		/* Transfer has completed */
+		nios_mmc_end_cmd(host, stat);
+	}
+	irq_count++;
+	return IRQ_HANDLED;
+}
+
+/* Function to start the CMD process */
+static void nios_mmc_start_cmd(NIOS_MMC_HOST * host, struct mmc_command *cmd)
+{
+	unsigned char resp_type = 0, nocrc = 0, rwn = 0;
+	struct mmc_data *data = cmd->data;
+	struct scatterlist *sg;
+	unsigned int current_address, bytes = 0, blocks = 0;
+
+	/* Do a sanity check that we are being passed the same CMD that is in host struct */
+	if (host->cmd != cmd) {
+		MMC_CRIT_ERR("Cmd doesn't match what is in structure");
+	}
+
+	MMC_DEBUG(2, "Opcode: %d Arg: 0x%X ", cmd->opcode, cmd->arg);
+	switch (mmc_resp_type(cmd)) {
+	case MMC_RSP_R3:
+		nocrc = 1;
+	case MMC_RSP_R1:
+	case MMC_RSP_R1B:
+		resp_type = 1;
+		break;
+	case MMC_RSP_R2:
+		resp_type = 2;
+		nocrc = 1;
+		break;
+	case MMC_RSP_NONE:
+		resp_type = 0;
+		break;
+	default:
+		MMC_CRIT_ERR("Unhandled MMC Response type!");
+		break;
+	}
+
+	sg = data->sg;
+	current_address = (unsigned int)sg_phys(sg);
+	cmd->error = 0;
+	if (data) {
+		if (data->sg_len > 1) {
+			MMC_CRIT_ERR("sg_len is > 1!");
+		}
+		MMC_DEBUG(3, "Block size: %d Blocks: %d sg_len: %d\n",
+			  data->blksz, data->blocks, data->sg_len);
+		if (data->stop)
+			MMC_DEBUG(2, "Stop command present\n");
+		/* Setup byte count */
+		bytes = data->blksz;
+		blocks = data->blocks - 1;
+
+		if (data->flags & MMC_DATA_READ)
+			rwn = 1;
+		else
+			rwn = 0;
+
+	}
+	nios_mmc_execute_cmd(host, cmd->opcode, cmd->arg,
+			     resp_type, nocrc, bytes, blocks, rwn,
+			     current_address);
+
+}
+
+/* Profiling functions */
+void nios_mmc_clear_prof(NIOS_MMC_HOST * host)
+{
+	unsigned int misc_reg;
+	misc_reg = nios_mmc_readl(host, NIOS_MMC_REG_MISC);
+	misc_reg |= NIOS_MMC_MISC_PROF_RESET;
+	nios_mmc_writel(misc_reg, host, NIOS_MMC_REG_MISC);
+}
+unsigned long long nios_mmc_prof_cnt(NIOS_MMC_HOST * host, unsigned char cnt)
+{
+	unsigned long long tmp = 0;
+	unsigned int misc_reg;
+	/* Select the counter first */
+	misc_reg = nios_mmc_readl(host, NIOS_MMC_REG_MISC);
+	misc_reg &= ~(0x7 << NIOS_MMC_MISC_PROF_CNT_SEL_SHIFT);
+	misc_reg |= (cnt << NIOS_MMC_MISC_PROF_CNT_SEL_SHIFT);
+	nios_mmc_writel(misc_reg, host, NIOS_MMC_REG_MISC);
+	tmp = nios_mmc_readl(host, NIOS_MMC_REG_PROF_CNT1);
+	tmp <<= 32;
+	tmp |= nios_mmc_readl(host, NIOS_MMC_REG_PROF_CNT0);
+	return tmp;
+}
+
+/****************** Driver-level interface *****************/
+
+/* This function is called from the driver level above */
+/* nios_mmc_request() initiates the MMC request as setup in the mrq structure */
+static void nios_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	NIOS_MMC_HOST *host = mmc_priv(mmc);
+
+	if (host->cmd != NULL) {
+		MMC_DEBUG(1, "HOST_CMD Not null!\n");
+	}
+	host->cmd = mrq->cmd;
+	MMC_DEBUG(3, "Start req\n");
+	nios_mmc_start_cmd(host, host->cmd);
+	return;
+}
+
+/* Function to cleanup previous call */
+static void nios_mmc_end_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	NIOS_MMC_HOST *host = mmc_priv(mmc);
+	host->cmd = NULL;
+	mmc_request_done(host->mmc, mrq);
+	return;
+}
+static int nios_mmc_get_ro(struct mmc_host *mmc)
+{
+	int ctlstat;
+	NIOS_MMC_HOST *host = mmc_priv(mmc);
+	MMC_DEBUG(3, "Get RO\n");
+	ctlstat = nios_mmc_readl(host, NIOS_MMC_REG_CTLSTAT);
+	if (ctlstat & NIOS_MMC_CTLSTAT_WP)
+		return 1;
+	return 0;
+}
+static void nios_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	NIOS_MMC_HOST *host = mmc_priv(mmc);
+	int div;
+
+	if (ios->clock) {
+		/* FIXME: Look at divider calculation! */
+		MMC_DEBUG(3, "Requesting clock: %d\n", ios->clock);
+		div = (host->clock_freq / (2 * ios->clock)) - 1;
+		/* Check if div is less than 1 */
+		if (div < 1)
+			div = 1;
+		nios_mmc_writel((div & 0xFFFF) | NIOS_MMC_CLK_CTL_CLK_EN,
+		       host, NIOS_MMC_REG_CLK_CTL);
+	} else {
+		/* Stop the clock */
+		MMC_DEBUG(3, "Request stop clock\n");
+		nios_mmc_writel(0, host, NIOS_MMC_REG_CLK_CTL);
+	}
+
+	if (ios->bus_width)
+		host->dat_width = 1;
+	else
+		host->dat_width = 0;
+
+	return;
+}
+
+static struct mmc_host_ops nios_mmc_ops = {
+	.request = nios_mmc_request,
+	.get_ro = nios_mmc_get_ro,
+	.set_ios = nios_mmc_set_ios,
+};
+
+static int nios_mmc_probe(struct platform_device *pdev)
+{
+	struct mmc_host *mmc;
+	struct resource *r;
+	NIOS_MMC_HOST *host = NULL;
+	struct nios_mmc_platform_mmc *platp = pdev->dev.platform_data;
+	int ret, irq;
+
+	MMC_DEBUG(3, "Starting NIOS_MMC Probe\n");
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (!r || irq < 0)
+		return -ENXIO;
+	r = request_mem_region(r->start, 16 * 4, DRIVER_NAME);
+	if (!r) {
+		MMC_DEBUG(3, "Error allocating mem. region\n");
+		return -EBUSY;
+	}
+	mmc = mmc_alloc_host(sizeof(NIOS_MMC_HOST), &pdev->dev);
+	if (!mmc) {
+		MMC_DEBUG(3, "Error allocating MMC Host\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+	mmc->ops = &nios_mmc_ops;
+	MMC_DEBUG(3, "Done initial probe\n");
+	/* SG DMA Caps */
+	/* Setup block-related parameters on host */
+	mmc->max_phys_segs = 1;
+	mmc->max_hw_segs = 1;
+	mmc->max_blk_size = 512;
+	mmc->max_blk_count = max_blk_count;
+	if (max_seg_size)
+		mmc->max_seg_size = max_seg_size;
+	if (max_req_size)
+		mmc->max_req_size = max_req_size;
+
+	host = mmc_priv(mmc);
+	host->mmc = mmc;
+	host->dat_width = 0;
+	host->cmd = NULL;
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+	spin_lock_init(&host->lock);
+	host->res = r;
+	host->irq = irq;
+	host->base = ioremap(r->start, 16 * 4);
+	if (!host->base) {
+		ret = -ENOMEM;
+		MMC_DEBUG(3, "Error in IO Remap\n");
+		goto out;
+	}
+	MMC_DEBUG(3, "Setup host with Base: 0x%X IRQ: %d\n",
+		  (unsigned int)host->base, host->irq);
+
+	/* Check that SD/MMC Core is present */
+	ret = 0;
+	ret = nios_mmc_readl(host, NIOS_MMC_REG_VERSION_INFO);
+	if ((ret & 0xFFFF) != 0xBEEF) {
+		MMC_DEBUG(3, "Core not present\n");
+		ret = -ENXIO;
+		goto out;
+	}
+	/* Setup clock frequency support */
+	host->clock_freq = platp->clk_src;
+	mmc->f_max = host->clock_freq / 4;
+	/* Assign FMAX to be minimum of cpu_clk/4 and 'fmax' variable */
+	if (mmc->f_max > fmax) {
+		mmc->f_max = fmax;
+	}
+	mmc->f_min = SD_MIN_FREQ;
+	printk("%s: FPS-Tech SD/SDIO/MMC Host, IP version %d.%d\n",
+	       mmc_hostname(host->mmc), ret >> 24, (ret >> 16) & 0xff);
+	printk("%s: F_MAX: %d KHz, F_MIN: %d KHz\n", mmc_hostname(host->mmc),
+	       mmc->f_max / 1000, mmc->f_min / 1000);
+	ret = nios_mmc_readl(host, NIOS_MMC_REG_CTLSTAT);
+	printk("%s: Host built with %s DAT driver\n",
+	       mmc_hostname(host->mmc),
+	       (ret & NIOS_MMC_CTLSTAT_HOST_4BIT) ? "4-bit" : "1-bit");
+	if (ret & NIOS_MMC_CTLSTAT_PROF_EN) {
+		MMC_DEBUG(1,
+			  "NIOS_MMC: Host built with profiling capabilities\n");
+		host->prof_en = 1;
+	} else
+		host->prof_en = 0;
+	if (!dat_width) {
+		/* Force dat_width to 1-bit */
+		mmc->caps = 0;
+		printk("NIOS_MMC: Forcing 1-bit DAT width\n");
+	} else {
+		/* Set dat_width based on host capabilities */
+		mmc->caps =
+		    (ret & NIOS_MMC_CTLSTAT_HOST_4BIT) ? MMC_CAP_4_BIT_DATA : 0;
+	}
+	/* Execute soft-reset on core */
+	nios_mmc_writel(NIOS_MMC_CTLSTAT_SOFT_RST, host, NIOS_MMC_REG_CTLSTAT);
+
+	/* Enable interrupts on CD and XFER_IF only */
+	/* Use BLK_PREFETCH for linux unless disabled */
+	/* This section sets up CTLSTAT for the rest of the driver.
+	 * Make sure all further writes to CTLSTAT are using bitwise OR!!! */
+	ret = NIOS_MMC_CTLSTAT_CD_IE | NIOS_MMC_CTLSTAT_XFER_IE;
+	if (blk_prefetch)
+		ret |= NIOS_MMC_CTLSTAT_BLK_PREFETCH;
+	/* Execute write to CTLSTAT here */
+	nios_mmc_writel(ret, host, NIOS_MMC_REG_CTLSTAT);
+	if (ret & NIOS_MMC_CTLSTAT_BLK_PREFETCH) {
+		MMC_DEBUG(1, "NIOS_MMC: Using block-prefetching\n");
+	} else {
+		MMC_DEBUG(1, "NIOS_MMC: Block-prefetching disabled!\n");
+	}
+
+	ret =
+	    request_irq(host->irq, nios_mmc_irq, IRQF_SHARED | IRQF_DISABLED, DRIVER_NAME, (void *)host);
+	if (ret) {
+		MMC_DEBUG(3, "Error allocating interrupt\n");
+		goto out;
+	}
+	platform_set_drvdata(pdev, mmc);
+	mmc_add_host(mmc);
+	MMC_DEBUG(1,
+		  "NIOS_MMC: max_blk_cnt: %d max_seg_size: %d max_req_size: %d\n",
+		  mmc->max_blk_count, mmc->max_seg_size, mmc->max_req_size);
+#ifdef CONFIG_PROC_FS
+	/* Setup Proc file system */
+	nios_mmc_procinit(host);
+#endif
+	MMC_DEBUG(3, "Completed full probe successfully\n");
+	return 0;
+
+      out:
+	if (host) {
+	}
+	if (mmc)
+		mmc_free_host(mmc);
+	release_resource(r);
+	return ret;
+}
+
+static int nios_mmc_remove(struct platform_device *pdev)
+{
+	struct mmc_host *mmc = platform_get_drvdata(pdev);
+
+	if (mmc) {
+		NIOS_MMC_HOST *host = mmc_priv(mmc);
+		mmc_remove_host(mmc);
+		free_irq(host->irq, (void *)host);
+		iounmap(host->base);
+		release_resource(host->res);
+		mmc_free_host(mmc);
+#ifdef CONFIG_PROC_FS
+		nios_mmc_procclose();
+#endif
+	}
+	return 0;
+}
+
+static struct platform_driver nios_mmc_driver = {
+	.probe = nios_mmc_probe,
+	.remove = nios_mmc_remove,
+	.driver = {
+		   .name = DRIVER_NAME,
+		   .pm = NULL,
+		   },
+};
+
+static int __init nios_mmc_init(void)
+{
+	return platform_driver_register(&nios_mmc_driver);
+}
+
+static void __exit nios_mmc_exit(void)
+{
+	platform_driver_unregister(&nios_mmc_driver);
+}
+
+module_init(nios_mmc_init);
+module_exit(nios_mmc_exit);
+
+module_param(max_blk_count, uint, 0444);
+module_param(max_req_size, uint, 0444);
+module_param(max_seg_size, uint, 0444);
+module_param(dat_width, uint, 0444);
+module_param(blk_prefetch, uint, 0444);
+module_param(fmax, uint, 0444);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("NIOS MMC Host Driver");
+
+/********** PROC FS Stuff **************/
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#define procfs_name "mmc_stats"
+
+static struct proc_dir_entry *mmc_proc_file;
+static struct proc_dir_entry *mmc_proc_root = NULL;
+
+int
+procfile_read(char *buffer, char **buffer_location, off_t offset,
+	      int buffer_length, int *eof, void *data)
+{
+	int ret;
+	unsigned long long xfer_len, busy_wait_len, bus_wait_len;
+
+	NIOS_MMC_HOST *host = (NIOS_MMC_HOST *) data;
+	if (offset > 0)
+		ret = 0;
+	else if (!host->prof_en) {
+		ret = sprintf(buffer, "Host does not have profiling enabled\n");
+	} else {
+		xfer_len = nios_mmc_prof_cnt(host, 0);
+		busy_wait_len = nios_mmc_prof_cnt(host, 1);
+		bus_wait_len = nios_mmc_prof_cnt(host, 2);
+		ret =
+		    sprintf(buffer,
+			    "Profiling Counters:\nInterrupts: %d\nXFER_LEN: %llds\nBUSY_WAIT_LEN: %llds\nBUS_WAIT_LEN: %llds\n",
+			    irq_count,
+			    xfer_len / host->clock_freq,
+			    busy_wait_len / host->clock_freq,
+			    bus_wait_len / host->clock_freq);
+		nios_mmc_clear_prof(host);
+		irq_count = 0;
+	}
+	return ret;
+}
+
+static int nios_mmc_procinit(NIOS_MMC_HOST * host)
+{
+	mmc_proc_root = proc_mkdir("nios_mmc", NULL);
+	mmc_proc_file = create_proc_entry(procfs_name, 0644, mmc_proc_root);
+	if (!mmc_proc_file || !mmc_proc_root) {
+		remove_proc_entry(procfs_name, mmc_proc_root);
+		printk("NIOS_MMC: Could not init. /proc/%s\n", procfs_name);
+		return -ENOMEM;
+	}
+	MMC_DEBUG(2, "/proc/%s added\n", procfs_name);
+	mmc_proc_file->read_proc = procfile_read;
+	mmc_proc_file->mode = S_IFREG | S_IRUGO;
+	mmc_proc_file->uid = 0;
+	mmc_proc_file->gid = 0;
+	mmc_proc_file->data = (void *)host;
+	irq_count = 0;
+
+	return 0;
+}
+
+static void nios_mmc_procclose()
+{
+	remove_proc_entry(procfs_name, mmc_proc_root);
+	remove_proc_entry("nios_mmc", NULL);
+}
+#endif
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 94bb61e..24c38c3 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -518,6 +518,7 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
  * correctly and is therefore not done	(particulary with interleaved chips
  * as each chip must be checked independantly of the others).
  */
+#ifndef CONFIG_NIOS2
 static int __xipram chip_ready(struct map_info *map, unsigned long addr)
 {
 	map_word d, t;
@@ -527,6 +528,28 @@ static int __xipram chip_ready(struct map_info *map, unsigned long addr)
 
 	return map_word_equal(map, d, t);
 }
+#else
+/* On avalon bus, there is no such a luxury of toggling bit ... 
+ * Use the polling bit, if we know the datum ...
+ */ 
+static int __xipram chip_ready_dq7(struct map_info *map, unsigned long addr, map_word datum)
+{
+	map_word d;
+
+	d = map_read(map, addr);
+
+	return map_word_equal(map, d, datum);
+}
+
+static int __xipram erase_is_done(struct map_info *map, unsigned long addr)
+{
+	map_word d;
+
+	d = map_read(map, addr);
+
+	return (d.x[0] & 0x80);
+}
+#endif
 
 /*
  * Return true if the chip is ready and has the correct value.
@@ -547,10 +570,16 @@ static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word
 {
 	map_word oldd, curd;
 
+#ifndef CONFIG_NIOS2
 	oldd = map_read(map, addr);
+#endif
 	curd = map_read(map, addr);
 
+#ifdef CONFIG_NIOS2
+	return
+#else
 	return	map_word_equal(map, oldd, curd) &&
+#endif
 		map_word_equal(map, curd, expected);
 }
 
@@ -568,8 +597,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
 
 	case FL_STATUS:
 		for (;;) {
+#ifndef CONFIG_NIOS2
 			if (chip_ready(map, adr))
 				break;
+#endif
 
 			if (time_after(jiffies, timeo)) {
 				printk(KERN_ERR "Waiting for chip to be ready timed out.\n");
@@ -589,6 +620,12 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
 		return 0;
 
 	case FL_ERASING:
+#ifdef CONFIG_NIOS2
+		/* Because of Avalon bus, it is impossible to tell if a
+		 * sector is suspended or not, better avoid erase suspending
+		 */
+		 	goto sleep;
+#endif
 		if (mode == FL_WRITING) /* FIXME: Erase-suspend-program appears broken. */
 			goto sleep;
 
@@ -612,8 +649,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
 		chip->state = FL_ERASE_SUSPENDING;
 		chip->erase_suspended = 1;
 		for (;;) {
+#ifndef CONFIG_NIOS2
 			if (chip_ready(map, adr))
 				break;
+#endif
 
 			if (time_after(jiffies, timeo)) {
 				/* Should have suspended the erase by now.
@@ -1065,7 +1104,11 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
 	 * depending of the conditions.	 The ' + 1' is to avoid having a
 	 * timeout of 0 jiffies if HZ is smaller than 1000.
 	 */
+#ifdef CONFIG_NIOS2
+	unsigned long uWriteTimeout = ( HZ / 1000 ) + 2;
+#else
 	unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
+#endif
 	int ret = 0;
 	map_word oldd;
 	int retry_cnt = 0;
@@ -1126,14 +1169,22 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
 			continue;
 		}
 
+#ifdef CONFIG_NIOS2
+		if (time_after(jiffies, timeo) && !chip_ready_dq7(map, adr, datum)){
+#else
 		if (time_after(jiffies, timeo) && !chip_ready(map, adr)){
+#endif
 			xip_enable(map, chip, adr);
 			printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
 			xip_disable(map, chip, adr);
 			break;
 		}
 
+#ifdef CONFIG_NIOS2
+		if (chip_ready_dq7(map, adr, datum))
+#else
 		if (chip_ready(map, adr))
+#endif
 			break;
 
 		/* Latency issues. Drop the lock, wait a while and retry */
@@ -1312,7 +1363,11 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
 	struct cfi_private *cfi = map->fldrv_priv;
 	unsigned long timeo = jiffies + HZ;
 	/* see comments in do_write_oneword() regarding uWriteTimeo. */
+#ifdef CONFIG_NIOS2
+	unsigned long uWriteTimeout = ( HZ / 1000 ) + 2;
+#else
 	unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
+#endif
 	int ret = -EIO;
 	unsigned long cmd_adr;
 	int z, words;
@@ -1387,10 +1442,18 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
 			continue;
 		}
 
+#ifdef CONFIG_NIOS2
+		if (time_after(jiffies, timeo) && !chip_ready_dq7(map, adr, datum))
+#else
 		if (time_after(jiffies, timeo) && !chip_ready(map, adr))
+#endif
 			break;
 
+#ifdef CONFIG_NIOS2
+		if (chip_ready_dq7(map, adr, datum)) {
+#else
 		if (chip_ready(map, adr)) {
+#endif
 			xip_enable(map, chip, adr);
 			goto op_done;
 		}
@@ -1560,7 +1623,11 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
 			chip->erase_suspended = 0;
 		}
 
+#ifdef CONFIG_NIOS2
+		if (erase_is_done(map, adr))
+#else
 		if (chip_ready(map, adr))
+#endif
 			break;
 
 		if (time_after(jiffies, timeo)) {
@@ -1596,6 +1663,9 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
 	unsigned long timeo = jiffies + HZ;
 	DECLARE_WAITQUEUE(wait, current);
 	int ret = 0;
+#ifdef CONFIG_NIOS2
+	int altera_retried = 0;
+#endif
 
 	adr += chip->start;
 
@@ -1609,6 +1679,10 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
 	DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
 	       __func__, adr );
 
+#ifdef CONFIG_NIOS2
+/* the erase sometimes needs a second try on altera platforms */
+altera_retry:
+#endif
 	XIP_INVAL_CACHED_RANGE(map, adr, len);
 	ENABLE_VPP(map);
 	xip_disable(map, chip, adr);
@@ -1648,7 +1722,11 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
 			chip->erase_suspended = 0;
 		}
 
+#ifdef CONFIG_NIOS2
+		if (erase_is_done(map, adr)) {
+#else
 		if (chip_ready(map, adr)) {
+#endif
 			xip_enable(map, chip, adr);
 			break;
 		}
@@ -1663,6 +1741,17 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
 		/* Latency issues. Drop the lock, wait a while and retry */
 		UDELAY(map, chip, adr, 1000000/HZ);
 	}
+
+#ifdef CONFIG_NIOS2
+	/* give altera's platform a second chance */
+	if (!altera_retried) {
+		altera_retried=1;
+		/* reset on all failures. */
+		map_write( map, CMD(0xF0), chip->start );
+		goto altera_retry;
+	}
+#endif
+
 	/* Did we succeed? */
 	if (!chip_good(map, adr, map_word_ff(map))) {
 		/* reset on all failures. */
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2bea67c..c81beba 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -9,7 +9,7 @@ menuconfig NETDEVICES
 	---help---
 	  You can say N here if you don't intend to connect your Linux box to
 	  any other computer at all.
-
+      
 	  You'll have to say Y if your computer contains a network card that
 	  you want to use under Linux. If you are going to run SLIP or PPP over
 	  telephone line or null modem cable you need say Y here. Connecting
@@ -890,12 +890,60 @@ config SMC9194
 	  To compile this driver as a module, choose M here. The module
 	  will be called smc9194.
 
+config OPEN_ETH
+	bool "Opencores (Igor) Emac support"
+	help
+	  This is support for the opencores Igor emac driver implemented
+	  in an FPGA.
+
+config MTIP1000_ETH
+	bool "MoreThanIP 10_100_1000 Emac support"
+	help
+	  This is support for the MoreThanIP 10_100_1000 emac driver implemented
+	  in an FPGA.
+
+config ATSE
+	bool "Altera Tripple Speed Ethernet support (EXPERIMENTAL)"
+	help
+
+	  This is support for Altera Tripple Speed (TSE) Ethernet MAC
+	  implemented in an FPGA.
+
+	  If you have one of the following of Development Board
+	  Daughter Cards, say y:
+	  "10/100/1000 Ethernet PHY Daughter Board with Marvell PHY (88E1111)"
+
+	   default n
+	   depends on NIOS2
+
+config ALT_TSE
+	tristate "Altera Triple Speed Ethernet MAC support(SLS)"
+	depends on NIOS2
+	select PHYLIB
+	---help---
+	  This is support for Altera Triple Speed Ethernet MAC driver implemented
+	  for uClinux.
+
+#config PHY_IRQ_PRESENCE
+#	tristate "Board phy irq connection"
+#	depends on ALT_TSE
+#	help
+#	 Select if Board have a phy irq connection.Don't select if you are using on
+#	 board ethernet of 3C120 board as it hasn't phy irq line.	
+#
+#config PHY_IRQ_NO
+#	hex "Give phy interrupt No"
+#	depends on PHY_IRQ_PRESENCE
+#	default "10"
+#	help
+#	  Give PHY irq number as per system.
+	  
 config SMC91X
 	tristate "SMC 91C9x/91C1xxx support"
 	select CRC32
 	select MII
 	depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \
-		MIPS || BLACKFIN || MN10300
+		MIPS || BLACKFIN || MN10300 || EMBEDDED
 	help
 	  This is a driver for SMC's 91x series of Ethernet chipsets,
 	  including the SMC91C94 and the SMC91C111. Say Y if you want it
@@ -930,7 +978,7 @@ config TI_DAVINCI_EMAC
 
 config DM9000
 	tristate "DM9000 support"
-	depends on ARM || BLACKFIN || MIPS
+	depends on ARM || BLACKFIN || MIPS || EMBEDDED
 	select CRC32
 	select MII
 	---help---
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index ae8cd30..27bbf61 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -113,6 +113,8 @@ obj-$(CONFIG_APNE) += apne.o 8390.o
 obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
 obj-$(CONFIG_HP100) += hp100.o
 obj-$(CONFIG_SMC9194) += smc9194.o
+obj-$(CONFIG_OPEN_ETH) += open_eth.o
+obj-$(CONFIG_MTIP1000_ETH) += mtip1000.o
 obj-$(CONFIG_FEC) += fec.o
 obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o
 ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y)
@@ -241,6 +243,10 @@ obj-$(CONFIG_DM9000) += dm9000.o
 obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o
 pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o
 obj-$(CONFIG_MLX4_CORE) += mlx4/
+obj-$(CONFIG_ATSE) += atse.o
+obj-$(CONFIG_ALT_TSE) += altera_tse_mdio.o
+obj-$(CONFIG_ALT_TSE) += altera_tse_ethtool.o
+obj-$(CONFIG_ALT_TSE) += altera_tse.o
 obj-$(CONFIG_ENC28J60) += enc28j60.o
 obj-$(CONFIG_ETHOC) += ethoc.o
 
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 3b79c6c..3a335a9 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -71,6 +71,8 @@ extern struct net_device *sonic_probe(int unit);
 extern struct net_device *SK_init(int unit);
 extern struct net_device *seeq8005_probe(int unit);
 extern struct net_device *smc_init(int unit);
+extern struct net_device *oeth_init(int unit);
+extern struct net_device *mtip1000_init(int unit);
 extern struct net_device *atarilance_probe(int unit);
 extern struct net_device *sun3lance_probe(int unit);
 extern struct net_device *sun3_82586_probe(int unit);
@@ -191,6 +193,12 @@ static struct devprobe2 isa_probes[] __initdata = {
 #ifdef CONFIG_SMC9194
 	{smc_init, 0},
 #endif
+#if defined(CONFIG_OPEN_ETH)
+	{oeth_init, 0},
+#endif
+#if defined(CONFIG_MTIP1000_ETH)
+	{mtip1000_init, 0},
+#endif
 #ifdef CONFIG_SEEQ8005
 	{seeq8005_probe, 0},
 #endif
diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c
new file mode 100644
index 0000000..18476f1
--- /dev/null
+++ b/drivers/net/altera_tse.c
@@ -0,0 +1,1844 @@
+/*******************************************************************************
+*  linux/drivers/net/altera_tse.c
+*
+* Copyright (C) 2008 Altera Corporation.
+*
+* History:
+*    o  SLS  - Linux 2.6.27                                                            
+*
+*  All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+* NON INFRINGEMENT.  See the GNU General Public License for more
+* details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*******************************************************************************/  
+
+#include <linux/module.h>	/* for module-version */
+#include <linux/kernel.h>	/* printk(), and other useful stuff */
+#include <linux/sched.h>	/* for jiffies, HZ, etc. */
+#include <linux/string.h>	/* inline memset(), etc. */
+#include <linux/ptrace.h>
+#include <linux/errno.h>	/* return codes */
+#include <linux/ioport.h>	/* request_region(), release_region() */
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/inet.h>
+#include <linux/netdevice.h>	/* struct device, and other headers */
+#include <linux/etherdevice.h>	/* eth_type_trans */
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/init.h>		/* __init (when not using as a module) */
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include <linux/pm.h>		/* pm_message_t */
+#include <linux/platform_device.h>
+
+#include <asm/irq.h>		/* For NR_IRQS only. */
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/cacheflush.h>
+
+#include <asm/processor.h>	/* Processor type for cache alignment. */
+#include <asm/bitops.h>
+#include <asm/io.h>		/* I/O functions */
+#include <asm/uaccess.h>	/* User space memory access functions */
+
+#include "altera_tse.h"    
+
+
+static const char version[] =
+    "Altera Triple Speed MAC IP Driver(v8.0) "
+    "developed by SLS,August-2008," "--Linux 2.6.27-rc3\n";
+
+/* DEBUG flags */
+//#define DEBUG_INFO     1  
+//#define DEBUG_WARNING  1
+//#define DEBUG_ERROR    1
+//
+//#if DEBUG_INFO == 1
+//#define PRINTK1(args...) printk(args)
+//#else                                
+//#define PRINTK1(args...)
+//#endif                                                     
+//
+//#if DEBUG_WARNING == 1
+//#define PRINTK2(args...) printk(args)
+//#else                                                          
+//#define PRINTK2(args...)
+//#endif                                                                  
+//
+//#if DEBUG_ERROR == 1
+//#define PRINTK3(args...) printk(args)
+//#else
+//#define PRINTK3(args...)
+//#endif
+
+//netif_msg_rx_err
+//netif_msg_rx_status
+//netif_msg_intr
+//netif_msg_tx_queued
+//netif_msg_link
+//netif_msg_drv
+//netif_msg_hw
+//netif_msg_ifdown
+
+/* 1 -> print contents of all tx packtes on printk
+ */
+#define TX_DEEP_DEBUG 0
+
+#if 1
+#define my_flush_dcache_range(x,y) do{flush_dcache_range(x,y);}while(0)
+#else
+#define my_flush_dcache_range(x,y) flush_cache_all()
+#endif
+
+static void sgdma_config(struct alt_tse_private *tse_priv);
+
+static void alt_sgdma_construct_descriptor_burst(volatile struct
+						 alt_sgdma_descriptor *desc,
+						 volatile struct
+						 alt_sgdma_descriptor *next,
+						 unsigned int *read_addr,
+						 unsigned int *write_addr,
+						 unsigned short length_or_eop,
+						 int generate_eop,
+						 int read_fixed,
+						 int write_fixed_or_sop,
+						 int read_burst,
+						 int write_burst,
+						 unsigned char atlantic_channel);
+
+static int sgdma_async_read(struct alt_tse_private *tse_priv,
+	volatile struct alt_sgdma_descriptor *rx_desc);
+
+static int sgdma_async_write(struct alt_tse_private *tse_priv,
+			    volatile struct alt_sgdma_descriptor *tx_desc);
+
+static int tse_sgdma_add_buffer(struct net_device *dev);
+static unsigned int sgdma_read_init(struct net_device *dev); 
+static int tse_poll(struct napi_struct *napi, int budget);
+static irqreturn_t alt_sgdma_isr(int irq, void *dev_id, struct pt_regs *regs);
+
+#ifdef CONFIG_NET_POLL_CONTROLLER                                        
+static void tse_net_poll_controller(struct net_device *dev);
+#endif
+
+static int tse_hardware_send_pkt(struct sk_buff *skb, struct net_device *dev);
+static int init_phy(struct net_device *dev);
+static void adjust_link(struct net_device *dev);
+static int init_mac(struct net_device *dev);
+static int tse_change_mtu(struct net_device *dev, int new_mtu);
+static struct net_device_stats *tse_get_statistics(struct net_device *dev);
+
+static void tse_set_hash_table(struct net_device *dev, int count,
+			       struct dev_mc_list *addrs);
+
+static void tse_set_multicast_list(struct net_device *dev);
+int tse_set_hw_address(struct net_device *dev, void *port);
+static int tse_open(struct net_device *dev);
+static int tse_shutdown(struct net_device *dev);
+
+/*******************************************************************************
+*	SGDMA Control Stuff
+*
+*******************************************************************************/
+
+/* Clear descriptor memory ,initialize SGDMA descriptor chain and reset SGDMA.
+* arg1     :TSE private data structure
+* @return  :1 on success
+*           less than zero on error
+*/
+static void sgdma_config(struct alt_tse_private *tse_priv)
+{
+	unsigned int mem_off, *mem_ptr = (unsigned int *)tse_priv->desc_mem_base,
+	    mem_size = ALT_TSE_TOTAL_SGDMA_DESC_SIZE;
+
+	//Clearing SGDMA desc Memory
+	for (mem_off = 0; mem_off < mem_size; mem_off += 4)
+		*mem_ptr++ = 0x00000000;
+
+	//reset rx_sgdma
+	tse_priv->rx_sgdma_dev->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
+	tse_priv->rx_sgdma_dev->control = 0x0;
+
+	//reset tx_sgdma
+	tse_priv->tx_sgdma_dev->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
+	tse_priv->tx_sgdma_dev->control = 0x0;                       
+}
+
+/* This is a generic routine that the SGDMA mode-specific routines
+* call to populate a descriptor.
+* arg1     :pointer to first SGDMA descriptor.
+* arg2     :pointer to next  SGDMA descriptor.
+* arg3     :Address to where data to be written.
+* arg4     :Address from where data to be read.
+* arg5     :no of byte to transaction.
+* arg6     :variable indicating to generate start of packet or not
+* arg7     :read fixed
+* arg8     :write fixed
+* arg9     :read burst
+* arg10    :write burst
+* arg11    :atlantic_channel number
+*/
+static void alt_sgdma_construct_descriptor_burst(volatile struct
+						 alt_sgdma_descriptor *desc,
+						 volatile struct
+						 alt_sgdma_descriptor *next,
+						 unsigned int *read_addr,
+						 unsigned int *write_addr,
+						 unsigned short length_or_eop,
+						 int generate_eop,
+						 int read_fixed,
+						 int write_fixed_or_sop,
+						 int read_burst,
+						 int write_burst,
+						 unsigned char atlantic_channel)
+{
+	/*
+	* Mark the "next" descriptor as "not" owned by hardware. This prevents
+	* The SGDMA controller from continuing to process the chain. This is
+	* done as a single IO write to bypass cache, without flushing
+	* the entire descriptor, since only the 8-bit descriptor status must
+	* be flushed.
+	*/
+	next->descriptor_control = (next->descriptor_control
+				    &
+				    ~ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK);
+	//	printk("read_addr %p\n", read_addr);
+#if TX_DEEP_DEBUG
+	if (read_addr != 0) {
+	  unsigned char *buf = ((unsigned char *)read_addr) + 2;
+	  int i;
+	  int len  = length_or_eop;
+
+	  /* first 2 bytes of the mac-address of my laptop...
+	   */
+	  if (buf[0] == 0 && buf[1] == 0x12) {
+
+	    printk("incoming tx descriptor read_addr:%p len:%d", read_addr, len);
+	    BUG_ON(write_addr != 0);	
+	    for (i = 0; i < len-2; i++) {
+	      if ((i % 16) == 0) {
+		printk("\n%04x: ", i);
+	      }
+	      if ((i % 16) == 8) { // emulate wireshark output
+		printk(" ");
+	      }
+	      printk("%02x ", buf[i]); //assume tx_shift
+	    }
+	    printk("\n -- end of packet data\n");
+	  }
+	}
+#endif
+	desc->source = read_addr;
+	desc->destination = write_addr;
+	desc->next = (unsigned int *)next;
+	desc->source_pad = 0x0;
+	desc->destination_pad = 0x0;
+	desc->next_pad = 0x0;
+	desc->bytes_to_transfer = length_or_eop;
+	desc->actual_bytes_transferred = 0;
+	desc->descriptor_status = 0x0;
+
+	/* SGDMA burst not currently supported */
+	desc->read_burst = 0;	//read_burst;  //TBD
+	desc->write_burst = 0;	//write_burst; //TBD
+
+	/*
+	* Set the descriptor control block as follows:
+	* - Set "owned by hardware" bit
+	* - Optionally set "generate EOP" bit
+	* - Optionally set the "read from fixed address" bit
+	* - Optionally set the "write to fixed address bit (which serves
+	*   serves as a "generate SOP" control bit in memory-to-stream mode).
+	* - Set the 4-bit atlantic channel, if specified
+	*
+	* Note that this step is performed after all other descriptor information
+	* has been filled out so that, if the controller already happens to be
+	* pointing at this descriptor, it will not run (via the "owned by hardware"
+	* bit) until all other descriptor information has been set up.
+	*/
+
+	desc->descriptor_control = ( 
+		(ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK) | 
+		(generate_eop ? ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK : 0x0) | 
+		(read_fixed ? ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK : 0x0) | 
+		(write_fixed_or_sop ? ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK : 0x0) | 
+		(atlantic_channel ? ((atlantic_channel & 0x0F) << 3) : 0)
+	    );
+}
+
+/* Start to copy from rxFIFO into given buffer memory area with Asynchronous .so the
+* function does not return the actual bytes transferred for current descriptor
+* arg1     :TSE private data structure
+* arg2     :Pointer to first descriptor structure of RX SGDMA chain
+* return   SUCCESS on success
+*          less than 0 on errors
+*/
+static int sgdma_async_read(struct alt_tse_private *tse_priv,
+			    volatile struct alt_sgdma_descriptor *rx_desc)
+{
+	unsigned int timeout;
+	unsigned int retval = 0;
+	struct net_device *dev = tse_priv->dev;
+
+	/* Make sure SGDMA controller is not busy from a former command */
+	timeout = 0;
+
+	if (netif_msg_rx_status(tse_priv))
+		printk(KERN_WARNING "%s :Waiting while rx SGDMA is busy........\n",
+			dev->name);
+
+	tse_priv->rx_sgdma_dev->control = 0;
+	tse_priv->rx_sgdma_dev->status = 0x1f;	//clear status
+
+	/* Wait for the descriptor (chain) to complete */
+	while (tse_priv->rx_sgdma_dev->status & ALT_SGDMA_STATUS_BUSY_MSK) {
+		ndelay(100);
+		if (timeout++ == ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) {
+			if (netif_msg_rx_status(tse_priv))
+				printk(KERN_WARNING "%s :RX SGDMA Timeout\n", dev->name);
+			return -EBUSY;
+		}
+	}
+
+	tse_priv->rx_sgdma_dev->next_descriptor_pointer = 
+           (int)(volatile struct alt_sgdma_descriptor *)rx_desc;
+	
+	//Don't just enable IRQs adhoc
+	tse_priv->rx_sgdma_dev->control = tse_priv->rx_sgdma_imask | ALT_SGDMA_CONTROL_RUN_MSK;
+
+	return retval;
+}
+
+static int sgdma_async_write(struct alt_tse_private *tse_priv,
+			    volatile struct alt_sgdma_descriptor *tx_desc)
+{
+	unsigned int timeout;
+	unsigned int retval = 0;
+	struct net_device *dev = tse_priv->dev;
+
+	/* Make sure SGDMA controller is not busy from a former command */
+	timeout = 0;
+//	if (netif_msg_tx_done(tse_priv))
+//		printk(KERN_WARNING "%s :Waiting while tx SGDMA is busy.........\n",
+//			dev->name);
+
+	tse_priv->tx_sgdma_dev->control = 0;
+	tse_priv->tx_sgdma_dev->status = 0x1f;	//clear status
+
+	/* Wait for the descriptor (chain) to complete */
+	while (tse_priv->tx_sgdma_dev->status & ALT_SGDMA_STATUS_BUSY_MSK) {
+		ndelay(100);
+		if (timeout++ == ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) {
+			if (netif_msg_rx_status(tse_priv))
+				printk(KERN_WARNING "%s :TX SGDMA Timeout\n", dev->name);
+			return -EBUSY;
+		}
+	}
+
+	tse_priv->tx_sgdma_dev->next_descriptor_pointer = 
+           (int)(volatile struct alt_sgdma_descriptor *)tx_desc;
+	
+	//Don't just enable IRQs adhoc
+	tse_priv->tx_sgdma_dev->control = tse_priv->tx_sgdma_imask | ALT_SGDMA_CONTROL_RUN_MSK;
+
+	return retval;
+}
+
+/* Create TSE descriptor for next buffer
+* or error if no buffer available
+*/
+static int tse_sgdma_add_buffer(struct net_device *dev)
+{
+
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	int next_head;
+	struct sk_buff *skb;
+	
+	next_head = ((tse_priv->rx_sgdma_descriptor_head +1) & (ALT_RX_RING_MOD_MASK));
+	    
+	if (next_head == tse_priv->rx_sgdma_descriptor_tail)
+		return -EBUSY;
+
+	//current MTU + 4 b/c input packet is aligned by 2;
+	skb = dev_alloc_skb(tse_priv->current_mtu + 4);
+	if (skb == NULL) {
+		if (netif_msg_rx_err(tse_priv))
+			printk(KERN_WARNING "%s :ENOMEM:::skb_size=%d\n", 
+				dev->name, tse_priv->current_mtu + 4);
+		return -ENOMEM;
+	}
+	flush_dcache_range((unsigned long)skb->data,
+			   ((unsigned long)skb->data) + skb->len);
+	skb->dev = dev;
+	
+	tse_priv->rx_skb[tse_priv->rx_sgdma_descriptor_head] = skb;
+
+	alt_sgdma_construct_descriptor_burst(
+		(volatile struct alt_sgdma_descriptor *)&tse_priv->sgdma_rx_desc[tse_priv->rx_sgdma_descriptor_head],
+		(volatile struct alt_sgdma_descriptor *)&tse_priv->sgdma_rx_desc[next_head],
+		NULL, //read addr
+		(unsigned int *)tse_priv->rx_skb[tse_priv->rx_sgdma_descriptor_head]->data,
+		0x0, //length or EOP
+		0x0, //gen eop
+		0x0, //read fixed
+		0x0, //write fixed or sop
+		0x0, //read burst
+		0x0, //write burst
+		0x0 //channel
+	);
+
+	tse_priv->rx_sgdma_descriptor_head = next_head;
+
+	return SUCCESS;
+
+}
+
+/* Init and setup SGDMA Descriptor chain.
+* arg1     :TSE private data structure
+* return    SUCCESS
+*/
+static unsigned int sgdma_read_init(struct net_device *dev)                       
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	int rx_loop;
+	
+	for (rx_loop = 0; rx_loop < ALT_TSE_RX_SGDMA_DESC_COUNT; rx_loop++) {
+		//Should do some checking here.
+		tse_sgdma_add_buffer(dev);
+	}
+	sgdma_async_read(tse_priv,
+			 &tse_priv->sgdma_rx_desc[tse_priv->
+						  rx_sgdma_descriptor_tail]);
+	if (netif_msg_rx_status(tse_priv))
+		printk(KERN_WARNING "%s :Read init is completed\n", dev->name);
+	
+	return SUCCESS;
+}
+
+
+/*******************************************************************************
+* actual ethernet stuff
+*
+*******************************************************************************/
+/* NAPI Polling function
+*	processes packets received, until end of received packets
+*	or budget is reached
+*	Clear TX buffers
+*	also restarts SGDMAs for TX, RX as needed
+*/
+static int tse_poll(struct napi_struct *napi, int budget)
+{
+	struct alt_tse_private *tse_priv = container_of(napi, struct alt_tse_private, napi);
+	struct net_device *dev = tse_priv->dev;
+	volatile struct alt_sgdma_descriptor *temp_desc_pointer;
+	unsigned int desc_status, desc_control;
+	int howmany = 0;
+	unsigned int rx_bytes, netif_rx_status;
+	unsigned char *skb_Rxbuffer;
+	struct sk_buff *skb;
+	unsigned long flags;
+	unsigned int tx_tail;
+	unsigned int tx_loop;
+	int done;
+
+	if (netif_msg_intr(tse_priv))
+		printk(KERN_WARNING "%s :Entering tse_poll with budget = 0x%x\n",
+			dev->name, budget);
+	
+	temp_desc_pointer =
+	    &tse_priv->sgdma_rx_desc[tse_priv->
+				     rx_sgdma_descriptor_tail];
+	desc_status = temp_desc_pointer->descriptor_status;
+
+	//loop over descriptors until one is not complete
+	while ((desc_status &
+	       ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) && (howmany < budget)) 
+	{
+		if (netif_msg_intr(tse_priv))
+			printk(KERN_WARNING "%s NAPI RX Loop\n", dev->name);
+		
+		if ((desc_status & ALT_SGDMA_DESCRIPTOR_STATUS_ERROR_MSK) &&
+			(netif_msg_rx_err(tse_priv)))
+				printk(KERN_WARNING "%s :TSE RX Err: Status = 0x%x\n",
+					dev->name, desc_status);
+		
+		//get desc SKB
+		skb =
+		    tse_priv->rx_skb[tse_priv->
+				     rx_sgdma_descriptor_tail];
+		tse_priv->rx_skb[tse_priv->rx_sgdma_descriptor_tail] =
+		    NULL;
+
+		rx_bytes = temp_desc_pointer->actual_bytes_transferred;
+		rx_bytes -= ALIGNED_BYTES;
+		
+		//process packet
+		/* Align IP header to 32 bits */
+		skb_reserve(skb, ALIGNED_BYTES);
+		skb_Rxbuffer = skb_put(skb, rx_bytes);
+		skb->protocol = eth_type_trans(skb, dev);
+
+		netif_rx_status = netif_receive_skb(skb);
+		
+		if (netif_rx_status == NET_RX_DROP)
+		{
+			if(netif_msg_rx_err(tse_priv))
+				printk(KERN_WARNING "%s :NET_RX_DROP occurred\n",
+					dev->name);
+			
+	//		tse_priv->mac_dev->command_config.image |= ALTERA_TSE_CMD_XOFF_GEN_MSK;	
+			tse_priv->status.rx_dropped++;
+		}                      
+
+		//next descriptor
+		tse_priv->rx_sgdma_descriptor_tail = 
+			((tse_priv->rx_sgdma_descriptor_tail + 1) & (ALT_RX_RING_MOD_MASK));                      
+		   
+		//add new desc	
+		if ((tse_sgdma_add_buffer(dev)) && (netif_msg_rx_err(tse_priv)))
+			printk(KERN_WARNING "%s :ah, something happened, and no desc was added to rx",
+				dev->name);
+
+		//update temp_desc to next desc
+		temp_desc_pointer =
+		    &tse_priv->sgdma_rx_desc[tse_priv->
+					     rx_sgdma_descriptor_tail];
+		desc_status = temp_desc_pointer->descriptor_status;
+		
+		howmany++;
+	}
+	
+	if (netif_msg_rx_status(tse_priv))
+		printk(KERN_INFO "%s : RX SGDMA STATUS=0x%x, tail=0x%x, head=0x%x\n",
+			dev->name, tse_priv->rx_sgdma_dev->status, 
+			tse_priv->rx_sgdma_descriptor_tail,
+			tse_priv->rx_sgdma_descriptor_head);
+	
+	//check sgdma status, and restart as needed
+	if ((tse_priv->rx_sgdma_dev->status & ALT_SGDMA_STATUS_CHAIN_COMPLETED_MSK) || 
+		!(tse_priv->rx_sgdma_dev->status & ALT_SGDMA_STATUS_BUSY_MSK)) 
+	{
+		if (netif_msg_rx_status(tse_priv))
+			printk(KERN_INFO "%s :starting with rx_tail = %d and rx_head = %d\n",
+				dev->name,
+				tse_priv->rx_sgdma_descriptor_tail, 
+				tse_priv->rx_sgdma_descriptor_head);
+//		spin_lock(tse_priv->rx_lock);
+		sgdma_async_read(tse_priv,
+			&tse_priv->sgdma_rx_desc[tse_priv->rx_sgdma_descriptor_tail]);
+//		spin_unlock(tse_priv->rx_lock);
+	}
+	
+
+	//now do TX stuff
+	if (tse_priv->tx_sgdma_descriptor_tail != tse_priv->tx_sgdma_descriptor_head) {
+		if (spin_trylock_irqsave(&tse_priv->tx_lock, flags))
+		{       
+			if (netif_msg_intr(tse_priv))
+				printk(KERN_WARNING "%s :NAPI TX Section\n", dev->name);     
+		
+			tx_tail = tse_priv->tx_sgdma_descriptor_tail; 
+			temp_desc_pointer = &tse_priv->sgdma_tx_desc[tx_tail];
+			desc_control = temp_desc_pointer->descriptor_control;	
+			
+			//loop over tx desc from tail till head, check for !hw owned
+			//for (tx_loop = 0; tx_loop < ALT_TSE_TX_SGDMA_DESC_COUNT; tx_loop++)
+			tx_loop = 0;
+			while(!(desc_control & ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK) &&
+				(tx_tail != tse_priv->tx_sgdma_descriptor_head))
+			{
+				dev_kfree_skb(tse_priv->tx_skb[tx_tail]);
+				tse_priv->tx_skb[tx_tail] = NULL;
+			
+				tx_loop++;
+				tx_tail = ((tx_tail + 1) & (ALT_TX_RING_MOD_MASK));         
+				temp_desc_pointer = &tse_priv->sgdma_tx_desc[tx_tail];
+				desc_control = temp_desc_pointer->descriptor_control;
+				
+				//if((desc_control & ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK))
+				//	break;
+			}
+			tse_priv->tx_sgdma_descriptor_tail = tx_tail;
+			temp_desc_pointer = &tse_priv->sgdma_tx_desc[tx_tail];                                    
+
+			//check is tx sgdma is running, and if it should be
+			if (!(tse_priv->tx_sgdma_dev->status & ALT_SGDMA_STATUS_BUSY_MSK) & 
+				(temp_desc_pointer->descriptor_control & ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK)) 
+			{
+				if (netif_msg_intr(tse_priv))
+					printk(KERN_WARNING "%s :NAPI Starting TX SGDMA with Desc %d\n", 
+						dev->name, tx_tail);
+				//restart sgdma
+				sgdma_async_write(tse_priv, &tse_priv->sgdma_tx_desc[tx_tail]);
+				
+			}
+			
+			//restart queue if it was stopped
+			if (netif_queue_stopped(dev))
+			{
+				if (netif_msg_intr(tse_priv))
+					printk(KERN_WARNING "%s :Cleared %d descriptors,tail = %d, head = %d, Waking QUEUE\n", 
+						dev->name, tx_loop, tx_tail, tse_priv->tx_sgdma_descriptor_head);
+				netif_wake_queue(dev);
+			}
+	
+			spin_unlock_irqrestore(&tse_priv->tx_lock, flags);
+		}
+	}
+	                                                        
+	done = 0;
+	/* if all packets processed, complete rx, and turn on normal IRQs */
+	if (howmany < budget) {
+		if (netif_msg_intr(tse_priv))
+			printk(KERN_WARNING "%s :NAPI Complete, did %d packets with budget = %d\n", 
+				dev->name, howmany, budget);
+		napi_complete(napi);
+
+		/* turn on desc irqs again */
+		tse_priv->rx_sgdma_imask |= ALT_SGDMA_CONTROL_IE_GLOBAL_MSK;
+		tse_priv->rx_sgdma_dev->control |= ALT_SGDMA_CONTROL_IE_GLOBAL_MSK;
+#ifndef NO_TX_IRQ
+		tse_priv->tx_sgdma_imask |= ALT_SGDMA_CONTROL_IE_GLOBAL_MSK;
+		tse_priv->tx_sgdma_dev->control |= ALT_SGDMA_CONTROL_IE_GLOBAL_MSK;
+#endif		
+		done = 1;
+	}
+
+        budget -= howmany;
+	return done?0:1;
+}
+
+
+
+/* SG-DMA TX & RX FIFO interrupt routing
+* arg1     :irq number
+* arg2     :user data passed to isr
+* arg3     :pt_resgs structure passed from kernel
+*/
+static irqreturn_t alt_sgdma_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = dev_id;
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	
+	if (netif_msg_intr(tse_priv))
+		printk(KERN_WARNING "%s :TSE IRQ TX head = %d, tail = %d\n", 
+			dev->name, tse_priv->tx_sgdma_descriptor_head, tse_priv->tx_sgdma_descriptor_tail);
+	//turn off desc irqs and enable napi rx 
+	if (napi_schedule_prep(&tse_priv->napi)) {
+		if (netif_msg_intr(tse_priv))
+			printk(KERN_WARNING "%s :NAPI Starting\n", dev->name);
+		tse_priv->rx_sgdma_imask &= ~ALT_SGDMA_CONTROL_IE_GLOBAL_MSK;
+		tse_priv->rx_sgdma_dev->control &= ~ALT_SGDMA_CONTROL_IE_GLOBAL_MSK;
+#ifndef NO_TX_IRQ
+		tse_priv->tx_sgdma_imask &= ~ALT_SGDMA_CONTROL_IE_GLOBAL_MSK;
+		tse_priv->tx_sgdma_dev->control &= ~ALT_SGDMA_CONTROL_IE_GLOBAL_MSK;
+#endif
+		__napi_schedule(&tse_priv->napi);
+	} else {
+	//if we get here, we received another irq while processing NAPI
+		if (netif_msg_intr(tse_priv))
+			printk(KERN_WARNING "%s :TSE IRQ Received while IRQs disabled\n",
+				dev->name);
+	}
+
+	//reset IRQ 	
+	tse_priv->rx_sgdma_dev->control |= ALT_SGDMA_CONTROL_CLEAR_INTERRUPT_MSK;
+	tse_priv->tx_sgdma_dev->control |= ALT_SGDMA_CONTROL_CLEAR_INTERRUPT_MSK;
+	
+	return IRQ_HANDLED;
+}      
+
+
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+* Polling receive - used by netconsole and other diagnostic tools
+* to allow network i/o with interrupts disabled.
+*/
+static void tse_net_poll_controller(struct net_device *dev)
+{
+
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	disable_irq(tse_priv->rx_fifo_interrupt);
+	disable_irq(tse_priv->tx_fifo_interrupt);
+	alt_sgdma_isr(tse_priv->rx_fifo_interrupt, dev, NULL);
+	enable_irq(tse_priv->rx_fifo_interrupt);
+	enable_irq(tse_priv->tx_fifo_interrupt);
+
+}
+#endif
+
+
+
+/*******************************************************************************
+* TX and RX functions
+*	Send Function
+*	Receive function, clears RX Ring - Called from NAPI softirq
+*	Clear Transmit buffers - Called from NAPI softirq
+*
+*******************************************************************************/
+
+
+/* Send Packet Function
+* arg1     :skb to send
+* arg2     :netdev device
+*/
+static int tse_hardware_send_pkt(struct sk_buff *skb, struct net_device *dev)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);             
+	unsigned int len;
+	unsigned int next_head;
+	unsigned int next_head_check;
+	unsigned int head;
+	unsigned int tail;
+	unsigned int aligned_tx_buffer;
+	unsigned long flags;
+	char	req_tx_shift_16;
+//	struct sk_buff *new_skb;
+	
+
+	aligned_tx_buffer = (unsigned int)skb->data;
+	len = skb->len;
+//	saved_len = skb->len;
+//	offset = aligned_tx_buffer & 0x3;
+	if ((unsigned int)skb->data & 0x2) {
+		req_tx_shift_16 = 0x1;
+		aligned_tx_buffer -= ALIGNED_BYTES;
+		len += ALIGNED_BYTES;
+	} else {
+		req_tx_shift_16 = 0x0;
+	}
+
+	 /* Align len on 4, otherwise it seems we get truncated frames */
+
+//       if (len & 3) {
+//	 printk(KERN_WARNING "TSE align to word, skb->data = 0x%x, start address = 0x%x, len=%d, saved_len=%d, offset = %d\n", (unsigned int) skb->data, aligned_tx_buffer, len, saved_len, offset); 
+         len += 3;
+         len &= ~3UL;
+//	 printk(KERN_WARNING "TSE new length = %d\n", len);
+//       }
+
+//	tse_priv->mac_dev->tx_cmd_stat.bits.tx_shift16 = 1;
+//	aligned_tx_buffer = (unsigned int)skb->data;
+//	len = skb->len;
+//	if (aligned_tx_buffer & 0x2) {
+//		aligned_tx_buffer -= ALIGNED_BYTES;
+//		len += ALIGNED_BYTES;
+//	} else {
+//		new_skb = alloc_skb(skb->len + ALIGNED_BYTES, GFP_KERNEL);
+//		skb_reserve(new_skb, ALIGNED_BYTES);
+//		memcpy(new_skb->data, skb->data,  skb->len);
+//		aligned_tx_buffer = (unsigned int)new_skb->data - ALIGNED_BYTES;
+//		len = skb->len + ALIGNED_BYTES;
+//		dev_kfree_skb(skb);
+//		skb = new_skb;
+//	}       
+
+	/* len in align later in alt_sgdma_construct_descriptor_burst(), but 
+	 * we can safely ingorned the extra alignement added in  on len here 
+	 * since it's not actually part of the data and/or checksum
+	 */	
+	//Flush raw data from data cache	
+	flush_dcache_range(aligned_tx_buffer, aligned_tx_buffer + len);
+	
+	spin_lock_irqsave(&tse_priv->tx_lock, flags);
+	//get the heads
+	head = tse_priv->tx_sgdma_descriptor_head;
+	tail = tse_priv->tx_sgdma_descriptor_tail;
+	next_head = (head + 1) & (ALT_TX_RING_MOD_MASK);
+	next_head_check = (head + 2) & (ALT_TX_RING_MOD_MASK);
+
+	if (netif_msg_tx_queued(tse_priv))
+		printk(KERN_WARNING "%s :head = %d, next_head = %d, tail = %d\n", 
+			dev->name, head, next_head, tse_priv->tx_sgdma_descriptor_tail);
+		
+	//if next next head is == tail, stop the queue                                 
+	//next_head = (next_head + 1) & (ALT_TX_RING_MOD_MASK);
+	if (next_head_check == tse_priv->tx_sgdma_descriptor_tail) {
+		//no space in ring, we stop the queue
+		if (netif_msg_tx_queued(tse_priv))
+			printk(KERN_WARNING "%s :TX next_head not clear, stopping queue, tail = %d, head = %d\n",
+				dev->name, tse_priv->tx_sgdma_descriptor_tail, tse_priv->tx_sgdma_descriptor_head);
+		if (!netif_queue_stopped(dev))
+			netif_stop_queue(dev);
+		napi_schedule(&tse_priv->napi);
+	}
+
+	tse_priv->tx_skb[head] = skb;
+
+	//wait till tx is done, change shift 16
+	if(req_tx_shift_16 != tse_priv->last_tx_shift_16)
+	{                                
+		if (netif_msg_tx_queued(tse_priv))
+			printk(KERN_WARNING "%s :tx_shift does not match\n", dev->name);
+		
+		while(tse_priv->tx_sgdma_dev->status & ALT_SGDMA_STATUS_BUSY_MSK)
+		{}
+		tse_priv->mac_dev->tx_cmd_stat.bits.tx_shift16 = req_tx_shift_16 & 0x1;
+		tse_priv->last_tx_shift_16 = req_tx_shift_16;
+	}               
+	
+	alt_sgdma_construct_descriptor_burst(
+		(volatile struct alt_sgdma_descriptor *)&tse_priv->sgdma_tx_desc[head],
+		(volatile struct alt_sgdma_descriptor *)&tse_priv->sgdma_tx_desc[next_head],
+		(unsigned int *)aligned_tx_buffer, //read addr
+		(unsigned int *)0,
+		(len), //length or EOP
+		0x1, //gen eop
+		0x0, //read fixed
+		0x1, //write fixed or sop                                            
+		0x0, //read burst
+		0x0, //write burst
+		0x0 //channel
+	);	
+
+
+                                                           
+	
+	//now check is the sgdma is running, if it is then do nothing.
+	//if it is not, start it up with irq's enabled.
+
+	if (!(tse_priv->tx_sgdma_dev->status & ALT_SGDMA_STATUS_BUSY_MSK)) {
+		if (netif_msg_tx_queued(tse_priv))
+			printk(KERN_WARNING "%s :TX SGDMA Not Running\n", dev->name);
+		sgdma_async_write(tse_priv, &tse_priv->sgdma_tx_desc[tail]);
+	}                                                        
+	
+	tse_priv->tx_sgdma_descriptor_head = next_head;
+	
+	spin_unlock_irqrestore(&tse_priv->tx_lock,flags);
+
+	
+	tse_priv->dev->trans_start = jiffies;	
+	
+	return SUCCESS;
+}            
+
+
+/*******************************************************************************
+* Phy init
+*	Using shared PHY control interface
+*
+*******************************************************************************/
+/* Initializes driver's PHY state, and attaches to the PHY.
+ * Returns 0 on success.
+ */
+static int init_phy(struct net_device *dev)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev); 
+	struct alt_tse_config * tse_config = tse_priv->tse_config;
+	struct phy_device *phydev;
+	char phy_id[MII_BUS_ID_SIZE];
+	char mii_id[MII_BUS_ID_SIZE];
+	
+	phy_interface_t interface;
+//	unsigned int phy_addr;
+	
+	
+	//hard code for now
+	interface = tse_config->interface;              
+	
+	tse_priv->oldlink = 0;
+	tse_priv->oldspeed = 0;
+	tse_priv->oldduplex = -1;	
+	
+	snprintf(mii_id, MII_BUS_ID_SIZE, "%x", tse_config->mii_id); 
+	snprintf(phy_id, MII_BUS_ID_SIZE, PHY_ID_FMT, mii_id, tse_config->phy_addr);
+	
+	phydev = phy_connect(dev, phy_id, &adjust_link, 0, interface);
+	
+	if (IS_ERR(phydev)) {
+		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
+		return PTR_ERR(phydev);
+	}
+
+	phydev->supported &= tse_config->tse_supported_modes;
+	phydev->advertising = phydev->supported;  
+
+	if (tse_config->autoneg == AUTONEG_DISABLE)
+	{
+		phydev->autoneg = tse_config->autoneg;
+		phydev->speed = tse_config->speed;
+		phydev->duplex = tse_config->duplex;
+	}
+	
+	tse_priv->phydev = phydev;
+	
+	return 0;
+}                           
+
+
+/* Called every time the controller might need to be made
+ * aware of new link state.  The PHY code conveys this                                  
+ * information through variables in the phydev structure, and this
+ * function converts those variables into the appropriate
+ * register values, and can bring down the device if needed.               
+ */                         
+static void adjust_link(struct net_device *dev)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev); 
+	unsigned long flags;                                              
+	struct phy_device *phydev = tse_priv->phydev;
+	int new_state = 0;
+	unsigned int refvar;
+	
+	//only change config if there is a link
+	spin_lock_irqsave(&tse_priv->tx_lock, flags);
+	if (phydev->link) 
+	{              
+		//read old config
+		refvar = tse_priv->mac_dev->command_config.image;
+		
+		//check duplex
+		if (phydev->duplex != tse_priv->oldduplex) 
+		{
+			new_state = 1;
+			//not duplex
+			if (!(phydev->duplex))
+				refvar |= ALTERA_TSE_CMD_HD_ENA_MSK;
+			else
+				refvar &= ~ALTERA_TSE_CMD_HD_ENA_MSK;
+			
+			if (netif_msg_link(tse_priv))
+				printk(KERN_WARNING "%s :Link duplex = 0x%x\n", dev->name, 
+					phydev->duplex);
+			
+			tse_priv->oldduplex = phydev->duplex;
+		}
+		
+		if (phydev->speed != tse_priv->oldspeed) 
+		{
+			new_state = 1;
+			switch (phydev->speed) {
+			case 1000:
+				refvar |= ALTERA_TSE_CMD_ETH_SPEED_MSK;
+				refvar &= ~ALTERA_TSE_CMD_ENA_10_MSK;
+				break;				
+			case 100:
+				refvar &= ~ALTERA_TSE_CMD_ETH_SPEED_MSK;
+				refvar &= ~ALTERA_TSE_CMD_ENA_10_MSK;
+				break;				
+			case 10:
+				refvar &= ~ALTERA_TSE_CMD_ETH_SPEED_MSK;
+				refvar |= ALTERA_TSE_CMD_ENA_10_MSK;
+				break;				
+			default:
+				if (netif_msg_link(tse_priv))
+					printk(KERN_WARNING
+						"%s: Ack!  Speed (%d) is not 10/100/1000!\n",
+						dev->name, phydev->speed);
+				break;
+			}
+			
+			tse_priv->oldspeed = phydev->speed;
+		}
+		
+		tse_priv->mac_dev->command_config.image = refvar;         
+		
+		netif_carrier_on(tse_priv->dev);
+		
+	} else if (tse_priv->oldlink) {
+		new_state = 1;
+		tse_priv->oldlink = 0;
+		tse_priv->oldspeed = 0;
+		tse_priv->oldduplex = -1;                   
+		netif_carrier_off(tse_priv->dev);
+	} 
+	
+	if (new_state && netif_msg_link(tse_priv))
+		phy_print_status(phydev);
+
+	spin_unlock_irqrestore(&tse_priv->tx_lock, flags);
+
+}
+
+/*******************************************************************************
+* MAC setup and control
+*	MAC init, and various setting functions
+*
+*******************************************************************************/ 
+/* Initialize MAC core registers
+*  arg1   : 'net_device' structure pointer 
+*
+*/
+static int init_mac(struct net_device *dev)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+        int counter;     
+	int dat;
+	
+	/* reset the mac */
+	tse_priv->mac_dev->command_config.bits.transmit_enable=0;
+	tse_priv->mac_dev->command_config.bits.receive_enable=0;      
+	tse_priv->mac_dev->command_config.bits.software_reset = 1;
+	
+	counter = 0;
+	while (tse_priv->mac_dev->command_config.bits.software_reset) {
+		ndelay(100);
+		if (counter++ > ALT_TSE_SW_RESET_WATCHDOG_CNTR)
+			break;
+	}
+
+	if ((counter >= ALT_TSE_SW_RESET_WATCHDOG_CNTR) && 
+		(netif_msg_drv(tse_priv)))
+	{
+		printk(KERN_WARNING "%s: TSEMAC SW reset bit never cleared!\n",
+			dev->name);
+	}
+	
+	//default config is enabled HERE including TX and rx
+	dat = tse_priv->mac_dev->command_config.image;
+
+	if ((dat & 0x03) && (netif_msg_drv(tse_priv))) {
+		printk
+		    (KERN_WARNING "%s: RX/TX not disabled after reset... CMD_CONFIG=0x%08x\n",
+		     dev->name, dat);
+	} else if (netif_msg_drv(tse_priv)) {
+		printk(KERN_INFO "%s: OK, counter=%d, CMD_CONFIG=0x%08x\n", 
+			dev->name, counter, dat);
+	}	
+	
+	/* Initialize MAC registers */
+	tse_priv->mac_dev->max_frame_length = tse_priv->current_mtu;	//ALT_TSE_MAX_FRAME_LENGTH;
+	tse_priv->mac_dev->rx_almost_empty_threshold = 8;
+	tse_priv->mac_dev->rx_almost_full_threshold = 8;
+	tse_priv->mac_dev->tx_almost_empty_threshold = 8;
+	tse_priv->mac_dev->tx_almost_full_threshold = 3;
+	tse_priv->mac_dev->tx_sel_empty_threshold = tse_priv->tse_tx_depth - 16;
+	tse_priv->mac_dev->tx_sel_full_threshold = 0;
+	tse_priv->mac_dev->rx_sel_empty_threshold = tse_priv->tse_rx_depth - 16;
+	tse_priv->mac_dev->rx_sel_full_threshold = 0;
+	
+	/*Enable RX shift 16 for alignment of all received frames on 16-bit start address */
+	tse_priv->mac_dev->rx_cmd_stat.bits.rx_shift16 = 1;                
+	tse_priv->last_rx_shift_16 = 1;
+	/* check if the MAC supports the 16-bit shift option at the RX CMD STATUS Register  */
+	if (tse_priv->mac_dev->rx_cmd_stat.bits.rx_shift16) {
+		tse_priv->rx_shift_16_ok = 1;
+	} else if (netif_msg_drv(tse_priv)) {
+		tse_priv->rx_shift_16_ok = 0;
+		printk(KERN_WARNING "%s: Incompatible with RX_CMD_STAT register return RxShift16 value. \n",
+			dev->name);
+		return -1;                                                  
+	}
+
+	/*Enable TX shift 16 for alignment of all transmitting frames on 16-bit start address */
+	tse_priv->mac_dev->tx_cmd_stat.bits.tx_shift16 = 1;
+	tse_priv->mac_dev->tx_cmd_stat.bits.omit_crc = 0;
+        tse_priv->last_tx_shift_16 = 1;
+	/*
+	* check if the MAC supports the 16-bit shift option allowing us
+	* to send frames without copying. Used by the send function later.
+	*/
+	if (tse_priv->mac_dev->tx_cmd_stat.bits.tx_shift16) {
+		tse_priv->tx_shift_16_ok = 1;
+	} else {
+		tse_priv->tx_shift_16_ok = 0;
+		printk(KERN_WARNING "%s: Incompatible value with TX_CMD_STAT register return TxShift16 value. \n",
+			dev->name);
+		return -1;
+	}	
+	
+	//pause quanta??
+	//tse_priv->mac_dev->pause_quanta=10;
+	
+	/* enable MAC */
+	dat = 0;
+	dat = ALTERA_TSE_CMD_TX_ENA_MSK | ALTERA_TSE_CMD_RX_ENA_MSK |
+
+	//enable pause frame generation
+//		ALTERA_TSE_CMD_XOFF_GEN_MSK |	
+#if ENABLE_PHY_LOOPBACK
+		ALTERA_TSE_CMD_PROMIS_EN_MSK |	// promiscuous mode
+		ALTERA_TSE_CMD_LOOPBACK_MSK |	// loopback mode
+#endif
+	    ALTERA_TSE_CMD_RX_ERR_DISC_MSK;	/* automatically discard frames with CRC errors */
+	    
+	    tse_priv->mac_dev->command_config.image = dat;
+	    
+	    if (netif_msg_drv(tse_priv))
+	    	printk(KERN_INFO "%s: MAC post-initialization: CMD_CONFIG=0x%08x\n",
+			dev->name, tse_priv->mac_dev->command_config.image);
+		/* Set the MAC address */
+	tse_priv->mac_dev->mac_addr_0 = ((tse_priv->dev->dev_addr[3]) << 24 |
+				      (tse_priv->dev->dev_addr[2]) << 16 |
+				      (tse_priv->dev->dev_addr[1]) << 8 |
+				      (tse_priv->dev->dev_addr[0]));
+
+	tse_priv->mac_dev->mac_addr_1 = ((tse_priv->dev->dev_addr[5] << 8 |
+				       (tse_priv->dev->dev_addr[4])) & 0xFFFF);
+
+	/* Set the MAC address */
+	tse_priv->mac_dev->supp_mac_addr_0_0 = tse_priv->mac_dev->mac_addr_0;
+	tse_priv->mac_dev->supp_mac_addr_0_1 = tse_priv->mac_dev->mac_addr_1;
+
+	/* Set the MAC address */
+	tse_priv->mac_dev->supp_mac_addr_1_0 = tse_priv->mac_dev->mac_addr_0;
+	tse_priv->mac_dev->supp_mac_addr_1_1 = tse_priv->mac_dev->mac_addr_1;
+
+	/* Set the MAC address */
+	tse_priv->mac_dev->supp_mac_addr_2_0 = tse_priv->mac_dev->mac_addr_0;
+	tse_priv->mac_dev->supp_mac_addr_2_1 = tse_priv->mac_dev->mac_addr_1;
+
+	/* Set the MAC address */
+	tse_priv->mac_dev->supp_mac_addr_3_0 = tse_priv->mac_dev->mac_addr_0;
+	tse_priv->mac_dev->supp_mac_addr_3_1 = tse_priv->mac_dev->mac_addr_1;
+
+	//tse_priv->mac_dev->command_config.bits.src_mac_addr_sel_on_tx=0;
+	return 0;
+}    
+
+
+
+/*
+* Open and Initialize the interface
+* The interface is opened whenever 'ifconfig' activates it
+*  arg1   : 'net_device' structure pointer 
+*  arg2   : new mtu value
+*  return : 0                     
+*/
+
+/* Jumbo-grams seem to work :-( */
+#define TSE_MIN_MTU 64
+#define TSE_MAX_MTU 16384
+
+static int tse_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	unsigned int free_loop;
+
+	if ((new_mtu > (tse_priv->tse_tx_depth * ALT_TSE_MAC_FIFO_WIDTH)) ||
+	    (new_mtu > (tse_priv->tse_rx_depth * ALT_TSE_MAC_FIFO_WIDTH))) {
+		printk
+		    ("Your system doesn't support new MTU size as TX/RX FIFO size is small\n");
+		return -EINVAL;
+	}
+
+	if (new_mtu < TSE_MIN_MTU || new_mtu > TSE_MAX_MTU)
+		return -EINVAL;
+
+	spin_lock(&tse_priv->rx_lock);
+
+	tse_priv->rx_sgdma_dev->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
+	tse_priv->rx_sgdma_dev->control = 0x0;
+
+	tse_priv->current_mtu = new_mtu;
+	dev->mtu = new_mtu;
+	tse_priv->mac_dev->max_frame_length = tse_priv->current_mtu;
+
+	/* Disable receiver and transmitter  descriptor(SGDAM) */
+	for (free_loop = 0; free_loop < ALT_TSE_RX_SGDMA_DESC_COUNT;
+	     free_loop++) {
+	/* Free the original skb */
+		if (tse_priv->rx_skb[free_loop] != NULL)
+			dev_kfree_skb(tse_priv->rx_skb[free_loop]);
+	}
+
+	/* Prepare RX SGDMA to receive packets */
+	sgdma_read_init(dev);
+
+	printk("TSE: new mtu is %d \n", new_mtu);
+
+	spin_unlock(&tse_priv->rx_lock);
+
+	return 0;
+}
+
+/*
+* Get the current Ethernet statistics.This may be called with the device open or closed.
+* arg1   : net device for which multicasts filter is adjusted
+* return : network statistics structure
+*/
+static struct net_device_stats *tse_get_statistics(struct net_device *dev)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	struct net_device_stats *net_status =
+	    (struct net_device_stats *)&tse_priv->status;
+	
+	/* total packets received without error*/
+	net_status->rx_packets =
+	    tse_priv->mac_dev->aFramesReceivedOK +
+	    tse_priv->mac_dev->ifInErrors;
+	
+	/* total packets received without error*/
+	net_status->tx_packets =
+	    tse_priv->mac_dev->aFramesTransmittedOK +
+	    tse_priv->mac_dev->ifOutErrors;
+	
+	/* total bytes received without error  */
+	net_status->rx_bytes = tse_priv->mac_dev->aOctetsReceivedOK;
+	
+	/* total bytes transmitted without error   */
+	net_status->tx_bytes = tse_priv->mac_dev->aOctetsTransmittedOK;
+	                                                               
+	/* bad received packets  */
+	net_status->rx_errors = tse_priv->mac_dev->ifInErrors;       
+	
+	/* bad Transmitted packets */
+	net_status->tx_errors = tse_priv->mac_dev->ifOutErrors;
+	
+	/* multicasts packets received */
+	net_status->multicast = tse_priv->mac_dev->ifInMulticastPkts;
+	
+	return net_status;
+}
+
+/*
+* Program multicasts mac addresses into hash look-up table                   
+* arg1    : net device for which multicasts filter is adjusted
+* arg2    : multicasts address count
+* arg3    : list of multicasts addresses
+*/
+
+static void tse_set_hash_table(struct net_device *dev, int count,
+			       struct dev_mc_list *addrs)
+{
+	int mac_octet, xor_bit, bitshift, hash, loop;
+	char octet;
+	struct dev_mc_list *cur_addr;
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	alt_tse_mac *p_mac_base = tse_priv->mac_dev;
+
+	cur_addr = addrs;
+	for (loop = 0; loop < count; loop++, cur_addr = cur_addr->next) 
+	{
+		/* do we have a pointer here? */
+		if (!cur_addr)
+			break;
+
+		/* make sure this is a multicasts address    */
+		if (!(*cur_addr->dmi_addr & 1))	//
+			continue;
+
+		//PRINTK1("dmi_addr %x-%x-%x-%x-%x-%x\n", cur_addr->dmi_addr[0],
+		//	cur_addr->dmi_addr[1],
+		//	cur_addr->dmi_addr[2],
+		//	cur_addr->dmi_addr[3],
+		//	cur_addr->dmi_addr[4], cur_addr->dmi_addr[5]);
+		hash = 0;	// the hash value
+
+		for (mac_octet = 5; mac_octet >= 0; mac_octet--) {
+			xor_bit = 0;
+			octet = cur_addr->dmi_addr[mac_octet];
+			for (bitshift = 0; bitshift < 8; bitshift++)
+				xor_bit ^= (int)((octet >> bitshift) & 0x01);
+			hash = (hash << 1) | xor_bit;
+			//PRINTK1("\t\thash=%d,xor_bit=%d octet=%x\n", hash,
+			//	xor_bit, octet);
+		}                
+
+		p_mac_base->hash_table[hash] = 1;                                
+	}
+
+}
+
+/*
+* Set/Clear multicasts filter
+* arg1    : net device for which multicasts filter is adjusted
+*           multicasts table from the linked list of addresses
+*           associated with this dev structure.
+*/
+static void tse_set_multicast_list(struct net_device *dev)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	int hash_loop;
+
+	if (dev->flags & IFF_PROMISC) 
+	{
+		/* Log any net taps */
+		//PRINTK1("%s: Promiscuous mode enabled.\n", dev->name);
+		tse_priv->mac_dev->command_config.image |=
+		    ALTERA_TSE_CMD_PROMIS_EN_MSK;
+	} else {
+		tse_priv->mac_dev->command_config.image &=
+		    ~ALTERA_TSE_CMD_PROMIS_EN_MSK;
+	}
+
+	if (dev->flags & IFF_ALLMULTI) {
+		for (hash_loop = 0; hash_loop < 64; hash_loop++)
+			tse_priv->mac_dev->hash_table[hash_loop] = 1;
+	} else {
+		for (hash_loop = 0; hash_loop < 64; hash_loop++)
+			tse_priv->mac_dev->hash_table[hash_loop] = 0;	// Clear any existing hash entries
+
+		if (dev->mc_count)
+			tse_set_hash_table(dev, dev->mc_count, dev->mc_list);
+	}
+}
+
+/*
+* Initialize the MAC address
+* arg1    : net device for which TSE MAC driver is registered
+* arg2    : address passed from upper layer
+* return : 0
+*/
+int tse_set_hw_address(struct net_device *dev, void *port)
+{
+	struct sockaddr *addr = port;
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+/* Set the MAC address */
+//tse_priv->mac_dev->mac_addr_0 = (( dev->dev_addr[2] ) << 24
+//                                |( dev->dev_addr[3] ) << 16
+//                                |( dev->dev_addr[4] ) <<  8
+//                                |( dev->dev_addr[5] ));
+
+//tse_priv->mac_dev->mac_addr_1 = (( dev->dev_addr[0] << 8
+//                                |( dev->dev_addr[1] )) & 0xFFFF );
+
+	tse_priv->mac_dev->mac_addr_0 = ((dev->dev_addr[3]) << 24
+					 | (dev->dev_addr[2]) << 16
+					 | (dev->dev_addr[1]) << 8
+					 | (dev->dev_addr[0]));
+
+	tse_priv->mac_dev->mac_addr_1 = ((dev->dev_addr[5] << 8
+					  | (dev->dev_addr[4])) & 0xFFFF);
+
+	/* Set the MAC address */
+	tse_priv->mac_dev->supp_mac_addr_0_0 = tse_priv->mac_dev->mac_addr_0;
+	tse_priv->mac_dev->supp_mac_addr_0_1 = tse_priv->mac_dev->mac_addr_1;
+
+	/* Set the MAC address */
+	tse_priv->mac_dev->supp_mac_addr_1_0 = tse_priv->mac_dev->mac_addr_0;
+	tse_priv->mac_dev->supp_mac_addr_1_1 = tse_priv->mac_dev->mac_addr_1;
+
+	/* Set the MAC address */
+	tse_priv->mac_dev->supp_mac_addr_2_0 = tse_priv->mac_dev->mac_addr_0;
+	tse_priv->mac_dev->supp_mac_addr_2_1 = tse_priv->mac_dev->mac_addr_1;
+
+	/* Set the MAC address */
+	tse_priv->mac_dev->supp_mac_addr_3_0 = tse_priv->mac_dev->mac_addr_0;
+	tse_priv->mac_dev->supp_mac_addr_3_1 = tse_priv->mac_dev->mac_addr_1;
+
+	if (netif_msg_hw(tse_priv))
+		printk(KERN_INFO "%s :Set Mac Address %2x:%2x:%2x:%2x:%2x:%2x\n", 
+			dev->name,
+			dev->dev_addr[0],
+			dev->dev_addr[1],
+			dev->dev_addr[2],
+			dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+	//PRINTK1("read add mac_0 = 0x%x\n", tse_priv->mac_dev->mac_addr_0);
+	//PRINTK1("read add mac_1 = 0x%x\n", tse_priv->mac_dev->mac_addr_1);
+	return 0;
+}
+
+
+
+/*******************************************************************************
+* Driver Open, shutdown, probe functions
+*
+*******************************************************************************/
+
+
+/*
+* Open and Initialize the interface
+* The interface is opened whenever 'ifconfig' activates it
+*  arg1   : 'net_device' structure pointer
+*  return : 0
+*/
+static int tse_open(struct net_device *dev)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	int status;
+	int retval = 0;
+
+	/* start NAPI */
+	napi_enable(&tse_priv->napi);
+
+	/* Reset and configure TSE MAC and probe associated PHY */
+	if(init_phy(dev)) {
+		napi_disable(&tse_priv->napi);
+		return -EAGAIN;
+	}
+
+	if(init_mac(dev)) {
+		napi_disable(&tse_priv->napi);
+		return -EAGAIN;  	
+	}
+
+	/* Initialize SGDMA */
+	tse_priv->rx_sgdma_descriptor_tail = 0;
+	tse_priv->rx_sgdma_descriptor_head = 0;
+	tse_priv->tx_sgdma_descriptor_tail = 0;
+	tse_priv->tx_sgdma_descriptor_head = 0;
+	
+	sgdma_config(tse_priv);
+
+	/* Prepare RX SGDMA to receive packets */
+	status = sgdma_read_init(dev);
+
+
+	/* Register RX SGDMA interrupt */
+	retval =
+	    request_irq(tse_priv->rx_fifo_interrupt, (void *)alt_sgdma_isr,
+			0, "SGDMA_RX", dev);
+	if (retval) {
+		printk
+		    ("%s:Unable to register Rx SGDMA interrupt %d (retval=%d).\n",
+		     dev->name, tse_priv->rx_fifo_interrupt, retval);
+		napi_disable(&tse_priv->napi);
+		return -EAGAIN;
+	}
+	/* Register TX SGDMA interrupt */
+	retval =
+	    request_irq(tse_priv->tx_fifo_interrupt, (void *)alt_sgdma_isr,
+			0, "SGDMA_TX", dev);
+	if (retval) {
+		printk
+		    ("%s:Unable to register TX SGDMA interrupt %d (retval=%d).\n",
+		     dev->name, tse_priv->tx_fifo_interrupt, retval);
+		free_irq(tse_priv->rx_fifo_interrupt, (void *)dev);
+		napi_disable(&tse_priv->napi);
+		return -EAGAIN;
+	}
+//#ifdef CONFIG_PHY_IRQ_PRESENCE
+//#error "ToDo"
+//#error "Left due to unavailability of Marvell PHY IRQ connection to NEEK/(3c120)"
+///* Register IRQ interrupt */
+//	retval =
+//	    request_irq(tse_priv->alarm_irq, (void *)alt_tse_link_isr, 0,
+//			"TSE_ALARM_LINK", dev);
+//	if (retval) {
+//		PRINTK3
+//		    ("%s:Unable to register timer interrupt %d (retval=%d).\n",
+//		     "TSE_ALARM_LINK", tse_priv->alarm_irq, retval);
+//		free_irq(tse_priv->rx_fifo_interrupt, (void *)dev);
+//		free_irq(tse_priv->tx_fifo_interrupt, (void *)dev);
+//		napi_disable(&tse_priv->napi);
+//		return -EAGAIN;
+//	}
+//#else
+//	phy_timer.expires = jiffies + msecs_to_jiffies(PHY_TIMER_MSEC);
+//	add_timer(&phy_timer);
+//#endif
+	//start phy
+	phy_start(tse_priv->phydev);
+
+	/* Start network queue */     	
+	netif_start_queue(dev);
+	tse_priv->tse_up = 1;
+	//tasklet_init(&tse_priv->tse_rx_tasklet, tse_sgdma_rx, (unsigned long)dev);
+	return SUCCESS;
+}
+
+/*
+*  Stop TSE MAC interface - this puts the device in an inactive state
+*  arg1   : 'net_device' structure pointer
+*  return : 0
+*/
+
+static int tse_shutdown(struct net_device *dev)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	unsigned int free_loop;
+	int counter;
+	
+
+	
+	napi_disable(&tse_priv->napi);
+	
+
+	//tasklet_kill(&tse_priv->tse_rx_tasklet);
+
+	/* Free interrupt handler */
+	free_irq(tse_priv->rx_fifo_interrupt, (void *)dev);
+	free_irq(tse_priv->tx_fifo_interrupt, (void *)dev);
+
+#ifdef CONFIG_PHY_IRQ_PRESENCE
+	free_irq(tse_priv->alarm_irq, (void *)dev);
+#endif
+
+	// disable and reset the MAC, empties fifo
+	tse_priv->mac_dev->command_config.bits.software_reset = 1;
+
+	counter = 0;
+	while (tse_priv->mac_dev->command_config.bits.software_reset) {
+		ndelay(100);
+		if (counter++ > ALT_TSE_SW_RESET_WATCHDOG_CNTR)
+			break;
+	}
+
+	if ((counter >= ALT_TSE_SW_RESET_WATCHDOG_CNTR) && 
+		netif_msg_ifdown(tse_priv))
+	{
+		printk(KERN_WARNING "%s :SHUTDOWN: TSEMAC SW reset bit never cleared!\n",
+			dev->name);
+	}
+	
+	spin_lock(&tse_priv->rx_lock);
+	spin_lock(&tse_priv->tx_lock);
+
+	//Need to reset/turn off sgdmas
+	sgdma_config(tse_priv);
+
+	/* Disable receiver and transmitter  descriptor(SGDAM) */
+	for (free_loop = 0; free_loop < ALT_TSE_TX_SGDMA_DESC_COUNT;
+	     free_loop++) 
+	{
+		/* Free the original skb */
+		if (tse_priv->tx_skb[free_loop] != NULL) {
+			dev_kfree_skb(tse_priv->tx_skb[free_loop]);
+			tse_priv->tx_skb[free_loop] = NULL;
+		}
+	}
+
+	/* Disable receiver and transmitter  descriptor(SGDMA) */
+	for (free_loop = 0; free_loop < ALT_TSE_RX_SGDMA_DESC_COUNT;
+	     free_loop++) 
+	{
+		/* Free the original skb */
+		if (tse_priv->rx_skb[free_loop] != NULL) {
+			dev_kfree_skb(tse_priv->rx_skb[free_loop]);
+			tse_priv->rx_skb[free_loop] = NULL;
+		}
+	}
+
+	spin_unlock(&tse_priv->rx_lock);
+	spin_unlock(&tse_priv->tx_lock);
+
+	phy_disconnect(tse_priv->phydev);
+	tse_priv->phydev = NULL;
+	
+	netif_stop_queue(dev);
+	
+	tse_priv->tse_up = 0;
+	
+	return SUCCESS;
+}
+
+static const struct net_device_ops tse_netdev_ops = {
+	.ndo_open		= tse_open,
+	.ndo_stop		= tse_shutdown,
+	.ndo_start_xmit		= tse_hardware_send_pkt,
+	.ndo_get_stats		= tse_get_statistics,
+	.ndo_set_mac_address	= tse_set_hw_address,
+	.ndo_set_multicast_list	= tse_set_multicast_list,
+	.ndo_change_mtu		= tse_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
+/*
+* Initialize 'net_device' structure, resets and re-configures MAC and PHY
+* arg1   : 'net_device' structure pointer allocated for TSE interface
+* arg2   : Interface number
+*/
+static void __devinit tse_dev_probe(struct net_device *dev)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	struct alt_tse_config *tse_config = tse_priv->tse_config;
+
+	tse_priv->dev = dev;
+
+	dev->base_addr = (unsigned long)tse_priv->mac_dev;	//TSE_MAC_BASE;
+
+	/* Set initial SGDMA descriptor address */
+	tse_priv->desc =
+	    (volatile struct alt_sgdma_descriptor *)tse_priv->desc_mem_base;
+	tse_priv->sgdma_tx_desc =
+	    (volatile struct alt_sgdma_descriptor *)tse_priv->desc;
+	tse_priv->sgdma_rx_desc =
+	    (volatile struct alt_sgdma_descriptor *)&tse_priv->
+	    desc[ALT_TSE_TX_SGDMA_DESC_COUNT];
+
+//	tse_priv->antoneg_enable = AUTONEG_ENABLE;
+
+	tse_priv->rx_sgdma_imask =  ( ALT_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK \
+                                    | ALT_SGDMA_STATUS_DESC_COMPLETED_MSK      \
+                                    | ALT_SGDMA_CONTROL_IE_GLOBAL_MSK );
+#ifndef NO_TX_IRQ
+	tse_priv->tx_sgdma_imask =  ( ALT_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK \
+                                    | ALT_SGDMA_CONTROL_IE_GLOBAL_MSK );
+#else
+	tse_priv->tx_sgdma_imask = 0;
+#endif
+
+	/* set MTU as max frame size */
+	tse_priv->current_mtu = ALT_TSE_MAX_FRAME_LENGTH;
+
+	/* Set default MAC address */
+	memcpy(dev->dev_addr, tse_config->ethaddr, ETH_ALEN);
+
+	/* Fill in the fields of the device structure with Ethernet values */
+	ether_setup(dev);
+
+	dev->netdev_ops = &tse_netdev_ops;
+	tse_set_ethtool_ops(dev);
+//	dev->features = NETIF_F_HIGHDMA;
+
+	/* add napi interface */
+	netif_napi_add(dev, &tse_priv->napi, tse_poll, ALT_TSE_RX_SGDMA_DESC_COUNT);
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+
+	dev->poll_controller = tse_net_poll_controller;
+#endif
+
+	/* Spin lock variable initialize */
+	spin_lock_init(&tse_priv->rx_lock);
+	spin_lock_init(&tse_priv->tx_lock);
+}
+
+/*
+* Driver entry point called by Platform devise driver
+* arg    : platform_device object
+* return : 'net_device' structure pointer on success else 0
+*/
+static int __devinit alt_tse_probe(struct platform_device *pdev)
+{
+	struct net_device *dev;
+	int ret = -ENODEV;
+	struct resource *res_alt_tse;
+	struct alt_tse_private *tse_priv;
+	struct alt_tse_config *tse_config = (struct alt_tse_config *) pdev->dev.platform_data;
+	resource_size_t mac_dev_base, sgdma_rx_base, sgdma_tx_base, desc_mem_base;
+	resource_size_t mac_dev_size, sgdma_rx_size, sgdma_tx_size, desc_mem_size;
+
+	dev = alloc_etherdev(sizeof(struct alt_tse_private));
+	if (!dev) {
+		printk(KERN_ERR "%s: Etherdev alloc failed, aborting.\n", dev->name);
+		return -ENODEV;
+	}
+	//printk("\n\nTSE DEV NAME : %s", dev->name);
+	//sprintf(dev->name, "eth0");
+	netdev_boot_setup_check(dev);
+	//dev->priv = (void *)ioremap_nocache((unsigned long)dev->priv,
+	//				    sizeof(struct alt_tse_private));
+	tse_priv = netdev_priv(dev);
+
+	/* Get TSE MAC base address */
+	/* ioremap() requires buffer_size as the 2nd argument, but it is not being used inside anyway, so put 0xFFFF */
+	/* 1. Get tse MAC resource */
+	res_alt_tse = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+			TSE_RESOURCE_MAC_DEV);
+	if (!res_alt_tse) {
+		printk(KERN_ERR "ERROR: %s:%d: platform_get_resource_byname() failed\n", __FILE__, __LINE__);
+		ret = -ENODEV;
+		goto out_mac_dev;
+	}
+
+	mac_dev_base = res_alt_tse->start;
+	mac_dev_size = resource_size(res_alt_tse);
+	if (!request_mem_region(mac_dev_base, mac_dev_size, "altera_tse")) {
+		printk(KERN_ERR "ERROR: %s:%d: request_mem_region() failed\n", __FILE__, __LINE__);
+		ret = -EBUSY;
+		goto out_mac_dev;
+	}
+
+	tse_priv->mac_dev = ioremap_nocache(mac_dev_base, sizeof(alt_tse_mac));
+	if (!tse_priv->mac_dev) {
+		printk(KERN_ERR "ERROR: %s:%d: ioremap_nocache() failed\n", __FILE__, __LINE__);
+		ret = -ENOMEM;
+		goto out_mac_dev_ioremap;
+	}
+
+	/* Get RX and TX SGDMA addresses */
+	/* 2. Get sgdma_rx mem resource */
+	res_alt_tse = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+			TSE_RESOURCE_SGDMA_RX_DEV);
+	if (!res_alt_tse) {
+		printk(KERN_ERR "ERROR: %s:%d: platform_get_resource_byname() failed\n", __FILE__, __LINE__);
+		ret = -ENODEV;
+		goto out_sgdma_rx;
+	}
+
+	sgdma_rx_base = res_alt_tse->start;
+	sgdma_rx_size = resource_size(res_alt_tse);
+	if (!request_mem_region(sgdma_rx_base, sgdma_rx_size, "altera_tse")) {
+		printk(KERN_ERR "ERROR: %s:%d: request_mem_region() failed\n", __FILE__, __LINE__);
+		ret = -EBUSY;
+		goto out_sgdma_rx;
+	}
+
+	tse_priv->rx_sgdma_dev = ioremap_nocache(sgdma_rx_base, sizeof(struct alt_sgdma_registers));
+	if (!tse_priv->rx_sgdma_dev) {
+		printk(KERN_ERR "ERROR: %s:%d: ioremap_nocache() failed\n", __FILE__, __LINE__);
+		ret = -ENOMEM;
+		goto out_sgdma_rx_ioremap;
+	}
+
+	/* 3. Get sgdma_tx mem resource */
+	res_alt_tse = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+			TSE_RESOURCE_SGDMA_TX_DEV);
+	if (!res_alt_tse) {
+		printk(KERN_ERR "ERROR: %s:%d: platform_get_resource_byname() failed\n", __FILE__, __LINE__);
+		ret = -ENODEV;
+		goto out_sgdma_tx;
+	}
+
+	sgdma_tx_base = res_alt_tse->start;
+	sgdma_tx_size = resource_size(res_alt_tse);
+	if (!request_mem_region(sgdma_tx_base, sgdma_tx_size, "altera_tse")) {
+		printk(KERN_ERR "ERROR: %s:%d: request_mem_region() failed\n", __FILE__, __LINE__);
+		ret = -EBUSY;
+		goto out_sgdma_tx;
+	}
+
+	tse_priv->tx_sgdma_dev = ioremap_nocache(sgdma_tx_base, sizeof(struct alt_sgdma_registers));
+	if (!tse_priv->tx_sgdma_dev) {
+		printk(KERN_ERR "ERROR: %s:%d: ioremap_nocache() failed\n", __FILE__, __LINE__);
+		ret = -ENOMEM;
+		goto out_sgdma_tx_ioremap;
+	}
+
+	/* 4. Get sgdma_rx irq resource */
+	res_alt_tse = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
+			TSE_RESOURCE_SGDMA_RX_IRQ);
+	if (!res_alt_tse) {
+		printk(KERN_ERR "ERROR: %s:%d: platform_get_resource_byname() failed\n", __FILE__, __LINE__);
+		ret = -ENODEV;
+		goto out_sgdma_irq;
+	}
+	tse_priv->rx_fifo_interrupt = res_alt_tse->start;;
+
+	/* 5. Get sgdma_tx irq resource */
+	res_alt_tse = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
+			TSE_RESOURCE_SGDMA_TX_IRQ);
+	if (!res_alt_tse) {
+		printk(KERN_ERR "ERROR: %s:%d: platform_get_resource_byname() failed\n", __FILE__, __LINE__);
+		ret = -ENODEV;
+		goto out_sgdma_irq;
+	}
+	tse_priv->tx_fifo_interrupt = res_alt_tse->start;
+
+	/* 6. Get sgdma_tx/rx fifo mem resource */
+
+	/* Set TSE MAC RX and TX fifo depth */
+	tse_priv->tse_rx_depth = tse_config->rx_fifo_depth;
+	tse_priv->tse_tx_depth = tse_config->tx_fifo_depth;
+
+	/* 7. Get sgdma descriptor mem resource */
+	res_alt_tse = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+			TSE_RESOURCE_SGDMA_DES_DEV);
+	if (!res_alt_tse) {
+		printk(KERN_ERR "ERROR: %s:%d: platform_get_resource_byname() failed\n", __FILE__, __LINE__);
+		ret = -ENODEV;
+		goto out_sgdma_irq;
+	}
+
+	desc_mem_base = res_alt_tse->start;
+	desc_mem_size = resource_size(res_alt_tse);
+#if 0
+	/* FIXME: this fails and I don't know why...
+	 * we don't need it since we'll just ioremap later...
+	 */
+	if (!request_mem_region (desc_mem_base, desc_mem_size, "altera_tse")) {
+		printk("ERROR: %s:%d: request_mem_region() failed\n", __FILE__,
+				__LINE__);
+		ret = -EBUSY;
+		goto out_sgdma_irq;
+	}
+#endif
+	tse_priv->desc_mem_base = (unsigned int) ioremap_nocache(desc_mem_base,
+			ALT_TSE_TOTAL_SGDMA_DESC_SIZE);
+	if (!tse_priv->desc_mem_base) {
+		printk(KERN_ERR "ERROR: %s:%d: ioremap_nocache() failed\n", __FILE__, __LINE__);
+		ret = -ENOMEM;
+		goto out_desc_mem;
+	}
+
+	tse_priv->tse_config = tse_config;
+
+	/* Probe ethernet device */
+	tse_dev_probe(dev);
+
+	/* Register ethernet device driver */
+	ret = register_netdev(dev);
+	if (ret) {
+		printk(KERN_ERR "%s: Failed to register TSE net device\n",
+				dev->name);
+		goto out;
+	}
+
+	SET_NETDEV_DEV(dev, &pdev->dev);
+	platform_set_drvdata(pdev, dev);
+
+	printk("%s", version);
+
+	return 0;
+
+out:
+	iounmap((void *) tse_priv->desc_mem_base);
+out_desc_mem:
+#if 0
+	release_mem_region(desc_mem_base, desc_mem_size);
+#endif
+out_sgdma_irq:
+	iounmap((void *) tse_priv->tx_sgdma_dev);
+out_sgdma_tx_ioremap:
+	release_mem_region(sgdma_tx_base, sgdma_tx_size);
+out_sgdma_tx:
+	iounmap((void *) tse_priv->rx_sgdma_dev);
+out_sgdma_rx_ioremap:
+	release_mem_region(sgdma_rx_base, sgdma_rx_size);
+out_sgdma_rx:
+	iounmap((void *) tse_priv->mac_dev);
+out_mac_dev_ioremap:
+	release_mem_region(mac_dev_base, mac_dev_size);
+out_mac_dev:
+	free_netdev(dev);
+	return ret;
+}
+
+static int __devexit alt_tse_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+
+	/* TODO: Release all mem regions and do iounmap, see error paths of
+	 * alt_tse_probe above */
+	platform_set_drvdata(pdev, NULL);
+	unregister_netdev(ndev);
+	free_netdev(ndev);
+
+	return 0;
+}
+
+/*******************************************************************************
+* Driver init, platform driver register
+*
+*******************************************************************************/
+static struct platform_driver alt_tse_driver = {
+	.driver = {
+		   .name = ALT_TSE_NAME,
+		   .owner = THIS_MODULE,
+		   },
+	.probe = alt_tse_probe,
+	.remove = __devexit_p(alt_tse_remove),
+	.suspend = NULL,
+	.resume = NULL,
+};
+
+static int __init atse_init(void)
+{
+	/* probe board and register */
+	return platform_driver_register(&alt_tse_driver);
+}
+
+static void __exit atse_exit(void)
+{
+	platform_driver_unregister(&alt_tse_driver);
+	printk("ALT:%s:%d:%s \n", __FILE__, __LINE__, __FUNCTION__);
+}
+
+module_init(atse_init);
+module_exit(atse_exit);
+
+MODULE_AUTHOR("Altera");
+MODULE_DESCRIPTION("Altera Triple Speed MAC IP");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/altera_tse.h b/drivers/net/altera_tse.h
new file mode 100644
index 0000000..d9d5d68
--- /dev/null
+++ b/drivers/net/altera_tse.h
@@ -0,0 +1,586 @@
+/*
+ *  linux/drivers/net/altera_tse.h
+ *
+ *  Copyright (C) 2008 Altera Corporation.
+ *  History:
+ *    o  SLS  - Linux 2.6.27-rc3
+ *
+ *
+ *  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _ALTERA_TSE_H_
+  #define _ALTERA_TSE_H_
+
+  
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <linux/module.h>
+#include <linux/crc32.h>
+#include <linux/workqueue.h>
+#include <linux/ethtool.h>
+#include <linux/fsl_devices.h>  
+
+
+#define __packed_1_    __attribute__ ((packed,aligned(1)))
+//#define REMAP_CACHED(address) ((unsigned int) address | 0x80000000)
+
+/*** Define global return types ***/
+
+#define SUCCESS             0  /* call was successfully returned */
+#define ENP_RESOURCE      -22  /* unavailable resource error */
+#define SOURCE_BUSY       -23
+
+#define ALT_TSE_NAME               "altera_tse"
+#define ALT_TSE_MDIO_NAME               "altera_tse_mdio"
+#define TSE_RESOURCE_MAC_DEV       "Altera_tse_resource_mac_dev"
+#define TSE_RESOURCE_SGDMA_RX_DEV  "Altera_tse_resource_sgdma_rx_dev"
+#define TSE_RESOURCE_SGDMA_TX_DEV  "Altera_tse_resource_sgdma_tx_dev"
+#define TSE_RESOURCE_SGDMA_RX_IRQ  "Altera_tse_resource_sgdma_rx_irq"
+#define TSE_RESOURCE_SGDMA_TX_IRQ  "Altera_tse_resource_sgdma_tx_irq"
+#define TSE_RESOURCE_FIFO_DEV      "Altera_tse_resource_fifo_dev"
+#define TSE_RESOURCE_SGDMA_DES_DEV "Altera_tse_resource_descriptor_dev"
+#define TSE_RESOURCE_SGDMA_PHY_DEV "Altera_tse_resource_sgdma_phy_dev"
+#define TSE_RESOURCE_SGDMA_PHY_IRQ "Altera_tse_resource_sgdma_phy_irq"
+
+/*** Define architecture specific parameters ***/
+
+#define MAC_UNITS                       8
+#define ALT_TSE_TOTAL_SGDMA_DESC_COUNT  128        /* Maximum number of descriptors for TX and RX*/
+#define ALT_TSE_TX_SGDMA_DESC_COUNT     64       /* Maximum number of descriptors for TX */
+#define ALT_TSE_RX_SGDMA_DESC_COUNT     64       /* Maximum number of descriptors for RX*/
+#define ALT_TSE_TOTAL_SGDMA_DESC_SIZE   (ALT_TSE_TOTAL_SGDMA_DESC_COUNT*0x20)
+#define ALT_TX_RING_MOD_MASK 		ALT_TSE_TX_SGDMA_DESC_COUNT - 1
+#define ALT_RX_RING_MOD_MASK		ALT_TSE_RX_SGDMA_DESC_COUNT - 1
+
+
+#define ALIGNED_BYTES                        2
+
+#define ALT_TSE_TX_RX_FIFO_DEPTH             1024     //for 4096 for 3C120
+
+/* define Mac address */
+
+#define  MAC_0_OCTET 0x00
+#define  MAC_1_OCTET 0x07
+#define  MAC_2_OCTET 0x11
+#define  MAC_3_OCTET 0x01
+#define  MAC_4_OCTET 0x02
+#define  MAC_5_OCTET 0x03
+
+// /* Stop compile if nios2.h is not generated with the Altera TSE-SGDMA FPGA design */
+// #ifndef na_tse_mac_control_port
+  // #error "@This build has not been configured with Altera example design of TSE-SGDMA."
+  // #error "@You need to unselect ATSE Ethernet driver with make menuconfig or use proper system"
+  // #error "@If your system contains different name then You need to fill following structure as "
+  // #error "@components name declared in nios2.h "
+// #endif
+
+/************************************************************************/
+/*                                                                      */
+/* Altera Triple Speed Ethernet MAC IP related definitions              */
+/*                                                                      */
+/************************************************************************/
+
+#define ENABLE_PHY_LOOPBACK                  0       /* set 1 for enable loopback*/
+
+#define ALT_TSE_MAX_FRAME_LENGTH             1518    /* maximum length for RX and TX packets */
+
+#define ALT_TSE_MAC_FIFO_WIDTH               4        /* TX/RX FIFO width in bytes */
+
+#define ALT_TSE_DEFAULT_DUPLEX_MODE          1
+#define ALT_TSE_DEFAULT_SPEED                1
+
+#define ALT_TSE_SW_RESET_WATCHDOG_CNTR       10000
+#define ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR     5000000
+#define ALT_AUTONEG_TIMEOUT_THRESHOLD        250000
+#define ALT_CHECKLINK_TIMEOUT_THRESHOLD      1000000
+#define ALT_NOMDIO_TIMEOUT_THRESHOLD         1000000
+#define ALT_DISGIGA_TIMEOUT_THRESHOLD        5000000
+#define ALT_ALARM_TIMEOUT_THRESHOLD          0xFFFFFFFF
+
+/* Command_Config Register Bit Definitions */
+
+typedef volatile union __alt_tse_command_config {
+  unsigned int image;
+  struct {
+    unsigned int  transmit_enable         :1, /* bit 0     enables transmit datapath */
+                  receive_enable          :1, /* bit 1     enables receive datapath */
+                  pause_frame_xon_gen     :1, /* bit 2     generates a pause frame with pause quanta 0*/
+                  ethernet_speed          :1, /* bit 3     speed control for MAC :10/100/1000 Mb*/
+                  promiscuous_enable      :1, /* bit 4     enables mac promiscuous operation */
+                  pad_enable              :1, /* bit 5     removes pad field from received frame */
+                  crc_forward             :1, /* bit 6     removes/forwards CRC field from received frame before forwarding it to application */
+                  pause_frame_forward     :1, /* bit 7     terminates or forwards pause frame*/
+                  pause_frame_ignore      :1, /* bit 8     ignore pause frame quanta */
+                  set_mac_address_on_tx   :1, /* bit 9     overwrite source MAC address in transmit frame as per setting in MAC core*/
+                  halfduplex_enable       :1, /* bit 10    enable half duplex mode */
+                  excessive_collision     :1, /* bit 11    discard frame after detecting collision on 16 consecutive retransmit ions */
+                  late_collision          :1, /* bit 12    detects a collision after 64 bytes are transmitted, and discards the frame*/
+                  software_reset          :1, /* bit 13    disable the transmit and receive logic, flush the receive FIFO, and reset the statistics counters.*/
+                  multicast_hash_mode_sel :1, /* bit 14    select multicasts address-resolution hash-code mode.*/
+                  loopback_enable         :1, /* bit 15    enables a loopback.*/
+                  src_mac_addr_sel_on_tx  :3, /* bit 18:16 determines which address the MAC function selects to overwrite the source MAC address*/
+                  magic_packet_detect     :1, /* bit 19    Enable magic packet detection or Wake-on-LAN*/
+                  sleep_mode_enable       :1, /* bit 20    1 puts the MAC function into sleep mode*/
+                  wake_up_request         :1, /* bit 21    indicate node wake up request */
+                  pause_frame_xoff_gen    :1, /* bit 22    generate a pause frame with the pause quanta set to the value configured in the pause_quant register*/
+                  control_frame_enable    :1, /* bit 23    enable to accept and forward MAC control frame*/
+                  payload_len_chk_disable :1, /* bit 24    check the actual payload length of received frames against the length field in the received frames*/
+                  enable_10mbps_intf      :1, /* bit 25    enables the 10Mbps interface*/
+                  rx_error_discard_enable :1, /* bit 26    discards erroneous frames received*/
+                  reserved_bits           :4, /* bit 30:27 reserve   */
+                  self_clear_counter_reset:1; /* bit 31    clears the statistics counters*/
+  } __packed_1_ bits;
+}__packed_1_ alt_tse_command_config;
+
+
+#define ALTERA_TSE_CMD_TX_ENA_MSK           (0x00000001)
+#define ALTERA_TSE_CMD_RX_ENA_MSK           (0x00000002)
+#define ALTERA_TSE_CMD_XON_GEN_MSK          (0x00000004)
+#define ALTERA_TSE_CMD_ETH_SPEED_MSK        (0x00000008)
+#define ALTERA_TSE_CMD_PROMIS_EN_MSK        (0x00000010)
+#define ALTERA_TSE_CMD_PAD_EN_MSK           (0x00000020)
+#define ALTERA_TSE_CMD_CRC_FWD_MSK          (0x00000040)
+#define ALTERA_TSE_CMD_PAUSE_FWD_MSK        (0x00000080)
+#define ALTERA_TSE_CMD_PAUSE_IGNORE_MSK     (0x00000100)
+#define ALTERA_TSE_CMD_TX_ADDR_INS_MSK      (0x00000200)
+#define ALTERA_TSE_CMD_HD_ENA_MSK           (0x00000400)
+#define ALTERA_TSE_CMD_EXCESS_COL_MSK       (0x00000800)
+#define ALTERA_TSE_CMD_LATE_COL_MSK         (0x00001000)
+#define ALTERA_TSE_CMD_SW_RESET_MSK         (0x00002000)
+#define ALTERA_TSE_CMD_MHASH_SEL_MSK        (0x00004000)
+#define ALTERA_TSE_CMD_LOOPBACK_MSK         (0x00008000)
+/* Bits (18:16) = address select */
+#define ALTERA_TSE_CMD_TX_ADDR_SEL_MSK      (0x00070000)
+#define ALTERA_TSE_CMD_MAGIC_ENA_MSK        (0x00080000)
+#define ALTERA_TSE_CMD_SLEEP_MSK            (0x00100000)
+#define ALTERA_TSE_CMD_WAKEUP_MSK           (0x00200000)
+#define ALTERA_TSE_CMD_XOFF_GEN_MSK         (0x00400000)
+#define ALTERA_TSE_CMD_CNTL_FRM_ENA_MSK     (0x00800000)
+#define ALTERA_TSE_CMD_NO_LENGTH_CHECK_MSK  (0x01000000)
+#define ALTERA_TSE_CMD_ENA_10_MSK           (0x02000000)
+#define ALTERA_TSE_CMD_RX_ERR_DISC_MSK      (0x04000000)
+/* Bits (30..27) reserved */
+#define ALTERA_TSE_CMD_CNT_RESET_MSK        (0x80000000)
+
+/* Tx_Cmd_Stat Register Bit Definitions */
+
+typedef volatile union __alt_tse_tx_cmd_stat {
+  unsigned int image;
+  struct {
+    unsigned int  reserved_lsbs  :17,  /* bit 16:0  */
+                  omit_crc       :1,   /* bit 17    enable or disable to calculate and append the CRC to the frame in MAC */
+                  tx_shift16     :1,   /* bit 18    remove the first two bytes from the frame before transmitting it for excepting 32 bits word aligned frames*/
+                  reserved_msbs  :13;  /* bit 31:19 */
+
+  }__packed_1_ bits;
+} alt_tse_tx_cmd_stat;
+#define ALTERA_TSE_TX_CMD_STAT_TX_SHIFT16   (0x00040000)
+#define ALTERA_TSE_TX_CMD_STAT_OMIT_CRC     (0x00020000)
+
+/* Rx_Cmd_Stat Register Bit Definitions */
+
+typedef volatile union __alt_tse_rx_cmd_stat {
+  unsigned int image;
+  struct {
+    unsigned int  reserved_lsbs  :25,  /* bit 24:0  */
+                  rx_shift16     :1,   /* bit 25    shifts the beginning of the packet to the right by 2 bytes and inserts zeros in the empty bytes to word align the packet*/
+                  reserved_msbs  :6;   /* bit 31:26 */
+
+  }__packed_1_ bits;
+} alt_tse_rx_cmd_stat;
+#define ALTERA_TSE_RX_CMD_STAT_RX_SHIFT16   (0x02000000)
+
+/* MDIO registers within MAC register Space */
+
+struct alt_tse_mdio{
+  unsigned int control;                       /*PHY device operation control register*/
+  unsigned int status;                        /*PHY device operation status register*/
+  unsigned int phy_id1;                       /*Bits 31:16 of PHY identifier.*/
+  unsigned int phy_id2;                       /*Bits 15:0 of PHY identifier.*/
+  unsigned int auto_negotiation_advertisement;/*Auto-negotiation advertisement register.*/
+  unsigned int remote_partner_base_page_ability;
+
+  unsigned int reg6;
+  unsigned int reg7;
+  unsigned int reg8;
+  unsigned int reg9;
+  unsigned int rega;
+  unsigned int regb;
+  unsigned int regc;
+  unsigned int regd;
+  unsigned int rege;
+  unsigned int regf;
+  unsigned int reg10;
+  unsigned int reg11;
+  unsigned int reg12;
+  unsigned int reg13;
+  unsigned int reg14;
+  unsigned int reg15;
+  unsigned int reg16;
+  unsigned int reg17;
+  unsigned int reg18;
+  unsigned int reg19;
+  unsigned int reg1a;
+  unsigned int reg1b;
+  unsigned int reg1c;
+  unsigned int reg1d;
+  unsigned int reg1e;
+  unsigned int reg1f;
+
+} ;
+
+
+
+/* MAC register Space */
+
+typedef volatile struct {
+  unsigned int            megacore_revision;              /* Bits 15:0: MegaCore function revision (0x0800). Bit 31:16: Customer specific revision*/
+  unsigned int            scratch_pad;                    /*Provides a memory location for user applications to test the device memory operation.*/
+  alt_tse_command_config  command_config;                 /*The host processor uses this register to control and configure the MAC block.*/
+  unsigned int            mac_addr_0;                     /*32-bit primary MAC address word 0 bits 0 to 31 of the primary MAC address.*/
+  unsigned int            mac_addr_1;                     /*32-bit primary MAC address word 1 bits 32 to 47 of the primary MAC address.*/
+  unsigned int            max_frame_length;               /*14-bit maximum frame length. The MAC receive logic*/
+  unsigned int            pause_quanta;                   /*The pause quanta is used in each pause frame sent to a remote Ethernet device, in increments of 512 Ethernet bit times.*/
+  unsigned int            rx_sel_empty_threshold;         /*12-bit receive FIFO section-empty threshold.*/
+  unsigned int            rx_sel_full_threshold;          /*12-bit receive FIFO section-full threshold*/
+  unsigned int            tx_sel_empty_threshold;         /*12-bit transmit FIFO section-empty threshold.*/
+  unsigned int            tx_sel_full_threshold;          /*12-bit transmit FIFO section-full threshold.*/
+  unsigned int            rx_almost_empty_threshold;      /*12-bit receive FIFO almost-empty threshold*/
+  unsigned int            rx_almost_full_threshold;       /*12-bit receive FIFO almost-full threshold.*/
+  unsigned int            tx_almost_empty_threshold;      /*12-bit transmit FIFO almost-empty threshold*/
+  unsigned int            tx_almost_full_threshold;       /*12-bit transmit FIFO almost-full threshold*/
+  unsigned int            mdio_phy0_addr;                 /*MDIO address of PHY Device 0. Bits 0 to 4 hold a 5-bit PHY address.*/
+  unsigned int            mdio_phy1_addr;                 /*MDIO address of PHY Device 1. Bits 0 to 4 hold a 5-bit PHY address.*/
+
+  /* only if 100/1000 BaseX PCS, reserved otherwise*/
+  unsigned int            reservedx44[5];
+
+  unsigned int            reg_read_access_status;         /*This register is used to check the correct completion of register read access*/
+  unsigned int            min_tx_ipg_length;              /*Minimum IPG between consecutive transmit frame in terms of bytes */
+
+ /* IEEE 802.3 oEntity Managed Object Support */
+  unsigned int            aMACID_1;                       /*The MAC addresses*/
+  unsigned int            aMACID_2;
+  unsigned int            aFramesTransmittedOK;           /*Number of frames transmitted without error including pause frames.*/
+  unsigned int            aFramesReceivedOK;              /*Number of frames received without error including pause frames.*/
+  unsigned int            aFramesCheckSequenceErrors;     /*Number of frames received with a CRC error.*/
+  unsigned int            aAlignmentErrors;               /*Frame received with an alignment error.*/
+  unsigned int            aOctetsTransmittedOK;           /*Sum of payload and padding octets of frames transmitted without error.*/
+  unsigned int            aOctetsReceivedOK;              /*Sum of payload and padding octets of frames received without error.*/
+
+  /* IEEE 802.3 oPausedEntity Managed Object Support */
+  unsigned int            aTxPAUSEMACCtrlFrames;          /*Number of transmitted pause frames.*/
+  unsigned int            aRxPAUSEMACCtrlFrames;          /*Number of Received pause frames.*/
+
+ /* IETF MIB (MIB-II) Object Support */
+  unsigned int            ifInErrors;                     /*Number of frames received with error*/
+  unsigned int            ifOutErrors;                    /*Number of frames transmitted with error*/
+  unsigned int            ifInUcastPkts;                  /*Number of valid received unicast frames.*/
+  unsigned int            ifInMulticastPkts;              /*Number of valid received multicasts frames (without pause).*/
+  unsigned int            ifInBroadcastPkts;              /*Number of valid received broadcast frames.*/
+  unsigned int            ifOutDiscards;
+  unsigned int            ifOutUcastPkts;                                             
+  unsigned int            ifOutMulticastPkts;
+  unsigned int            ifOutBroadcastPkts;
+
+  /* IETF RMON MIB Object Support */
+  unsigned int            etherStatsDropEvent;           /*Counts the number of dropped packets due to internal errors of the MAC client.*/
+  unsigned int            etherStatsOctets;              /*Total number of bytes received. Good and bad frames.*/
+  unsigned int            etherStatsPkts;                /*Total number of packets received. Counts good and bad packets.*/
+  unsigned int            etherStatsUndersizePkts;       /*Number of packets received with less than 64 bytes.*/
+  unsigned int            etherStatsOversizePkts;        /*Number of each well-formed packet that exceeds the valid maximum programmed frame length*/
+  unsigned int            etherStatsPkts64Octets;        /*Number of received packet with 64 bytes*/
+  unsigned int            etherStatsPkts65to127Octets;   /*Frames (good and bad) with 65 to 127 bytes*/
+  unsigned int            etherStatsPkts128to255Octets;  /*Frames (good and bad) with 128 to 255 bytes*/
+  unsigned int            etherStatsPkts256to511Octets;  /*Frames (good and bad) with 256 to 511 bytes*/
+  unsigned int            etherStatsPkts512to1023Octets; /*Frames (good and bad) with 512 to 1023 bytes*/
+  unsigned int            etherStatsPkts1024to1518Octets;/*Frames (good and bad) with 1024 to 1518 bytes*/
+
+  unsigned int            etherStatsPkts1519toXOctets;   /*Any frame length from 1519 to the maximum length configured in the frm_length register, if it is greater than 1518.*/
+  unsigned int            etherStatsJabbers;             /*Too long frames with CRC error.*/
+  unsigned int            etherStatsFragments;           /*Too short frames with CRC error.*/
+
+  unsigned int            reservedxE4;
+
+  /*FIFO control register.*/
+  alt_tse_tx_cmd_stat     tx_cmd_stat;
+  alt_tse_rx_cmd_stat     rx_cmd_stat;
+
+  unsigned int            ipaccTxConf;                    // TX configuration
+  unsigned int            ipaccRxConf;                    // RX configuration
+  unsigned int            ipaccRxStat;                    // IP status
+  unsigned int            ipaccRxStatSum;                 // current frame's IP payload sum result
+
+  /*Multicast address resolution table, mapped in the controller address space.*/
+  unsigned int            hash_table[64];
+
+  /*Registers 0 to 31 within PHY device 0/1 connected to the MDIO PHY management interface.*/
+  struct alt_tse_mdio     mdio_phy0;
+  struct alt_tse_mdio     mdio_phy1;
+
+  /*4 Supplemental MAC Addresses*/
+  unsigned int            supp_mac_addr_0_0;
+  unsigned int            supp_mac_addr_0_1;
+  unsigned int            supp_mac_addr_1_0;
+  unsigned int            supp_mac_addr_1_1;
+  unsigned int            supp_mac_addr_2_0;
+  unsigned int            supp_mac_addr_2_1;
+  unsigned int            supp_mac_addr_3_0;
+  unsigned int            supp_mac_addr_3_1;
+
+  unsigned int            reservedx320[56];
+} alt_tse_mac;
+
+
+
+/* TSE Setup info mainly for phy, but need to also report supported TSE modes */
+struct alt_tse_config {
+	unsigned int mii_id;			//id for mii bus, pdev->id
+	unsigned int phy_addr;			//phy's mdio address
+	unsigned int tse_supported_modes;	//supported modes for the TSE as defined in phy.h
+	phy_interface_t interface;		//Physical insterface MII/RMII/RGMII/SGMII
+	unsigned int flags;			//flags to pass to the phy config functions
+	int autoneg;
+	int speed;
+	int duplex;
+	int rx_fifo_depth;
+	int tx_fifo_depth;
+	char ethaddr[6];
+};
+	
+
+/*
+* This structure is private to each device. It is used to pass
+* packets in and out, so there is place for a packet
+*/
+struct alt_tse_private {
+	struct net_device_stats status;
+	struct net_device *dev;
+
+/* NAPI struct for NAPI interface */
+	struct napi_struct napi;
+	                           
+	alt_tse_mac *mac_dev;
+
+	volatile struct alt_sgdma_registers *rx_sgdma_dev;
+	volatile struct alt_sgdma_registers *tx_sgdma_dev;
+
+	struct alt_tse_phy_profile *pphy_profile;
+	unsigned int phy_address;
+
+	unsigned int tx_fifo_interrupt;
+	unsigned int rx_fifo_interrupt;
+	unsigned char tx_shift_16_ok;
+	unsigned char rx_shift_16_ok;
+	unsigned char last_tx_shift_16;
+	unsigned char last_rx_shift_16;
+	
+	unsigned int desc_mem_base;	/* Base address of Descriptor Memory if ext_desc_mem = 1 */
+	unsigned int chain_loop;
+
+	unsigned int tse_tx_depth;	/* TX Receive FIFO depth                                 */
+	unsigned int tse_rx_depth;	/* RX Receive FIFO depth                                 */
+
+// Location for the SGDMA Descriptors
+	volatile struct alt_sgdma_descriptor *desc;
+	volatile struct alt_sgdma_descriptor *sgdma_rx_desc;
+	volatile struct alt_sgdma_descriptor *sgdma_tx_desc;
+
+	volatile struct alt_sgdma_descriptor *desc_pointer;
+
+	unsigned int current_mtu;
+	
+	unsigned int rx_sgdma_imask;
+	unsigned int tx_sgdma_imask;
+	
+	unsigned int rx_sgdma_descriptor_tail;
+	unsigned int rx_sgdma_descriptor_head;
+
+	//unsigned int tse_tx_sgdma_cur;
+	unsigned int tx_sgdma_descriptor_tail;
+	unsigned int tx_sgdma_descriptor_head;
+
+	struct sk_buff *rx_skb[ALT_TSE_RX_SGDMA_DESC_COUNT];
+	struct sk_buff *tx_skb[ALT_TSE_TX_SGDMA_DESC_COUNT];
+	
+/* Tasklets for handling hardware IRQ related operations outside hw IRQ handler */
+//	struct tasklet_struct tse_rx_tasklet;
+	spinlock_t rx_lock;
+	spinlock_t tx_lock;
+
+/* system info */
+	struct phy_device *phydev;
+	struct mii_bus *mii_bus;
+	int oldspeed;
+	int oldduplex;
+	int oldlink;
+	
+/*	unsigned int link_status;
+	unsigned int speed;
+	unsigned int duplex;
+	unsigned int phy_speed;
+	unsigned int phy_duplex;
+	unsigned int antoneg_enable;
+*/
+
+	struct alt_tse_config *tse_config;
+	
+/*link info */
+//	unsigned int alarm_irq;
+//	struct timer_reg *alarm_link_check;
+	unsigned int tse_up;
+	
+	uint32_t msg_enable;
+
+};
+
+/*----------------------------------------------------------------------*/
+
+
+/************************************************************************/
+/*                                                                      */
+/* Altera SG-DMA related definitions                                    */
+/*                                                                      */
+/************************************************************************/
+
+
+
+#define ALT_SGDMA_STATUS_ERROR_MSK                            (0x00000001)
+#define ALT_SGDMA_STATUS_EOP_ENCOUNTERED_MSK                  (0x00000002)
+#define ALT_SGDMA_STATUS_DESC_COMPLETED_MSK                   (0x00000004)
+#define ALT_SGDMA_STATUS_CHAIN_COMPLETED_MSK                  (0x00000008)
+#define ALT_SGDMA_STATUS_BUSY_MSK                             (0x00000010)
+
+#define ALT_SGDMA_CONTROL_IE_ERROR_MSK                        (0x00000001)
+#define ALT_SGDMA_CONTROL_IE_EOP_ENCOUNTERED_MSK              (0x00000002)
+#define ALT_SGDMA_CONTROL_IE_DESC_COMPLETED_MSK               (0x00000004)
+#define ALT_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK              (0x00000008)
+#define ALT_SGDMA_CONTROL_IE_GLOBAL_MSK                       (0x00000010)
+#define ALT_SGDMA_CONTROL_RUN_MSK                             (0x00000020)
+#define ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK                     (0x00000040)
+#define ALT_SGDMA_CONTROL_IE_MAX_DESC_PROCESSED_MSK           (0x00000080)
+#define ALT_SGDMA_CONTROL_MAX_DESC_PROCESSED_MSK              (0x0000FF00)
+#define ALT_SGDMA_CONTROL_SOFTWARERESET_MSK                   (0x00010000)
+#define ALT_SGDMA_CONTROL_PARK_MSK                            (0x00020000)
+#define ALT_SGDMA_CONTROL_CLEAR_INTERRUPT_MSK                 (0x80000000)
+
+#define ALTERA_TSE_SGDMA_INTR_MASK  ( ALT_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK \
+                                    | ALT_SGDMA_STATUS_DESC_COMPLETED_MSK      \
+                                    | ALT_SGDMA_CONTROL_IE_GLOBAL_MSK )
+
+/*
+ * Buffer Descriptor data structure
+ *
+ * The SGDMA controller buffer descriptor allocates
+ * 64 bits for each address. To support ANSI C, the
+ * struct implementing a descriptor places 32-bits
+ * of padding directly above each address; each pad must
+ * be cleared when initializing a descriptor.
+ */
+struct alt_sgdma_descriptor{
+  unsigned int     *source;                 /*Specifies the address of data to be read.*/
+  unsigned int     source_pad;
+
+  unsigned int     *destination;            /*Specifies the address to which data should be written.*/
+  unsigned int     destination_pad;
+
+  unsigned int     *next;                   /*Specifies the next descriptor in the linked list.*/
+  unsigned int     next_pad;
+
+  unsigned short   bytes_to_transfer;       /*Specifies the number of bytes to transfer*/
+  unsigned char    read_burst;
+  unsigned char    write_burst;
+
+  unsigned short   actual_bytes_transferred;/*Specifies the number of bytes that are successfully transferred by the DMA hardware*/
+  unsigned char    descriptor_status;
+  unsigned char    descriptor_control;
+
+}__packed_1_;
+
+
+/*
+ * Descriptor control bit masks & offsets
+ *
+ * Note: The control byte physically occupies bits [31:24] in memory.
+ *       The following bit-offsets are expressed relative to the LSB of
+ *       the control register bitfield.
+ */
+#define ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK         (0x00000001)
+#define ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK   (0x00000002)
+#define ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK  (0x00000004)
+#define ALT_SGDMA_DESCRIPTOR_CONTROL_ATLANTIC_CHANNEL_MSK     (0x00000008)
+#define ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK          (0x00000080)
+
+/*
+ * Descriptor status bit masks & offsets
+ *
+ * Note: The status byte physically occupies bits [23:16] in memory.
+ *       The following bit-offsets are expressed relative to the LSB of
+ *       the status register bitfield.
+ */
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_CRC_MSK                 (0x00000001)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_PARITY_MSK              (0x00000002)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_OVERFLOW_MSK            (0x00000004)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_SYNC_MSK                (0x00000008)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_UEOP_MSK                (0x00000010)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_MEOP_MSK                (0x00000020)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_MSOP_MSK                (0x00000040)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK     (0x00000080)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_ERROR_MSK                 (0x0000007F)
+
+/* SG-DMA Control/Status Slave registers map */
+
+struct alt_sgdma_registers {
+  unsigned int      status;
+  unsigned int      status_pad[3];
+  unsigned int      control;
+  unsigned int      control_pad[3];
+//  struct alt_sgdma_descriptor      *next_descriptor_pointer;
+  unsigned int      next_descriptor_pointer;
+  unsigned int      descriptor_pad[3];
+};
+
+/*----------------------------------------------------------------------*/
+//MDIO stuff
+
+struct alt_tse_mdio_private {
+	int irq[32];
+};
+
+extern void tse_set_ethtool_ops(struct net_device *netdev);
+
+#endif /* _ALTERA_TSE_H_ */
diff --git a/drivers/net/altera_tse_ethtool.c b/drivers/net/altera_tse_ethtool.c
new file mode 100644
index 0000000..7121844
--- /dev/null
+++ b/drivers/net/altera_tse_ethtool.c
@@ -0,0 +1,255 @@
+                   
+/*******************************************************************************
+*  linux/drivers/net/altera_tse_ethtool.c
+*
+* Copyright (C) 2008 Altera Corporation.
+*
+* History:
+*    o  SLS  - Linux 2.6.27
+*
+*  All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+* NON INFRINGEMENT.  See the GNU General Public License for more
+* details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*                                                                       
+*******************************************************************************/       
+
+#include <linux/module.h>	/* for module-version */
+#include <linux/kernel.h>	/* printk(), and other useful stuff */
+#include <linux/sched.h>	/* for jiffies, HZ, etc. */
+#include <linux/string.h>	/* inline memset(), etc. */
+#include <linux/ptrace.h>
+#include <linux/errno.h>	/* return codes */
+#include <linux/ioport.h>	/* request_region(), release_region() */
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/inet.h>                                                        
+#include <linux/netdevice.h>	/* struct device, and other headers */
+#include <linux/etherdevice.h>	/* eth_type_trans */
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/init.h>		/* __init (when not using as a module) */
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include <linux/pm.h>		/* pm_message_t */
+#include <linux/platform_device.h>
+
+#include <asm/irq.h>		/* For NR_IRQS only. */
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/cacheflush.h>
+
+#include <asm/processor.h>	/* Processor type for cache alignment. */
+#include <asm/bitops.h>
+#include <asm/io.h>		/* I/O functions */
+#include <asm/uaccess.h>	/* User space memory access functions */
+
+#include "altera_tse.h"    
+
+
+static void tse_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
+static uint32_t tse_get_msglevel(struct net_device *dev);
+static void tse_set_msglevel(struct net_device *dev, uint32_t data);
+static int tse_reglen(struct net_device *dev);
+static void tse_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf);
+static int tse_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
+static int tse_set_settings(struct net_device *dev, struct ethtool_cmd *cmd);
+
+#define TSE_STATS_LEN 35
+
+static char stat_gstrings[][ETH_GSTRING_LEN] = {
+	"aFramesTransmittedOK",
+	"aFramesReceivedOK",  
+	"aFramesCheckSequenceErrors",
+	"aAlignmentErrors",          
+	"aOctetsTransmittedOK",      
+	"aOctetsReceivedOK",         
+	"aTxPAUSEMACCtrlFrames",
+	"aRxPAUSEMACCtrlFrames",
+	"ifInErrors",       
+	"ifOutErrors",      
+	"ifInUcastPkts",    
+	"ifInMulticastPkts",
+	"ifInBroadcastPkts",
+	"ifOutDiscards",                       
+	"ifOutUcastPkts",
+	"ifOutMulticastPkts",
+	"ifOutBroadcastPkts",
+	"etherStatsDropEvent",          
+	"etherStatsOctets",             
+	"etherStatsPkts",               
+	"etherStatsUndersizePkts",      
+	"etherStatsOversizePkts",       
+	"etherStatsPkts64Octets",       
+	"etherStatsPkts65to127Octets",  
+	"etherStatsPkts128to255Octets", 
+	"etherStatsPkts256to511Octets", 
+	"etherStatsPkts512to1023Octets",
+	"etherStatsPkts1024to1518Octets",
+	"etherStatsPkts1519toXOctets",  
+	"etherStatsJabbers",            
+	"etherStatsFragments",          
+	"ipaccTxConf",  
+	"ipaccRxConf",  
+	"ipaccRxStat",  
+	"ipaccRxStatSum",   
+};                                    
+
+
+/* Ethtool support... */
+
+static void tse_get_drvinfo(struct net_device *dev,
+			    struct ethtool_drvinfo *info)
+{
+	strcpy(info->driver, "Altera Triple Speed MAC IP Driver");
+	strcpy(info->version, "v 8.0");
+	sprintf(info->bus_info, "AVALON");
+//	PRINTK1("Drvinfo :Drv=%s ,version=%s,bus=%s\n", info->driver,
+//		info->version, info->bus_info);
+}
+   
+/* Fill in a buffer with the strings which correspond to the
+ * stats */
+static void tse_gstrings(struct net_device *dev, u32 stringset, u8 * buf)
+{
+        
+	memcpy(buf, stat_gstrings, TSE_STATS_LEN * ETH_GSTRING_LEN);
+	
+}
+
+static void tse_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	
+	buf[0] = (u64) tse_priv->mac_dev->aFramesTransmittedOK;
+	buf[1] = (u64) tse_priv->mac_dev->aFramesReceivedOK;  
+	buf[2] = (u64) tse_priv->mac_dev->aFramesCheckSequenceErrors;
+	buf[3] = (u64) tse_priv->mac_dev->aAlignmentErrors;          
+	buf[4] = (u64) tse_priv->mac_dev->aOctetsTransmittedOK;      
+	buf[5] = (u64) tse_priv->mac_dev->aOctetsReceivedOK;         
+	buf[6] = (u64) tse_priv->mac_dev->aTxPAUSEMACCtrlFrames;
+	buf[7] = (u64) tse_priv->mac_dev->aRxPAUSEMACCtrlFrames;
+	buf[8] = (u64) tse_priv->mac_dev->ifInErrors;       
+	buf[9] = (u64) tse_priv->mac_dev->ifOutErrors;      
+	buf[10] = (u64) tse_priv->mac_dev->ifInUcastPkts;    
+	buf[11] = (u64) tse_priv->mac_dev->ifInMulticastPkts;
+	buf[12] = (u64) tse_priv->mac_dev->ifInBroadcastPkts;
+	buf[13] = (u64) tse_priv->mac_dev->ifOutDiscards;                       
+	buf[14] = (u64) tse_priv->mac_dev->ifOutUcastPkts;
+	buf[15] = (u64) tse_priv->mac_dev->ifOutMulticastPkts;
+	buf[16] = (u64) tse_priv->mac_dev->ifOutBroadcastPkts;
+	buf[17] = (u64) tse_priv->mac_dev->etherStatsDropEvent;          
+	buf[18] = (u64) tse_priv->mac_dev->etherStatsOctets;             
+	buf[19] = (u64) tse_priv->mac_dev->etherStatsPkts;               
+	buf[20] = (u64) tse_priv->mac_dev->etherStatsUndersizePkts;      
+	buf[21] = (u64) tse_priv->mac_dev->etherStatsOversizePkts;       
+	buf[22] = (u64) tse_priv->mac_dev->etherStatsPkts64Octets;       
+	buf[23] = (u64) tse_priv->mac_dev->etherStatsPkts65to127Octets;  
+	buf[24] = (u64) tse_priv->mac_dev->etherStatsPkts128to255Octets; 
+	buf[25] = (u64) tse_priv->mac_dev->etherStatsPkts256to511Octets; 
+	buf[26] = (u64) tse_priv->mac_dev->etherStatsPkts512to1023Octets;
+	buf[27] = (u64) tse_priv->mac_dev->etherStatsPkts1024to1518Octets;
+	buf[28] = (u64) tse_priv->mac_dev->etherStatsPkts1519toXOctets;  
+	buf[29] = (u64) tse_priv->mac_dev->etherStatsJabbers;            
+	buf[30] = (u64) tse_priv->mac_dev->etherStatsFragments;          
+	buf[31] = (u64) tse_priv->mac_dev->ipaccTxConf;  
+	buf[32] = (u64) tse_priv->mac_dev->ipaccRxConf;  
+	buf[33] = (u64) tse_priv->mac_dev->ipaccRxStat;  
+	buf[34] = (u64) tse_priv->mac_dev->ipaccRxStatSum;  	
+}
+
+static int tse_sset_count(struct net_device *dev, int sset)
+{                               
+
+	switch (sset) {
+	case ETH_SS_STATS:
+		return TSE_STATS_LEN;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+
+
+static uint32_t tse_get_msglevel(struct net_device *dev)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	return tse_priv->msg_enable;
+}
+
+static void tse_set_msglevel(struct net_device *dev, uint32_t data)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	tse_priv->msg_enable = data;
+}
+
+
+static int tse_reglen(struct net_device *dev)
+{
+	return sizeof (struct alt_tse_private);
+}
+
+static void tse_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
+{
+	int i;
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	u32 *tse_mac_regs = (u32 *) tse_priv;
+	u32 *buf = (u32 *) regbuf;
+
+	for (i = 0; i < sizeof (struct alt_tse_private) / sizeof (u32); i++)
+		buf[i] = tse_mac_regs[i];
+}
+
+static int tse_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	struct phy_device *phydev = tse_priv->phydev;
+	
+	if (NULL == phydev)                                              
+		return -ENODEV;
+
+	return phy_ethtool_gset(phydev, cmd);
+}
+
+static int tse_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct alt_tse_private *tse_priv = netdev_priv(dev);
+	struct phy_device *phydev = tse_priv->phydev;
+
+	if (NULL == phydev)
+		return -ENODEV;
+
+	return phy_ethtool_sset(phydev, cmd);
+}
+
+static const struct ethtool_ops tse_ethtool_ops = {
+	.get_drvinfo = tse_get_drvinfo,
+	.get_regs_len = tse_reglen,
+	.get_regs = tse_get_regs,
+	.get_link = ethtool_op_get_link,
+	.get_settings = tse_get_settings,
+	.set_settings = tse_set_settings,
+	.get_strings = tse_gstrings,
+	.get_sset_count = tse_sset_count,
+	.get_ethtool_stats = tse_fill_stats,
+	.get_msglevel = tse_get_msglevel,
+	.set_msglevel = tse_set_msglevel,
+};
+
+void tse_set_ethtool_ops(struct net_device *netdev)
+{
+	SET_ETHTOOL_OPS(netdev, &tse_ethtool_ops);
+}
diff --git a/drivers/net/altera_tse_mdio.c b/drivers/net/altera_tse_mdio.c
new file mode 100644
index 0000000..0f57776
--- /dev/null
+++ b/drivers/net/altera_tse_mdio.c
@@ -0,0 +1,223 @@
+
+/*
+*  linux/drivers/net/altera_tse_mdio.c
+*
+* Copyright (C) 2008 Altera Corporation.
+*
+* History:
+*    o  SLS  - Linux 2.6.27
+*
+*  All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+* NON INFRINGEMENT.  See the GNU General Public License for more
+* details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*/
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include "altera_tse.h"
+
+static int tse_mdio_reset(struct mii_bus *bus)
+{
+	/* No TSE MDIO Reset */
+	return 0;
+}
+
+static int tse_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+	alt_tse_mac *mac_dev;
+	unsigned int *mdio_regs;
+	unsigned int data;
+	u16 value;
+
+	mac_dev = (alt_tse_mac *) bus->priv;
+
+	/* set mdio address */
+	mac_dev->mdio_phy0_addr = mii_id;
+	mdio_regs = (unsigned int *) &mac_dev->mdio_phy0;
+
+	/* get the data */
+	data = mdio_regs[regnum];
+
+	value = data & 0xffff;
+
+	return value;
+}
+
+static int tse_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
+{
+	alt_tse_mac *mac_dev;
+	unsigned int *mdio_regs;
+	unsigned int data;
+
+	mac_dev = (alt_tse_mac *) bus->priv;
+
+	/* set mdio address */
+	mac_dev->mdio_phy0_addr = mii_id;
+	mdio_regs = (unsigned int *) &mac_dev->mdio_phy0;
+
+	/* get the data */
+	data = (unsigned int) value;
+
+	mdio_regs[regnum] = data;
+
+	return 0;
+}
+
+static int tse_mdio_probe(struct platform_device *pdev)
+{
+	struct mii_bus *new_bus;
+	struct resource *res_alt_tse;
+	int ret = -ENODEV;
+	int i;
+	alt_tse_mac *mac_dev;
+	struct alt_tse_mdio_private *tse_mdio_priv;
+
+	if (NULL == pdev)
+		return -EINVAL;
+
+	new_bus = mdiobus_alloc();
+
+	if (NULL == new_bus)
+		return -ENOMEM;
+
+	tse_mdio_priv = (struct alt_tse_mdio_private *) pdev->dev.platform_data;
+
+	new_bus->name = "Altera TSE MII Bus",
+	new_bus->read = &tse_mdio_read,
+	new_bus->write = &tse_mdio_write,
+	new_bus->reset = &tse_mdio_reset,
+	snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id);
+
+	printk(KERN_INFO "%s : New Bus ID\n",new_bus->id);
+
+	res_alt_tse =
+		platform_get_resource_byname(pdev, IORESOURCE_MEM,
+					 TSE_RESOURCE_MAC_DEV);
+	if (!res_alt_tse) {
+		printk("ERROR :%s:%d:platform_get_resource_byname() failed\n",
+		       __FILE__, __LINE__);
+		ret = -ENODEV;
+		goto out;
+	}
+
+	mac_dev =
+		(alt_tse_mac *) ioremap_nocache((unsigned long)
+			res_alt_tse->start, sizeof(alt_tse_mac));
+
+	new_bus->priv = (void *) mac_dev;
+
+	new_bus->irq = tse_mdio_priv->irq;
+
+//	new_bus->dev =  dev;
+//	dev_set_drvdata(dev, new_bus);
+	platform_set_drvdata(pdev, new_bus);
+
+	ret = mdiobus_register(new_bus);
+
+	/* probe bus, report phys */
+	for (i = 31; i >= 0; i--) {
+		u32 phy_id;
+		u32 phy_id_bottom;
+		u32 phy_id_top;
+		int r;
+
+		r = get_phy_id(new_bus, i, &phy_id);
+		phy_id_top = (phy_id>>16) & (0xffff);
+		phy_id_bottom = (phy_id) & (0xffff);
+		if (r)
+			return r;
+
+		if (phy_id_top != phy_id_bottom)
+			printk(KERN_INFO "Found phy with ID=0x%x at address=0x%x\n",
+				phy_id, i);
+	}
+
+	if (0 != ret) {
+		printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
+				new_bus->name);
+		goto out;
+	}
+
+	printk(KERN_INFO "%s: MDIO Bus Registered\n", new_bus->name);
+
+	return 0;
+
+out:
+	return ret;
+}
+
+static int tse_mdio_remove(struct platform_device *pdev)
+{
+	struct mii_bus *bus = platform_get_drvdata(pdev);
+
+	mdiobus_unregister(bus);
+
+	platform_set_drvdata(pdev, NULL);
+
+	iounmap(bus->priv);
+	bus->priv = NULL;
+	kfree(bus);
+
+	return 0;
+}
+
+static struct platform_driver alt_tse_mdio_driver = {
+	.driver =	{
+			.name = ALT_TSE_MDIO_NAME,
+			.owner = THIS_MODULE,
+			},
+	.probe = tse_mdio_probe,
+	.remove = tse_mdio_remove,
+	.suspend = NULL,
+	.resume = NULL,
+};
+
+static int __init tse_mdio_init(void)
+{
+	return platform_driver_register(&alt_tse_mdio_driver);
+}
+
+static void __exit tse_mdio_exit(void)
+{
+	platform_driver_unregister(&alt_tse_mdio_driver);
+}
+
+module_init(tse_mdio_init);
+module_exit(tse_mdio_exit);
+
+MODULE_AUTHOR("Altera");
+MODULE_DESCRIPTION("Altera Triple Speed MAC IP MDIO Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/atse.c b/drivers/net/atse.c
new file mode 100644
index 0000000..b7fabd9
--- /dev/null
+++ b/drivers/net/atse.c
@@ -0,0 +1,1761 @@
+/*
+ *  linux/drivers/net/atse.c
+ *
+ *  Copyright (C) 2008       Joseph "Camel" Chen (camel4joe@gmail.com)
+ *
+ *  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * Modified by: Eintisy Chuang (eintisy.chuang@gfec.com.tw) 
+ * Updated: 1. Add TDK78Q2120CPHY infor for Microtronix Ethernet PHY Design Kit
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+MODULE_LICENSE("GPL");
+
+#include <linux/delay.h>
+
+#include <linux/pm.h>  /* pm_message_t */
+#include <linux/platform_device.h>
+
+#include <linux/mii.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+
+#include <asm/cacheflush.h>
+
+#include "atse.h"
+
+#define ATSE_CAN_USE_DATACS 1
+
+
+/* #define ATSE_SGDMA_DO_UNALIGNED_TRANSFER */
+#undef ATSE_SGDMA_DO_UNALIGNED_TRANSFER
+
+
+static const char atse_version_str[] =
+	"atse.c: v1.1, June 3, 2008 by Joseph (Camel) Chen <joe4camel@gmail.com>";
+static const char atse_version_str1[] =
+	"atse.c: modified version by Eintisy Chuang <eintisy.chuang@gfec.com.tw>";
+
+
+/* static struct sk_buff *g_skb_array[ATSE_SGDMA_RX_DESC_CHAIN_SIZE]; */
+static unsigned char *g_rx_data_buffer = NULL;
+static unsigned char *g_rx_data_buffer_ptr = NULL;
+
+static int g_tx_bytes_transferred = 0;
+
+/*
+ * Buffer Descriptor data structure
+ *
+ * The SGDMA controller buffer descriptor allocates
+ * 64 bits for each address. To support ANSI C, the
+ * struct implementing a descriptor places 32-bits
+ * of padding directly above each address; each pad must
+ * be cleared when initializing a descriptor.
+ */
+struct atse_sgdma_desc {
+	u32   *read_addr;
+	u32   read_addr_pad;
+	
+	u32   *write_addr;
+	u32   write_addr_pad;
+	
+	u32   *next_desc;
+	u32   next_desc_pad;
+	
+	u16   bytes_to_transfer;
+	u8    read_burst_size;
+	u8    write_burst_size;
+	
+	u16   bytes_transferred;
+	u8    status;
+	u8    control;
+};
+
+
+
+static struct atse_sgdma_desc *g_desc = (struct atse_sgdma_desc *)ATSE_SGDMA_DESC_MEM_BASE;
+static struct atse_sgdma_desc *g_rx_desc      = NULL;
+static struct atse_sgdma_desc *g_rx_desc_next = NULL;
+
+static struct atse_sgdma_desc *g_tx_desc      = NULL;
+static struct atse_sgdma_desc *g_tx_desc_next = NULL;
+
+
+
+struct atse_phy_device {
+	char *name;
+	u32 phy_id;
+	u8  link_stat_reg_num;
+
+	u32 phy_addr;
+	int (*get_link_speed)  (void);
+	int (*link_is_full_dup)(void);
+	int (*link_is_established)(void);
+};
+
+
+/* #define ATSE_DEBUG_PHY_DEV_FLAG */
+/* #define ATSE_DEBUG_FUNC_TRACE_ENTER */
+/* #define ATSE_DEBUG_FUNC_TRACE_EXIT */
+
+/*  #define ATSE_DEBUG_DESC */
+/* #define ATSE_DEBUG_TX_DATA */
+/* #define ATSE_DEBUG_RX_DATA */
+
+#ifdef ATSE_DEBUG_PHY_DEV_FLAG
+#define ATSE_DEBUG_PRINT_PHY_DEV(oui, mod_num, rev_num, phy_dev) atse_debug_pring_phy_dev(__FILE__, __LINE__, oui, mod_num, rev_num, phy_dev)
+static void atse_debug_pring_phy_dev(char *file, int line, int oui, int mod_num, int rev_num, struct atse_phy_device *phy_dev)
+{
+	printk("%s:%d:oui = %x, mod_num = %x, rev_num = %x, phy_name = %s\n", file, line,
+	       oui, mod_num, rev_num, phy_dev->name);
+	       
+
+	return;
+}
+#else
+#define ATSE_DEBUG_PRINT_PHY_DEV(oui, model_num, rev_num, phy_dev)
+#endif
+
+
+
+#ifdef ATSE_DEBUG_DESC
+#define ATSE_DEBUG_PRINT_DESC(this_desc) atse_debug_print_desc(this_desc, __FILE__, __LINE__, #this_desc)
+static void atse_debug_print_desc(struct atse_sgdma_desc *desc, char *file, int line, char *s)
+{
+	int i;
+	unsigned char *pc;
+
+	if (desc == NULL)
+		return;
+	printk("----ATSE_DEBUG:%s:%d:printing %s contents:\n", file, line, s);
+	printk("\t%s addr = 0x%p\n",             s, desc);
+
+	printk("\t read_addr=\t 0x%p\n",         desc->read_addr);
+	printk("\t read_addr_pad=\t %x\n",     desc->read_addr_pad);
+	
+	printk("\t write_addr=\t 0x%p\n",        desc->write_addr);
+	printk("\t write_addr_pad=\t %x\n",    desc->write_addr_pad);
+	
+	printk("\t next_desc=\t 0x%p\n",         desc->next_desc);
+	printk("\t next_desc_pad=\t %x\n",     desc->next_desc_pad);
+	
+	printk("\t bytes_to_transfer=\t %x\n", desc->bytes_to_transfer);
+	printk("\t read_burst_size=\t %x\n",   desc->read_burst_size);
+	printk("\t write_burst_size=\t %x\n",  desc->write_burst_size);
+	
+	printk("\t bytes_transferred=\t %x\n", desc->bytes_transferred);
+	printk("\t status=\t %x\n",            desc->status);
+	printk("\t control=\t %x\n",           desc->control);
+
+	printk("\n");
+	printk("\t data tied to read_addr: len = %d\n", desc->bytes_to_transfer);
+
+	pc = (unsigned char *) desc->read_addr;
+	printk("\t\t");
+	for (i = 0; i < desc->bytes_to_transfer; i++) {
+		printk(" %02x", *(pc + i) );
+		if ( (i + 1) % 8 == 0)
+			printk(" ");
+		if ( (i + 1) % 16 == 0)
+			printk("\n\t\t");
+	}
+	printk("\n");
+
+	return;
+}
+#else
+#define ATSE_DEBUG_PRINT_DESC(this_desc)
+#endif /* #ifdef ATSE_DEBUG_DESC */
+
+
+
+#ifdef ATSE_DEBUG_TX_DATA
+#define ATSE_DEBUG_PRINT_TX_DATA(data, len, align_offset) atse_debug_print_tx_data(data, len, align_offset, __FILE__, __LINE__)
+static int tx_data_num = 0;
+static void atse_debug_print_tx_data(char *data, int len, int align_offset, char *file, int line)
+{
+	int i;
+
+	++tx_data_num;
+	printk("----ATSE_DEBUG:%s:%d:kernel tx_data: num = %d, addr = 0x%p, len = %d, align_offset = %d\n",
+	       file, line, tx_data_num, data, len, align_offset);
+	for (i = 0; i < len; i++) {
+		printk(" %02x", ((unsigned char *)data)[i]);
+		
+		if ((i+1) % 8 == 0)
+			printk(" ");
+
+		if ((i+1) % 16 == 0)
+			printk("\n");
+	}
+	printk("\n\n");
+}
+
+#else
+#define ATSE_DEBUG_PRINT_TX_DATA(data, len, align_offset)
+#endif /* #ifdef ATSE_DEBUG_TX_DATA */
+
+
+#ifdef ATSE_DEBUG_RX_DATA
+#define ATSE_DEBUG_PRINT_RX_DATA(this_desc, this_data) atse_debug_print_rx_data(this_desc, this_data, __FILE__, __LINE__)
+static void atse_debug_print_rx_data(struct atse_sgdma_desc *rx_desc, unsigned char *rx_data, char *file, int line)
+{
+	int j;
+	int rx_datalen;
+	
+	printk("----ATSE_DEBUG%s:%d:ATSE_GET_SGDMA_DESC_STATUS(rx_desc) = %0x\n", 
+	       __FILE__, __LINE__, ATSE_GET_SGDMA_DESC_STATUS(rx_desc));
+
+	printk("----ATSE_DEBUG:%s:%d:rx_desc = 0x%p\n", __FILE__, __LINE__, rx_desc);
+
+	rx_datalen = rx_desc->bytes_transferred;
+
+	printk("----ATSE_DEBUG:%s:%d:rx_datalen = %d\n", file, line, rx_datalen);
+	
+	printk("----ATSE_DEBUG:%s:%d:rx_data addr = 0x%p\n", __FILE__, __LINE__, rx_data);
+	printk("----ATSE_DEBUG:%s:%d:rx_data = \n", __FILE__, __LINE__);
+	for (j = 0; j < rx_datalen; j++) {
+		printk(" %02x", rx_data[j]);
+		if ((j+1) % 16  == 0)
+			printk("\n");
+		else if ((j+1) % 16 == 8)
+			printk(" ");
+		
+	}
+	printk("\n");
+
+
+	return;
+}
+#else
+#define ATSE_DEBUG_PRINT_RX_DATA(this_desc, this_data)
+#endif /* #ifdef ATSE_DEBUG_RX_DATA */
+
+
+
+#ifdef ATSE_DEBUG_FUNC_TRACE_ENTER
+#define ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER() printk("----%s:%d: ENTER %s()\n", __FILE__, __LINE__, __FUNCTION__)
+#else
+#define ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER()
+#endif
+
+#ifdef ATSE_DEBUG_FUNC_TRACE_EXIT
+#define ATSE_DEBUG_PRINT_FUNC_TRACE_EXIT()  printk("----%s:%d: EXIT  %s()\n", __FILE__, __LINE__, __FUNCTION__)
+#else
+#define ATSE_DEBUG_PRINT_FUNC_TRACE_EXIT()
+#endif
+
+
+
+
+/* store this information for the driver.. */
+struct atse_board_priv {
+	spinlock_t tx_lock;
+	spinlock_t rx_lock;
+	struct atse_phy_device *phy_dev;
+//	int      link_is_full_dup;
+//	int      link_is_1000;
+	int      link_is_mdix; /* crossover cable */
+	int        tx_pkt_cnt;
+	int        queue_pkt_len;
+ 	struct net_device_stats stats;
+ 	struct sk_buff *pending_tx_skb;
+	struct resource *res_desc_mem;
+	struct resource *res_sgdma_rx_mem;
+	struct resource *res_sgdma_tx_mem;
+	struct resource *res_sgdma_rx_irq;
+	struct resource *res_sgdma_tx_irq;
+};
+
+
+static irqreturn_t atse_sgdma_tx_irq_handler(int irq, void *dev_id)
+{
+	struct net_device *dev;
+	struct atse_board_priv  *bd_priv;
+
+	dev = (struct net_device *)dev_id;
+	bd_priv = netdev_priv(dev);
+	spin_lock(&bd_priv->tx_lock);
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	ATSE_DEBUG_PRINT_DESC(tx_desc);
+
+	ATSE_SET_SGDMA_TX_CONTROL(ATSE_SGDMA_CONTROL_CLEAR_INTERRUPT_BIT);
+
+	ATSE_CLEAR_SGDMA_TX_CONTROL();
+	ATSE_CLEAR_SGDMA_TX_STATUS();
+
+	/* a transmission is over: free the skb */
+	bd_priv->stats.tx_packets++;
+	bd_priv->stats.tx_bytes += g_tx_bytes_transferred;
+	dev_kfree_skb_irq(bd_priv->pending_tx_skb);
+	bd_priv->pending_tx_skb = NULL;
+
+	spin_unlock(&bd_priv->tx_lock);
+
+	return IRQ_HANDLED;
+}
+
+
+static int atse_sgdma_tx_init(struct net_device *dev)
+{
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	g_tx_desc->status &= ~ATSE_SGDMA_DESC_STATUS_TERMINATED_BY_EOP_BIT;
+
+	ATSE_SET_SGDMA_TX_CONTROL(ATSE_SGDMA_CONTROL_SW_RESET_BIT);
+	ATSE_SET_SGDMA_TX_CONTROL(ATSE_SGDMA_CONTROL_CLEAR_INTERRUPT_BIT);
+	ATSE_CLEAR_SGDMA_TX_STATUS();
+	ATSE_CLEAR_SGDMA_TX_CONTROL();
+
+	return 0;
+}
+
+/*
+ * atse_mac_rcv() function assumes that the data passed in do not have
+ * any issues with cached or uncached data.
+ *
+ */
+
+static void atse_mac_rcv(struct net_device *ndev, struct atse_sgdma_desc *rx_desc, unsigned char *rx_data_buffer)
+{
+	struct sk_buff *skb;
+	struct atse_board_priv *bd_priv = netdev_priv(ndev);
+	int pktdatalen;
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+	
+	if (!(rx_desc->status & ATSE_SGDMA_DESC_STATUS_TERMINATED_BY_EOP_BIT)) {
+		printk("ATSE driver:%s:%d: not ATSE_SGDMA_DESC_STATUS_TERMINATED_BY_EOP_BIT\n",
+		       __FILE__, __LINE__);
+		goto out_atse_mac_rcv;
+	}
+
+	rx_desc->status &= ~ ATSE_SGDMA_DESC_STATUS_TERMINATED_BY_EOP_BIT;
+
+	if ( (rx_desc->status & ( ATSE_SGDMA_DESC_STATUS_E_CRC_BIT |
+				ATSE_SGDMA_DESC_STATUS_E_PARITY_BIT |
+				ATSE_SGDMA_DESC_STATUS_E_OVERFLOW_BIT |
+				ATSE_SGDMA_DESC_STATUS_E_SYNC_BIT |
+				ATSE_SGDMA_DESC_STATUS_E_UEOP_BIT |
+				ATSE_SGDMA_DESC_STATUS_E_MEOP_BIT |
+				ATSE_SGDMA_DESC_STATUS_E_MSOP_BIT
+		      ) ) != 0) {
+		printk("ATSE driver:%s:%d: rx_desc->status ERROR\n", __FILE__, __LINE__);
+		goto out_atse_mac_rcv;
+	}
+    
+	pktdatalen = rx_desc->bytes_transferred;
+	/* saw adding extra 2 bytes from the device driver book, don't know why */
+	skb = dev_alloc_skb(pktdatalen + 6);
+	if(!skb) {
+		if (printk_ratelimit())
+			printk(KERN_NOTICE "ATSE driver:%s:%d:%s(): low on mem - packet dropped\n",
+			       __FILE__, __LINE__, __FUNCTION__);
+		bd_priv->stats.rx_dropped++;
+		goto out_atse_mac_rcv;
+	}
+	/*
+	 * Call skb_reserve() to align IP header to 32bits, don't konw
+	 * why.  Without this call, kernel woun't work for the IP data.
+	 */
+	skb_reserve(skb, 2);
+
+	/* sync the cache memory with the uncached memory ???? */
+	memcpy(skb_put(skb, pktdatalen), rx_data_buffer, pktdatalen);
+	
+	/* write metadata, and then pass to the receive level */
+	skb->dev = ndev;
+	skb->protocol = eth_type_trans(skb, ndev);
+	bd_priv->stats.rx_packets++;
+	bd_priv->stats.rx_bytes += pktdatalen;
+	netif_rx(skb);
+	
+out_atse_mac_rcv:
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_EXIT();
+
+	return;
+}
+
+
+static int atse_sgdma_rx_enable_async_read(struct atse_sgdma_desc *rx_desc)
+{
+	int timeout;
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	/*  Make sure SGDMA controller is not busy from a former command */
+	timeout = 0;
+
+	while ( (ATSE_GET_SGDMA_RX_STATUS() & ATSE_SGDMA_STATUS_BUSY_BIT) ) {
+		if(timeout++ == ATSE_SGDMA_BUSY_TIMEOUT_COUNT) {
+			printk("ATSE driver:%s:%d:Timeout\n", __FILE__, __LINE__);
+			return -EBUSY;
+		}
+	}
+
+	ATSE_CLEAR_SGDMA_RX_STATUS();
+
+	/* flush the descriptor out of the cache */
+	flush_dcache_range((unsigned long)rx_desc, 
+		(unsigned long)rx_desc + sizeof(struct atse_sgdma_desc));
+
+	/* Point the controller at the descriptor */
+	ATSE_SET_SGDMA_RX_WITH_DESC((u32)rx_desc);
+
+	/*
+	 * Set up agdma controller to:
+	 *  - Run
+	 *  - Stop on an error with any particular descriptor
+	 *  - Include any control register bits registered with along with
+	 *    the callback routine (effectively, interrupts are controlled
+	 *    via the control bits set during callback-register time).
+	 */
+	
+	ATSE_SET_SGDMA_RX_CONTROL(
+		ATSE_SGDMA_CONTROL_IE_CHAIN_COMPLETED_BIT |
+		ATSE_SGDMA_CONTROL_IE_GLOBAL_BIT          |
+		ATSE_SGDMA_CONTROL_RUN_BIT                |
+		ATSE_SGDMA_CONTROL_STOP_DMA_ER_BIT        |
+		ATSE_GET_SGDMA_RX_CONTROL()
+		);
+	
+	return 0;
+}
+
+
+static int atse_sgdma_rx_prepare_desc(void)
+{
+	struct atse_sgdma_desc *cur_desc = g_rx_desc;
+	struct atse_sgdma_desc *next_desc = g_rx_desc_next;
+	u32 * clear_uncached_data_addr;
+
+	/*
+	 * this is a starting write_address, and make sure to
+	 * clear the uncache-bit (bit 31) before passing to
+	 * SGDMA controller
+	 */
+	/* ioremap() requires buffer_size as the 2nd argument, but it is not being used inside anyway, so put 1234 */
+	clear_uncached_data_addr = ioremap_fullcache((unsigned long)g_rx_data_buffer_ptr, 1234);
+
+	/* initialize the dscriptor structure data */
+	
+	memset(cur_desc, 0, sizeof(struct atse_sgdma_desc));
+	memset(next_desc, 0, sizeof(struct atse_sgdma_desc));
+	
+	/* cur_desc->read_addr = 0; */
+	cur_desc->write_addr = clear_uncached_data_addr;
+	cur_desc->next_desc = (u32 *) next_desc;
+	/* cur_desc->read_addr_pad  = 0x0; */
+	/* cur_desc->next_desc_pad  = 0x0; */
+	/* cur_desc->bytes_to_transfer = 0; */
+ 	/* cur_desc->bytes_transferred = 0; */
+	/* cur_desc->status = 0x0; */
+	/* SGDMA burst not currently supported */
+	/* cur_desc->read_burst_size = 0; */
+	/* cur_desc->write_burst_size = 0; */
+	/* set the descriptor control as follows */
+	cur_desc->control = ATSE_SGDMA_DESC_CONTROL_OWNED_BY_HW_BIT;
+	
+	return 0;
+}
+
+
+static int atse_sgdma_rx_init(struct net_device *ndev)
+{
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	
+	ATSE_SET_SGDMA_RX_CONTROL(ATSE_SGDMA_CONTROL_SW_RESET_BIT);
+	ATSE_SET_SGDMA_RX_CONTROL(ATSE_SGDMA_CONTROL_CLEAR_INTERRUPT_BIT);
+	ATSE_CLEAR_SGDMA_RX_STATUS();
+	ATSE_CLEAR_SGDMA_RX_CONTROL();
+	
+	atse_sgdma_rx_prepare_desc();
+
+	return 0;
+}
+
+
+static int atse_mac_init(struct net_device *ndev)
+{
+	u32 mac_tx_cmd_stat;
+	u32 mac_rx_cmd_stat;
+	u32 not_bits_group;
+	int x;
+	volatile u32 dat;
+	struct atse_board_priv  *bd_priv = netdev_priv(ndev);
+
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+
+	ATSE_SET_MAC_CMD_CONFIG(ATSE_MAC_CC_SW_RESET_BIT |
+				ATSE_MAC_CC_TX_ENA_BIT   |
+				ATSE_MAC_CC_RX_ENA_BIT
+		);
+
+	x = 0;
+	while(ATSE_GET_MAC_CMD_CONFIG() & ATSE_MAC_CC_SW_RESET_BIT) {
+		if( x++ > 10000 )
+			break;
+	}
+
+	if(x >= 10000)
+		printk("ATSE driver:%s:%d:MAC SW reset bit never cleared!\n", __FILE__, __LINE__); \
+
+
+	if ((ATSE_GET_MAC_CMD_CONFIG() & (ATSE_MAC_CC_TX_ENA_BIT | ATSE_MAC_CC_RX_ENA_BIT) )  != 0)
+		printk("ATSE driver:%s:%d:WARN: RX/TX not disabled after reset... missing PHY clock?\n", __FILE__, __LINE__);
+
+
+	/* Initialize MAC registers */
+	ATSE_SET_MAC_FRM_LEN(1518);
+	ATSE_SET_MAC_RX_ALMOST_EMPTY(8);
+	ATSE_SET_MAC_RX_ALMOST_FULL(8);
+	ATSE_SET_MAC_TX_ALMOST_EMPTY(8);
+	ATSE_SET_MAC_TX_ALMOST_FULL(3);
+	ATSE_SET_MAC_TX_SECTION_EMPTY(1024 - 16);
+	ATSE_SET_MAC_TX_SECTION_FULL(0);
+	ATSE_SET_MAC_RX_SECTION_EMPTY(1024 - 16);
+	ATSE_SET_MAC_RX_SECTION_FULL(0);
+
+
+	 /* 
+	  * Some required settings:
+	  *
+	  * 1. Do not let MAC to use 16-bit shift in TX, since the
+	  *    data provided by the kernel seems aligned already
+	  *
+	  * 2. Do not let MAC to omit CRC, since the kernel does not
+	  *    provide it in this case.
+	  */
+	mac_tx_cmd_stat = ATSE_GET_MAC_TX_CMD_STAT();
+	not_bits_group = ~(
+		ATSE_MAC_TX_CMD_STAT_TXSHIFT16_BIT |
+		ATSE_MAC_TX_CMD_STAT_OMIT_CRC_BIT
+		);
+	ATSE_SET_MAC_TX_CMD_STAT(mac_tx_cmd_stat & not_bits_group);
+
+	mac_rx_cmd_stat = ATSE_GET_MAC_RX_CMD_STAT();
+	not_bits_group = ~(
+		ATSE_MAC_RX_CMD_STAT_RXSHIFT16_BIT |
+		0x0
+		);
+	ATSE_SET_MAC_RX_CMD_STAT(mac_tx_cmd_stat & not_bits_group);
+	/* enable mac */
+	dat = ATSE_MAC_CC_TX_ENA_BIT                |
+		ATSE_MAC_CC_RX_ENA_BIT              |
+		ATSE_MAC_CC_RX_ERR_DISCD_BIT        |
+		0x0;
+
+	if (bd_priv->phy_dev->get_link_speed() == 1000)
+		dat |= ATSE_MAC_CC_ETH_SPEED_BIT;
+
+
+	if (!bd_priv->phy_dev->link_is_full_dup())
+		dat |= ATSE_MAC_CC_HD_ENA_BIT;
+
+	ATSE_SET_MAC_CMD_CONFIG(dat);
+	
+	return 0;
+}
+
+
+
+static void atse_reset_and_enable(struct net_device *ndev)
+{
+	int i;
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	/* 
+	 * Reset is to do the folowing 4 steps:
+	 *
+	 * 1. reset SGDMA_TX
+	 * 2. reset SGDMA_RX
+	 * 3. reset PHY
+	 * 4. reset MAC
+	 *
+	 */
+	/* clear SGDMA descriptors */
+	for (i = 0; i < ATSE_TOTAL_SGDMA_DESC_MEM / BYTES_IN_WORD; i++)
+		writel(0x0, ATSE_SGDMA_DESC_MEM_BASE + i *BYTES_IN_WORD);
+
+	/* reset sgdma */
+	atse_sgdma_tx_init(ndev);
+	atse_sgdma_rx_init(ndev);
+	atse_sgdma_rx_enable_async_read(g_rx_desc);
+			
+	/* reset mac */
+	atse_mac_init(ndev);
+
+	return;
+}
+
+
+
+static irqreturn_t atse_sgdma_rx_irq_handler(int irq, void *dev_id)
+{
+	struct net_device *ndev;
+	struct atse_board_priv  *bd_priv;
+	struct atse_sgdma_desc *desc;
+	struct atse_sgdma_desc *rx_desc;
+	unsigned char *uncached_rx_data_buffer_ptr = g_rx_data_buffer;
+
+	ndev = (struct net_device *)dev_id;
+	bd_priv = netdev_priv(ndev);
+	spin_lock(&bd_priv->rx_lock);
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	/* First the firs to clear the pending interrupts */
+	ATSE_SET_SGDMA_RX_CONTROL(ATSE_SGDMA_CONTROL_CLEAR_INTERRUPT_BIT);
+
+	desc = (struct atse_sgdma_desc *)ATSE_SGDMA_DESC_MEM_BASE;
+	rx_desc = &desc[ATSE_SGDMA_RX_FIRST_DESC_OFFSET];
+
+	/* 
+	 * since both rx_desc and rx_data were just written by the hw controller, they may
+	 * not be in the cache yet, so use the uncacched access
+	 *
+	 */
+	uncached_rx_data_buffer_ptr = (unsigned char *)ioremap_nocache((unsigned long)uncached_rx_data_buffer_ptr, 1234);
+	rx_desc = (struct atse_sgdma_desc *) ioremap_nocache((unsigned long)rx_desc, 1234);
+	ATSE_DEBUG_PRINT_RX_DATA(rx_desc,uncached_rx_data_buffer_ptr);
+
+	atse_mac_rcv(ndev, rx_desc, uncached_rx_data_buffer_ptr);
+	/* done with received packet, prepare for the next receiving enevent */
+	ATSE_CLEAR_SGDMA_RX_CONTROL();
+	ATSE_ENABLE_SGDMA_RX_INT();
+
+	if (!(ATSE_GET_SGDMA_RX_STATUS() & ATSE_SGDMA_STATUS_CHAIN_COMPLETED_BIT)) {
+		printk("ATSE driver:%s:%d:CHAINE_COMPLETED is false\n", __FILE__, __LINE__);
+	}
+
+	atse_sgdma_rx_prepare_desc();
+
+	
+	atse_sgdma_rx_enable_async_read(rx_desc);
+
+	spin_unlock(&bd_priv->rx_lock);
+
+	return IRQ_HANDLED;
+} /* end of atse_sgdma_rx_irq_handler() */
+
+static int atse_phy_init(struct net_device *ndev)
+{
+	unsigned int stat;
+	int count = 0;
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	/* see if need reset PHY */
+	if ((ATSE_GET_PHY_MDIO_STATUS() &
+	     ATSE_PHY_MDIO_CONTROL_AUTO_NEG_COMPLETE_BIT) > 0)
+	{
+		/* auto negotiation is complete, so no reset needed */
+		return 0;
+	} else {
+		/* reset now */
+		ATSE_SET_PHY_MDIO_CONTROL(
+			ATSE_PHY_MDIO_CONTROL_RESET_BIT           |
+			ATSE_PHY_MDIO_CONTROL_AUTO_NEGO_ENA_BIT   |
+			0x0
+			);
+	
+		stat = ATSE_GET_PHY_MDIO_STATUS();
+		if ((stat & ATSE_PHY_MDIO_CONTROL_AUTO_NEG_COMPLETE_BIT) == 0) {
+			printk("ATSE: Waiting on PHY link ......\n");
+			while ((ATSE_GET_PHY_MDIO_STATUS() & 
+				ATSE_PHY_MDIO_CONTROL_AUTO_NEG_COMPLETE_BIT) == 0) {
+				if (count > ATSE_PHY_AUTONEG_TIMEOUT_COUNT) {
+					printk("ATSE:PHY Auto negotiation faild, continue anyway ... \n");
+					break;
+				}
+				mdelay(1000);
+				++count;
+			} /* end while() */
+		}
+	}
+
+	return 0;
+}
+
+
+static int atse_open(struct net_device *ndev)
+{
+	struct atse_board_priv *bd_priv = netdev_priv(ndev);
+	int ret;
+	int n;
+	DECLARE_MAC_BUF(mac_buf);
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	atse_phy_init(ndev);
+
+	/* initialize globle data */
+	g_rx_desc      = &g_desc[ATSE_SGDMA_RX_FIRST_DESC_OFFSET];
+	g_rx_desc_next = &g_desc[ATSE_SGDMA_RX_SECOND_DESC_OFFSET];
+
+	g_tx_desc      = &g_desc[ATSE_SGDMA_TX_FIRST_DESC_OFFSET];
+	g_tx_desc_next = &g_desc[ATSE_SGDMA_TX_SECOND_DESC_OFFSET];
+
+
+	/* allocate memory for each of rx_data_buffer[i] */
+	if (g_rx_data_buffer == NULL) {
+		g_rx_data_buffer = kmalloc(ETH_DATA_LEN + 2 + 3, GFP_KERNEL);
+		if (!g_rx_data_buffer) {
+			if (printk_ratelimit( ))
+				printk(KERN_NOTICE "ATSE driver:%s:%d:rx: low on mem - packet dropped\n", __FILE__, __LINE__);
+			goto out_atse_open_error;
+		}
+	}
+
+	g_rx_data_buffer_ptr = g_rx_data_buffer;
+	/* make sure the addr is 32-bit aligned: JoeCamel, FIXME */
+	n = (int)g_rx_data_buffer_ptr % 4;
+	if (n  != 0) {
+		g_rx_data_buffer_ptr += (4 - n);
+		printk("++++++++ATSE driver:%s:%d:rx_data_buffer manually aligned here: remainder = %d\n", __FILE__, __LINE__, n);
+	}
+
+
+	/* register interrupt callback function for rx_sgdma controller */
+	ret = request_irq(ATSE_SGDMA_RX_IRQ, atse_sgdma_rx_irq_handler, IRQF_DISABLED, "atse ether driver rx", ndev);
+	if(ret) {
+		printk("********ATSE driver:%s:%d:can't request assigned irq=%d\n", __FILE__, __LINE__, ATSE_SGDMA_RX_IRQ);
+	}
+
+	/* register interrupt callback function for tx_sgdma controller */
+	ret = request_irq(ATSE_SGDMA_TX_IRQ, atse_sgdma_tx_irq_handler, IRQF_DISABLED, "atse ether dirver tx", ndev);
+	if(ret) {
+		printk("********ATSE driver:%s:%d:can't request assigned irq=%d\n", __FILE__, __LINE__, ATSE_SGDMA_TX_IRQ);
+	}
+
+
+	/* reset the hardware */
+	atse_reset_and_enable(ndev);
+	netif_start_queue(ndev);
+
+	printk("%s up, link speed %d, %s duplex",
+	       ndev->name, bd_priv->phy_dev->get_link_speed(),
+	       bd_priv->phy_dev->link_is_full_dup() == 1? "full":"half");
+	if (bd_priv->link_is_mdix)
+		printk(", crossover\n");
+	printk(", eth hw addr %s", print_mac(mac_buf, ndev->dev_addr));
+	
+	printk("\n");
+
+ 
+	return 0;
+out_atse_open_error:
+
+	return -1;
+}
+
+
+static int atse_close(struct net_device *ndev)
+{
+
+	struct atse_board_priv  *bd_priv = netdev_priv(ndev);
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	netif_stop_queue(ndev);
+
+	ATSE_SET_SGDMA_RX_CONTROL(ATSE_GET_SGDMA_RX_CONTROL() &
+				  ~ATSE_SGDMA_CONTROL_CLEAR_INTERRUPT_BIT);
+
+	ATSE_CLEAR_SGDMA_RX_CONTROL();
+
+
+	ATSE_SET_SGDMA_TX_CONTROL(ATSE_GET_SGDMA_TX_CONTROL() &
+				  ~ATSE_SGDMA_CONTROL_CLEAR_INTERRUPT_BIT);
+
+	ATSE_CLEAR_SGDMA_TX_CONTROL();
+
+	ATSE_SET_PHY_POWER_DOWN();
+
+	if (bd_priv->pending_tx_skb) {
+		dev_kfree_skb(bd_priv->pending_tx_skb);
+		bd_priv->pending_tx_skb = NULL;
+	}
+
+	/* de-register irq for both SGDMA-TX and SGDMA-RX controllers */
+	free_irq(ATSE_SGDMA_TX_IRQ, ndev);
+	free_irq(ATSE_SGDMA_RX_IRQ, ndev);
+
+	if (g_rx_data_buffer) {
+		kfree(g_rx_data_buffer);
+		g_rx_data_buffer     = NULL;
+		g_rx_data_buffer_ptr = NULL;
+	}
+
+	printk("%s down\n", ndev->name);
+
+	return 0;
+}
+
+#define ATSE_MARVELL_PHY_ID_88E1111 0x01410cc2
+#define ATSE_MARVELL_PHY_ID_88E1145 0x01410dc2
+#define ATSE_NATIONAL_PHY_ID_83848  0x20005c90  /* National 83848, 10/100 */
+#define ATSE_NATIONAL_PHY_ID_83865  0x20005c7a  /* National DP83865 */
+#define ATSE_TDK_PHY_ID_78Q2120C    0x000e70c5  /* TDK 78Q2120 10/100 PHY */
+
+
+
+/* PHY ID */
+/* Marvell PHY on PHYWORKX board */
+enum {
+    MV88E1111_OUI       = 0x005043,
+    MV88E1111_MODEL     = 0x0c,
+    MV88E1111_REV       = 0x02
+};
+
+/* Marvell Quad PHY on PHYWORKX board */
+enum {
+    MV88E1145_OUI       = 0x005043,
+    MV88E1145_MODEL     = 0x0d,
+    MV88E1145_REV       = 0x02
+};
+
+/* National PHY on PHYWORKX board */
+enum {
+    DP83865_OUI       = 0x080017,
+    DP83865_MODEL     = 0x07,
+    DP83865_REV       = 0x10
+};
+
+/* National 10/100 PHY on PHYWORKX board */
+enum {
+    DP83848C_OUI       = 0x080017,
+    DP83848C_MODEL     = 0x09,
+    DP83848C_REV       = 0x00
+};
+
+
+
+/* Marvell PHY 88E1111 */
+
+static int atse_phy_marvell_88E1111_get_link_speed(void)
+{
+	unsigned int stat;
+
+	stat = ATSE_GET_MVLPHY_LINK_STATUS();
+	if (ATSE_MVLPHY_IS_1000(stat)) {
+		return 1000;
+	}
+
+	return 100;
+}
+
+static int atse_phy_marvell_88E1111_link_is_full_dup(void)
+{
+	unsigned int stat;
+	stat = ATSE_GET_MVLPHY_LINK_STATUS();
+	return (ATSE_MVLPHY_IS_FULL_DUP(stat));
+}
+
+
+/*  National 83848, 10/100 */
+
+static int atse_phy_national_83848_get_link_speed(void)
+{
+	/* Reference: National DP83848C datasheet */
+	unsigned int stat;
+
+	/* register 0x10 is an Extended Register for PHY Status Register */
+	stat = ATSE_READ_PHY_MDIO_REG(0x10);
+	/* Bit 1 is for Speed Status */
+	if ((stat & (0x1 << 1)) == 0)
+		return 100;
+	else
+		return 100;
+}
+
+static int atse_phy_national_83848_link_is_full_dup(void)
+{
+	/* Reference: National DP83848C datasheet */
+	unsigned int stat;
+
+	/* register 0x10 is an Extended Register for PHY Status Register */
+	stat = ATSE_READ_PHY_MDIO_REG(0x10);
+	/* Bit 2 is for Duples Status  */
+	if ((stat & (0x1 << 2)) == 0)
+		return 0; /* Half duplex mode */
+	
+	/* Full duplex mode */
+	return 1;
+}
+
+static int atse_phy_national_83848_link_is_established(void)
+{
+	/* Reference: National DP83848C datasheet */
+	unsigned int stat;
+
+	/* register 0x10 is an Extended Register for PHY Status Register */
+	stat = ATSE_READ_PHY_MDIO_REG(0x10);
+	/* Bit 0 is for Duples Status  */
+	if ((stat & (0x1 << 0)) == 0)
+		return 0; /* not established */
+	
+	/* established */
+	return 1;
+}
+
+
+/*  National 83865 */
+
+static int atse_phy_national_83865_get_link_speed(void)
+{
+	/* Reference: National DP83865 datasheet */
+	unsigned int stat;
+
+	/* register 0x10 is an Extended Register for PHY Status Register */
+	stat = ATSE_READ_PHY_MDIO_REG(0x10);
+	/* Bit 3 is for Speed Status */
+	if ((stat & (0x1 << 3)) == 0)
+		return 100;
+	else
+		return 100;
+}
+
+static int atse_phy_national_83865_link_is_full_dup(void)
+{
+	/* Reference: National DP83865 datasheet */
+	unsigned int stat;
+
+	/* register 0x10 is an Extended Register for PHY Status Register */
+	stat = ATSE_READ_PHY_MDIO_REG(0x10);
+	/* Bit 1 is for Duples Status  */
+	if ((stat & (0x1 << 1)) == 0)
+		return 0; /* Half duplex mode */
+	
+	/* Full duplex mode */
+	return 1;
+}
+
+static int atse_phy_national_83865_link_is_established(void)
+{
+	/* Reference: National DP83865 datasheet */
+	unsigned int stat;
+
+	/* register 0x10 is an Extended Register for PHY Status Register */
+	stat = ATSE_READ_PHY_MDIO_REG(0x10);
+	/* Bit 2 is for Duples Status  */
+	if ((stat & (0x1 << 2)) == 0)
+		return 0; /* not established */
+	
+	/* established */
+	return 1;
+}
+
+/*  TDK 78Q2120C PHY */
+
+static int atse_phy_tdk_78Q2120_get_link_speed(void)
+{
+	/* Reference: TDK 78Q2120C datasheet */
+	unsigned int stat;
+
+	/* Using MR1 (Status Register) to check ANEGC */
+	stat = ATSE_READ_PHY_MDIO_REG(0x01);
+	/* MR1.5 ANEGC: Auto-Negotiation Complete */
+	if((stat & (0x01 << 5)) == 1) {
+
+	  /* Using MR0 (Control Register) */
+	  stat = ATSE_READ_PHY_MDIO_REG(0x00);
+	  /* Bit 13 is for Speed Selection */
+	  if ((stat & (0x1 << 13)) == 0)
+	    return 10;
+	  else
+	    return 100;
+
+	}
+
+	return 100; // Default to 100MB
+
+}
+
+static int atse_phy_tdk_78Q2120_link_is_full_dup(void)
+{
+	/* Reference: TDK 78Q2120C datasheet */
+	unsigned int stat;
+
+	/* Using MR1 (Status Register) to check ANEGC */
+	stat = ATSE_READ_PHY_MDIO_REG(0x01);
+	/* MR1.5 ANEGC: Auto-Negotiation Complete */
+	if((stat & (0x01 << 5)) == 1) {
+
+	  /* Using MR0 (Control Register) */
+	  stat = ATSE_READ_PHY_MDIO_REG(0x00);
+	  /* Bit 13 is for Speed Selection */
+	  if ((stat & (0x1 << 8)) == 0)
+	    return 0;
+	  else
+	    return 1;
+
+	}
+
+	return 1; // Default to Full-Duplex
+}
+
+static int atse_phy_tdk_78Q2120_link_is_established(void)
+{
+	/* Reference: TDK 78Q2120C datasheet */
+	unsigned int stat;
+
+	/* Using MR1 (Status Register) to check LINK */
+	stat = ATSE_READ_PHY_MDIO_REG(0x01);
+	/* MR1.5 ANEGC: Auto-Negotiation Complete */
+	if((stat & (0x01 << 2)) == 0)
+	    return 0; /* not established / link is not ready */
+	else
+	    return 1; /* ok */
+	    
+}
+
+
+static struct atse_phy_device atse_phy_dev_list[] = {
+	[0] = {
+		.name = "Marvell 88E1111 PHY",
+		.phy_id = ATSE_MARVELL_PHY_ID_88E1111,
+		.link_stat_reg_num = 0x11,
+
+		.get_link_speed   = atse_phy_marvell_88E1111_get_link_speed,
+		.link_is_full_dup = atse_phy_marvell_88E1111_link_is_full_dup,
+	},
+
+	[1] = {
+		.name = "Marvell 88E1145 PHY",
+		.phy_id = ATSE_MARVELL_PHY_ID_88E1145,
+		.link_stat_reg_num = 0x11,
+		/* functions are compatible with 88E111, so reuse here */
+		.get_link_speed   = atse_phy_marvell_88E1111_get_link_speed,
+		.link_is_full_dup = atse_phy_marvell_88E1111_link_is_full_dup,
+	},
+
+	[2] = {
+		.name = "National DP83848C PHY",
+		.phy_id = ATSE_NATIONAL_PHY_ID_83848,
+		.link_stat_reg_num = 0x10,
+
+		.get_link_speed      = atse_phy_national_83848_get_link_speed,
+		.link_is_full_dup    = atse_phy_national_83848_link_is_full_dup,
+		.link_is_established = atse_phy_national_83848_link_is_established,
+
+	},
+
+	[3] = {
+		.name = "National DP83865 PHY",
+		.phy_id = ATSE_NATIONAL_PHY_ID_83865,
+		.link_stat_reg_num = 0x10,
+
+		.get_link_speed      = atse_phy_national_83865_get_link_speed,
+		.link_is_full_dup    = atse_phy_national_83865_link_is_full_dup,
+		.link_is_established = atse_phy_national_83865_link_is_established,
+
+	},
+
+	[4] = {
+		.name = "TDK 78Q2120 PHY",
+		.phy_id = ATSE_TDK_PHY_ID_78Q2120C,
+		.link_stat_reg_num = 0x01,
+
+		.get_link_speed      = atse_phy_tdk_78Q2120_get_link_speed,
+		.link_is_full_dup    = atse_phy_tdk_78Q2120_link_is_full_dup,
+		.link_is_established = atse_phy_tdk_78Q2120_link_is_established,
+
+	}
+};
+
+
+static struct atse_phy_device *
+get_phy_dev(u32 phy_id_1, u32 phy_id_2)
+{
+	int num_of_phys;
+	int i;
+	int oui;
+	int model_num;
+	int rev_num;
+
+	struct atse_phy_device *phy_dev;
+
+	/* calculate OUI, model number, and revision number from phy_id_1 and phy_id_2 */
+	oui = (phy_id_1 << 6) | ((phy_id_2 >> 10) & 0x3F);
+	model_num = ((phy_id_2 >> 4)) & 0x3F;
+	rev_num = phy_id_2 & 0x0F;
+
+		     
+
+	num_of_phys = sizeof(atse_phy_dev_list) / sizeof(atse_phy_dev_list[0]);
+	for (i = 0; i < num_of_phys; i++) {
+		phy_dev = &(atse_phy_dev_list[i]);
+		if ((phy_dev->phy_id >> 16) == phy_id_1 && 
+		    ((phy_dev->phy_id & 0xFFFF) == phy_id_2)) {
+			/* found a known phy */
+			goto found_phy_dev;
+		}
+	}
+	
+	printk("ATSE Driver:%s:%d: failed to find phy dev: phy_id_1 = 0x%x, phy_id_2 = 0x%x\n", __FILE__, __LINE__, phy_id_1, phy_id_2);
+	return NULL;
+
+found_phy_dev:
+	ATSE_DEBUG_PRINT_PHY_DEV(oui, model_num, rev_num, phy_dev);
+	return phy_dev;
+}
+
+
+/*
+ *------------------------------------------------------------------------------
+ *  Side Effect:  Write detected PHY address to MAC register mdio_addr_0.
+ *
+ *------------------------------------------------------------------------------
+ */
+static struct atse_phy_device *
+atse_detect_phy(void)
+{
+	int phy_addr;
+	int phy_id_1;
+	int phy_id_2;
+	int found_phy;
+	
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	/* Detect if a valid phy exists */
+	/* probe Marvel PHY MDIO address by blindliy scanning all the
+	 * addresses until a valid PHY ID is abtained.  When a valid
+	 * PHY is detected, the MAC register for mdio_addr_0 will be
+	 * written with the valid PHY address from which a valid PHY
+	 * ID was detected.
+	 */
+	
+	found_phy = 0;
+	for (phy_addr = 0x0; phy_addr < 0xFF; phy_addr++) {
+		/* set the phy address to the mac map data */
+		writel(phy_addr, ATSE_MAC_REG_MDIO_ADDR_0);
+		phy_id_1 = readl(ATSE_MAC_REG_MDIO_SPACE_0 + ATSE_PHY_ID_1_OFFSET);
+		phy_id_2 = readl(ATSE_MAC_REG_MDIO_SPACE_0 + ATSE_PHY_ID_2_OFFSET);
+		if (phy_id_1 != phy_id_2) {
+			found_phy = 1;
+			break;
+		}
+	}
+
+	if (!found_phy) {
+		/* failed to detect phy */
+		return NULL;
+	}
+
+	return get_phy_dev(phy_id_1, phy_id_2);
+}
+
+
+static int atse_hw_send_data(char *data, int len, struct net_device *ndev)
+{
+	/* This function is to wirte data to TX FIFO */
+
+	int timeout = 0;
+	struct atse_sgdma_desc *desc = (struct atse_sgdma_desc *)ATSE_SGDMA_DESC_MEM_BASE;
+	struct atse_sgdma_desc *cur_desc = &(desc[ATSE_SGDMA_TX_FIRST_DESC_OFFSET]);
+	struct atse_sgdma_desc *next_desc = &(desc[ATSE_SGDMA_TX_SECOND_DESC_OFFSET]);
+
+#ifndef ATSE_SGDMA_DO_UNALIGNED_TRANSFER
+	int align_offset;
+#endif /* ATSE_SGDMA_DO_UNALIGNED_TRANSFER */
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+#ifndef ATSE_SGDMA_DO_UNALIGNED_TRANSFER
+	/* Since sgdma hardware can not do unaligned transfer,
+	 * software needs to do extra for 32-bit alignment with the
+	 * data pointer.
+	 */
+
+	/* Aligment check */
+	/*check if the first 2 LSBs are all zeros */
+	align_offset  = (u32)data & 0x02;
+	if (align_offset != 0) {
+		data -= 2;
+		len += 2;
+		ATSE_SET_MAC_TX_SHIFT16_ON();
+	} else {
+		ATSE_SET_MAC_TX_SHIFT16_OFF();
+	}
+#endif /* not ATSE_SGDMA_DO_UNALIGNED_TRANSFER */
+
+ 	ATSE_DEBUG_PRINT_TX_DATA(data, len, align_offset);
+
+	/* clear bit 31, if any, to get rid of uncashed flag.  Not portable, FIXMEJOE*/
+	data = (char *)ioremap_fullcache((unsigned long)data, 1234);
+	/* flush data out of cache */
+	flush_dcache_range((unsigned long)data, (unsigned long)data + len);
+
+	/* prepare mem-to-stream memory buffer descriptores */
+	/*
+	 * Mark the "next" descriptor as "not" owned by hardware. This
+	 * prevents The SGDMA controller from continuing to process the
+	 * chain. This is done as a single IO write to bypass cache, without
+	 * flushing the entire descriptor, since only the 8-bit descriptor
+	 * status must be flushed.
+	 */
+	memset(cur_desc, 0, sizeof(struct atse_sgdma_desc));
+	memset(next_desc, 0, sizeof(struct atse_sgdma_desc));
+	next_desc->control &= ~ATSE_SGDMA_DESC_CONTROL_OWNED_BY_HW_BIT;
+
+	/* now assemble the descriptor */
+	cur_desc->read_addr = (u32 *) data;
+	cur_desc->write_addr = NULL; /* N/A for mem-stream interface */
+	cur_desc->next_desc = (u32 *)next_desc;
+	/* cur_desc->read_addr_pad = 0x0; */
+	/* cur_desc->write_addr_pad = 0x0; */
+	/* cur_desc->next_desc_pad = 0x0; */
+	cur_desc->bytes_to_transfer = len;
+	/* cur_desc->bytes_transferred = 0; */
+	/* cur_desc->read_burst_size = 0; */
+	/* cur_desc->write_burst_size = 0; */
+
+	/*
+	 * Set the descriptor control block as follows:
+	 * - Set "owned by hardware" bit
+	 * - Set "generte EOP" bit
+	 * - Unset the "read from fixed address" bit
+	 * - Set the "write to fixed address bit (which serves
+	 *   serves as a "generate SOP" control bit in memory-to-stream mode).
+	 * - Unet the 4-bit atlantic channel
+	 *
+	 * Note that for the unset part, nothing to do because of
+	 * memset() has been called
+	 *
+	 * Note that this step is performed after all other descriptor information
+	 * has been filled out so that, if the controller already happens to be
+	 * pointing at this descriptor, it will not run (via the "owned by hardware"
+	 * bit) until all other descriptor information has been set up.
+	 */
+	cur_desc->control = (
+		ATSE_SGDMA_DESC_CONTROL_OWNED_BY_HW_BIT             |
+		ATSE_SGDMA_DESC_CONTROL_GENERATE_EOP_BIT            |
+		ATSE_SGDMA_DESC_CONTROL_WRITE_FIXED_ADDRESS_BIT
+		);
+	
+	/* flush the cached descriptos to the physical memory */
+	flush_dcache_range((unsigned long)cur_desc, 
+		(unsigned long)cur_desc + sizeof(struct atse_sgdma_desc));
+	flush_dcache_range((unsigned long)next_desc, 
+		(unsigned long)next_desc + sizeof(struct atse_sgdma_desc));
+
+	/*
+	 * Now to do Synchronous SGDMA copy from buffer memory into
+	 * transmit FIFO. Waits until SGDMA has completed.  Raw
+	 * function without any error checks.
+	 */
+
+	/* Make sure DMA controller is not busy from a former command
+	 *  and TX is able to accept data timeout = 0;
+	 */
+	while ( ATSE_GET_SGDMA_TX_STATUS() & ATSE_SGDMA_STATUS_BUSY_BIT ) {
+		if(timeout++ == ATSE_SGDMA_BUSY_TIMEOUT_COUNT) {
+			printk("ATSE driver sgdma timedout:%s:%d\n", __FILE__, __LINE__);
+			return -1;  /*  avoid being stuck here */
+		}
+	}
+
+	ATSE_CLEAR_SGDMA_TX_CONTROL();
+	ATSE_CLEAR_SGDMA_TX_STATUS();
+
+	/* Point the controller at the descriptor */
+	ATSE_SET_SGDMA_TX_WITH_DESC((u32)cur_desc);
+
+	ATSE_DEBUG_PRINT_DESC(cur_desc);
+	ATSE_DEBUG_PRINT_DESC(next_desc);
+
+	/* Set up and Start SGDMA (blocking call) */
+	/*
+	 * Set up SGDMA controller to:
+	 * - Disable interrupt generation ????
+	 * - Run once a valid descriptor is written to controller
+	 * - Stop on an error with any particular descriptor
+	 */
+	ATSE_SET_SGDMA_TX_CONTROL(
+		ATSE_SGDMA_CONTROL_IE_CHAIN_COMPLETED_BIT |
+		ATSE_SGDMA_CONTROL_IE_GLOBAL_BIT          |
+		ATSE_SGDMA_CONTROL_RUN_BIT                |
+		ATSE_SGDMA_CONTROL_STOP_DMA_ER_BIT        |
+		ATSE_GET_SGDMA_TX_CONTROL()
+		);
+
+	/* wait for descriptor chain to complete */
+	while ( (ATSE_GET_SGDMA_TX_STATUS() & ATSE_SGDMA_STATUS_BUSY_BIT) );
+
+	/* Clear the Run Bit */
+	ATSE_SET_SGDMA_TX_CONTROL( ATSE_GET_SGDMA_TX_CONTROL() &
+				~ATSE_SGDMA_CONTROL_RUN_BIT );
+
+	ATSE_DEBUG_PRINT_DESC(cur_desc);
+	cur_desc = (struct atse_sgdma_desc *) ((u32)cur_desc | (((u32) 1) << 31));
+	ATSE_DEBUG_PRINT_DESC(cur_desc);
+
+	g_tx_bytes_transferred = cur_desc->bytes_transferred;
+
+	ATSE_CLEAR_SGDMA_TX_STATUS();
+
+	return 0;
+
+}
+
+
+static int atse_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	int len;
+	char shortpkt[ETH_ZLEN];
+	char *data;
+
+	struct atse_board_priv *bd_priv = netdev_priv(ndev);
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	data = skb->data;
+	len = skb->len;
+
+	if (len < ETH_ZLEN) {
+		memset(shortpkt, 0, ETH_ZLEN);
+		memcpy(shortpkt, skb->data, skb->len);
+		len = ETH_ZLEN;
+		data = shortpkt;
+	}
+	ndev->trans_start = jiffies;  /* save the timestamp */
+
+	/* remember the skb, so we can free it at interrupt time */
+	bd_priv->pending_tx_skb = skb;
+
+	/* hardware transmit now */
+	atse_hw_send_data(data, len, ndev);
+
+
+
+	return 0;
+}
+
+static void atse_timeout(struct net_device *ndev)
+{
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	return;
+}
+
+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct net_device_stats *atse_query_stats(struct net_device *ndev)
+{
+	struct atse_board_priv *bd_priv = netdev_priv(ndev);
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+
+	return &bd_priv->stats;
+}
+
+static void atse_set_multicast_list(struct net_device *ndev)
+{
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+}
+
+
+static void
+atse_shutdown(struct net_device *ndev)
+{
+	struct atse_board_priv *bd_priv;
+	struct sk_buff *pending_tx_skb;
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+	printk("++++JoeCamel:%s:%d:%s: FIXME\n", __FILE__, __LINE__, __FUNCTION__);
+
+
+	bd_priv = netdev_priv(ndev);
+	/* no more interrupts for me */
+	spin_lock_irq(&bd_priv->tx_lock);
+	pending_tx_skb = bd_priv->pending_tx_skb;
+	bd_priv->pending_tx_skb = NULL;
+	spin_unlock_irq(&bd_priv->tx_lock);
+	if (pending_tx_skb)
+		dev_kfree_skb(pending_tx_skb);
+
+	ATSE_SET_PHY_POWER_DOWN();
+
+	/* RESET device */
+	
+	/* PHY RESET */
+
+	/* Power-Down PHY */
+
+	/* Disable all interrupt */
+
+	/* Disable RX */
+
+}
+
+static const struct net_device_ops atse_netdev_ops = {
+	.ndo_open               = atse_open,
+	.ndo_stop               = atse_close,
+	.ndo_start_xmit         = atse_hard_start_xmit,
+	.ndo_tx_timeout         = atse_timeout,
+	.ndo_set_multicast_list = atse_set_multicast_list,
+};
+
+
+static int atse_probe(struct net_device *ndev)
+{
+	struct atse_board_priv *bd_priv;
+	union {
+		unsigned char c[4];
+		unsigned int i;
+	} mac_addr_0, mac_addr_1;
+
+	DECLARE_MAC_BUF(mac_buf);
+	int ret;
+	struct atse_phy_device *phy_dev;
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	/* 
+	 * PHY Hardware has to be there: When detected, the phy
+	 * address will be written in MAC register, a side effect.
+	 */
+	phy_dev = atse_detect_phy();
+	if (!phy_dev) {
+		printk("ATSE driver failed to detect an ether phy:%s:%d:%s()\n",
+		       __FILE__, __LINE__, __FUNCTION__);
+		return -1;
+	}
+
+	/* So a valid PHY exists, we assume that we have found netowrk hardware. */
+	/* then shut everything down to save power */
+	ATSE_SET_PHY_POWER_DOWN();
+
+	/* Set up network device data structure*/
+
+	/* Set up the board priv data */
+	bd_priv = (struct atse_board_priv *)netdev_priv(ndev);
+	memset(bd_priv, 0, sizeof(*bd_priv));
+
+	spin_lock_init(&bd_priv->tx_lock);
+	spin_lock_init(&bd_priv->rx_lock);
+	bd_priv->phy_dev = phy_dev;
+
+	/* fill in data for net_device stucture */
+	ether_setup(ndev);
+	mac_addr_0.i = readl(ATSE_MAC_REG_MAC_ADDR_0);
+	mac_addr_1.i = readl(ATSE_MAC_REG_MAC_ADDR_1);
+
+	/* fill in ethernet HW address */
+	ndev->dev_addr[0] = mac_addr_0.c[0];
+	ndev->dev_addr[1] = mac_addr_0.c[1];
+	ndev->dev_addr[2] = mac_addr_0.c[2];
+	ndev->dev_addr[3] = mac_addr_0.c[3];
+	ndev->dev_addr[4] = mac_addr_1.c[0];
+	ndev->dev_addr[5] = mac_addr_1.c[1];
+	ndev->get_stats = atse_query_stats;
+	ndev->netdev_ops = &atse_netdev_ops;
+
+	ret = register_netdev(ndev);
+	if (ret != 0) {
+		printk("ATSE driver:%s:%d:register_netdev() failed\n", __FILE__, __LINE__);
+		goto OUT_ERR;
+	} else {
+		/*
+		 * now, print out the card info, in a short format:
+		 * 1. Device name
+		 * 2. Driver version
+		 * 3. PHY revision number
+		 * 4. Ethernet hardware address
+		 * 
+		 *
+		 */
+		printk("%s: %s \n", ndev->name, atse_version_str);
+		printk("%s: %s \n", ndev->name, atse_version_str1);
+		printk("%s: Altera Tripple Speed, ether hw addr %s",
+		       ndev->name, print_mac(mac_buf, ndev->dev_addr));
+		printk(", %s", bd_priv->phy_dev->name);
+		printk("\n");
+
+
+	}
+
+	return 0;
+
+OUT_ERR:
+	free_netdev(ndev);
+	return ret;
+}
+
+
+static inline void atse_request_datacs(struct platform_device *pdev, struct net_device *ndev)
+{
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	return;
+}
+
+
+static void __exit atse_exit(void)
+{
+	/* platform_driver_unregister(&atse_driver); */
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+	printk("++++JoeCamel:%s:%d:%s: FIXME\n", __FILE__, __LINE__, __FUNCTION__);
+
+}
+
+static void atse_release_board(struct platform_device *pdev, struct atse_board_priv *bd_priv)
+{
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+	printk("++++JoeCamel:%s:%d:%s: FIXME\n", __FILE__, __LINE__, __FUNCTION__);
+
+}
+
+
+static int atse_drv_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct atse_board_priv *bd_priv = netdev_priv(ndev);
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	platform_set_drvdata(pdev, NULL);
+
+	unregister_netdev(ndev);
+	atse_release_board(pdev, bd_priv);
+	free_netdev(ndev);
+
+	return 0;
+}
+
+static int
+atse_drv_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct net_device *ndev = platform_get_drvdata(dev);
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+	printk("++++JoeCamel:%s:%d:%s: FIXME\n", __FILE__, __LINE__, __FUNCTION__);
+
+	if (ndev) {
+		if (netif_running(ndev)) {
+			netif_device_detach(ndev);
+			atse_shutdown(ndev);
+		}
+	}
+	return 0;
+}
+
+/*
+ * Initilize ATSE Whole Board
+ */
+static void atse_init_atse(struct net_device *ndev)
+{
+  struct atse_board_priv *bd_priv = (struct atse_board_priv *) netdev_priv(ndev);
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+	printk("++++JoeCamel:%s:%d:%s: FIXME\n", __FILE__, __LINE__, __FUNCTION__);
+
+	/* Init PHY  */
+
+	/* Init Descriptors */
+
+	/* Init SGDMA_TX Controller */
+
+	/* Init SGDMA_RX Controller */
+
+	/* Init Driver variable */
+	bd_priv->tx_pkt_cnt = 0;
+	bd_priv->queue_pkt_len = 0;
+	ndev->trans_start = 0;
+}
+
+
+static void atse_reset(struct atse_board_priv *bd_priv)
+{
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+	printk("++++JoeCamel:%s:%d:%s: FIXME\n", __FILE__, __LINE__, __FUNCTION__);
+
+	/* RESET device */
+	//writeb(DM9000_NCR, db->io_addr);
+	//udelay(200);
+	//writeb(NCR_RST, db->io_data);
+	//udelay(200);
+}
+
+
+
+static int atse_drv_resume(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct atse_board_priv *bd_priv = (struct atse_board_priv *) netdev_priv(ndev);
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+	printk("++++JoeCamel:%s:%d:%s: FIXME\n", __FILE__, __LINE__, __FUNCTION__);
+
+	if (ndev) {
+		if (netif_running(ndev)) {
+			atse_reset(bd_priv);
+			atse_init_atse(ndev);
+			netif_device_attach(ndev);
+		}
+	}
+	return 0;
+}
+
+
+
+static int atse_drv_probe(struct platform_device *pdev)
+{
+	struct net_device *ndev;
+	struct atse_board_priv *bd_priv;
+	struct resource *res_desc_mem;
+	struct resource *res_sgdma_rx_mem;
+	struct resource *res_sgdma_tx_mem;
+	struct resource *res_sgdma_rx_irq;
+	struct resource *res_sgdma_tx_irq;
+	int ret;
+
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+
+	/* 1. Get descriptor mem resurce */
+	res_desc_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, ATSE_RESOURCE_NAME_STR_DESC_MEM);
+	if (!res_desc_mem) {
+		printk("++++ATSE:%s:%d:platform_get_resource_byname() failed\n", __FILE__, __LINE__);
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (!request_mem_region(res_desc_mem->start, res_desc_mem->end - res_desc_mem->start + 1, ATSE_CARDNAME)) {
+		printk("******ATSE:%s:%d:request_mem_region() failed\n", __FILE__, __LINE__);
+		ret = -EBUSY;
+		goto out;
+	}
+	
+	/* 2. Get sgdma_rx mem resurce */
+	res_sgdma_rx_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, ATSE_RESOURCE_NAME_STR_SGDMA_RX_MEM);
+	if (!res_sgdma_rx_mem) {
+		printk("++++ATSE:%s:%d:platform_get_resource_byname() failed\n", __FILE__, __LINE__);
+		ret = -ENODEV;
+		goto out;
+	}
+	if (!request_mem_region(res_sgdma_rx_mem->start, res_sgdma_rx_mem->end - res_sgdma_rx_mem->start + 1, ATSE_CARDNAME)) {
+		printk("******ATSE:%s:%d:request_mem_region() failed\n", __FILE__, __LINE__);
+		ret = -EBUSY;
+		goto out;
+	}
+	
+	/* 3. Get sgdma_tx mem resurce */
+	res_sgdma_tx_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, ATSE_RESOURCE_NAME_STR_SGDMA_TX_MEM);
+	if (!res_sgdma_tx_mem) {
+		printk("++++ATSE:%s:%d:platform_get_resource_byname() failed\n", __FILE__, __LINE__);
+		ret = -ENODEV;
+		goto out;
+	}
+	if (!request_mem_region(res_sgdma_tx_mem->start, res_sgdma_tx_mem->end - res_sgdma_tx_mem->start + 1, ATSE_CARDNAME)) {
+		printk("******ATSE:%s:%d:request_mem_region() failed\n", __FILE__, __LINE__);
+		ret = -EBUSY;
+		goto out;
+	}
+	
+	/* 4. Get sgdma_tx irq resurce */
+	res_sgdma_tx_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, ATSE_RESOURCE_NAME_STR_SGDMA_TX_IRQ);
+	if (!res_sgdma_tx_irq) {
+		printk("++++ATSE:%s:%d:platform_get_resource_byname() failed\n", __FILE__, __LINE__);
+		ret = -ENODEV;
+		goto out;
+	}
+
+
+	/* 5. Get sgdma_rx irq resurce */
+	res_sgdma_rx_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, ATSE_RESOURCE_NAME_STR_SGDMA_RX_IRQ);
+	if (!res_sgdma_rx_irq) {
+		printk("++++ATSE:%s:%d:platform_get_resource_byname() failed\n", __FILE__, __LINE__);
+		ret = -ENODEV;
+		goto out;
+	}
+
+
+
+
+
+	ndev = alloc_etherdev( sizeof(struct atse_board_priv) );
+	if (!ndev) {
+		printk("%s:%d:%s could not allocate device\n", __FILE__, __LINE__, ATSE_CARDNAME);
+		ret = -ENOMEM;
+		goto out;
+	}
+	
+	bd_priv = netdev_priv(ndev);
+	bd_priv->res_desc_mem     =     res_desc_mem;    
+	bd_priv->res_sgdma_rx_mem = res_sgdma_rx_mem;
+	bd_priv->res_sgdma_tx_mem = res_sgdma_tx_mem;
+	bd_priv->res_sgdma_rx_irq = res_sgdma_rx_irq;
+	bd_priv->res_sgdma_tx_irq = res_sgdma_tx_irq;
+
+
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+
+	platform_set_drvdata(pdev, ndev);	
+	atse_probe(ndev);
+	
+	
+	return 0;
+	
+out:
+	return ret;
+
+}
+
+
+static struct platform_driver atse_driver = {
+	.driver	= {
+		/* the name must be the same as in struct platform_device */
+		.name    = ATSE_CARDNAME,
+		.owner	 = THIS_MODULE,
+	},
+	.probe   = atse_drv_probe,
+	.remove  = atse_drv_remove,
+	.suspend = atse_drv_suspend,
+	.resume  = atse_drv_resume,
+};
+
+
+static int __init
+atse_init(void)
+{
+	ATSE_DEBUG_PRINT_FUNC_TRACE_ENTER();
+	/* probe board and register */
+	return platform_driver_register(&atse_driver);
+}
+
+module_init(atse_init);
+module_exit(atse_exit);
diff --git a/drivers/net/atse.h b/drivers/net/atse.h
new file mode 100644
index 0000000..132e714
--- /dev/null
+++ b/drivers/net/atse.h
@@ -0,0 +1,424 @@
+/*
+ *  linux/drivers/net/atse.h
+ *
+ *  Copyright (C) 2008       Joseph "Camel" Chen (joe4camel@gmail.com)
+ *
+ *  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _ATSE_H_
+#define _ATSE_H_
+
+/* Stop compile if nios2.h is not generated with the Altera TSE-SGDMA FPGA design */
+#ifndef na_tse_mac_control_port
+#error "**** This build has not been configured with Alteras example design of TSE-SGDMA."
+#error "**** You need to do: make vendor_hwselect SYSPTF=<your_path>/NiosII_stratixII_2s60_RoHS_TSE_SGDMA_sopc.ptf"
+#error "**** Or, You need to unselect ATSE ethernet driver with make menuconfig"
+#endif
+
+#define NIOS2_DCACHE_LINE_SIZE  32
+
+#define ATSE_CARDNAME "atse"
+
+
+#define ATSE_RESOURCE_NAME_STR_DESC_MEM     "atse_resource_desc_mem"
+#define ATSE_RESOURCE_NAME_STR_SGDMA_RX_MEM "atse_resource_sgdma_rx_mem"
+#define ATSE_RESOURCE_NAME_STR_SGDMA_TX_MEM "atse_resource_sgdma_tx_mem"
+#define ATSE_RESOURCE_NAME_STR_SGDMA_RX_IRQ "atse_resource_sgdma_rx_irq"
+#define ATSE_RESOURCE_NAME_STR_SGDMA_TX_IRQ "atse_resource_sgdma_tx_irq"
+
+
+
+/* 4 bytes in a register word */
+#define BYTES_IN_WORD                            4
+
+/*  macros starting with na_ are defined in nios2.h */
+#define ATSE_MAC_BASE                     ioremap(na_tse_mac_control_port, 0x3FC + 1)
+#define ATSE_MAC_REG_MAC_ADDR_0          (ATSE_MAC_BASE + 0x0C)
+#define ATSE_MAC_REG_MAC_ADDR_1          (ATSE_MAC_BASE + 0x10)
+
+/* the memory descriptore */
+#define ATSE_SGDMA_DESC_MEM_BASE          na_descriptor_memory_s1
+
+#define ATSE_SGDMA_TX_IRQ                 na_sgdma_tx_irq
+#define ATSE_SGDMA_RX_IRQ                 na_sgdma_rx_csr_irq
+
+/*
+ * The hard coded numbers are from the following documents: Tables
+ * 4-10 and 4-11
+ *
+ * 1.  Triple * Speed Ethernet, MegaCore Function user Guide, MegaCore
+ * Version 7.2, * Document Date October 2007, Altera
+ *
+ */
+
+
+/* number of bytes in one MDIO register */
+#define ATSE_PHY_ID_1_OFFSET   (2 * BYTES_IN_WORD)
+#define ATSE_PHY_ID_2_OFFSET   (3 * BYTES_IN_WORD)
+#define ATSE_MAC_REG_MDIO_ADDR_0   (ATSE_MAC_BASE + 0x3C  )
+#define ATSE_MAC_REG_MDIO_ADDR_1   (ATSE_MAC_BASE + 0x40  )
+#define ATSE_MAC_REG_MDIO_SPACE_0  (ATSE_MAC_BASE + 0x0200)
+#define ATSE_MAC_REG_MDIO_SPACE_1  (ATSE_MAC_BASE + 0x0280)
+
+#define ATSE_SET_PHY_MDIO_CONTROL(n) writel((n), ATSE_MAC_REG_MDIO_SPACE_0)
+#define ATSE_GET_PHY_MDIO_CONTROL()  readl(ATSE_MAC_REG_MDIO_SPACE_0)
+
+#define ATSE_GET_PHY_MDIO_STATUS()   readl(ATSE_MAC_REG_MDIO_SPACE_0 + 1 * BYTES_IN_WORD)
+
+#define ATSE_PHY_MDIO_CONTROL_RESET_BIT                  (0x01 << 15)
+
+#define ATSE_PHY_MDIO_CONTROL_AUTO_NEGO_ENA_BIT          (0x01 << 12)
+#define ATSE_PHY_MDIO_CONTROL_POWER_DOWN_BIT             (0x01 << 11)
+
+#define ATSE_PHY_MDIO_CONTROL_START_AUTO_NEGO_BIT        (0x01 << 9)
+#define ATSE_PHY_MDIO_CONTROL_FULL_DUP_MODE_BIT          (0x01 << 8)
+
+#define ATSE_PHY_MDIO_CONTROL_AUTO_NEG_COMPLETE_BIT      (0x01 << 5)
+
+/* PHY Speed Settings */
+#define ATSE_SET_PHY_SPEED(the_speed)					\
+	do {								\
+		u32 i;							\
+		i = ATSE_GET_PHY_MDIO_CONTROL();			\
+		switch(the_speed) {					\
+		case 1000:						\
+			i |= (0x01 << 6);				\
+                        i &= ~(0x01 << 13);				\
+                        break;						\
+		default:						\
+			printk("ATSE: unkonw phy speed:%d\n", the_speed); \
+			printk("ATSE: use 100 phy speed\n");		\
+		case 100:						\
+			i &= ~(0x01 << 6);				\
+			i |= (0x01 << 13);				\
+                        break;						\
+		case 10:						\
+			i &= ~(0x01 << 6);				\
+			i &= ~(0x01 << 13);				\
+                        break;						\
+		}							\
+		ATSE_SET_PHY_MDIO_CONTROL(i);                           \
+	} while(0)
+
+                 
+/* PHY ID for Marvell 88E1111 */
+#define ATSE_PHY_ID_MARVELL                 0x0141
+#define ATSE_PHY_VENDOR_NAME_STR_MARVELL    "Marvell 88E1111 PHY"
+
+/* Marvell Vendor Specific, according to Altera source code */
+#define ATSE_READ_PHY_MDIO_REG(n)     readl(ATSE_MAC_REG_MDIO_SPACE_0 + (n) * BYTES_IN_WORD)
+
+#define ATSE_GET_MVLPHY_LINK_STATUS() ATSE_READ_PHY_MDIO_REG(17)
+#define ATSE_MVLPHY_IS_1000(dat)     (((dat) >> 14) & 0x03) == 2 ? 1: 0
+#define ATSE_MVLPHY_IS_FULL_DUP(dat) ( (dat) >> 13) & 0x1
+
+/* PHY ID for National DP83865 */
+#define ATSE_PHY_ID_NATIONAL_1          0x20005c7a
+#define ATSE_PHY_VENDOR_NAME_STR_NATIONAL_1   "National DP83865 PHY"
+
+/* this PHY reportedly comes with Altera NEEK kit board */
+#define ATSE_PHY_ID_NATIONAL_2          0x20005c90
+#define ATSE_PHY_VENDOR_NAME_STR_NATIONAL_2   "National Semiconductor"
+
+/* Microtronix Ethernet PHY Design Kit, added by Eintisy */
+#define ATSE_PHY_ID_TDK_78Q2120C        0x000e70c5
+#define ATSE_PHY_VENDOR_NAME_MICROTRONIX      "Microtronix Ethernet PHY"
+
+/* make up an unknown phy ID */
+#define ATSE_PHY_ID_UNKNOWN             0x12345678
+
+/* na_sgdma_tx is parsed from the PTF file and defined in nios2_syste.h */
+#define ATSE_SGDMA_TX_BASE    ioremap(na_sgdma_tx, 0x400)
+/* na_sgdma_rx_csr is parsed from PTF file  and defined in nios2_syste.h */
+#define ATSE_SGDMA_RX_BASE    ioremap(na_sgdma_rx_csr, 0x400)
+
+/* Regsiter 0 offset */
+#define ATSE_SGDMA_TX_STATUS_BASE  ATSE_SGDMA_TX_BASE
+#define ATSE_SGDMA_RX_STATUS_BASE  ATSE_SGDMA_RX_BASE
+
+/* Register 4 Offset, a 4-byte register */
+#define ATSE_SGDMA_TX_CONTROL_BASE (ATSE_SGDMA_TX_BASE + 4*BYTES_IN_WORD)
+#define ATSE_SGDMA_RX_CONTROL_BASE (ATSE_SGDMA_RX_BASE + 4*BYTES_IN_WORD)
+
+
+/* sgdma Control Register Map  */
+#define ATSE_SGDMA_CONTROL_IE_ERROR_BIT                      (0x01 << 0)
+#define ATSE_SGDMA_CONTROL_IE_EOP_ENCOUNTERED_BIT            (0x01 << 1)
+#define ATSE_SGDMA_CONTROL_IE_DESC_COMPLETED_BIT             (0x01 << 2)
+#define ATSE_SGDMA_CONTROL_IE_CHAIN_COMPLETED_BIT            (0x01 << 3)
+#define ATSE_SGDMA_CONTROL_IE_GLOBAL_BIT                     (0x01 << 4)
+#define ATSE_SGDMA_CONTROL_RUN_BIT                           (0x01 << 5)
+#define ATSE_SGDMA_CONTROL_STOP_DMA_ER_BIT                   (0x01 << 6)
+#define ATSE_SGDMA_CONTROL_SW_RESET_BIT                      (0x01 << 16)
+#define ATSE_SGDMA_CONTROL_PARK_BIT                          (0x01 << 17)
+#define ATSE_SGDMA_CONTROL_CLEAR_INTERRUPT_BIT               (0x01 << 31)
+
+/* sgdms status Register Map */
+#define ATSE_SGDMA_STATUS_ERROR_BIT                          (0x01 << 0)
+#define ATSE_SGDMA_STATUS_EOP_ENCOUNTERED_BIT                (0x01 << 1)
+#define ATSE_SGDMA_STATUS_DESCRIPTOR_COMPLETED_BIT           (0x01 << 2)
+#define ATSE_SGDMA_STATUS_CHAIN_COMPLETED_BIT                (0x01 << 3)
+#define ATSE_SGDMA_STATUS_BUSY_BIT                           (0x01 << 4)
+
+
+/*
+ * sgdma buffer descriptor status bit map
+ */
+#define ATSE_SGDMA_DESC_STATUS_E_CRC_BIT                       (0x01 << 0)
+#define ATSE_SGDMA_DESC_STATUS_E_PARITY_BIT                    (0x01 << 1)
+#define ATSE_SGDMA_DESC_STATUS_E_OVERFLOW_BIT                  (0x01 << 2)
+#define ATSE_SGDMA_DESC_STATUS_E_SYNC_BIT                      (0x01 << 3)
+#define ATSE_SGDMA_DESC_STATUS_E_UEOP_BIT                      (0x01 << 4)
+#define ATSE_SGDMA_DESC_STATUS_E_MEOP_BIT                      (0x01 << 5)
+#define ATSE_SGDMA_DESC_STATUS_E_MSOP_BIT                      (0x01 << 6)
+#define ATSE_SGDMA_DESC_STATUS_TERMINATED_BY_EOP_BIT           (0x01 << 7)
+
+#define ATSE_ENABLE_SGDMA_RX_INT()                                       \
+	do {                                                             \
+	ATSE_SET_SGDMA_RX_CONTROL(                                       \
+		ATSE_SGDMA_CONTROL_IE_ERROR_BIT           |              \
+		ATSE_SGDMA_CONTROL_IE_EOP_ENCOUNTERED_BIT |              \
+		ATSE_SGDMA_CONTROL_IE_DESC_COMPLETED_BIT  |              \
+		ATSE_SGDMA_CONTROL_IE_CHAIN_COMPLETED_BIT |              \
+		ATSE_SGDMA_CONTROL_IE_GLOBAL_BIT          |              \
+		ATSE_GET_SGDMA_RX_CONTROL()                              \
+		);                                                       \
+	} while(0)
+	
+
+
+#define ATSE_SGDMA_BUSY_TIMEOUT_COUNT                         1000
+#define ATSE_PHY_AUTONEG_TIMEOUT_COUNT                          10
+
+
+
+/* set the control field bit 0 to 1 */
+#define ATSE_SGDMA_DESC_CONTROL_GENERATE_EOP_BIT              0x01
+/* set the control field bit 1 to 1 */
+#define ATSE_SGDMA_DESC_CONTROL_READ_FIXED_ADDRESS_BIT        (0x1 << 1)
+/* set the control field bit 2 to 1 */
+#define ATSE_SGDMA_DESC_CONTROL_WRITE_FIXED_ADDRESS_BIT       (0x1 << 2)
+/* set the control field bit 7 to 1 */
+#define ATSE_SGDMA_DESC_CONTROL_OWNED_BY_HW_BIT               (0x1 << 7)
+
+
+
+/* Altera TSE MAC Bit Maps */
+#define ATSE_MAC_TX_CMD_STAT_OMIT_CRC_BIT     (1 << 17)
+#define ATSE_MAC_TX_CMD_STAT_TXSHIFT16_BIT    (1 << 18)
+#define ATSE_MAC_RX_CMD_STAT_RXSHIFT16_BIT    (1 << 25)
+
+
+#define ATSE_GET_MAC_REV()                readl(ATSE_MAC_BASE + 0x0)
+
+#define ATSE_SET_MAC_SCRATCH(n)           writel((n), ATSE_MAC_BASE + 0x04)
+#define ATSE_GET_MAC_SCRATCH()            readl( ATSE_MAC_BASE + 0x04)
+
+#define ATSE_SET_MAC_CMD_CONFIG(n)        writel((n), ATSE_MAC_BASE + 0x08)
+#define ATSE_GET_MAC_CMD_CONFIG()         readl(ATSE_MAC_BASE + 0x08)
+
+#define ATSE_SET_MAC_REG_STAT(n)          writel((n), ATSE_MAC_BASE + 0x58))
+#define ATSE_GET_MAC_REG_STAT()           readl(ATSE_MAC_BASE + 0x58)
+
+#define ATSE_SET_MAC_TX_CMD_STAT(n)       writel((n), ATSE_MAC_BASE + 0xE8)
+#define ATSE_GET_MAC_TX_CMD_STAT()        readl(ATSE_MAC_BASE + 0xE8)
+
+#define ATSE_SET_MAC_RX_CMD_STAT(n)       writel((n), ATSE_MAC_BASE + 0xEC)
+#define ATSE_GET_MAC_RX_CMD_STAT()        readl(ATSE_MAC_BASE + 0xEC)
+
+
+
+/* Altera TSE MAC Command-Config register Bit map */
+#define ATSE_MAC_CC_TX_ENA_BIT        0x01
+#define ATSE_MAC_CC_RX_ENA_BIT       (0x01 << 1 )
+#define ATSE_MAC_CC_XON_GEN_BIT      (0x01 << 2 )
+#define ATSE_MAC_CC_ETH_SPEED_BIT    (0x01 << 3 )
+#define ATSE_MAC_CC_PROMIS_ENA_BIT   (0x01 << 4 )
+#define ATSE_MAC_CC_PAD_ENA_BIT      (0x01 << 5 )
+#define ATSE_MAC_CC_CRC_FWD_BIT      (0x01 << 6 )
+#define ATSE_MAC_CC_PAUSE_FWD_BIT    (0x01 << 7 )
+#define ATSE_MAC_CC_PAUSE_IGN_BIT    (0x01 << 8 )
+#define ATSE_MAC_CC_TX_ADDR_INS_BIT  (0x01 << 9 )
+#define ATSE_MAC_CC_HD_ENA_BIT       (0x01 << 10)
+#define ATSE_MAC_CC_EXCESS_COL_BIT   (0x01 << 11)
+#define ATSE_MAC_CC_LATE_COL_BIT     (0x01 << 12)
+#define ATSE_MAC_CC_SW_RESET_BIT     (0x01 << 13)
+#define ATSE_MAC_CC_MHASH_SEL_BIT    (0x01 << 14)
+#define ATSE_MAC_CC_LOOP_ENA_BIT     (0x01 << 15)
+#define ATSE_MAC_CC_TX_ADDR_SEL_MAC_0_MAC_1_BIT        (0x00 << 16)
+#define ATSE_MAC_CC_TX_ADDR_SEL_SMAC_0_0_SMAC_0_1_BIT  (0x04 << 16)
+#define ATSE_MAC_CC_TX_ADDR_SEL_SMAC_1_0_SMAC_1_1_BIT  (0x05 << 16)
+#define ATSE_MAC_CC_TX_ADDR_SEL_SMAC_2_0_SMAC_2_1_BIT  (0x06 << 16)
+#define ATSE_MAC_CC_TX_ADDR_SEL_SMAC_3_0_SMAC_3_1_BIT  (0x07 << 16)
+#define ATSE_MAC_CC_MAGIC_ENA_BIT                      (0x01 << 19)
+#define ATSE_MAC_CC_SLEEP_BIT                          (0x01 << 20)
+#define ATSE_MAC_CC_WAKEUP_BIT                         (0x01 << 21)
+#define ATSE_MAC_CC_XOFF_GEN_BIT                       (0x01 << 22)
+#define ATSE_MAC_CC_CNTL_FRM_ENA_BIT                   (0x01 << 23)
+#define ATSE_MAC_CC_NO_LEN_CK_BIT                      (0x01 << 24)
+#define ATSE_MAC_CC_ENA_10_BIT                         (0x01 << 25)
+#define ATSE_MAC_CC_RX_ERR_DISCD_BIT                    (0x01 << 26)
+/* Bits 27 -- 30 are reserved */
+#define ATSE_MAC_CC_CNT_RESET_BIT                      (0x01 << 31)
+
+
+
+
+#define ATSE_SET_MAC_FRM_LEN(n)          writel((n), (ATSE_MAC_BASE + 0x14))
+#define ATSE_SET_MAC_RX_SECTION_EMPTY(n) writel((n), (ATSE_MAC_BASE + 0x1C))
+#define ATSE_SET_MAC_RX_SECTION_FULL(n)  writel((n), (ATSE_MAC_BASE + 0x20))
+#define ATSE_SET_MAC_TX_SECTION_EMPTY(n) writel((n), (ATSE_MAC_BASE + 0x24))
+#define ATSE_SET_MAC_TX_SECTION_FULL(n)  writel((n), (ATSE_MAC_BASE + 0x28))
+#define ATSE_SET_MAC_RX_ALMOST_EMPTY(n)  writel((n), (ATSE_MAC_BASE + 0x2C))
+#define ATSE_SET_MAC_RX_ALMOST_FULL(n)   writel((n), (ATSE_MAC_BASE + 0x30))
+#define ATSE_SET_MAC_TX_ALMOST_EMPTY(n)  writel((n), (ATSE_MAC_BASE + 0x34))
+#define ATSE_SET_MAC_TX_ALMOST_FULL(n)   writel((n), (ATSE_MAC_BASE + 0x38))
+
+
+
+
+
+
+#define ATSE_SET_SGDMA_TX_CONTROL(n)        writel((n), ATSE_SGDMA_TX_CONTROL_BASE)
+#define ATSE_GET_SGDMA_TX_CONTROL()         readl(ATSE_SGDMA_TX_CONTROL_BASE)
+#define ATSE_SET_SGDMA_TX_WITH_DESC(n)      writel((n), ATSE_SGDMA_TX_BASE + 8 * BYTES_IN_WORD)
+
+#define ATSE_SET_SGDMA_RX_CONTROL(n)        writel((n), ATSE_SGDMA_RX_CONTROL_BASE)
+#define ATSE_GET_SGDMA_RX_CONTROL()         readl(ATSE_SGDMA_RX_CONTROL_BASE)
+#define ATSE_SET_SGDMA_RX_WITH_DESC(n)      writel((n), ATSE_SGDMA_RX_BASE + 8 * BYTES_IN_WORD)
+
+
+
+#define ATSE_MAC_INIT()   abcd						\
+	do {								\
+		int x=0;						\
+		/* reset phy if neccessary */				\
+                							\
+                /* reset mac */						\
+		while(ATSE_GET_MAC_CMD_CONFIG() & ATSE_MAC_CC_SW_RESET_BIT) { \
+			if( x++ > 10000 ) {				\
+				break;					\
+			}						\
+		}							\
+									\
+		if(x >= 10000) {					\
+			printk("**** JoeCamel:%s:%d:MAC SW reset bit never cleared!\n", __FILE__, __LINE__); \
+		}							\
+									\
+		if ((ATSE_GET_MAC_CMD_CONFIG() & (ATSE_MAC_CC_TX_ENA_BIT | ATSE_MAC_CC_RX_ENA_BIT) )  != 0) \
+			printk("**** JoeCamel:%s:%d:WARN: RX/TX not disabled after reset... missing PHY clock?\n", __FILE__, __LINE__); \
+									\
+		ATSE_SET_MAC_CMD_CONFIG(				\
+			(ATSE_MAC_CC_TX_ENA_BIT    |			\
+			 ATSE_MAC_CC_RX_ENA_BIT    |			\
+			 ATSE_MAC_CC_ETH_SPEED_BIT |			\
+			 0x0) &						\
+			~ATSE_MAC_CC_PROMIS_ENA_BIT			\
+			);						\
+									\
+                							\
+                /* Initialize MAC registers */				\
+                							\
+		ATSE_SET_MAC_FRM_LEN(1518);				\
+                ATSE_SET_MAC_RX_ALMOST_EMPTY(8);			\
+                ATSE_SET_MAC_RX_ALMOST_FULL(8);				\
+                ATSE_SET_MAC_TX_ALMOST_EMPTY(8);			\
+                ATSE_SET_MAC_TX_ALMOST_FULL(3);				\
+                ATSE_SET_MAC_TX_SECTION_EMPTY(1024 - 16);		\
+                ATSE_SET_MAC_TX_SECTION_FULL(0);			\
+                ATSE_SET_MAC_RX_SECTION_EMPTY(1024 - 16);		\
+                ATSE_SET_MAC_RX_SECTION_FULL(0);			\
+        } while (0)
+
+
+
+/* the following number is obtained by inspecting the PTF file:
+ *  0x01401FFF - 0x01400000 + 1 = 0x2000 
+ */
+
+#define ATSE_TOTAL_SGDMA_DESC_MEM            0x2000
+
+
+
+#define ATSE_SGDMA_TX_SW_RESET()   writel(ATSE_SGDMA_CONTROL_SWRESET_BIT, ATSE_SGDMA_TX_CONTROL_BASE)
+#define ATSE_SGDMA_RX_SW_RESET()   writel(ATSE_SGDMA_CONTROL_SWRESET_BIT, ATSE_SGDMA_RX_CONTROL_BASE)
+
+#define ATSE_GET_SGDMA_TX_STATUS() readl(ATSE_SGDMA_TX_STATUS_BASE)
+#define ATSE_GET_SGDMA_RX_STATUS() readl(ATSE_SGDMA_RX_STATUS_BASE)
+
+#define ATSE_CLEAR_SGDMA_TX_CONTROL() writel(0x0,  ATSE_SGDMA_TX_CONTROL_BASE)
+#define ATSE_CLEAR_SGDMA_TX_STATUS()  writel(0x1F, ATSE_SGDMA_TX_STATUS_BASE)
+#define ATSE_CLEAR_SGDMA_RX_CONTROL() writel(0x0,  ATSE_SGDMA_RX_CONTROL_BASE)
+#define ATSE_CLEAR_SGDMA_RX_STATUS()  writel(0x1F, ATSE_SGDMA_RX_STATUS_BASE)
+
+#define ATSE_GET_NEXT_SGDMA_DESC_PTR(desc_addr) readl(desc_addr + 4*BYTES_IN_WORD)
+
+#define ATSE_SGDMA_TX_DESC_CHAIN_SIZE                                      1
+#define ATSE_SGDMA_RX_DESC_CHAIN_SIZE                                      1
+
+#define ATSE_SGDMA_TX_FIRST_DESC_OFFSET   0
+#define ATSE_SGDMA_TX_SECOND_DESC_OFFSET  1
+#define ATSE_SGDMA_RX_FIRST_DESC_OFFSET   2
+#define ATSE_SGDMA_RX_SECOND_DESC_OFFSET  3
+
+
+/* bits 0 through 15 of the offset 7 contain the acutal bytes transferred */
+#define ATSE_GET_SGDMA_DESC_ACTUAL_BYTES_TRANSFERRED(desc_addr) (readl((desc_addr)+7*BYTES_IN_WORD)&0xFFFF) 
+#define ATSE_GET_SGDMA_DESC_STATUS(desc_addr)  ((readl(desc_addr + 7*BYTES_IN_WORD) >> 16) & 0xFF)
+
+#define ATSE_SET_PHY_POWER_DOWN()					\
+	do {								\
+		ATSE_SET_PHY_MDIO_CONTROL(ATSE_GET_PHY_MDIO_CONTROL() |	\
+					  ATSE_PHY_MDIO_CONTROL_POWER_DOWN_BIT); \
+	} while(0)
+
+
+#define	ATSE_SET_MAC_TX_SHIFT16_ON()					\
+	do {								\
+		ATSE_SET_MAC_TX_CMD_STAT(ATSE_GET_MAC_TX_CMD_STAT() |   \
+                                         ATSE_MAC_TX_CMD_STAT_TXSHIFT16_BIT); \
+        }while(0)
+
+#define	ATSE_SET_MAC_TX_SHIFT16_OFF()					\
+	do {								\
+		ATSE_SET_MAC_TX_CMD_STAT(ATSE_GET_MAC_TX_CMD_STAT() &   \
+                                         ~ATSE_MAC_TX_CMD_STAT_TXSHIFT16_BIT); \
+        }while(0)
+
+
+
+#define ATSE_MVLPHY_IS_MDIX(dat)     (dat) & (1 << 6)
+#define ATSE_MVLPHY_IS_1000(dat)     (((dat) >> 14) & 0x03) == 2 ? 1: 0
+#define ATSE_MVLPHY_IS_FULL_DUP(dat) ( (dat) >> 13) & 0x1
+
+
+
+struct atse_plat_data {
+	unsigned int flags;
+	/* allow replacement IO routines */
+	
+	void	(*inblk)(void __iomem *reg, void *data, int len);
+	void	(*outblk)(void __iomem *reg, void *data, int len);
+	void	(*dumpblk)(void __iomem *reg, int len);
+	
+};
+
+#endif /*  _ATSE_H_ */
+
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index b7311bc..22df0a6 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -19,6 +19,10 @@
 #include <linux/platform_device.h>
 #include <net/ethoc.h>
 
+static int buffer_size = 0x8000; /* 32 KBytes */
+module_param(buffer_size, int, 0);
+MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size");
+
 /* register offsets */
 #define	MODER		0x00
 #define	INT_SOURCE	0x04
@@ -167,6 +171,7 @@
  * struct ethoc - driver-private device structure
  * @iobase:	pointer to I/O memory region
  * @membase:	pointer to buffer memory region
+ * @dma_alloc:	dma allocated buffer size
  * @num_tx:	number of send buffers
  * @cur_tx:	last send buffer written
  * @dty_tx:	last buffer actually sent
@@ -185,6 +190,7 @@
 struct ethoc {
 	void __iomem *iobase;
 	void __iomem *membase;
+	int dma_alloc;
 
 	unsigned int num_tx;
 	unsigned int cur_tx;
@@ -284,7 +290,7 @@ static int ethoc_init_ring(struct ethoc *dev)
 	dev->cur_rx = 0;
 
 	/* setup transmission buffers */
-	bd.addr = 0;
+	bd.addr = virt_to_phys(dev->membase);
 	bd.stat = TX_BD_IRQ | TX_BD_CRC;
 
 	for (i = 0; i < dev->num_tx; i++) {
@@ -295,7 +301,7 @@ static int ethoc_init_ring(struct ethoc *dev)
 		bd.addr += ETHOC_BUFSIZ;
 	}
 
-	bd.addr = dev->num_tx * ETHOC_BUFSIZ;
+	bd.addr += 2; /* offset to help memcpy in rx */
 	bd.stat = RX_BD_EMPTY | RX_BD_IRQ;
 
 	for (i = 0; i < dev->num_rx; i++) {
@@ -400,8 +406,12 @@ static int ethoc_rx(struct net_device *dev, int limit)
 		if (ethoc_update_rx_stats(priv, &bd) == 0) {
 			int size = bd.stat >> 16;
 			struct sk_buff *skb = netdev_alloc_skb(dev, size);
+
+			size -= 4; /* strip the CRC */
+			skb_reserve(skb, 2); /* align TCP/IP header */
+
 			if (likely(skb)) {
-				void *src = priv->membase + bd.addr;
+				void *src = phys_to_virt(bd.addr);
 				memcpy_fromio(skb_put(skb, size), src, size);
 				skb->protocol = eth_type_trans(skb, dev);
 				priv->stats.rx_packets++;
@@ -653,9 +663,9 @@ static int ethoc_open(struct net_device *dev)
 	if (ret)
 		return ret;
 
-	/* calculate the number of TX/RX buffers */
-	num_bd = (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ;
-	priv->num_tx = min(min_tx, num_bd / 4);
+	/* calculate the number of TX/RX buffers, maximum 128 supported */
+	num_bd = min(128, (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ);
+	priv->num_tx = max(min_tx, num_bd / 4);
 	priv->num_rx = num_bd - priv->num_tx;
 	ethoc_write(priv, TX_BD_NUM, priv->num_tx);
 
@@ -823,7 +833,7 @@ static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	else
 		bd.stat &= ~TX_BD_PAD;
 
-	dest = priv->membase + bd.addr;
+	dest = phys_to_virt(bd.addr);
 	memcpy_toio(dest, skb->data, skb->len);
 
 	bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK);
@@ -903,22 +913,19 @@ static int ethoc_probe(struct platform_device *pdev)
 
 	/* obtain buffer memory space */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	if (!res) {
-		dev_err(&pdev->dev, "cannot obtain memory space\n");
-		ret = -ENXIO;
-		goto free;
-	}
-
-	mem = devm_request_mem_region(&pdev->dev, res->start,
+	if (res) {
+		mem = devm_request_mem_region(&pdev->dev, res->start,
 			res->end - res->start + 1, res->name);
-	if (!mem) {
-		dev_err(&pdev->dev, "cannot request memory space\n");
-		ret = -ENXIO;
-		goto free;
+		if (!mem) {
+			dev_err(&pdev->dev, "cannot request memory space\n");
+			ret = -ENXIO;
+			goto free;
+		}
+
+		netdev->mem_start = mem->start;
+		netdev->mem_end   = mem->end;
 	}
 
-	netdev->mem_start = mem->start;
-	netdev->mem_end   = mem->end;
 
 	/* obtain device IRQ number */
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -933,6 +940,7 @@ static int ethoc_probe(struct platform_device *pdev)
 	/* setup driver-private data */
 	priv = netdev_priv(netdev);
 	priv->netdev = netdev;
+	priv->dma_alloc = 0;
 
 	priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr,
 			mmio->end - mmio->start + 1);
@@ -942,12 +950,27 @@ static int ethoc_probe(struct platform_device *pdev)
 		goto error;
 	}
 
-	priv->membase = devm_ioremap_nocache(&pdev->dev, netdev->mem_start,
-			mem->end - mem->start + 1);
-	if (!priv->membase) {
-		dev_err(&pdev->dev, "cannot remap memory space\n");
-		ret = -ENXIO;
-		goto error;
+	if (netdev->mem_end) {
+		priv->membase = devm_ioremap_nocache(&pdev->dev,
+			netdev->mem_start, mem->end - mem->start + 1);
+		if (!priv->membase) {
+			dev_err(&pdev->dev, "cannot remap memory space\n");
+			ret = -ENXIO;
+			goto error;
+		}
+	} else {
+		/* Allocate buffer memory */
+		priv->membase = dma_alloc_coherent(NULL,
+			buffer_size, (void *)&netdev->mem_start,
+			GFP_KERNEL);
+		if (!priv->membase) {
+			dev_err(&pdev->dev, "cannot allocate %dB buffer\n",
+				buffer_size);
+			ret = -ENOMEM;
+			goto error;
+		}
+		netdev->mem_end = netdev->mem_start + buffer_size;
+		priv->dma_alloc = buffer_size;
 	}
 
 	/* Allow the platform setup code to pass in a MAC address. */
@@ -1034,6 +1057,9 @@ free_mdio:
 	kfree(priv->mdio->irq);
 	mdiobus_free(priv->mdio);
 free:
+	if (priv->dma_alloc)
+		dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
+			netdev->mem_start);
 	free_netdev(netdev);
 out:
 	return ret;
@@ -1059,7 +1085,9 @@ static int ethoc_remove(struct platform_device *pdev)
 			kfree(priv->mdio->irq);
 			mdiobus_free(priv->mdio);
 		}
-
+		if (priv->dma_alloc)
+			dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
+				netdev->mem_start);
 		unregister_netdev(netdev);
 		free_netdev(netdev);
 	}
diff --git a/drivers/net/mtip1000.c b/drivers/net/mtip1000.c
new file mode 100644
index 0000000..fdfab22
--- /dev/null
+++ b/drivers/net/mtip1000.c
@@ -0,0 +1,2481 @@
+/*----------------------------------------------------------------------
+ . mtip1000.c
+ .
+ . Driver: MoreThanIP 10/100/1000Mbps Emac IP
+ .
+ . Copyright (C) 2004 Microtronix Datacom Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ . Sources:
+ .    o   MoreThanIP 10/100/1000Mbps Reference Guide V3.2 - May 2003
+ .    o   MoreThanIP Altera Plugs sources
+ .          - mtip_10_100_1000.c
+ .          - mtip_10_100_1000_adapter.c
+ .          - mac_stream_test.c
+ .    o   Smc9111 uClinux port(s)
+ .
+ . History:
+ .    o   Apr2004   DGT Microtronix Datacom - Linux 2.6.5
+ .
+ -----------------------------------------------------------------------*/
+
+static const char version[] =
+    "MoreThanIP 10/100/1000 Driver"
+    "(v1.0)"
+        ", Linux 2.6.5 Apr2004\n";
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <asm/bitops.h>
+#include <asm/system.h>
+
+#include <asm/io.h>
+
+#ifdef CONFIG_EXCALIBUR
+    #include <asm/nios.h>
+    #include <asm/ndma.h>
+    #include <asm/cacheflush.h>
+#endif  // CONFIG_EXCALIBUR
+
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include "mtip1000.h"
+#include "stdphy.h"
+
+#define ANNOUNCEPHY
+//#undef  ANNOUNCEPHY
+
+//#undef MTIPPHYIRQ_AVAIL
+#if 1
+  #if defined (na_mii_irq_irq)
+      #define MTIPPHYIRQ_AVAIL
+    #define mtip_mii_control_port ((unsigned int *) (((unsigned int) (na_mii_irq)) | 0x80000000))
+  #endif    // na_mii_irq_irq
+#else
+  #undef na_mii_irq_irq
+  #undef na_mii_irq
+#endif
+
+//#define NS83865PHY
+#define TDK78Q2120PHY
+
+#ifdef NS83865PHY
+    #include "ns83865phy.h"
+    #define PHYTYPE "NS83865"
+#else
+    #ifdef TDK78Q2120PHY
+        #include "tdk78phy.h"
+    #define PHYTYPE "TDK78Q2120"
+    #endif
+#endif
+
+#ifdef CONFIG_SYSCTL
+    #include <linux/proc_fs.h>
+    #include <linux/sysctl.h>
+#endif  // CONFIG_SYSCTL
+
+//#undef na_dma                   // Force "Pio" mode
+#if defined (na_dma)
+    #define MTIPDMA_AVAIL
+    #define mtip_dma_control_port   ((np_dma *) (((unsigned int) (na_dma)) | 0x80000000))
+    #define IOTYPE "DMA"
+
+#else
+    #undef  MTIPDMA_AVAIL
+    #define IOTYPE "PIO"
+#endif  // na_dma
+
+
+/*----------------------------------------------------------------------
+ . DEBUGGING LEVELS
+ .
+ . 0 for normal operation
+ . 1 for slightly more details
+ . 2 for interrupt tracking, status flags
+ . 3 for packet info
+ . 4 for complete packet dumps
+ -----------------------------------------------------------------------*/
+//#define MTIP_DEBUG 4
+//#define MTIP_DEBUG 3
+//#define MTIP_DEBUG 2
+//#define MTIP_DEBUG 1
+#define MTIP_DEBUG 0
+
+#if (MTIP_DEBUG > 2 )
+    #define PRINTK3(args...) printk(args)
+#else
+    #define PRINTK3(args...)
+#endif
+
+#if MTIP_DEBUG > 1
+    #define PRINTK2(args...) printk(args)
+#else
+    #define PRINTK2(args...)
+#endif
+
+#ifdef MTIP_DEBUG
+    #define PRINTK(args...) printk(args)
+#else
+    #define PRINTK(args...)
+#endif
+
+
+typedef unsigned char           byte;
+typedef unsigned short          word;
+typedef unsigned long int       dword;
+
+
+/*-----------------------------------------------------------
+ Port address(es). Array must end in zero.
+*/
+#if defined(CONFIG_EXCALIBUR)
+    static unsigned int mtip_portlist[] =
+        {  ((int)
+             ((((unsigned int) (na_mtip_mac_control_port)) | 0x80000000)))
+         , 0 };
+    static unsigned int mtip_irqlist[]  =
+        { na_mtip_mac_rxFIFO_irq, 0 };
+    #define PIO_port_rxFIFO  (((unsigned int) (na_mtip_mac_rxFIFO)) | 0x80000000)
+    #define PIO_port_txFIFO  (((unsigned int) (na_mtip_mac_txFIFO)) | 0x80000000)
+#else
+    #define PIO_port_rxFIFO  (((unsigned int) (na_mtip_mac_rxFIFO)))
+    #define PIO_port_txFIFO  (((unsigned int) (na_mtip_mac_txFIFO)))
+  ............
+#endif  // CONFIG_EXCALIBUR
+
+
+struct mtip_local
+  {
+    struct   net_device_stats   stats;
+
+#ifdef CONFIG_SYSCTL
+
+    // Root directory /proc/sys/dev
+    // Second entry must be null to terminate the table
+    ctl_table root_table[2];
+
+    // Directory for this device /proc/sys/dev/ethX
+    // Again the second entry must be zero to terminate
+    ctl_table eth_table[2];
+
+    // This is the parameters (file) table
+    ctl_table param_table[CTL_MTIP_LAST_ENTRY];
+
+    // Saves the sysctl header returned by register_sysctl_table()
+    // we send this to unregister_sysctl_table()
+    struct ctl_table_header *sysctl_header;
+
+    // Parameter variables (files) go here
+    char ctl_info[1024];    // ?...?
+
+/*
+....tbd.............
+    int ctl_xxxxxx's;
+......................*/
+
+#endif // CONFIG_SYSCTL
+  };
+
+
+/*-----------------------------------------------------------
+ | Print out a packet.
+*/
+#if MTIP_DEBUG > 3
+  static void print_packet( byte * buf, int length )
+    {
+      #if 1
+        #if MTIP_DEBUG > 3
+            int i;
+            int remainder;
+            int lines;
+        #endif
+
+        printk("Packet length %d \n", length );
+
+        #if MTIP_DEBUG > 3
+            lines = length / 16;
+            remainder = length % 16;
+
+            for ( i = 0; i < lines ; i ++ ) {
+                int cur;
+
+                for ( cur = 0; cur < 8; cur ++ ) {
+                    byte a, b;
+
+                    a = *(buf ++ );
+                    b = *(buf ++ );
+                    printk("%02x %02x ", a, b );
+                }
+                printk("\n");
+            }
+            for ( i = 0; i < remainder/2 ; i++ ) {
+                byte a, b;
+
+                a = *(buf ++ );
+                b = *(buf ++ );
+                printk("%02x %02x ", a, b );
+            }
+            printk("\n");
+        #endif
+      #endif
+    }
+#endif
+
+
+/*-----------------------------------------------------------
+*/
+#define PRINTSTDPHYREGS(pmac)                                   \
+                                                                \
+    printk("    PhyCtl0: %04X"                                  \
+            "   PhySts1:  %04X"                                 \
+            "  PhyID1:     %04X\n",                             \
+           (pmac->mdio0).CONTROL,                               \
+           (pmac->mdio0).STATUS,                                \
+           (pmac->mdio0).PHY_ID1);                              \
+    printk("    PhyID2:  %04X"                                  \
+            "   PhyAdv4:  %04X"                                 \
+            "  PhyRemcap5: %04X\n",                             \
+           (pmac->mdio0).PHY_ID2,                               \
+           (pmac->mdio0).ADV,                                   \
+           (pmac->mdio0).REMADV);
+
+
+#ifdef NS83865PHY
+  #define PRINTNS83PHYREGS(pmac,                                \
+                           nsIntstsReg20,                       \
+                           nsIntieReg21,                        \
+                           nsLnkstsReg17)                       \
+                                                                \
+      PRINTSTDPHYREGS(pmac);                                    \
+                                                                \
+        printk("    Ns20Ists:%04X"                              \
+                "   Ns21Intie:%04X"                             \
+                "  Ns17Lnksts: %04X\n",                         \
+               nsIntstsReg20,                                   \
+               nsIntieReg21,                                    \
+               nsLnkstsReg17);
+#endif
+
+
+#ifdef TDK78Q2120PHY
+    #define PRINTTDKPHYREGS(pmac,                               \
+                            tdkintCtlStsReg17,                  \
+                            tdkDiagReg18)                       \
+                                                                \
+        PRINTSTDPHYREGS(pmac);                                  \
+                                                                \
+        printk("    Tdk16:   %04X"                              \
+                "   Tdk17Int: %04X"                             \
+                "  Tdk18Diag:  %04X\n",                         \
+               (pmac->mdio0).reg10,                             \
+               tdkintCtlStsReg17,                               \
+               tdkDiagReg18);
+#endif
+
+
+/*-----------------------------------------------------------
+*/
+unsigned int       gMtipDisabledRxints;
+unsigned int       gMtipDisabledTxints;
+unsigned long      gMtipDiscardSink;            // RxFifo discard
+unsigned int       gMtipDmaints;
+unsigned int       gMtipDmaintsBusy;
+unsigned int       gMtipDmaintsBusyDone;
+unsigned int       gMtipDmaintsNoDone;
+unsigned int       gMtipRxints;
+unsigned int       gMtipRxintsRxdmaBusy;
+unsigned int       gMtipRxintsRxdmaQued;
+unsigned int       gMtipRxNoints;
+int                gMtipRxSkbFifoNumL32s;
+word               gMtipRxSkbframelenbyts;
+unsigned int       gMtipTxints;
+unsigned int       gMtipTxintsIncomplete;
+int                gMtipTxSkbFifoNumL32s;
+word               gMtipTxSkbframelenbyts;
+unsigned int       gMtipUnexpDmaints;
+unsigned int       gMtipUnexpRxints;
+unsigned int       gMtipUnexpTxints;
+byte              *gpMtipRxData;
+struct   sk_buff  *gpMtipRxSkbInProg;
+byte              *gpMtipTxData;
+struct   sk_buff  *gpMtipTxSkbInProg;
+
+#if defined (MTIPDMA_AVAIL)
+
+unsigned int       gMtipDmaQ;
+unsigned int       gMtipDmaState;
+
+unsigned char gMtipTmpDmaBuf[MTIP_MAC_MAX_FRAME_SIZE + MTIP_MI_XBUF_BYTS];
+  // Nios alignment requirements...very inconvenient...
+  // for now...but should be in "on chip sram" if any...
+  //  (perhaps used as "ring[s]"...
+  // for now...rx and tx share same temporary 1 only "dma buffer"
+
+enum
+  {
+      Mtip_DmaQ_TxSkb2Tmp        = (1 << 0)
+    , Mtip_DmaQ_RxFifo2Tmp       = (1 << 1)
+    , Mtip_DmaQ_RxFifo2Trash     = (1 << 2)
+  };
+
+enum
+  {
+      Mtip_DmaState_Idle         = 0
+    , Mtip_DmaState_RxFifo2Tmp   = 1
+    , Mtip_DmaState_RxTmp2Skb    = 2
+    , Mtip_DmaState_TxSkb2Tmp    = 3
+    , Mtip_DmaState_TxTmp2Fifo   = 4
+    , Mtip_DmaState_RxFifo2Trash = 5
+  };
+
+
+/*-----------------------------------------------------------
+*/
+static void dma_start
+    (int      bytes_per_transfer,
+     void    *source_address,
+     void    *destination_address,
+     int      transfer_count,       // In units of bytes_per_transfer
+     int      mode)                 // wcon, rcon, i_en, ... bit(s)
+  {
+    // Caller must have already flushed any "memory" range
+    //  involved in this transfer that stands at risk.
+
+    int         control_bits    = 0;
+    np_dma     *dma             = mtip_dma_control_port;
+
+    dma->np_dmacontrol = 0;
+      // | 1. Halt anything that's going on
+
+    dma->np_dmastatus       = 0;
+    dma->np_dmareadaddress  = (int)source_address;
+    dma->np_dmawriteaddress = (int)destination_address;
+    dma->np_dmalength       = transfer_count * bytes_per_transfer;
+
+    control_bits =
+        mode
+      | (bytes_per_transfer  &  7)  // low three bits of control reg
+      | ((bytes_per_transfer &  8) ? np_dmacontrol_doubleword_mask : 0)
+      | ((bytes_per_transfer & 16) ? np_dmacontrol_quadword_mask   : 0)
+      | np_dmacontrol_leen_mask     // enable length
+//      | np_dmacontrol_reen_mask     //;dgt;tmp;test; Enable read end-of-packet
+//      | np_dmacontrol_ween_mask     //;dgt;tmp;test; Enable write end-of-packet
+      | np_dmacontrol_go_mask;      // and... go!
+
+    dma->np_dmacontrol = control_bits;
+
+    return;
+  }
+
+/*-----------------------------------------------------------
+*/
+void dma_start_RxFifo2Tmp(void)
+  {
+    // Caller must have already set gMtipDmaState
+    //  to Mtip_DmaState_RxFifo2Tmp (under semaphore),
+    //  and disabled Rx ready interrupts.
+
+    flush_dcache_range (((unsigned long) (gpMtipRxData)),
+                 ((unsigned long) (gpMtipRxData)) + gMtipRxSkbframelenbyts);
+
+    dma_start
+        (4,                               // Byts per transfer
+         ((void *) (na_mtip_mac_rxFIFO)), // 32 bit source fifo
+         gMtipTmpDmaBuf,                  // 32 bit aligned dest
+         gMtipRxSkbFifoNumL32s,           // # of 4 byte transfers
+         (  np_dmacontrol_rcon_mask       // Source is a Fifo
+          | np_dmacontrol_i_en_mask       // Dma done:interrupt
+          ));
+  }
+
+/*-----------------------------------------------------------
+*/
+void dma_start_TxSkb2Tmp(void)
+  {
+    // Caller must have already set gMtipDmaState
+    //  to Mtip_DmaState_TxSkb2Tmp (under semaphore)
+
+    flush_dcache_range (((unsigned long) (gpMtipTxData)),
+                 ((unsigned long) (gpMtipTxData)) + gMtipTxSkbframelenbyts);
+    dma_start
+        (2,                               // Byts per transfer
+         gpMtipTxData,                    // 16 bit aligned src,
+         gMtipTmpDmaBuf,                  // 32 bit aligned dest,
+         (gMtipTxSkbFifoNumL32s << 1),    // # of 2 byte transfers
+         (  0                             // Neither end a fifo
+          | np_dmacontrol_i_en_mask       // Dma done:interrupt
+          ));
+      // At the risk of possibly incurring twice the copy
+      //  time, save some cpu cycles by assuming outbound
+      //  data starts on a 16 bit boundary (Have never
+      //  empirically observed it on anything but...)...
+  }
+
+/*-----------------------------------------------------------
+*/
+void dma_start_RxFifo2Trash(void)
+  {
+    // Caller must have already set gMtipDmaState
+    //  to Mtip_DmaState_RxFifo2Trash (under semaphore),
+    //  and disabled Rx ready interrupts.
+
+    dma_start
+        (4,                               // Byts per transfer
+         ((void *) (na_mtip_mac_rxFIFO)), // 32 bit source fifo
+         ((unsigned char *)
+            &(gMtipDiscardSink)),         // 32 bit aligned dest
+         gMtipRxSkbFifoNumL32s,           // # of 4 byte transfers
+         (  np_dmacontrol_rcon_mask       // Source is a Fifo
+          | np_dmacontrol_wcon_mask       // Dest is a sinkhole
+          | np_dmacontrol_i_en_mask       // Dma done:interrupt
+          ));
+  }
+#endif  // MTIPDMA_AVAIL
+
+/*-----------------------------------------------------------
+ | Entry condition: Cpu interrupts DISabled.
+*/
+static void mtip_NuRxReady(struct   net_device  *dev,
+                           unsigned int          cmplnstatus)
+  {
+    // Caller must have already verified cmplnstatus's
+    //  mmac_rcs_VALID_mask bit is SET.
+
+    struct   mtip_local    *lp;
+    np_mtip_mac            *pmac;
+
+    lp   = (struct mtip_local *)dev->priv;
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    gMtipRxSkbframelenbyts = ( cmplnstatus & mmac_rcs_FRAME_LENGTH_mask );
+
+    PRINTK3
+//  printk
+           (
+            "mtip_NuRxReady:%s, asts:0x%04X, csts:0x%08X, Len:%d\n",
+            dev->name,
+            pmac->AVL_STATUS,
+            cmplnstatus,
+            gMtipRxSkbframelenbyts);
+
+    if(gMtipRxSkbframelenbyts == 0)
+      {
+//      PRINTK3
+        printk
+               (
+                "mtip_NuRxReady:%s, ZERO len frame,"
+                    " asts:0x%04X, csts:0x%08X\n",
+                dev->name,
+                pmac->AVL_STATUS,
+                cmplnstatus);
+      }
+
+    gMtipRxSkbFifoNumL32s = ((gMtipRxSkbframelenbyts + 3) >> 2);
+
+    if( cmplnstatus & mmac_rcs_ERROR_mask )
+      {
+        PRINTK3
+//      printk
+              (
+               "mtip_NuRxReady:%s, Bad frame:0x%08X, Len:%d\n",
+               dev->name,
+               cmplnstatus,
+               gMtipRxSkbframelenbyts);
+
+        lp->stats.rx_errors++;
+
+        //;...can't differentiate...lp->stats.rx_frame_errors++;
+        //;...can't differentiate...lp->stats.rx_length_errors++;
+        //;...can't differentiate...lp->stats.rx_crc_errors++;
+
+      #if defined (MTIPDMA_AVAIL)
+        pmac->IRQ_CONFIG &= (~(mmac_ic_EN_RX_FRAME_AVAILABLE_mask));
+          // disable rx ready interrupt
+
+        if(gMtipDmaState == Mtip_DmaState_Idle)
+          {
+            gMtipDmaState = Mtip_DmaState_RxFifo2Trash;
+
+            dma_start_RxFifo2Trash();
+          }
+          else
+          {
+            gMtipDmaQ |= Mtip_DmaQ_RxFifo2Trash;
+          }
+
+        return;
+      #else
+        {
+          int       FifoL32     = 0;
+          pmac->RX_CMD_STAT = mmac_rcs_READ_CMD_mask;
+          while( (pmac->RX_CMD_STAT) & mmac_rcs_READ_CMD_mask )
+            {
+              FifoL32 |= *((volatile unsigned long *) PIO_port_rxFIFO);
+            }
+          gMtipDiscardSink = FifoL32;
+        }
+
+        return;
+      #endif  // MTIPDMA_AVAIL
+      }
+
+    //;...?...lp->stats.multicast++;
+
+    if(gMtipRxSkbframelenbyts > MTIP_MAC_MAX_FRAME_SIZE)
+      {
+//      PRINTK3
+        printk
+              (
+//             KERN_NOTICE
+                 "mtip_NuRxReady:%s, oversized %d byte packet.\n",
+               dev->name,
+               gMtipRxSkbframelenbyts);
+        goto Dropfrm_label;
+      }
+
+    gpMtipRxSkbInProg =
+        dev_alloc_skb( (gMtipRxSkbFifoNumL32s << 2) +
+                       MTIP_SKB_XBUF_BYTS );
+      // Extra bytes: Dma requirements
+
+    if ( gpMtipRxSkbInProg == NULL )
+      {
+        PRINTK3
+//      printk
+              (
+//             KERN_NOTICE
+                 "mtip_NuRxReady:%s, Low memory, packet dropped.\n",
+               dev->name);
+        goto Dropfrm_label;
+      }
+
+    skb_reserve( gpMtipRxSkbInProg, 2 );   /* 16 bit alignment */
+
+    gpMtipRxSkbInProg->dev = dev;
+
+    gpMtipRxData = skb_put( gpMtipRxSkbInProg, gMtipRxSkbframelenbyts );
+
+    lp->stats.rx_packets++;
+
+    #if defined (MTIPDMA_AVAIL)
+      pmac->IRQ_CONFIG &= (~(mmac_ic_EN_RX_FRAME_AVAILABLE_mask));
+        // disable rx ready interrupt
+
+      if(gMtipDmaState == Mtip_DmaState_Idle)
+        {
+          gMtipDmaState = Mtip_DmaState_RxFifo2Tmp;
+
+          dma_start_RxFifo2Tmp();
+        }
+        else
+        {
+          gMtipDmaQ |= Mtip_DmaQ_RxFifo2Tmp;
+        }
+
+      return;
+    #else
+      insl(((unsigned long) PIO_port_rxFIFO),
+           gpMtipRxData,
+           gMtipRxSkbFifoNumL32s);
+
+      PRINTK3
+            (
+             "%s:Received %d byte Packet 0x%08X\n",
+             dev->name,
+             gMtipRxSkbframelenbyts,
+             ((unsigned long) gpMtipRxData));
+
+      #if MTIP_DEBUG > 3
+        print_packet( gpMtipRxData, gMtipRxSkbframelenbyts );
+      #endif
+
+      gpMtipRxSkbInProg->protocol =
+          eth_type_trans(gpMtipRxSkbInProg, dev );
+
+      netif_rx(gpMtipRxSkbInProg);
+
+      pmac->RX_CMD_STAT = mmac_rcs_READ_CMD_mask;
+        // acknowledge frame reception
+
+      return;
+    #endif  // MTIPDMA_AVAIL
+
+Dropfrm_label:
+
+    /* Oversized Rx frame, or dev_alloc_skb(...) failure                */
+
+    lp->stats.rx_dropped++;
+
+    #if defined (MTIPDMA_AVAIL)
+      pmac->IRQ_CONFIG &= (~(mmac_ic_EN_RX_FRAME_AVAILABLE_mask));
+        // disable rx ready interrupt
+
+      if(gMtipDmaState == Mtip_DmaState_Idle)
+        {
+          gMtipDmaState = Mtip_DmaState_RxFifo2Trash;
+
+          dma_start_RxFifo2Trash();
+        }
+        else
+        {
+          gMtipDmaQ |= Mtip_DmaQ_RxFifo2Trash;
+        }
+
+      return;
+    #else
+      {
+        int           FifoL32     = 0;
+        int           FifoLoop;
+        for ( FifoLoop = 0; FifoLoop < gMtipRxSkbFifoNumL32s ; FifoLoop++ )
+          {
+            FifoL32 |= *((volatile unsigned long *) PIO_port_rxFIFO);
+          }
+        gMtipDiscardSink = FifoL32;
+      }
+
+      pmac->RX_CMD_STAT = mmac_rcs_READ_CMD_mask;
+        // acknowledge frame reception
+
+      return;
+    #endif  // MTIPDMA_AVAIL
+  }
+
+#if defined (MTIPDMA_AVAIL)
+/*-----------------------------------------------------------
+ | Driver entry point
+ |
+ | Entry condition: Cpu interrupts DISabled.
+ */
+static irqreturn_t mtip_DmaInterrupt(int             irq,
+                                     void           *dev_id)
+  {
+    unsigned int       cmplnstatus;
+    struct net_device *dev      = dev_id;
+    np_dma            *dma      = mtip_dma_control_port;
+    int                old_dmastatus;
+    np_mtip_mac       *pmac;
+
+    ++gMtipDmaints;
+
+    pmac          = ((np_mtip_mac *) dev->base_addr);
+    old_dmastatus = dma->np_dmastatus;
+
+    if(old_dmastatus & np_dmastatus_busy_mask)
+      {
+        ++gMtipDmaintsBusy;
+
+        if(old_dmastatus & np_dmastatus_done_mask)
+          {
+            ++gMtipDmaintsBusyDone;
+          }
+
+        return IRQ_HANDLED;
+          // ...This could be interesting...!
+      }
+
+    if(!(old_dmastatus & np_dmastatus_done_mask))
+      {
+        ++gMtipDmaintsNoDone;
+          // presumably gMtipDmaState .eq. Mtip_DmaState_Idle
+      }
+
+    dma->np_dmastatus = 0;  // Clear done bit (and ack the interrupt)
+
+    switch (gMtipDmaState)
+      {
+        case Mtip_DmaState_RxFifo2Tmp:
+
+          pmac->RX_CMD_STAT = mmac_rcs_READ_CMD_mask;
+            // acknowledge frame reception
+
+          gMtipDmaState = Mtip_DmaState_RxTmp2Skb;
+          dma_start
+              (2,                               // Byts per transfer
+               gMtipTmpDmaBuf,                  // 32 bit aligned src
+               gpMtipRxData,                    // 16 bit aligned dest
+               (gMtipRxSkbFifoNumL32s << 1),    // # of 2 byte transfers
+               (  0                             // Neither end a fifo
+                | np_dmacontrol_i_en_mask       // Dma done:interrupt
+                ));
+
+          goto DmaIntExit_label;
+
+        case Mtip_DmaState_RxTmp2Skb:
+
+//;see state RxFifo2Tmp; pmac->RX_CMD_STAT = mmac_rcs_READ_CMD_mask;
+            // acknowledge frame reception
+
+          PRINTK3
+                (
+                 "%s:Received %d byte Packet 0x%08X\n",
+                 dev->name,
+                 gMtipRxSkbframelenbyts,
+                 ((unsigned long) gpMtipRxData));
+
+          #if MTIP_DEBUG > 3
+            print_packet( gpMtipRxData, gMtipRxSkbframelenbyts );
+          #endif
+
+          gpMtipRxSkbInProg->protocol =
+              eth_type_trans(gpMtipRxSkbInProg, dev );
+
+          netif_rx(gpMtipRxSkbInProg);
+
+          pmac->IRQ_CONFIG |= mmac_ic_EN_RX_FRAME_AVAILABLE_mask;
+            // enable rx ready interrupt
+          // Note DmaMaybe2Idle_label will find NEITHER
+          //  of gMtipDmaQ's Mtip_DmaQ_RxFifo2Tmp NOR
+          //  Mtip_DmaQ_RxFifo2Trash bits set!
+
+          goto DmaMaybe2Idle_label;
+
+        case Mtip_DmaState_TxSkb2Tmp:
+
+          gMtipDmaState = Mtip_DmaState_TxTmp2Fifo;
+          pmac->TX_CMD_STAT = (gMtipTxSkbframelenbyts   |
+                               mmac_tcs_FRAME_COMPLETE_mask);
+          dma_start
+              (4,                               // Byts per transfer
+               gMtipTmpDmaBuf,                  // 32 bit aligned src
+               ((void *) (na_mtip_mac_txFIFO)), // 32 bit dest fifo
+               gMtipTxSkbFifoNumL32s,           // # of 4 byte transfers
+               (  np_dmacontrol_wcon_mask       // Dest is a Fifo
+                | np_dmacontrol_i_en_mask       // Dma done:interrupt
+                ));
+
+          goto DmaIntExit_label;
+
+        case Mtip_DmaState_TxTmp2Fifo:
+
+          pmac->IRQ_CONFIG |= mmac_ic_EN_TX_FIFO_EMPTY_mask;
+            // enable tx done interrupt
+
+          goto DmaMaybe2Idle_label;
+
+        case Mtip_DmaState_RxFifo2Trash:
+
+          pmac->RX_CMD_STAT = mmac_rcs_READ_CMD_mask;
+            // acknowledge frame reception
+
+          pmac->IRQ_CONFIG |= mmac_ic_EN_RX_FRAME_AVAILABLE_mask;
+            // enable rx ready interrupt
+          // Note DmaMaybe2Idle_label will find NEITHER
+          //  of gMtipDmaQ's Mtip_DmaQ_RxFifo2Tmp NOR
+          //  Mtip_DmaQ_RxFifo2Trash bits set!
+          goto DmaMaybe2Idle_label;
+
+//      case Mtip_DmaState_Idle:
+        default:
+
+          ++gMtipUnexpDmaints;
+
+          PRINTK3
+//        printk
+                (
+                 "mtip_DmaInterrupt:%s,"
+                    " Unexpected state:0x%02X"
+                    " (sts:0x%02X,"
+                    " ctl:0x%04X)\n",
+                 dev->name,
+                 gMtipDmaState,
+                 dma->np_dmastatus,
+                 dma->np_dmacontrol);
+
+          // fall thru to DmaMaybe2Idle_label
+      }
+
+DmaMaybe2Idle_label:
+
+    if(gMtipDmaQ & Mtip_DmaQ_TxSkb2Tmp)
+      {
+        gMtipDmaQ &= (~(Mtip_DmaQ_TxSkb2Tmp));
+
+        gMtipDmaState = Mtip_DmaState_TxSkb2Tmp;
+
+        dma_start_TxSkb2Tmp();
+      }
+    else if (gMtipDmaQ & Mtip_DmaQ_RxFifo2Tmp)
+      {
+        gMtipDmaQ &= (~(Mtip_DmaQ_RxFifo2Tmp));
+
+        gMtipDmaState = Mtip_DmaState_RxFifo2Tmp;
+
+        dma_start_RxFifo2Tmp();
+      }
+    else if (gMtipDmaQ & Mtip_DmaQ_RxFifo2Trash)
+      {
+        gMtipDmaQ &= (~(Mtip_DmaQ_RxFifo2Trash));
+
+        gMtipDmaState = Mtip_DmaState_RxFifo2Trash;
+
+        dma_start_RxFifo2Trash();
+      }
+    else
+      {
+        gMtipDmaState = Mtip_DmaState_Idle;
+
+        if(( (pmac->AVL_STATUS) & (mmac_as_RX_FRAME_AVAILABLE_mask) ))
+          {
+            cmplnstatus = pmac->RX_CMD_STAT;
+            if(( cmplnstatus & mmac_rcs_VALID_mask ))
+              {
+                ++gMtipRxNoints;
+
+                mtip_NuRxReady(dev, cmplnstatus);
+                  // mtip_NuRxReady (re)disables Rx interrupts...
+              }
+          }
+      }
+
+DmaIntExit_label:
+
+    return IRQ_HANDLED;
+  }
+#endif  // MTIPDMA_AVAIL
+
+
+#ifdef CONFIG_SYSCTL
+/*-----------------------------------------------------------
+ |
+*/
+static const char mtip_info_string[] =
+"\n"
+"info           Provides this information blurb\n"
+"....           Remind author to complete\n"
+" ...           ...\n"
+"....           Remind author to complete\n"
+"";
+#endif /* endif CONFIG_SYSCTL */
+
+
+#ifdef CONFIG_SYSCTL
+/*-----------------------------------------------------------
+ | Sysctl handler for all integer parameters
+*/
+static int mtip_sysctl_handler(ctl_table    *ctl,
+                               int           write,
+                               struct file  *filp,
+                               void         *buffer,
+                               size_t       *lenp)
+{
+    int                ret;
+
+    ret = 0;
+/*
+....tbd.............
+.....................*/
+
+    return ret;
+}
+#endif /* endif CONFIG_SYSCTL */
+
+
+#ifdef CONFIG_SYSCTL
+/*-----------------------------------------------------------
+ | Sysctl registration function for all parameters (files)
+ |
+ | Initilizes device's sysctl proc filesystem
+ |
+ | Entry condition: Cpu interrupts ENabled.
+*/
+static void mtip_sysctl_register(struct net_device *dev)
+{
+    struct mtip_local *lp = (struct mtip_local *)dev->priv;
+    static int ctl_name = CTL_MTIP1000;
+    ctl_table* ct;
+    int i;
+
+    // Make sure the ctl_tables start out as all zeros
+    memset(lp->root_table, 0, sizeof lp->root_table);
+    memset(lp->eth_table, 0, sizeof lp->eth_table);
+    memset(lp->param_table, 0, sizeof lp->param_table);
+
+    // Initialize the root table
+    ct = lp->root_table;
+    ct->ctl_name = CTL_DEV;
+    ct->procname = "dev";
+    ct->maxlen = 0;
+    ct->mode = 0555;
+    ct->child = lp->eth_table;
+    // remaining fields are zero
+
+    // Initialize the ethX table (this device's table)
+    ct = lp->eth_table;
+    ct->ctl_name = ctl_name++; // Must be unique
+    ct->procname = dev->name;
+    ct->maxlen = 0;
+    ct->mode = 0555;
+    ct->child = lp->param_table;
+    // remaining fields are zero
+
+    // Initialize the parameter (files) table
+    // Make sure the last entry remains null
+    ct = lp->param_table;
+    for (i = 0; i < (CTL_MTIP_LAST_ENTRY-1); ++i)
+        {
+        // Initialize fields common to all table entries
+        ct[i].proc_handler = mtip_sysctl_handler;
+        ct[i].extra1 = (void*)dev; // Save our device pointer
+        ct[i].extra2 = (void*)lp;  // Save our mtip_local data pointer
+        }
+
+    // INFO - this is our only string parameter
+    i = 0;
+    ct[i].proc_handler = proc_dostring; // use default handler
+    ct[i].ctl_name = CTL_MTIP_INFO;
+    ct[i].procname = "info";
+    ct[i].data = (void*)mtip_info_string;
+    ct[i].maxlen = sizeof mtip_info_string;
+    ct[i].mode = 0444; // Read only
+
+    // SWVER
+    ++i;
+    ct[i].proc_handler = proc_dostring; // use default handler
+    ct[i].ctl_name = CTL_MTIP_SWVER;
+    ct[i].procname = "swver";
+    ct[i].data = (void*)version;
+    ct[i].maxlen = sizeof version;
+    ct[i].mode = 0444; // Read only
+
+/*
+....tbd.............
+.....................*/
+  #ifdef MTIP_DEBUG
+/*
+....tbd.............
+.....................*/
+  #endif // MTIP_DEBUG
+
+    // Register /proc/sys/dev/ethX
+    lp->sysctl_header = register_sysctl_table(lp->root_table, 1);
+}
+#endif /* endif CONFIG_SYSCTL */
+
+
+#ifdef CONFIG_SYSCTL
+/*-----------------------------------------------------------
+ | Sysctl unregistration when driver closed
+*/
+static void mtip_sysctl_unregister(struct net_device *dev)
+{
+    struct mtip_local *lp = (struct mtip_local *)dev->priv;
+
+    unregister_sysctl_table(lp->sysctl_header);
+}
+#endif /* endif CONFIG_SYSCTL */
+
+
+void mtip_phymac_synch (struct net_device *dev, int callerflg)
+  {
+    unsigned long        cmdcfg;
+    unsigned long        phy100mbitflg;
+    unsigned long        phyfulldupflg;
+    unsigned long        phymr1sts;
+    unsigned long        phyanegfailedflg;
+    np_mtip_mac         *pmac;
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    phymr1sts = (pmac->mdio0).STATUS;
+    /* Read twice to get CURRENT status...?...                          */
+    phymr1sts = (pmac->mdio0).STATUS;
+
+    cmdcfg = pmac->COMMAND_CONFIG;
+
+    #ifdef NS83865PHY
+       unsigned long        phymr17linkan;
+
+       phymr17linkan = (pmac->mdio0).reg11;
+
+       phy100mbitflg    = (phymr17linkan & 0x0008);
+       phyfulldupflg    = (phymr17linkan & 0x0002);
+
+       phyanegfailedflg = (((pmac->mdio0).reg14) & 0x0100);
+    #else
+       #if defined(TDK78Q2120PHY)
+         {
+           unsigned long        phymr18diag;
+
+           phymr18diag = (pmac->mdio0).reg12;
+
+           phy100mbitflg    = (phymr18diag & 0x0400);
+           phyanegfailedflg = (phymr18diag & 0x1000);
+           phyfulldupflg    = (phymr18diag & 0x0800);
+         }
+       #else
+         ...?...
+         ...?...
+       #endif   // TDK78Q2120PHY
+    #endif  // NS83865PHY
+
+    if(callerflg == 0)
+      {
+        // Caller = NOT Phy interrupt handler
+
+        if((phymr1sts & 0x00000004) != 0)
+          {
+            // Link is ostensibly OK
+
+            if((((pmac->mdio0).CONTROL) & 0x00001000) != 0)
+              {
+                // Auto negotiation ostensibly enabled
+
+                if((phymr1sts & 0x00000020) != 0)
+                  {
+                    // Auto negotiation ostensibly has completed
+
+                    if(phyanegfailedflg)
+                      {
+                        // Auto negotiation ostensibly has failed
+
+                        if(phy100mbitflg | phyfulldupflg)
+                          {
+                            // Auto negotiation failure expected to
+                            //  have fallen back to 10 mbit half
+                            //  duplex - perhaps phy registers aren't
+                            //  actually available, and we've been
+                            //  reading 0xFFFF's...
+
+                            // A 10 mbit, 1/2 duplex remote partner
+                            //  mandates a 1/2 duplex Emac (else any
+                            //  amount of traffic at all will almost
+                            //  certainly collide up a storm...)
+                            // 100 mbit remote partners seem to allow
+                            //  duplex mismatches without severe
+                            //  loss, at least at the low end of
+                            //  their nominal capacity.
+                            // A 10 mbit, full duplex remote partner
+                            //  probably also requires a matched Emac,
+                            //  but hasn't been confirmed...
+
+                            printk("\nmtip_phymac_synch:%s"
+                                     " No phyregs?-assuming HalfD\n",
+                                   dev->name);
+
+                            pmac->COMMAND_CONFIG |= mmac_cc_HD_ENA_mask;
+
+                            if((pmac->COMMAND_CONFIG  &
+                                mmac_cc_HD_ENA_mask) == 0)
+                              {
+                                printk("\nmtip_phymac_synch:%s"
+                                         " HalfD phy, but FullD emac\n",
+                                       dev->name);
+                              }
+
+                            return;
+                          }
+                      }
+                  }
+              }
+          }
+      }
+//    else
+//    {
+//      // Caller = Phy interrupt handler
+//      // If we've got a phy interrupt, then we're so likely
+//      //  to also have actual phy registers that we won't
+//      //  bother trying to confirm...
+//    }
+
+    #if defined(ANNOUNCEPHY)
+      printk("\nmtip_phymac_synch:%s  MR1: 0x%08lX\n",
+             dev->name,
+             phymr1sts);
+      if((phymr1sts & 0x00000002) != 0)
+        {
+          printk("                               Jabber\n");
+        }
+      if((phymr1sts & 0x00000010) != 0)
+        {
+          printk("                               Remote Fault\n");
+        }
+      if((phymr1sts & 0x00000020) != 0)
+        {
+          printk("                               Autoneg'd\n");
+        }
+    #endif
+
+    if((phymr1sts & 0x00000004) != 0)
+      {
+        /* Phy MR1 (status register) indicates link is (now) OK.        */
+
+        #if defined(ANNOUNCEPHY)
+          printk("             Link OK:\n");
+        #endif
+
+        if(phyfulldupflg)
+          {
+            /* Link is (now) running full duplex.                    */
+
+            pmac->COMMAND_CONFIG = (cmdcfg &
+                                    (~(mmac_cc_HD_ENA_mask)));
+
+            #if defined(ANNOUNCEPHY)
+              printk("             FullD\n");
+            #endif
+          }
+          else
+          {
+            /* Link is (now) running half duplex.                    */
+
+            pmac->COMMAND_CONFIG = (cmdcfg | mmac_cc_HD_ENA_mask);
+
+            if((pmac->COMMAND_CONFIG & mmac_cc_HD_ENA_mask) == 0)
+              {
+                printk("\nmtip_phymac_synch:%s"
+                         " HalfD phy, but FullD emac\n",
+                       dev->name);
+              }
+
+            #if defined(ANNOUNCEPHY)
+              printk("             HalfD\n");
+            #endif
+          }
+
+        #if defined(ANNOUNCEPHY)
+          printk("             %s\n",
+                 (phy100mbitflg) ? "100BASE-TX" : "10BASE-T");
+        #endif
+      }
+    #if defined(ANNOUNCEPHY)
+      else
+      {
+        printk("             Link Down\n");
+
+        // ...what if link comes up without a phy interrupt
+        // ... and the emac/phy duplexs don't match...?...
+      }
+    #endif
+
+    #if defined(ANNOUNCEPHY)
+      printk("             CMDCF: 0x%08X\n",
+             pmac->COMMAND_CONFIG);
+      printk("\n");
+    #endif
+
+    return;
+  }
+
+
+/*-----------------------------------------------------------
+ | Entry condition: Cpu interrupts ENabled.
+*/
+static void mtip_phy_configure(struct net_device* dev)
+  {
+    /* No need to (re)configure advertisement register or (re)start     */
+    /*  auto negotiation after the reset that our caller has probably   */
+    /*  recently performed if auto negotiation is enabled by default    */
+    /*  and all capabilities are to be advertised. Advertisement        */
+    /*  register has already defaulted to our capabilities on last      */
+    /*  reset, and phy automatically renegotiates when reset, and/or    */
+    /*  when link comes (back) up, etc.                                 */
+
+    /* If phy interrupts are required, DO need to reconfigure the       */
+    /*  phy's interrupt control register after the reset our caller     */
+    /*  has probably recently performed.                                */
+
+    unsigned int    msecswaited;
+    unsigned int    my_ad_caps;     // My Advertised capabilities
+    unsigned int    my_phy_caps;    // My PHY capabilities
+    np_mtip_mac    *pmac;
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    my_ad_caps  = PHY_ADV_CSMA;
+    my_phy_caps = (pmac->mdio0).STATUS;
+
+    /* Note Mx TDK phy board's (9) switches control its inherrent       */
+    /*  capabilibles (at the moment, prototype:all off =                */
+    /*  all capabilities available)..                                   */
+
+    if(my_phy_caps & (PHY_STS_CAP_TXF_MASK))
+      {
+//      if(..we're allowing 100mbit full duplex...)
+          {
+            my_ad_caps |= PHY_ADV_TX_FDX;
+          }
+      }
+
+    if(my_phy_caps & (PHY_STS_CAP_TXH_MASK))
+      {
+//      if(..we're allowing 100mbit half duplex...)
+          {
+            my_ad_caps |= PHY_ADV_TX_HDX;
+          }
+      }
+
+    if(my_phy_caps & (PHY_STS_CAP_TF_MASK))
+      {
+//      if(..we're allowing 10mbit full duplex...)
+          {
+            my_ad_caps |= PHY_ADV_10_FDX;
+          }
+      }
+
+    if(my_phy_caps & (PHY_STS_CAP_TH_MASK))
+      {
+//      if(..we're allowing 10mbit half duplex...)
+          {
+            my_ad_caps |= PHY_ADV_10_HDX;
+          }
+      }
+
+    (pmac->mdio0).ADV = my_ad_caps;
+
+  #if defined (MTIPPHYIRQ_AVAIL)
+    #ifdef NS83865PHY
+            (pmac->mdio0).reg15 =
+                (  0
+                 | NS883865_INTIE_ANEGDONE_MASK
+                 | NS883865_INTIE_LSCHG_MASK
+                );
+    #else
+        #ifdef TDK78Q2120PHY
+            (pmac->mdio0).reg11 =
+                (  0
+                 | TDK78_INTIE_ANEGDONE_MASK
+                 | TDK78_INTIE_LSCHG_MASK
+//               | TDK78_INTIE_RXER_MASK
+                );
+        #else
+            ......
+        #endif  // TDK78Q2120PHY
+    #endif  // NS83865PHY
+  #endif  // MTIPPHYIRQ_AVAIL
+
+    (pmac->mdio0).CONTROL =
+        (   0
+          | PHY_CTL_ANEG_EN_MASK
+          | PHY_CTL_ANEG_RST_MASK
+        );
+
+    msecswaited = 0;
+    while(((((pmac->mdio0).STATUS) & 0x00000020) == 0) &
+          (msecswaited < 15000))
+      {
+	    mdelay(100);
+        msecswaited += 100;
+      }
+
+  #if 1
+    if((((pmac->mdio0).STATUS) & 0x00000020) != 0)
+      {
+        printk("mtip_phy_configure:%s, autoneg complete\n",
+               dev->name);
+      }
+      else
+      {
+        printk("mtip_phy_configure:%s, autoneg started\n",
+               dev->name);
+      }
+
+    #ifdef NS83865PHY
+        PRINTNS83PHYREGS(pmac,
+                        ((unsigned int) ((pmac->mdio0).reg14)),
+                        ((unsigned int) ((pmac->mdio0).reg15)),
+                        ((unsigned int) ((pmac->mdio0).reg11)));
+    #else
+      #ifdef TDK78Q2120PHY
+        PRINTTDKPHYREGS(pmac,
+                        ((unsigned int) ((pmac->mdio0).reg11)),
+                        ((unsigned int) ((pmac->mdio0).reg12)));
+      #else
+        ......
+      #endif
+    #endif
+  #endif
+  }
+
+
+/*-----------------------------------------------------------
+ | Enable Receive and Transmit, and Rx Interrupts
+ |
+ | Entry condition: Cpu interrupts ENabled.
+*/
+static void mtip_enable( struct net_device *dev )
+{
+    np_mtip_mac  *pmac;
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    PRINTK2("%s:mtip_enable\n", dev->name);
+
+    pmac->COMMAND_CONFIG =
+        (  mmac_cc_TX_ENA_mask      // enable transmit
+         | mmac_cc_RX_ENA_mask      // enable receive
+         | mmac_cc_TX_ADDR_INS_mask // always overwrite source MAC addr
+        );
+
+    pmac->IRQ_CONFIG = mmac_ic_EN_RX_FRAME_AVAILABLE_mask;
+      // enable rx ready interrupt
+
+  #if defined (MTIPPHYIRQ_AVAIL)
+    #if defined (na_mii_irq)
+      (*(volatile unsigned long *)
+           (((unsigned long *)
+                ((((char *)
+                      (((int) (mtip_mii_control_port)) +
+                       0x0008))))))) =
+              ((unsigned long) (0x0001));
+        // Enable phy interrupt pass thru to na_mii_irq
+    #endif        // na_mii_irq
+  #endif        // MTIPPHYIRQ_AVAIL
+}
+
+
+/*-----------------------------------------------------------
+ | Perform a software Reset.
+ | Takes some time so we need to wait until it is finshed.
+ |
+ | Entry condition: Cpu interrupts ENabled.
+*/
+static void mtip_mac_SwReset( struct net_device* dev )
+  {
+////    struct mtip_local  *lp      = (struct mtip_local *)dev->priv;
+    np_mtip_mac        *pmac;
+    int                 timeout;
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    (pmac->mdio0).CONTROL = PHY_CTL_RST_MASK; // Reset the phy
+
+    // set reset and Gig-Speed bits to make sure we have an
+    //  incoming clock on tx side.
+    // If there is a 10/100 PHY, we will still have a valid clock on
+    //  tx_clk no matter what setting we have here, but on a Gig phy the
+    // MII clock may be missing.
+
+    pmac->COMMAND_CONFIG = mmac_cc_SW_RESET_mask | mmac_cc_ETH_SPEED_mask;
+
+    // wait for completion with fallback in case there is no PHY or it is
+    // not connected and hence might not provide any clocks at all.
+    timeout=0;
+    while( (pmac->COMMAND_CONFIG & mmac_cc_SW_RESET_mask) != 0 &&
+           timeout < 10000) timeout++;
+
+    pmac->COMMAND_CONFIG = 0;
+
+    // Cleanup pending "forgotten" DMAs
+
+    #if defined (MTIPDMA_AVAIL)
+        ((np_dma *) (na_dma))->np_dmacontrol = 0;
+        ((np_dma *) (na_dma))->np_dmastatus  = 0;
+        gMtipDmaState                        = Mtip_DmaState_Idle;
+    #endif  // MTIPDMA_AVAIL
+
+    // flush RX FIFO
+
+/*
+....?...tbd....?............
+............................*/
+  }
+
+
+/*-----------------------------------------------------------
+ | soft reset the device
+ |
+ | Sets the Emac to its normal state.
+ |
+ | Entry condition: Cpu interrupts ENabled.
+*/
+static void mtip_reset( struct net_device* dev )
+{
+    np_mtip_mac  *pmac;
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    PRINTK2("%s:mtip_reset\n", dev->name);
+
+    mtip_mac_SwReset( dev );
+
+    // disable all IRQs
+    //
+    pmac->IRQ_CONFIG = 0;
+    //
+    #ifdef NS83865PHY
+        (pmac->mdio0).reg15 = 0;
+    #else
+      #ifdef TDK78Q2120PHY
+        (pmac->mdio0).reg11 = 0;
+      #else
+        ......
+      #endif
+    #endif
+    //
+  #if defined (MTIPPHYIRQ_AVAIL)
+    #if defined (na_mii_irq)
+      (*(volatile unsigned long *)
+           (((unsigned long *)
+                ((((char *)
+                      (((int) (mtip_mii_control_port)) +
+                       0x0008))))))) =
+              ((unsigned long) (0x0000));
+        // Disable phy interrupt pass thru to na_mii_irq
+    #endif        // na_mii_irq
+  #endif        // MTIPPHYIRQ_AVAIL
+}
+
+
+/*-----------------------------------------------------------
+ */
+static void mtip_reset_config(struct net_device *dev)
+  {
+    np_mtip_mac  *pmac;
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    mtip_reset( dev );
+
+    pmac->MAC_0             =
+        ((unsigned int)
+            (*((unsigned long *)
+                  (&(((unsigned char *)
+                         (dev->dev_addr))[0])))));
+    pmac->MAC_1             =
+        ((unsigned int)
+            (*((unsigned short *)
+                  (&(((unsigned char *)
+                         (dev->dev_addr))[4])))));
+
+    pmac->FRM_LENGTH        = MTIP_MAC_MAX_FRAME_SIZE;
+    pmac->PAUSE_QUANT       = 0xff00;
+
+    pmac->RX_SECTION_EMPTY  = 0;        // Auto tx pause DISabled
+//  pmac->RX_SECTION_EMPTY  = 1900/4;
+      // If RX FIFO fills to this level, PAUSE frame is sent
+
+    pmac->RX_SECTION_FULL   = 0;        // Store&forward (must be zero)
+    pmac->TX_SECTION_EMPTY  = (256-16)/4;
+
+    pmac->TX_SECTION_FULL   = 0;        // NO Early start tx
+//  pmac->TX_SECTION_FULL   = 128/4;    // Early start tx: 128 bytes in FIFO
+      // If TxFifo smaller than outbound packet, early start Tx
+      //  MUST be enabled.
+      // Slow memory feeding TxFifo must NOT enable early start Tx.
+
+    pmac->RX_ALMOST_EMPTY   = 8;        //
+    pmac->RX_ALMOST_FULL    = 10;       //
+    pmac->TX_ALMOST_EMPTY   = 8;        //
+    pmac->TX_ALMOST_FULL    = 16;       // Need at least 14 to cope
+                                        //  with Avalon/DMA latency
+    return;
+  }
+
+
+/*-----------------------------------------------------------
+ | Driver entry point
+ |
+ | Entry condition: Cpu interrupts ENabled
+ */
+static void mtip_timeout (struct net_device *dev)
+{
+//  PRINTK3
+    printk
+          (
+//         KERN_WARNING
+               "%s:mtip_timeout\n",
+           dev->name);
+
+    /* If we get here, some higher level has decided we are broken. */
+
+  #if 0
+....FIXME:...preemption sensitive stuff to be accessed with
+.... cpu interrupts DISabled...
+....If Dma state one of the TX states, must stop the
+.... Dma and change to idle state or handle gMtipDmaQ
+.... Mtip_DmaQ_RxFifo2Tmp/Mtip_DmaQ_RxFifo2Trash flag(s)
+....Ensure Tx "done" interrupt is DISabled
+....
+....Empirical observation: we are toast no matter
+.... what we do [not]do...........
+    if(gpMtipTxSkbInProg)
+      {
+        #if 0
+          printk("%s:mtip_timeout, txSkb 0x%08X freed\n",
+                 dev->name,
+                 ((unsigned int) (gpMtipTxSkbInProg)));
+        #endif
+
+        dev_kfree_skb_any (gpMtipTxSkbInProg);
+        gpMtipTxSkbInProg = NULL;
+
+        #if defined (MTIPDMA_AVAIL)
+          gMtipDmaQ &= (~(Mtip_DmaQ_TxSkb2Tmp));
+        #endif
+      }
+
+    mtip_reset_config( dev );
+    mtip_enable( dev );
+    mtip_phy_configure(dev);
+
+    mtip_phymac_synch(dev,
+                      0);  // Caller = NOT Phy interrupt handler
+
+    netif_wake_queue(dev);
+  #endif
+}
+
+
+/*-----------------------------------------------------------
+ | Driver entry point
+ |
+ | Entry condition: Cpu interrupts ENabled.
+ */
+static int mtip_hard_start_xmit( struct sk_buff    * skb,
+                                 struct net_device * dev )
+  {
+    unsigned long      flags;
+    struct mtip_local *lp       = (struct mtip_local *)dev->priv;
+    np_mtip_mac       *pmac;
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    dev->trans_start = jiffies;
+    netif_stop_queue(dev);
+
+    PRINTK3("%s:mtip_hard_start_xmit\n", dev->name);
+
+    if ( gpMtipTxSkbInProg ) {
+        lp->stats.tx_aborted_errors++;
+        printk("mtip_hard_start_xmit:%s, - tx request while busy.\n",
+               dev->name);
+        return 1;   // Tell caller to retry "later" (if/after someone
+                    //  invokes netif_wake_queue(...))...
+    }
+
+    gMtipTxSkbframelenbyts = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+
+    if(gMtipTxSkbframelenbyts > MTIP_MAC_MAX_FRAME_SIZE)
+      {
+        printk("mtip_hard_start_xmit:%s, oversized %d byte packet.\n",
+               dev->name,
+               gMtipTxSkbframelenbyts);
+        dev_kfree_skb (skb);
+        netif_wake_queue(dev);
+        return 0;
+      }
+
+    gpMtipTxData = skb->data;
+
+    PRINTK3
+          (
+           "%s:Transmitting %d byte Packet 0x%08X\n",
+           dev->name,
+           gMtipTxSkbframelenbyts,
+           ((unsigned long) (gpMtipTxData)));
+    #if MTIP_DEBUG > 3
+      print_packet( gpMtipTxData, gMtipTxSkbframelenbyts );
+    #endif
+
+    gMtipTxSkbFifoNumL32s = ((gMtipTxSkbframelenbyts + 3) >> 2);
+
+    ++(lp->stats.tx_packets);
+
+    local_irq_save(flags);
+
+    gpMtipTxSkbInProg = skb;
+
+    #if defined (MTIPDMA_AVAIL)
+
+      if(gMtipDmaState == Mtip_DmaState_Idle)
+        {
+          gMtipDmaState = Mtip_DmaState_TxSkb2Tmp;
+          local_irq_restore(flags);
+
+          dma_start_TxSkb2Tmp();
+        }
+        else
+        {
+          gMtipDmaQ |= Mtip_DmaQ_TxSkb2Tmp;
+
+          local_irq_restore(flags);
+        }
+    #else
+      pmac->TX_CMD_STAT = (gMtipTxSkbframelenbyts  |
+                           mmac_tcs_FRAME_COMPLETE_mask);
+
+      outsl(((unsigned long) PIO_port_txFIFO),
+            gpMtipTxData,
+            gMtipTxSkbFifoNumL32s );
+        // If TxFifo smaller than outbound packet, early start Tx
+        //  must be enabled, else we'll overrun the TxFifo (which
+        //  "could" happen anyway with a "fast" cpu).
+        // If early start Tx enabled, preemption must be disabled,
+        //  else we might underrun the TxFifo.
+
+      local_irq_restore(flags);
+
+      pmac->IRQ_CONFIG |= mmac_ic_EN_TX_FIFO_EMPTY_mask;
+        // enable tx done interrupt
+    #endif  // MTIPDMA_AVAIL
+
+    return 0;
+  }
+
+
+/*-----------------------------------------------------------
+ | Driver entry point
+ |
+ | Entry condition: Cpu interrupts DISabled.
+ */
+static irqreturn_t mtip_RxInterrupt(int             irq,
+                                    void           *dev_id)
+  {
+    unsigned int            cmplnstatus;
+    struct   net_device    *dev         = dev_id;
+    np_mtip_mac            *pmac;
+
+    /* RxInterrupt condition self clears if/when RxFifo accessed.       */
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    ++gMtipRxints;
+
+    if(!((pmac->IRQ_CONFIG) & (mmac_ic_EN_RX_FRAME_AVAILABLE_mask)))
+      {
+        ++gMtipDisabledRxints;
+      }
+
+    #if defined (MTIPDMA_AVAIL)
+
+    switch (gMtipDmaState)
+      {
+        case Mtip_DmaState_RxFifo2Tmp:
+        case Mtip_DmaState_RxTmp2Skb:
+        case Mtip_DmaState_RxFifo2Trash:
+
+          ++gMtipRxintsRxdmaBusy;
+
+          return IRQ_HANDLED;
+            // ...This could be interesting...!
+
+//      case Mtip_DmaState_TxSkb2Tmp:
+//      case Mtip_DmaState_TxTmp2Fifo:
+//      case Mtip_DmaState_Idle:
+//      default:
+      }
+
+    if (gMtipDmaQ & (Mtip_DmaQ_TxSkb2Tmp    |
+                     Mtip_DmaQ_RxFifo2Tmp   |
+                     Mtip_DmaQ_RxFifo2Trash))
+      {
+        ++gMtipRxintsRxdmaQued;
+
+        return IRQ_HANDLED;
+          // ...This could be interesting...!
+
+      }
+    #endif  // MTIPDMA_AVAIL
+
+    cmplnstatus = pmac->RX_CMD_STAT;
+
+    if(!( cmplnstatus & mmac_rcs_VALID_mask ))
+      {
+        ++gMtipUnexpRxints;
+
+        PRINTK3
+//      printk
+              (
+               "mtip_RxInterrupt:%s, but RxStatus:0x%08X INvalid\n",
+               dev->name,
+               cmplnstatus);
+
+        /* ?...RxInterrupt condition...?                                */
+      }
+      else
+      {
+        mtip_NuRxReady(dev, cmplnstatus);
+      }
+
+    return IRQ_HANDLED;
+  }
+
+
+/*-----------------------------------------------------------
+ | Driver entry point
+ |
+ | Entry condition: Cpu interrupts DISabled.
+ */
+static irqreturn_t mtip_TxInterrupt(int             irq,
+                                    void           *dev_id)
+  {
+    unsigned long        cmdcfg;
+    struct   net_device *dev        = dev_id;
+    struct   mtip_local *lp;
+    int                  old_txcmdstat;
+    np_mtip_mac         *pmac;
+
+    // Mtip's Tx fifo supposedly could alternatively
+    //  "flow control" the Dma adequately enough to let
+    //  us save this interrupt (if we don't need tx done
+    //  error tallying).
+    //...Jun2004...NOT the case?...perhaps early tx start
+    //... plays a part therein...?...
+
+    lp   = (struct mtip_local *)dev->priv;
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    ++gMtipTxints;
+
+    if(!((pmac->IRQ_CONFIG) & (mmac_ic_EN_TX_FIFO_EMPTY_mask)))
+      {
+        ++gMtipDisabledTxints;
+      }
+
+    cmdcfg = pmac->COMMAND_CONFIG;
+    if((cmdcfg & mmac_cc_EXCESS_COL_mask) != 0)
+      {
+        ++(lp->stats.collisions);
+      }
+    if((cmdcfg & mmac_cc_LATE_COL_mask) != 0)
+      {
+		lp->stats.tx_window_errors++;
+          // ifconfig displays as "carrier" errors.
+
+        PRINTK3
+//      printk
+              (
+//             KERN_NOTICE
+			   "mtip_TxInterrupt:%s, Late collision on last xmit.\n",
+			   dev->name);
+              }
+
+    old_txcmdstat = pmac->TX_CMD_STAT;
+
+    if(gpMtipTxSkbInProg)
+      {
+        if(!(old_txcmdstat & mmac_tcs_FRAME_COMPLETE_mask))
+          {
+            dev_kfree_skb_any (gpMtipTxSkbInProg);
+            gpMtipTxSkbInProg = NULL;
+          }
+          else
+          {
+            ++gMtipTxintsIncomplete;
+
+            return IRQ_HANDLED;
+              // ...This could be interesting...!
+          }
+      }
+      else
+      {
+        ++gMtipUnexpTxints;
+      }
+
+    pmac->IRQ_CONFIG &= (~(mmac_ic_EN_TX_FIFO_EMPTY_mask));
+
+    netif_wake_queue(dev);
+
+    return IRQ_HANDLED;
+  }
+
+
+#if defined (MTIPPHYIRQ_AVAIL)
+/*-----------------------------------------------------------
+ | Driver entry point
+ |
+ | Entry condition: Cpu interrupts DISabled.
+ */
+static irqreturn_t mtip_PhyInterrupt(int             irq,
+                                     void           *dev_id)
+  {
+    struct   net_device    *dev      = dev_id;
+    np_mtip_mac            *pmac;
+  #ifdef NS83865PHY
+      unsigned int          nsIntstsReg20;
+      unsigned int          nsIntieReg21;
+      unsigned int          nsLnkstsReg17;
+  #else
+    #ifdef TDK78Q2120PHY
+      unsigned int          tdkDiagReg18;
+      unsigned int          tdkintCtlStsReg17;
+    #endif
+  #endif
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    #if defined(ANNOUNCEPHY)
+      printk
+             (
+              "mtip_PhyInterrupt:%s\n",
+              dev->name);
+    #endif
+
+    #ifdef NS83865PHY
+        nsIntstsReg20 = (pmac->mdio0).reg14;
+        nsIntieReg21  = (pmac->mdio0).reg15;
+        nsLnkstsReg17 = (pmac->mdio0).reg11;
+
+        #if 0
+          PRINTNS83PHYREGS(pmac,
+                           nsIntstsReg20,
+                           nsIntieReg21,
+                           nsLnkstsReg17);
+        #endif
+
+        (pmac->mdio0).reg17 = nsIntstsReg20;
+          // Ack (all) interrupt condition(s)
+    #else
+      #ifdef TDK78Q2120PHY
+        tdkintCtlStsReg17 = (pmac->mdio0).reg11;
+          // Read TDK 78Q2120 interrupt control/status register
+          // Also acks the interrupt condition(s)
+
+        tdkDiagReg18 = (pmac->mdio0).reg12;
+          // Read TDK 78Q2120 diagnostic register
+          // Also clears auto-negotiation failed bit
+
+        #if 0
+          PRINTTDKPHYREGS(pmac, tdkintCtlStsReg17, tdkDiagReg18);
+        #endif
+      #else
+          ......
+      #endif
+    #endif
+
+    mtip_phymac_synch((struct net_device *) dev_id,
+                      1);  // Caller = Phy interrupt handler
+
+    return IRQ_HANDLED;
+  }
+#endif // MTIPPHYIRQ_AVAIL
+
+
+/*-----------------------------------------------------------
+ | Driver entry point (eg: ifconfig ethX up).
+ |                    (eg: ifattach ...)
+ |
+ | Open and Initialize the board
+ |
+ | Set up everything, reset the card, etc ..
+ |
+ | Entry condition: Cpu interrupts ENabled.
+ */
+static int mtip_open(struct net_device *dev)
+{
+    np_mtip_mac  *pmac;
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    PRINTK2("%s:mtip_open\n", dev->name);
+
+    memset(dev->priv, 0, sizeof(struct mtip_local));
+
+
+  #ifdef CONFIG_SYSCTL
+    // Set default parameters (files)
+/*
+....tbd.............
+.....................*/
+  #endif
+
+    mtip_reset_config( dev );
+    mtip_enable( dev );
+    mtip_phy_configure(dev);
+
+    mtip_phymac_synch(dev,
+                      0);  // Caller = NOT Phy interrupt handler
+
+#ifdef CONFIG_SYSCTL
+    mtip_sysctl_register(dev);
+#endif /* CONFIG_SYSCTL */
+
+    netif_start_queue(dev);
+
+    return 0;
+}
+
+
+/*-----------------------------------------------------------
+ | close down the Emac
+ |
+ | put the device in an inactive state
+ |
+*/
+static void mtip_shutdown( struct net_device *dev )
+{
+    PRINTK2("%s:mtip_shutdown\n", dev->name);
+
+/*
+....tbd.............
+...........................*/
+}
+
+
+/*-----------------------------------------------------------
+ | Driver entry point (eg: ifconfig ethX down).
+ |
+ | Clean up everything from the open routine
+*/
+static int mtip_close(struct net_device *dev)
+{
+    PRINTK2("%s:mtip_close\n", dev->name);
+
+    netif_stop_queue(dev);
+
+    if(gpMtipTxSkbInProg)
+      {
+        dev_kfree_skb_any (gpMtipTxSkbInProg);
+        gpMtipTxSkbInProg = NULL;
+
+        #if defined (MTIPDMA_AVAIL)
+          gMtipDmaQ &= (~(Mtip_DmaQ_TxSkb2Tmp));
+        #endif
+      }
+
+  #if defined (MTIPDMA_AVAIL)
+    gMtipDmaQ         = 0;
+    gMtipDmaState     = Mtip_DmaState_Idle;
+  #endif        // MTIPDMA_AVAIL
+
+#ifdef CONFIG_SYSCTL
+    mtip_sysctl_unregister(dev);
+#endif /* CONFIG_SYSCTL */
+
+    /* clear everything */
+    mtip_shutdown( dev );
+
+    /* Update the statistics here. */
+
+    return 0;
+}
+
+
+/*-----------------------------------------------------------
+ | Driver entry point (re unregister_netdev()).
+ |
+ | Cleaning up before driver finally unregistered and discarded.
+ |
+ |   Input parameters:
+ |  dev, pointer to the device structure
+ |
+ |   Output:
+ |  None.
+ |
+ ---------------------------------------------------------------------------
+*/
+void mtip_destructor(struct net_device *dev)
+{
+    PRINTK2("%s:mtip_destructor\n", dev->name);
+}
+
+
+/*-----------------------------------------------------------
+ | Driver entry point.
+ |
+ | Get the current statistics.
+ |
+ | Allows proc file system to query the driver's statistics.
+ |
+ | May be called with the card open or closed.
+ |
+ | Entry condition: Cpu interrupts ENabled.
+*/
+static struct net_device_stats* mtip_query_statistics(struct net_device *dev)
+  {
+    struct mtip_local *lp = (struct mtip_local *)dev->priv;
+
+    PRINTK2("%s:mtip_query_statistics\n", dev->name);
+
+    return &lp->stats;
+  }
+
+
+/*-----------------------------------------------------------
+ | Clear the multicast table to disable multicast reception.
+ |
+ | Entry condition: Cpu interrupts ENabled.
+*/
+static void mtip_mac_clearMulticast(struct net_device *dev)
+  {
+    int           i;
+    np_mtip_mac  *pmac;
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    for(i=0; i < 64; i++ )
+      {
+        (pmac->hashtable)[i] = 0;
+      }
+  }
+
+
+/*-----------------------------------------------------------
+ | Fill the multicast table to enable reception of all multicast frames.
+ |
+ | Entry condition: Cpu interrupts ENabled.
+*/
+static void mtip_mac_promiscuousMulticast(struct net_device *dev)
+  {
+    int           i;
+    np_mtip_mac  *pmac;
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    for(i=0; i < 64; i++ )
+      {
+        (pmac->hashtable)[i] = 1;
+      }
+  }
+
+
+/*-----------------------------------------------------------
+ | Reprogram multicast mac addresses into hardware multicast table
+ |
+ | Caller has already cleared existing hash entries as appropriate
+ |
+ | Entry condition: Cpu interrupts ENabled.
+*/
+static void mtip_setmulticast( struct net_device    *dev,
+                                      int            count,
+                               struct dev_mc_list   *addrs )
+  {
+    int                   a;
+    int                   bit;
+    int                   bitidx;
+    int                   hash;
+    int                   i;
+    char                  ch;
+    struct   dev_mc_list *cur_addr;
+    np_mtip_mac          *pmac;
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    PRINTK2
+          (
+           "mtip_setmulticast:%s\n",
+           dev->name);
+
+    cur_addr = addrs;
+
+    for ( i = 0; i < count ; i ++, cur_addr = cur_addr->next )
+      {
+        /* do we have a pointer here? */
+        if ( !cur_addr )
+            break;
+
+        /* make sure this is a multicast address    */
+        if ( !( *cur_addr->dmi_addr & 1 ) )
+            continue;
+
+        hash = 0; // the hash value
+
+        for(a=5; a >= 0; a--)
+          {
+            // loop through all 6 bytes of this mac address
+
+            bit = 0; // the bit calculated from the byte
+            ch = (cur_addr->dmi_addr)[a];
+
+            for(bitidx=0;bitidx < 8;bitidx++)
+              {
+                bit ^= (int)((ch >> bitidx) & 0x01);
+              }
+
+            hash = (hash << 1) | bit;
+          }
+
+          #if (MTIP_DEBUG > 2 )
+//          printk("  ");
+            printk("mtip_setmulticast: ");
+            for(a=0; a < 6; a++)
+              {
+                ch = (cur_addr->dmi_addr)[a];
+
+                printk("  %02X",ch);
+              }
+            printk("  hash(%d)\n",hash);
+          #endif
+
+        (pmac->hashtable)[ hash ] = 1;
+      }
+  }
+
+
+/*-----------------------------------------------------------
+ | Driver entry point.
+ |
+ | This routine will, depending on the values passed to it,
+ | either make it accept multicast packets, go into
+ | promiscuous mode ( for TCPDUMP and cousins ) or accept
+ | a select set of multicast packets
+ |
+ | Entry condition: Cpu interrupts ENabled.
+*/
+static void mtip_set_multicast_list(struct net_device *dev)
+  {
+    np_mtip_mac          *pmac;
+
+    pmac = ((np_mtip_mac *) dev->base_addr);
+
+    PRINTK2
+          (
+           "%s:mtip_set_multicast_list\n",
+           dev->name);
+
+    if ( dev->flags & IFF_PROMISC )
+      {
+        PRINTK2
+//      printk
+               (
+                "%s:mtip_set_multicast_list:RCR_PRMS\n", dev->name);
+
+        mtip_mac_setPromiscuous(pmac);
+      }
+      else
+      {
+        PRINTK2
+//      printk
+              (
+               "%s:mtip_set_multicast_list:~RCR_PRMS\n", dev->name);
+
+        mtip_mac_clearPromiscuous(pmac);
+      }
+
+    if (dev->flags & IFF_ALLMULTI)
+      {
+        PRINTK2
+//      printk
+              (
+               "%s:mtip_set_multicast_list:RCR_ALMUL\n", dev->name);
+
+        mtip_mac_promiscuousMulticast(dev);
+      }
+      else
+      {
+        PRINTK2
+              (
+               "%s:mtip_set_multicast_list:~RCR_ALMUL\n", dev->name);
+
+        mtip_mac_clearMulticast(dev); // Clear any existing hash entries
+
+        if(dev->mc_count)
+          {
+            mtip_setmulticast( dev,
+                               dev->mc_count,
+                               dev->mc_list );
+          }
+      }
+  }
+
+
+/*-----------------------------------------------------------
+ | Entry condition: Cpu interrupts ENabled
+ |                   (in SPITE of claims disabled...).
+*/
+static int __init mtip_probe(struct net_device *dev, unsigned int ioaddr )
+{
+    int              i;
+    np_mtip_mac     *pmac;
+    int              retval;
+    static unsigned  version_printed        = 0;
+
+
+    pmac = ((np_mtip_mac *) ioaddr);
+
+    PRINTK2("%s:mtip_probe\n", dev->name);
+
+    SET_MODULE_OWNER (dev);
+
+#if 1
+    #ifdef CONFIG_EXCALIBUR
+        printk("mtip_probe:%s, %d Khz Nios (%s) (%s)\n",
+               dev->name,
+               nasys_clock_freq_1000,
+               PHYTYPE,
+               IOTYPE);
+    #endif
+#endif
+
+    /* Grab the region so that no one else tries to probe our ioports. */
+    if (!request_region(ioaddr,
+                        MTIP1000_IO_EXTENT,
+                        dev->name)) return -EBUSY;
+
+    if (version_printed++ == 0) printk("%s", version);
+
+    dev->base_addr = ioaddr;
+
+  #ifdef NS83865PHY
+    {
+      int            oldmdioaddr0;
+      int            phyaddr                = -1;
+
+      // Empirical observation: expect NS83865PHY's phy address = 2
+
+      oldmdioaddr0 = pmac->MDIO_ADDR0;
+
+      for (i = 0; i <= 31; i++)
+        {
+          pmac->MDIO_ADDR0 = i;
+
+          if(((pmac->mdio0).PHY_ID1) == 0x2000)
+            {
+              phyaddr = i;
+
+              break;
+            }
+        }
+
+      if(phyaddr >= 0)
+        {
+          pmac->MDIO_ADDR0 = phyaddr;
+        }
+        else
+        {
+          pmac->MDIO_ADDR0 = oldmdioaddr0;
+
+          printk("mtip_probe:%s, (%s) phy not found"
+                   ", defaulting to addr:0x%02X\n",
+                 dev->name,
+                 PHYTYPE,
+                 pmac->MDIO_ADDR0);
+        }
+    }
+    #else
+      #ifdef TDK78Q2120PHY
+        // TDK78Q2120PHY's respond to the "broadcast" phy address 0,
+        //  so leave pmac->MDIO_ADDR0 at its default value 0
+      #else
+          ......
+      #endif
+  #endif    // NS83865PHY
+
+    mtip_reset( dev );
+
+    printk("mtip_probe:%s, REV=0x%08x, (%s) Phyaddr:0x%02X\n",
+           dev->name,
+           pmac->REV,
+           PHYTYPE,
+           pmac->MDIO_ADDR0);
+
+  #if 0
+    #ifdef NS83865PHY
+        PRINTNS83PHYREGS(pmac,
+                        ((unsigned int) ((pmac->mdio0).reg14)),
+                        ((unsigned int) ((pmac->mdio0).reg15)),
+                        ((unsigned int) ((pmac->mdio0).reg11)));
+    #else
+      #ifdef TDK78Q2120PHY
+        PRINTTDKPHYREGS(pmac,
+                        ((unsigned int) ((pmac->mdio0).reg11)),
+                        ((unsigned int) ((pmac->mdio0).reg12)));
+      #else
+          ......
+      #endif
+    #endif
+  #endif
+
+#ifdef CONFIG_EXCALIBUR
+    {
+      extern unsigned char *excalibur_enet_hwaddr;
+
+      memcpy(dev->dev_addr, excalibur_enet_hwaddr, 6);
+    }
+#else
+    .........
+#endif
+
+    /*
+     . Print the Ethernet address
+    */
+    printk("    ADDR: ");
+    for (i = 0; i < 5; i++)
+        printk("%2.2x:", dev->dev_addr[i] );
+    printk("%2.2x \n", dev->dev_addr[5] );
+
+    /* set the private data to zero by default */
+    memset(dev->priv, 0, sizeof(struct mtip_local));
+
+    /* Fill in the fields of the device structure with ethernet values. */
+    ether_setup(dev);
+
+    /* Grab the RxIRQ */
+    retval = request_irq(dev->irq,
+                         mtip_RxInterrupt,
+                         0,
+                         dev->name,
+                         dev);
+    if (retval) {
+          printk("mtip_probe:%s unable to hook RxIRQ %d (retval=%d).\n",
+                 dev->name,
+                 dev->irq,
+                 retval);
+
+          goto frepriv_err_out;
+    }
+
+    retval = request_irq(na_mtip_mac_txFIFO_irq,
+                         mtip_TxInterrupt,
+                         0,
+                         dev->name,
+                         dev);
+    if (retval) {
+          printk("mtip_probe:%s unable to hook TxIRQ %d (retval=%d).\n",
+                 dev->name,
+                 na_mtip_mac_txFIFO_irq,
+                 retval);
+
+          goto freRxIrq_err_out;
+    }
+
+  #if defined (MTIPPHYIRQ_AVAIL)
+    /* Grab the PhyIRQ */
+    retval = request_irq(na_mii_irq_irq,
+                         mtip_PhyInterrupt,
+                         0,
+                         dev->name,
+                         dev);
+    if (retval)
+      {
+        printk("mtip_probe:%s unable to hook PhyIRQ %d (retval=%d).\n",
+               dev->name,
+               na_mii_irq_irq,
+               retval);
+
+        goto freTxIrq_err_out;
+      }
+  #endif    // MTIPPHYIRQ_AVAIL
+
+    gMtipDisabledRxints   = 0;
+    gMtipDisabledTxints   = 0;
+    gMtipDmaints          = 0;
+    gMtipDmaintsBusy      = 0;
+    gMtipDmaintsBusyDone  = 0;
+    gMtipDmaintsNoDone    = 0;
+    gMtipRxints           = 0;
+    gMtipRxintsRxdmaBusy  = 0;
+    gMtipRxintsRxdmaQued  = 0;
+    gMtipRxNoints         = 0;
+    gMtipTxints           = 0;
+    gMtipTxintsIncomplete = 0;
+    gMtipUnexpDmaints     = 0;
+    gMtipUnexpRxints      = 0;
+    gMtipUnexpTxints      = 0;
+    gpMtipTxSkbInProg     = NULL;
+
+  #if defined (MTIPDMA_AVAIL)
+    gMtipDmaQ         = 0;
+    gMtipDmaState     = Mtip_DmaState_Idle;
+
+    /* Grab the DmaIRQ */
+    retval = request_irq(na_dma_irq,
+                         mtip_DmaInterrupt,
+                         0,
+                         dev->name,
+                         dev);
+    if (retval) {
+        printk("mtip_probe:%s unable to hook DmaIRQ %d (retval=%d).\n",
+               dev->name,
+               na_dma_irq,
+               retval);
+
+        goto frePhyIrq_err_out;
+    }
+  #endif        // MTIPDMA_AVAIL
+
+//  see mtip_phymac_synch for full/half duplex coordination
+
+    dev->open               = mtip_open;
+    dev->stop               = mtip_close;
+    dev->hard_start_xmit    = mtip_hard_start_xmit;
+    dev->tx_timeout         = mtip_timeout;
+    dev->get_stats          = mtip_query_statistics;
+  #ifdef    HAVE_MULTICAST
+    dev->set_multicast_list = &mtip_set_multicast_list;
+  #endif
+
+    return 0;
+
+  #if defined (MTIPPHYIRQ_AVAIL)
+    #if defined (MTIPDMA_AVAIL)
+frePhyIrq_err_out:
+    #endif      // MTIPDMA_AVAIL
+
+    free_irq(na_mii_irq_irq, dev);
+
+freTxIrq_err_out:
+  #endif      // MTIPPHYIRQ_AVAIL
+
+    free_irq(na_mtip_mac_txFIFO_irq,
+             dev);
+
+freRxIrq_err_out:
+
+    free_irq(na_mtip_mac_rxFIFO_irq,
+             dev);
+
+frepriv_err_out:
+
+    kfree (dev->priv);
+    dev->priv = NULL;
+
+//err_out:
+    release_region (ioaddr, MTIP1000_IO_EXTENT);
+    return retval;
+}
+
+
+/*-----------------------------------------------------------
+ | Driver entry point (called by ethif_probe2()).
+ |
+ | Return:  0   success.
+ |
+ | Entry condition: Cpu interrupts ENabled
+ |                   (in SPITE of claims disabled...).
+*/
+struct net_device * __init mtip1000_init(int unit)
+{
+    struct net_device *dev = alloc_etherdev(sizeof(struct mtip_local));
+    int                err = 0;
+    int                i;
+
+    if (!dev) return ERR_PTR(-ENODEV);
+
+    sprintf(dev->name, "eth%d", unit);
+    netdev_boot_setup_check(dev);
+
+    PRINTK2("%s:mtip1000_init\n", dev->name);
+
+    for (i = 0; mtip_portlist[i]; i++) {
+        dev->irq = mtip_irqlist[i];
+
+        if (mtip_probe(dev, mtip_portlist[i]) == 0) break;
+    }
+
+    if (!mtip_portlist[i]) err = -ENODEV;
+    if (err) goto out;
+
+    err = register_netdev(dev);
+    if (err) goto out;
+    return dev;
+out:
+    free_netdev(dev);
+    //  printk(KERN_WARNING "mtip1000: no emac unit %d detected.\n",unit);
+    return ERR_PTR(err);
+}
diff --git a/drivers/net/mtip1000.h b/drivers/net/mtip1000.h
new file mode 100644
index 0000000..18d784d
--- /dev/null
+++ b/drivers/net/mtip1000.h
@@ -0,0 +1,408 @@
+/*----------------------------------------------------------------------
+ . mtip1000.c
+ .
+ . Driver: MoreThanIP 10/100/1000Mbps Emac IP
+ .
+ . Copyright ...
+    to
+        be
+            completed
+                        ...
+ .
+ . Sources:
+ .    o   MoreThanIP 10/100/1000Mbps Reference Guide V3.2 - May 2003
+ .    o   MoreThanIP Altera Plugs sources
+ .    o   Smc9111 uClinux port(s)
+ .
+ . History:
+ .    o   Apr2004   DGT Microtronix Datacom
+ .
+ -----------------------------------------------------------------------*/
+
+#ifndef _MTIP1000_H_
+    #define _MTIP1000_H_
+
+/*----------------------------------------------------------------------*/
+
+#ifndef na_mtip_mac_control_port
+  #if defined (na_mip_mac_control_port)
+    #define na_mtip_mac_control_port    na_mip_mac_control_port
+  #endif
+#endif
+#ifndef na_mtip_mac_rxFIFO
+  #if defined (na_mip_mac_rxFIFO)
+    #define na_mtip_mac_rxFIFO    na_mip_mac_rxFIFO
+  #endif
+#endif
+#ifndef na_mtip_mac_rxFIFO_irq
+  #if defined (na_mip_mac_rxFIFO_irq)
+    #define na_mtip_mac_rxFIFO_irq    na_mip_mac_rxFIFO_irq
+  #endif
+#endif
+#ifndef na_mtip_mac_txFIFO
+  #if defined (na_mip_mac_txFIFO)
+    #define na_mtip_mac_txFIFO    na_mip_mac_txFIFO
+  #endif
+#endif
+#ifndef na_mtip_mac_txFIFO_irq
+  #if defined (na_mip_mac_txFIFO_irq)
+    #define na_mtip_mac_txFIFO_irq    na_mip_mac_txFIFO_irq
+  #endif
+#endif
+
+/*----------------------------------------------------------------------*/
+
+// Number of bytes the largest frame can have.
+// For receive, should be at least the MAC's FRAME_LENGTH
+//  programmed value + 8.
+#define MTIP_MAC_MAX_FRAME_SIZE     1524
+//
+// Receive buffer must be at least 'maximum possible frame size'+16.
+#define MTIP_MI_XBUF_BYTS           24
+#define MTIP_SKB_XBUF_BYTS          MTIP_MI_XBUF_BYTS
+
+// MDIO registers within MAC register Space
+// memory mapped access
+//
+typedef volatile struct
+{
+  unsigned int CONTROL;
+  unsigned int STATUS;
+  unsigned int PHY_ID1;
+  unsigned int PHY_ID2;
+  unsigned int ADV;
+  unsigned int REMADV;
+
+  unsigned int reg6;
+  unsigned int reg7;
+  unsigned int reg8;
+  unsigned int reg9;
+  unsigned int rega;
+  unsigned int regb;
+  unsigned int regc;
+  unsigned int regd;
+  unsigned int rege;
+  unsigned int regf;
+  unsigned int reg10;
+  unsigned int reg11;
+  unsigned int reg12;
+  unsigned int reg13;
+  unsigned int reg14;
+  unsigned int reg15;
+  unsigned int reg16;
+  unsigned int reg17;
+  unsigned int reg18;
+  unsigned int reg19;
+  unsigned int reg1a;
+  unsigned int reg1b;
+  unsigned int reg1c;
+  unsigned int reg1d;
+  unsigned int reg1e;
+  unsigned int reg1f;
+
+} np_mtip_mdio;
+
+// MAC Registers - 32 Bit
+//
+typedef volatile struct
+{
+  unsigned int REV;
+  unsigned int SCRATCH;
+  unsigned int COMMAND_CONFIG;
+  unsigned int MAC_0;
+  unsigned int MAC_1;
+  unsigned int FRM_LENGTH;
+  unsigned int PAUSE_QUANT;
+  unsigned int RX_SECTION_EMPTY;
+  unsigned int RX_SECTION_FULL;
+  unsigned int TX_SECTION_EMPTY;
+  unsigned int TX_SECTION_FULL;
+  unsigned int RX_ALMOST_EMPTY;
+  unsigned int RX_ALMOST_FULL;
+  unsigned int TX_ALMOST_EMPTY;
+  unsigned int TX_ALMOST_FULL;
+  unsigned int MDIO_ADDR0;
+  unsigned int MDIO_ADDR1;
+
+  unsigned int AUTONEG_CNTL;
+    // only if 100/1000 BaseX PCS, reserved otherwise
+
+  unsigned int AN_ABILITY_INT;
+  unsigned int LP_ABILITY_INT;
+  unsigned int LINK_TIMER_INT;
+
+  unsigned int reservedx54;
+  unsigned int reservedx58;
+  unsigned int reservedx5C;
+
+  unsigned int aMACID_1;
+  unsigned int aMACID_2;
+  unsigned int aFramesTransmittedOK;
+  unsigned int aFramesReceivedOK;
+  unsigned int aFramesCheckSequenceErrors; 
+  unsigned int aAlignmentErrors;
+  unsigned int aOctetsTransmittedOK;
+  unsigned int aOctetsReceivedOK;
+  unsigned int aTxPAUSEMACCtrlFrames;
+  unsigned int aRxPAUSEMACCtrlFrames;
+  unsigned int ifInErrors;
+  unsigned int ifOutErrors;
+  unsigned int ifInUcastPkts;
+  unsigned int ifInBroadcastPkts;
+  unsigned int ifInMulticastPkts;
+  unsigned int ifOutDiscards;
+  unsigned int ifOutUcastPkts;
+  unsigned int ifOutBroadcastPkts;
+  unsigned int ifOutMulticastPkts;
+  unsigned int etherStatsDropEvent;
+  unsigned int etherStatsOctets;
+  unsigned int etherStatsPkts;
+  unsigned int etherStatsUndersizePkts;
+  unsigned int etherStatsOversizePkts;
+  unsigned int etherStatsPkts64Octets;
+  unsigned int etherStatsPkts65to127Octets;
+  unsigned int etherStatsPkts128to255Octets;
+  unsigned int etherStatsPkts256to511Octets;
+  unsigned int etherStatsPkts512to1023Octets;
+  unsigned int etherStatsPkts1024to1518Octets;
+
+  unsigned int reservedxD8;
+  unsigned int reservedxDC;
+
+  unsigned int AVL_STATUS;
+  unsigned int IRQ_CONFIG;
+           int TX_CMD_STAT;
+           int RX_CMD_STAT;
+
+  unsigned int reservedxF0;
+  unsigned int reservedxF4;
+  unsigned int reservedxF8;
+  unsigned int reservedxFC;
+
+  unsigned int hashtable[64];
+
+  np_mtip_mdio mdio0;
+  np_mtip_mdio mdio1;
+
+} np_mtip_mac;
+
+
+// Base-Structure for all library functions
+
+typedef struct {
+
+  np_mtip_mac     *mac;
+#ifdef nasys_dma_0
+  np_dma          *dma;
+  np_dma          *dma_rx;
+#else
+  int             *dma;
+  int             *dma_rx;
+#endif
+  volatile unsigned int *rxFIFO;
+  volatile unsigned int *txFIFO;
+
+  unsigned int    cfgflags;
+     // flags or'ed during initialization of COMMAND_CONFIG
+
+  int            *rxbuf;        // receive buffer to use
+
+} mtip_mac_trans_info;
+
+// COMMAND_CONFIG Register Bits
+//
+enum
+{
+  mmac_cc_TX_ENA_bit        = 0,
+  mmac_cc_RX_ENA_bit        = 1,
+  mmac_cc_XOFF_GEN_bit      = 2,
+  mmac_cc_ETH_SPEED_bit     = 3,
+  mmac_cc_PROMIS_EN_bit     = 4,
+  mmac_cc_PAD_EN_bit        = 5,
+  mmac_cc_CRC_FWD_bit       = 6,
+  mmac_cc_PAUSE_FWD_bit     = 7,
+  mmac_cc_PAUSE_IGNORE_bit  = 8,
+  mmac_cc_TX_ADDR__INS_bit  = 9,
+  mmac_cc_HD_ENA_bit        = 10,
+  mmac_cc_EXCESS_COL_bit    = 11,
+  mmac_cc_LATE_COL_bit      = 12,
+  mmac_cc_SW_RESET_bit      = 13,
+//;dgt2;  mmac_cc_MHASH_SEL_bit     = 13,
+  mmac_cc_MHASH_SEL_bit     = 14,   //;dgt2;
+  mmac_cc_LOOPBACK_bit      = 15,
+  mmac_cc_TX_ADDR_SEL_bit   = 16,   // bits 18:16 = address select
+  mmac_cc_MAGIC_ENA_bit     = 19,
+  mmac_cc_SLEEP_ENA_bit     = 20,
+
+  mmac_cc_TX_ENA_mask       = (1 << 0), // enable TX
+  mmac_cc_RX_ENA_mask       = (1 << 1), // enable RX
+  mmac_cc_XOFF_GEN_mask     = (1 << 2), // generate Pause frame with Quanta
+  mmac_cc_ETH_SPEED_mask    = (1 << 3), // Select Gigabit
+  mmac_cc_PROMIS_EN_mask    = (1 << 4), // enable Promiscuous mode
+  mmac_cc_PAD_EN_mask       = (1 << 5), // enable padding remove on RX
+  mmac_cc_CRC_FWD_mask      = (1 << 6), // forward CRC to application on RX (as opposed to stripping it off)
+  mmac_cc_PAUSE_FWD_mask    = (1 << 7), // forward Pause frames to application
+  mmac_cc_PAUSE_IGNORE_mask = (1 << 8), // ignore Pause frames
+  mmac_cc_TX_ADDR_INS_mask  = (1 << 9), // MAC overwrites bytes 6 to 12 of frame with address on all transmitted frames
+  mmac_cc_HD_ENA_mask       = (1 << 10),// enable half-duplex operation
+  mmac_cc_EXCESS_COL_mask   = (1 << 11),// indicator
+  mmac_cc_LATE_COL_mask     = (1 << 12),// indicator
+  mmac_cc_SW_RESET_mask     = (1 << 13),// issue register and counter reset
+  mmac_cc_MHASH_SEL_mask    = (1 << 14),// select multicast hash method
+  mmac_cc_LOOPBACK_mask     = (1 << 15),// enable GMII loopback
+  mmac_cc_MAGIC_ENA_mask    = (1 << 19),// enable magic packet detect
+  mmac_cc_SLEEP_ENA_mask    = (1 << 20) // enter sleep mode
+};
+
+// AVL_STATUS Register Bits
+
+enum
+{
+  mmac_as_RX_FRAME_AVAILABLE_mask   = (1 << 0),
+  mmac_as_TX_FIFO_EMPTY_mask        = (1 << 1),
+  mmac_as_TX_FIFO_SEPTY_mask        = (1 << 2)
+};
+
+
+// IRQ_CONFIG Register Bits
+
+enum
+{
+  mmac_ic_EN_RX_FRAME_AVAILABLE_mask = (1 << 0),  // rx frame available (status FIFO)
+  mmac_ic_EN_TX_FIFO_EMPTY_mask      = (1 << 1),  // tx section empty
+  mmac_ic_EN_RX_MAGIC_FRAME_mask     = (1 << 2),  // magic frame received interrupt when in sleep mode
+  mmac_ic_OR_WRITE                   = (1 << 30), // if set, write data is OR'ed with current register bits
+  mmac_ic_AND_WRITE                  = (1 << 31)  // if set, write data is AND'ed with current register bits
+};
+
+
+// TX_CMD_STAT Register bits
+//
+enum{
+  mmac_tcs_LENGTH_mask            = 0x3fff,        // length portion
+  mmac_tcs_FRAME_COMPLETE_mask    = (1 << 31),     // negative as long as frame is not complete
+  mmac_tcs_SET_ERROR_mask         = (1 << 16),
+  mmac_tcs_OMIT_CRC_mask          = (1 << 17)
+};
+
+
+// RX_CMD_STAT Register bits
+//
+enum{
+  mmac_rcs_FRAME_LENGTH_mask    = 0x0000ffff,
+  mmac_rcs_ERROR_mask           = (1 << 16),
+  //mmac_rcs_FIFO_OVERFLOW_mask   = (1 << xx),  //;dgt2; ???
+  mmac_rcs_VLAN_mask            = (1 << 17),
+  mmac_rcs_MCAST_mask           = (1 << 18),
+  mmac_rcs_BCAST_mask           = (1 << 19),
+  mmac_rcs_UNICAST_mask         = (1 << 20),    //;dgt2; 20 or 23 ?...
+  mmac_rcs_READ_CMD_mask        = (1 << 24),
+  mmac_rcs_VALID_mask           = (1 << 31)
+};
+
+
+/** extracts AVL_STATUS' VALID bit to detect if there is a frame in the RX fifo. */
+//
+//;dgt2;nix;
+//;dgt2;-only if;
+//;dgt2;  Avl_Status;
+//;dgt2;   says frame;
+//;dgt2;    available...?...;
+//;dgt2; #define mtip_mac_isFrameAvail( pmtip_mac ) ( pmtip_mac->RX_CMD_STAT & mmac_rcs_VALID_mask )
+
+/** extracts length of frame currently available in the FIFO. */
+//
+#define mtip_mac_getFrameLength( pmtip_mac) ( pmtip_mac->RX_CMD_STAT & mmac_rcs_FRAME_LENGTH_mask )
+
+/** set promiscous bit. */
+//
+#define mtip_mac_setPromiscuous( pmtip_mac) ( pmtip_mac->COMMAND_CONFIG |= mmac_cc_PROMIS_EN_mask )
+
+/** clear promiscuous bit. */
+//
+#define mtip_mac_clearPromiscuous(pmtip_mac) ( pmtip_mac->COMMAND_CONFIG &= ~mmac_cc_PROMIS_EN_mask )
+
+
+/** switch MAC into MII (10/100) mode. */
+//
+#define mtip_mac_setMIImode( pmtip_mac ) ( pmtip_mac->COMMAND_CONFIG &= ~mmac_cc_ETH_SPEED_mask )
+
+/** switch MAC into GMII (Gigabit) mode. */
+#define mtip_mac_setGMIImode( pmtip_mac ) ( pmtip_mac->COMMAND_CONFIG |= mmac_cc_ETH_SPEED_mask )
+
+
+// PCS --------------
+
+/** PCS Control Register Bits. IEEE 802.3 Clause 22.2.4.1
+ */
+enum {
+        PCS_CTL_speed1      = 1<<6,  // speed select
+        PCS_CTL_speed0      = 1<<13, 
+        PCS_CTL_fullduplex  = 1<<8,  // fullduplex mode select
+        PCS_CTL_an_restart  = 1<<9,  // Autonegotiation restart command
+        PCS_CTL_isolate     = 1<<10, // isolate command
+        PCS_CTL_powerdown   = 1<<11, // powerdown command
+        PCS_CTL_an_enable   = 1<<12, // Autonegotiation enable
+        PCS_CTL_rx_slpbk    = 1<<14, // Serial Loopback enable
+        PCS_CTL_sw_reset    = 1<<15  // perform soft reset
+
+  };
+
+/** PCS Status Register Bits. IEEE 801.2 Clause 22.2.4.2
+ */
+enum {
+        PCS_ST_has_extcap   = 1<<0,  // PHY has extended capabilities registers 
+        PCS_ST_rx_sync      = 1<<2,  // RX is in sync (8B/10B codes o.k.)
+        PCS_ST_an_ability   = 1<<3,  // PHY supports autonegotiation
+        PCS_ST_rem_fault    = 1<<4,  // Autonegotiation completed
+        PCS_ST_an_done      = 1<<5
+
+  };
+
+/** Autonegotiation Capabilities Register Bits. IEEE 802.3 Clause 37.2.1 */
+
+enum {
+        ANCAP_NEXTPAGE      = 1 << 15,
+        ANCAP_ACK           = 1 << 14,
+        ANCAP_RF2           = 1 << 13,
+        ANCAP_RF1           = 1 << 12,
+        ANCAP_PS2           = 1 << 8,
+        ANCAP_PS1           = 1 << 7,
+        ANCAP_HD            = 1 << 6,
+        ANCAP_FD            = 1 << 5
+        // all others are reserved
+  }; 
+
+/*----------------------------------------------------------------------*/
+
+    #define MTIP1000_IO_EXTENT      (sizeof(np_mtip_mac))
+
+/*----------------------------------------------------------------------*/
+
+  #ifdef CONFIG_SYSCTL
+
+    /*
+     * Declarations for the sysctl interface, which allows users to
+     * control the finer aspects of the Emac. Since the 
+     * module registers its sysctl table dynamically, the sysctl path
+     * for module FOO is /proc/sys/dev/ethX/FOO
+     */
+    #define CTL_MTIP1000    (CTL_BUS+1389)
+      // arbitrary and hopefully unused
+
+    enum
+      {
+        CTL_MTIP_INFO = 1,  // Sysctl files information
+        CTL_MTIP_SWVER,     // Driver Software Version Info
+        //...fixme...
+      #ifdef MTIP_DEBUG
+        // Register access for debugging
+        //...fixme...
+      #endif
+        // ---------------------------------------------------
+        CTL_MTIP_LAST_ENTRY // Add new entries above the line
+      };
+
+  #endif // CONFIG_SYSCTL
+
+#endif  /* _MTIP1000_H_ */
diff --git a/drivers/net/open_eth.c b/drivers/net/open_eth.c
new file mode 100644
index 0000000..fe10b77
--- /dev/null
+++ b/drivers/net/open_eth.c
@@ -0,0 +1,2502 @@
+/*--------------------------------------------------------------------
+ * open_eth.c
+ *
+ * Ethernet driver for Open Ethernet Controller (www.opencores.org).
+ *
+ * Based on:
+ *
+ * Ethernet driver for Motorola MPC8xx.
+ *      Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+ *
+ * mcen302.c: A Linux network driver for Mototrola 68EN302 MCU
+ *
+ *      Copyright (C) 1999 Aplio S.A. Written by Vadim Lebedev
+ *
+ * Copyright (c) 2002 Simon Srot (simons@opencores.org)
+ * Copyright (C) 2004 Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * History:
+ *    Jun/20/2004   DGT Microtronix Datacom NiosII
+ *
+ ---------------------------------------------------------------------*/
+
+
+/*--------------------------------------------------------------------
+ * Rigt now XXBUFF_PREALLOC must be used, bacause MAC does not
+ * handle unaligned buffers yet.  Also the cache inhibit calls
+ * should be used some day.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/crc32.h>
+
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/bitops.h>
+#include <asm/page.h>
+
+#define OETH_REVISION_DATECODE 20050321
+
+#define MACADDR0 0x00
+#define MACADDR1 0x07
+#define MACADDR2 0xed
+#define MACADDR3 0x0a
+#define MACADDR4 0x03
+#define MACADDR5 0x29
+
+#define ANNOUNCEPHYINT
+//#undef  ANNOUNCEPHYINT
+#undef OETH_SW_CRC_CHECKING
+
+#ifdef CONFIG_EXCALIBUR
+    #include <asm/nios2.h>
+    #include <asm/cacheflush.h>
+    #define _print              printk
+    #define MACIRQ_NUM          na_igor_mac_irq
+    #define ETH_BASE_ADD        na_igor_mac
+    #ifdef na_mii_irq
+      #define PHYIRQ_NUM        na_mii_irq_irq
+      #define PHYIRQ_BASE_ADDR  na_mii_irq
+    #endif
+    /* #define TDK78Q2120PHY */
+    #if defined(TDK78Q2120PHY)
+      #define PHY_ADDRESS                           0x00
+    #else /* generic PHY, eg NS,Micrel */
+      #define PHY_ADDRESS                           0x01
+      #undef PHYIRQ_NUM       // No PHY irq with generic MII
+    #endif /* defined(TDK78Q2120PHY) */
+#endif  /* CONFIG_EXCALIBUR */
+
+#include "open_eth.h"
+
+#ifdef OETH_SYSFS_MDIO_ACCESS
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+
+/*
+ * This is a list of the PHY numbers to probe.
+ */
+static const int probe_mdio_phys[] = OETH_SYSFS_MDIO_ACCESS;
+#endif
+
+#define __clear_user(add,len) memset((add),0,(len))
+
+#define OETH_DEBUG 0
+//#define OETH_DEBUG 1
+
+#if OETH_DEBUG > 1
+    #define PRINTK2(args...) printk(args)
+#else
+    #define PRINTK2(args...)
+#endif  // OETH_DEBUG > 1
+
+#ifdef OETH_DEBUG
+    #define PRINTK(args...) printk(args)
+#else
+    #define PRINTK(args...)
+#endif  // OETH_DEBUG
+
+#undef SANCHKEPKT
+//#define SANCHKEPKT
+
+#define RXBUFF_PREALLOC 1
+#define TXBUFF_PREALLOC 1
+
+/* The transmitter timeout
+ */
+#define TX_TIMEOUT  (2*HZ)
+
+/* Buffer number (must be 2^n)
+ */
+//;dgt;;;#define OETH_RXBD_NUM      8
+#define OETH_RXBD_NUM       16
+//;dgt;;;#define OETH_TXBD_NUM      8
+#define OETH_TXBD_NUM       16
+
+#define OETH_RXBD_NUM_MASK  (OETH_RXBD_NUM-1)
+#define OETH_TXBD_NUM_MASK  (OETH_TXBD_NUM-1)
+
+/* Buffer size
+ */
+#define OETH_RX_BUFF_SIZE   2048
+#define OETH_TX_BUFF_SIZE   2048
+
+/* How many buffers per page
+ */
+#define OETH_RX_BUFF_PPGAE  (PAGE_SIZE/OETH_RX_BUFF_SIZE)
+#define OETH_TX_BUFF_PPGAE  (PAGE_SIZE/OETH_TX_BUFF_SIZE)
+
+/* How many pages is needed for buffers
+ */
+#define OETH_RX_BUFF_PAGE_NUM   (OETH_RXBD_NUM/OETH_RX_BUFF_PPGAE)
+#define OETH_TX_BUFF_PAGE_NUM   (OETH_TXBD_NUM/OETH_TX_BUFF_PPGAE)
+
+/* Buffer size  (if not XXBUF_PREALLOC
+ */
+#define MAX_FRAME_SIZE      1518
+
+#ifdef CONFIG_EXCALIBUR
+  #define TOTBYTSALLRXBUFS  (OETH_RXBD_NUM * OETH_RX_BUFF_SIZE)
+  #define TOTBYTSALLTXBUFS  (OETH_TXBD_NUM * OETH_TX_BUFF_SIZE)
+  #define TOTBYTSALLBUFS    (TOTBYTSALLRXBUFS + TOTBYTSALLTXBUFS)
+#if defined(na_sram_size) && (na_sram_size >= TOTBYTSALLBUFS)
+    #define SRAM_BUFF   1
+    #define SRAM_BUFF_BASE  (na_sram_base)
+  #else
+    #undef SRAM_BUFF
+    #undef SRAM_BUFF_BASE
+  #endif
+#else
+  //#define SRAM_BUFF   1
+  //#define SRAM_BUFF_BASE  (FBMEM_BASE_ADD + 0x80000)
+#endif
+
+/* The buffer descriptors track the ring buffers.
+ */
+struct oeth_private {
+    struct sk_buff  *rx_skbuff[OETH_RXBD_NUM];
+    struct sk_buff  *tx_skbuff[OETH_TXBD_NUM];
+
+    ushort           tx_next;   /* Next buffer to be sent */
+    ushort           tx_last;   /* Next buffer to be checked if packet sent */
+    ushort           tx_full;   /* Buffer ring fuul indicator */
+    ushort           rx_cur;    /* Next buffer to be checked if packet received */
+
+    volatile oeth_regs       *regs;      /* Address of controller registers. */
+    volatile oeth_bd         *rx_bd_base;/* Address of Rx BDs. */
+    volatile oeth_bd         *tx_bd_base;/* Address of Tx BDs. */
+
+    struct net_device_stats stats;
+    struct tasklet_struct	oeth_rx_tasklet;
+    struct tasklet_struct	oeth_tx_tasklet;
+
+    struct mii_if_info mii;
+    spinlock_t       lock;
+};
+
+void oeth_phymac_synch (struct net_device *dev, int callerflg);
+
+#ifdef SANCHKEPKT
+
+  #ifndef UCHAR
+    #define UCHAR                   unsigned char
+  #endif  // UCHAR
+
+  #ifndef USHORT
+    #define USHORT                  unsigned short
+  #endif  // USHORT
+
+  #ifndef ULONG
+    #define ULONG                   unsigned long
+  #endif  // ULONG
+
+  #ifndef IP_TYPE_HFMT
+    #define IP_TYPE_HFMT            0x0800
+  #endif  // IP_TYPE_HFMT
+
+  #ifndef ICMP_PROTOCOL
+    #define ICMP_PROTOCOL           1
+  #endif  // ICMP_PROTOCOL
+
+  #ifndef TCP_PROTOCOL
+    #define TCP_PROTOCOL            6
+  #endif  // TCP_PROTOCOL
+
+  #ifndef UDP_PROTOCOL
+    #define UDP_PROTOCOL            17
+  #endif  // UDP_PROTOCOL
+
+  #ifdef CONFIG_EXCALIBUR
+
+    #define read_b8(addr)   (*(volatile unsigned char *) (addr))
+
+    #define rd8(addr)       read_b8((volatile unsigned char *) (addr))
+
+    static USHORT read_w16(volatile USHORT *addr)
+      {
+        if((((ULONG) (addr)) & 0x00000001) == 0)
+          {
+            return *((volatile USHORT *) (addr));
+          }
+          else
+          {
+            return (rd8(                   addr)             |
+                   (rd8(((unsigned char *) addr) + 1) << 8));
+          }
+      }
+
+    #define rd16(addr)   read_w16((volatile USHORT *) (addr))
+
+//    static ULONG read_l32(volatile ULONG *addr)
+//      {
+//        if((((ULONG) (addr)) & 0x00000003) == 0)
+//          {
+//            return *((volatile ULONG *) (addr));
+//          }
+//          else
+//          {
+//            return (rd16(                     addr)                 |
+//                   (rd16(((((unsigned char *) addr) + 2))) << 16));
+//          }
+//      }
+//
+//    #define rd32(addr)   read_l32((volatile ULONG *) (addr))
+
+  #endif  // CONFIG_EXCALIBUR
+
+  USHORT onessum(const UCHAR      *buf,
+                 const USHORT      len,
+                 const USHORT      inisum)
+  {
+    USHORT      iLen16      = (len >> 1);
+    USHORT      iLen2_8;
+    USHORT      i;
+    ULONG       finalsum;
+    ULONG       sum         = inisum;
+    USHORT      din;
+
+    iLen2_8 = (iLen16 << 1);
+
+    for (i = 0; i < iLen2_8; i += 2)
+      {
+        din = htons(rd16(buf + i));
+        sum = sum + din;
+      }
+
+    if((len & 1) != 0)
+      {
+        sum = sum + ((buf [iLen2_8]) << 8);
+      }
+
+    finalsum = (sum & 0xffff) + ((sum >> 16) & 0xffff);
+
+    sum = (finalsum & 0xffff) + ((finalsum >> 16) & 0xffff);
+      // Addition of carries can in turn produce yet another
+      //  (at the most 1) carry (whose addition in turn can
+      //  produce no further carries).
+
+    sum &= 0xffff;
+
+    /* (Final) caller must complement our return value (and, if,        */
+    /*  applicable, complement once again if zero and Udp)              */
+
+    return (USHORT)sum;
+  }
+
+  USHORT psuchksum(const UCHAR    *tcpudpbuf,
+                   const USHORT    tcpudplen,
+                   const UCHAR    *ipbuf,
+                   const USHORT    uoset2chksm)
+  {
+    unsigned int            uiChksum;
+    unsigned int            uiTmp;
+
+
+    // Tcp/Udp pseudo header
+
+    uiChksum = onessum((ipbuf + 0x0C),4, 0);
+
+    uiChksum = onessum((ipbuf + 0x10),4, uiChksum);
+
+    uiTmp = ((ipbuf [0x09]) << 8);
+    uiChksum = onessum(((UCHAR *) (&(uiTmp))),2, uiChksum);
+
+    uiTmp    = htons(tcpudplen);
+    uiChksum = onessum(((UCHAR *) (&(uiTmp))),2, uiChksum);
+      // Txp/Udp message length, including real header
+
+    // Real header and payload
+
+    uiChksum = onessum(tcpudpbuf,
+                       uoset2chksm,
+                       uiChksum);
+
+    uiChksum = (onessum((tcpudpbuf + (uoset2chksm + 2)),
+                        (tcpudplen - (uoset2chksm + 2)),
+                        uiChksum)
+               ^ 0xffff);
+
+    if(uoset2chksm == 6)
+      {
+        /* UDP                                                          */
+
+        if(uiChksum == 0)
+          {
+            uiChksum = 0xFFFF;
+          }
+      }
+
+    return uiChksum;
+  }
+
+  USHORT icmpchksum(const UCHAR   *icmpbuf,
+                    const USHORT   icmplen)
+  {
+    unsigned int            uiChksum;
+
+
+    uiChksum = onessum(icmpbuf,
+                       0x02,
+                       0);
+
+    uiChksum = (onessum((icmpbuf + 0x04),
+                        (icmplen     -
+                         0x04),
+                        uiChksum)
+               ^ 0xffff);
+
+    return uiChksum;
+  }
+
+  USHORT ipchksum(const UCHAR     *iphdrbuf,
+                  const USHORT     iphdrlen)
+  {
+    unsigned int            uiChksum;
+
+
+    uiChksum = onessum(iphdrbuf,
+                       0x0A,
+                       0);
+
+    uiChksum = (onessum((iphdrbuf + 0x0C),
+                        (iphdrlen     -
+                         0x0C),
+                        uiChksum)
+               ^ 0xffff);
+
+    return uiChksum;
+  }
+
+  static void DoSanchkEpkt(const char            *ptrEpkt,
+                           const unsigned long    ulBytcntNOcrc,
+                           const char            *ptrBfnam)
+  {
+    int             iActChksum;
+    int             iExptdChksum;
+    int             iLenIphdrbyts;
+    int             iLenIpinclhdrbyts;
+
+    if(ulBytcntNOcrc >= 0x12)
+      {
+        if(rd16(&(ptrEpkt [0x0C])) == htons(IP_TYPE_HFMT))
+          {
+            unsigned short      ui16motoipflgsfrgo;
+
+            // Bluebook etyp 0x0008 (Moto(0x0800)) = IP
+
+            if(((ptrEpkt [0x0E]) & 0xF0) == 0x40)
+              {
+                // IP version 4
+
+                iLenIphdrbyts = ((ptrEpkt [0x0E]) & 0x0F) * 4;
+
+                iLenIpinclhdrbyts =
+                    ntohs(rd16(&(ptrEpkt [0x10])));
+
+                if((iLenIphdrbyts     >= 20)                      &&
+                   (iLenIpinclhdrbyts >= iLenIphdrbyts)           &&
+                   (ulBytcntNOcrc     >= (iLenIpinclhdrbyts + 0x0E)))
+                                            // Dix Machdr 14 bytes
+                  {
+                    iExptdChksum = ipchksum(&(ptrEpkt [0x0E]),
+                                            iLenIphdrbyts);
+
+                    iActChksum = ntohs(rd16(&(ptrEpkt [0x18])));
+
+                    if(iActChksum != iExptdChksum)
+                      {
+                        if((iExptdChksum != 0x0000)   &&
+                           (iExptdChksum != 0xFFFF)   &&
+                           (iActChksum   != 0x0000)   &&
+                           (iActChksum   != 0xFFFF))
+                          {
+                            printk("\n...IP %s{0x%08X} xptd"
+                                       " csum: 0x%04X"
+                                       ", 0x%04X seen (%ld ebyts)\n",
+                                   ptrBfnam,
+                                   ((unsigned long) ptrEpkt),
+                                   iExptdChksum,
+                                   iActChksum,
+                                   ulBytcntNOcrc);
+
+                            return;
+                          }
+                      }
+                  }
+                  else
+                  {
+                    printk("\n...Malformed IP %s{0x%08X}"
+                               " header (%ld ebyts)\n",
+                           ptrBfnam,
+                           ((unsigned long) ptrEpkt),
+                           ulBytcntNOcrc);
+
+                    return;
+                  }
+
+                ui16motoipflgsfrgo = rd16(&(ptrEpkt [0x14]));
+
+                if((ntohs(ui16motoipflgsfrgo) & 0x2000) == 0)
+                  {
+                    /* Final or only IP fragment                        */
+
+                    if(((ntohs(ui16motoipflgsfrgo) & 0x1FFF)) == 0)
+                      {
+                        // One and only IP fragment
+
+                        if(ptrEpkt [0x17] == ICMP_PROTOCOL)
+                          {
+                            // IP payload 0x01 = ICMP
+
+                            if((iLenIpinclhdrbyts - iLenIphdrbyts) >= 4)
+                              {
+                                iExptdChksum =
+                                    icmpchksum(&(ptrEpkt
+                                                   [0x0E          +
+                                                    iLenIphdrbyts]),
+                                               (iLenIpinclhdrbyts  -
+                                                iLenIphdrbyts));
+
+                                iActChksum =
+                                    ntohs(rd16(&(ptrEpkt
+                                                   [0x0E          +
+                                                    iLenIphdrbyts +
+                                                    2])));
+
+                                if(iActChksum != iExptdChksum)
+                                  {
+                                    if((iExptdChksum != 0x0000)   &&
+                                       (iExptdChksum != 0xFFFF)   &&
+                                       (iActChksum   != 0x0000)   &&
+                                       (iActChksum   != 0xFFFF))
+                                      {
+                                        printk("\n...ICMP %s{0x%08X}"
+                                                 " xptd csum:"
+                                                 " 0x%04X, 0x%04X"
+                                                 " seen (%ld ebyts)\n",
+                                               ptrBfnam,
+                                               ((unsigned long) ptrEpkt),
+                                               iExptdChksum,
+                                               iActChksum,
+                                               ulBytcntNOcrc);
+
+                                        return;
+                                      }
+                                  }
+                              }
+                              else
+                              {
+                                printk("\n...Malformed ICMP"
+                                         " %s{0x%08X}"
+                                         " pkt (%ld ebyts)\n",
+                                       ptrBfnam,
+                                       ((unsigned long) ptrEpkt),
+                                       ulBytcntNOcrc);
+
+                                return;
+                              }
+
+                            return;
+                          }
+
+                        if(ptrEpkt [0x17] == TCP_PROTOCOL)
+                          {
+                            // IP payload 0x06 = TCP
+
+                            if((iLenIpinclhdrbyts - iLenIphdrbyts) >= 20)
+                              {
+                                iActChksum =
+                                    ntohs(rd16(&(ptrEpkt [0x0E        +
+                                                         iLenIphdrbyts +
+                                                         16])));
+
+                                iExptdChksum =
+                                    psuchksum(&(ptrEpkt
+                                                  [0x0E           +
+                                                   iLenIphdrbyts]),
+                                              (iLenIpinclhdrbyts  -
+                                               iLenIphdrbyts),
+                                              &(ptrEpkt [0x0E]),
+                                              16);
+
+                                if(iActChksum != iExptdChksum)
+                                  {
+                                   printk("\n...TCP %s{0x%08X}"
+                                            " xptd csum:"
+                                            " 0x%04X, 0x%04X"
+                                            " seen (%ld ebyts)\n",
+                                          ptrBfnam,
+                                          ((unsigned long) ptrEpkt),
+                                          iExptdChksum,
+                                          iActChksum,
+                                          ulBytcntNOcrc);
+
+                                    return;
+                                  }
+                              }
+                              else
+                              {
+                                printk("\n...Malformed TCP"
+                                         " %s{0x%08X}"
+                                         " pkt (%ld ebyts)\n",
+                                       ptrBfnam,
+                                       ((unsigned long) ptrEpkt),
+                                       ulBytcntNOcrc);
+
+                                return;
+                              }
+                          }
+
+                        if(ptrEpkt [0x17] == UDP_PROTOCOL)
+                          {
+                            // IP payload 0x11 = UDP
+
+                            if((iLenIpinclhdrbyts - iLenIphdrbyts) >= 8)
+                              {
+                                iActChksum =
+                                    ntohs(rd16(&(ptrEpkt [0x0E        +
+                                                         iLenIphdrbyts +
+                                                         6])));
+
+                                if(iActChksum != 0x0000)
+                                  {
+                                    iExptdChksum =
+                                        psuchksum(&(ptrEpkt
+                                                      [0x0E           +
+                                                       iLenIphdrbyts]),
+                                                  (iLenIpinclhdrbyts  -
+                                                   iLenIphdrbyts),
+                                                  &(ptrEpkt [0x0E]),
+                                                  6);
+
+                                    if(iActChksum != iExptdChksum)
+                                      {
+                                       printk("\n...UDP %s{0x%08X}"
+                                                " xptd csum:"
+                                                " 0x%04X, 0x%04X"
+                                                " seen (%ld ebyts)\n",
+                                              ptrBfnam,
+                                              ((unsigned long) ptrEpkt),
+                                              iExptdChksum,
+                                              iActChksum,
+                                              ulBytcntNOcrc);
+
+                                        return;
+                                      }
+                                  }
+                              }
+                              else
+                              {
+                                printk("\n...Malformed UDP"
+                                         " %s{0x%08X}"
+                                         " pkt (%ld ebyts)\n",
+                                       ptrBfnam,
+                                       ((unsigned long) ptrEpkt),
+                                       ulBytcntNOcrc);
+
+                                return;
+                              }
+                          }
+                      }
+                      else
+                      {
+                        // Final of many IP fragments
+                      }
+
+                    return;
+                  }
+                  else
+                  {
+                    // One of many IP fragments
+
+                    return;
+                  }
+              }
+
+            return;
+          }
+      }
+
+    return;
+  }
+#endif // SANCHKEPKT
+
+#if OETH_DEBUG
+static void
+oeth_print_packet(unsigned long add, int len)
+{
+    int i;
+
+    _print("ipacket: add = %x len = %d\n", add, len);
+    for(i = 0; i < len; i++) {
+        if(!(i % 16))
+                _print("\n");
+        _print(" %.2x", *(((unsigned char *)add) + i));
+    }
+    _print("\n");
+}
+#endif
+
+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct oeth_private *np = netdev_priv(dev);
+	int rc;
+	if (!netif_running(dev))
+		return -EINVAL;
+
+	spin_lock_irq(&np->lock);
+	rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
+	if (cmd == SIOCSMIIREG)
+	    oeth_phymac_synch(dev, 0);/* synchronize MAC if MII updated */
+	spin_unlock_irq(&np->lock);
+
+	return rc;
+}
+
+// Read a phy register
+int eth_mdread(struct net_device *dev,
+               int                fiad_phy_addr,
+               int                phyreg)
+  {
+    int                  rdata;
+    volatile oeth_regs  *regs = (oeth_regs *)dev->base_addr;
+
+    // ensure busy not set
+    do
+      {
+        rdata = regs->miistatus;
+
+      } while (rdata & OETH_MIISTATUS_BUSY);
+
+    regs->miiaddress = ((unsigned long) (((phyreg << 8) |
+                                          fiad_phy_addr)));
+    regs->miicommand = ((unsigned long) (OETH_MIICOMMAND_RSTAT));
+
+    // wait while busy set
+    do
+      {
+        rdata = regs->miistatus;
+
+      } while (rdata & OETH_MIISTATUS_BUSY);
+
+    rdata = regs->miirx_data;
+
+    return rdata;
+  }
+
+// Write a phy register
+void eth_mdwrite(struct net_device *dev,
+                 int                fiad_phy_addr,
+                 int                phyreg,
+                 int                wdata)
+  {
+    int                  rdata;
+    volatile oeth_regs  *regs = (oeth_regs *)dev->base_addr;
+
+    // ensure busy not set
+    do
+      {
+        rdata = regs->miistatus;
+
+      } while (rdata & OETH_MIISTATUS_BUSY);
+
+    regs->miiaddress = ((unsigned long) (((phyreg << 8) |
+                                         fiad_phy_addr)));
+    regs->miitx_data = ((unsigned long) (wdata));
+    regs->miicommand = ((unsigned long) (OETH_MIICOMMAND_WCTRLDATA));
+
+    // wait while busy set
+    do
+      {
+        rdata = regs->miistatus;
+
+      } while (rdata & OETH_MIISTATUS_BUSY);
+
+    return;
+  }
+
+void oeth_phymac_synch (struct net_device *dev, int callerflg)
+  {
+    volatile oeth_regs  *regs = (oeth_regs *)dev->base_addr;
+    unsigned long        ulmoderval;
+    unsigned long        ulmr1sts;
+#if defined(TDK78Q2120PHY)
+    unsigned long        ulphydiagval;
+#else
+    struct oeth_private  *cep = (struct oeth_private *)netdev_priv(dev);
+    struct ethtool_cmd   ecmd;
+#endif
+
+    ulmr1sts = eth_mdread(dev, PHY_ADDRESS, MII_BMSR);
+    /* Read twice to get CURRENT status                                 */
+    ulmr1sts = eth_mdread(dev, PHY_ADDRESS, MII_BMSR);
+
+    ulmoderval = regs->moder;
+
+#if defined(TDK78Q2120PHY)
+    ulphydiagval = eth_mdread(dev, PHY_ADDRESS, 18);
+#endif
+
+    if(callerflg == 0)
+      {
+        // Caller = NOT Phy interrupt handler
+
+	if((ulmr1sts & BMSR_LSTATUS) != 0)
+          {
+            // Link is ostensibly OK
+
+            if((eth_mdread(dev, PHY_ADDRESS, MII_BMCR) & BMCR_ANENABLE) != 0)
+              {
+                // Auto negotiation ostensibly enabled
+
+                if((ulmr1sts & 0x00000020) != 0)
+                  {
+                    // Auto negotiation ostensibly has completed
+
+#if defined(TDK78Q2120PHY)
+                      if((ulphydiagval & 0x1000) != 0)
+                        {
+                          // Auto negotiation ostensibly has failed
+
+                          if((ulphydiagval & (0x0800 | 0x0400 )) != 0)
+                            {
+                              // Auto negotiation failure expected to
+                              //  have fallen back to 10 mbit half
+                              //  duplex - perhaps phy registers aren't
+                              //  actually available, and we've been
+                              //  reading 0xFFFF's ?
+
+                              // A 10 mbit, 1/2 duplex remote partner
+                              //  mandates a 1/2 duplex Emac (else any
+                              //  amount of traffic at all will almost
+                              //  certainly collide up a storm...)
+                              // 100 mbit remote partners seem to allow
+                              //  duplex mismatches without severe
+                              //  loss, at least at the low end of
+                              //  their nominal capacity.
+                              // A 10 mbit, full duplex remote partner
+                              //  probably also requires a matched Emac,
+                              //  but hasn't been confirmed...
+
+                              printk("\noeth_phymac_synch:%s"
+                                       " No phyregs?-assuming HalfD\n",
+                                     dev->name);
+
+                              regs->moder =
+                                  ((unsigned long)
+                                        (ulmoderval &
+                                         (~(OETH_MODER_FULLD))));
+                              // FIXME:...
+                              // ...Note manual says not supposed
+                              // ... to "change registers after ModeR's
+                              // ... TxEn or RxEn bit(s) have been set"
+                              regs->ipgt = ((unsigned long) (0x00000012));
+
+                              return;
+                            }
+                        }
+#endif /* defined(TDK78Q2120PHY) */
+                  }
+              }
+          }
+      }
+//    else
+//    {
+//      // Caller = Phy interrupt handler
+//      // If we've got a phy interrupt, then we're so likely
+//      //  to also have actual phy registers that we won't
+//      //  bother trying to confirm.
+//    }
+
+    #if defined(ANNOUNCEPHYINT)
+      printk("\noeth_phymac_synch:%s  MR1: 0x%08lX\n",
+             dev->name,
+             ulmr1sts);
+      if((ulmr1sts & BMSR_JCD) != 0)
+        {
+          printk("                               Jabber\n");
+        }
+      if((ulmr1sts & BMSR_RFAULT) != 0)
+        {
+          printk("                               Remote Fault\n");
+        }
+      if((ulmr1sts & BMSR_ANEGCOMPLETE) != 0)
+        {
+          printk("                               Autoneg'd\n");
+        }
+    #endif
+
+    if((ulmr1sts & BMSR_LSTATUS) != 0)
+      {
+        /* Phy MR1 (status register) indicates link is (now) OK.        */
+
+        /* (dgt:07FEB2003) miistatus:                                   */
+        /*  ...will NOT show current OETH_MIISTATUS_LINKFAIL            */
+        /*  ... status, no matter how many times it's read...           */
+        /*  ...one must first read phy status register (MR1),           */
+        /*  ... then read miistatus...                                  */
+        /* ... so, we just use phy status directly.                     */
+
+        #if defined(ANNOUNCEPHYINT)
+          printk("             Link OK: MODER: 0x%08lX\n",
+                 ulmoderval);
+        #endif
+
+        /* Recommended ipgt register (0x000c) value:
+         * Back to Back Inter Packet Gap
+         *  Full Duplex: 0x15: 0.96 uSecs IPG for 100 mbps
+         *                     9.60 uSecs IPG for 10  mbps
+         *      Desired period in nibble times minus 6
+         *       96 bits = 24 nibbles - 6 = 18 = 0x12 (but
+         *          reference guide says 0x15 (what's backwards,
+         *          6, or 0x15 ?))
+         *  Half Duplex: 0x12: 0.96 uSecs IPG for 100 mbps
+         *                     9.60 uSecs IPG for 10  mbps
+         *  Desired period in nibble times minus 3
+         *       96 bits = 24 nibbles - 3 = 21 = 0x15 (but
+         *          reference guide says 0x12 (what's backwards,
+         *          3, or 0x12 ?))
+         */
+
+#if defined(TDK78Q2120PHY)
+
+          if((ulphydiagval & 0x0800) != 0)
+            {
+              /* Phy MR18 (diagnostics register) indicates              */
+              /*  link is (now) running full duplex.                    */
+
+              if((ulmoderval & (OETH_MODER_FULLD)) == 0)
+                {
+                  regs->moder = ((unsigned long) (ulmoderval |
+                                                  (OETH_MODER_FULLD)));
+                }
+              // FIXME:...
+              // ...Note manual says not supposed to "change
+              // ... registers after ModeR's TxEn or RxEn
+              // ...  bit(s) have been set"
+              if(regs->ipgt != ((unsigned long) (0x00000015)))
+                {
+                  regs->ipgt = ((unsigned long) (0x00000015));
+                }
+
+              #if defined(ANNOUNCEPHYINT)
+                printk("             FullD:    MR18: 0x%08lX\n",
+                       ulphydiagval);
+              #endif
+            }
+            else
+            {
+              /* Phy MR18 (diagnostics register) indicates              */
+              /*  link is (now) running half duplex.                    */
+
+              if((ulmoderval & (OETH_MODER_FULLD)) != 0)
+                {
+                  regs->moder = ((unsigned long) (ulmoderval &
+                                                  (~(OETH_MODER_FULLD))));
+                }
+              // FIXME:...
+              // ...Note manual says not supposed to "change
+              // ... registers after ModeR's TxEn or RxEn
+              // ...  bit(s) have been set"
+              if(regs->ipgt != ((unsigned long) (0x00000012)))
+                {
+                  regs->ipgt = ((unsigned long) (0x00000012));
+                }
+
+              #if defined(ANNOUNCEPHYINT)
+                printk("             HalfD:    MR18: 0x%08lX\n",
+                       ulphydiagval);
+              #endif
+            }
+
+          #if defined(ANNOUNCEPHYINT)
+            printk("             %s\n",
+                   (ulphydiagval & 0x0400) ? "100BASE-TX" : "10BASE-T");
+          #endif
+
+#else /* generic PHY, use generic MII functions */
+	    mii_ethtool_gset(&cep->mii, &ecmd);
+
+	    if (ecmd.duplex)
+            {
+	      if (!(ulmoderval & OETH_MODER_FULLD))
+                {
+                  regs->moder = ulmoderval | OETH_MODER_FULLD;
+                }
+              if(regs->ipgt != ((unsigned long) (0x00000015)))
+                {
+                  regs->ipgt = ((unsigned long) (0x00000015));
+                }
+
+# if defined(ANNOUNCEPHYINT)
+                printk("             FullD\n");
+# endif
+            }
+            else	/* half duplex */
+            {
+              if (ulmoderval & OETH_MODER_FULLD)
+                {
+                  regs->moder = ulmoderval & ~OETH_MODER_FULLD;
+                }
+              // FIXME:...
+              // ...Note manual says not supposed to "change
+              // ... registers after ModeR's TxEn or RxEn
+              // ...  bit(s) have been set"
+              if(regs->ipgt != ((unsigned long) (0x00000012)))
+                {
+                  regs->ipgt = ((unsigned long) (0x00000012));
+                }
+
+# if defined(ANNOUNCEPHYINT)
+                printk("             HalfD\n");
+# endif
+            }
+
+# if defined(ANNOUNCEPHYINT)
+            printk("             %s\n", (ecmd.speed == 100) ? "100BASE-TX" : "10BASE-T");
+# endif
+
+#endif /* generic PHY */
+      }
+    #if defined(ANNOUNCEPHYINT)
+      else
+      {
+        printk("                               Link Down\n");
+      }
+    #endif
+
+    #if defined(ANNOUNCEPHYINT)
+      printk("\n");
+    #endif
+
+    return;
+  }
+
+#if defined(PHYIRQ_NUM)
+/*-----------------------------------------------------------
+ | Driver entry point
+ |
+ | Entry condition: Cpu interrupts DISabled.
+ */
+static irqreturn_t oeth_PhyInterrupt(int             irq,
+                                     void           *dev_id)
+{
+      struct   net_device           *dev        = dev_id;
+
+#if defined(TDK78Q2120PHY)
+      volatile struct oeth_private  *cep =
+	(struct oeth_private *)netdev_priv(dev);
+      unsigned long                  ulmr17sts;
+
+
+      ulmr17sts = eth_mdread(((struct net_device *) dev_id),
+                             PHY_ADDRESS, 17);
+        // Read Clears (no ack req'd)
+
+      if((ulmr17sts & 0x00000040) != 0)
+        {
+          cep->stats.rx_frame_errors++;
+        }
+
+# if defined(ANNOUNCEPHYINT)
+        printk("\noeth_PhyInterrupt:%s  MR17: 0x%08lX\n",
+               dev->name,
+               ulmr17sts);
+        if((ulmr17sts & 0x00000080) != 0)
+          {
+            printk("                               Jabber\n");
+          }
+        if((ulmr17sts & 0x00000040) != 0)
+          {
+            printk("                               Rxer\n");
+          }
+        if((ulmr17sts & 0x00000020) != 0)
+          {
+            printk("                               Pagerec\n");
+          }
+        if((ulmr17sts & 0x00000010) != 0)
+          {
+            printk("                               Pfd\n");
+          }
+        if((ulmr17sts & 0x00000008) != 0)
+          {
+            printk("                               Lpack\n");
+          }
+        if((ulmr17sts & 0x00000004) != 0)
+          {
+            printk("                               Lschg\n");
+          }
+        if((ulmr17sts & 0x00000002) != 0)
+          {
+            printk("                               Rfault\n");
+          }
+        if((ulmr17sts & 0x00000001) != 0)
+          {
+            printk("                               Anegcomp\n");
+          }
+# endif
+
+      oeth_phymac_synch((struct net_device *) dev_id,
+                        1);  // Caller = Phy interrupt handler
+#endif  /* defined(TDK78Q2120PHY) */
+
+    return IRQ_HANDLED;
+  }
+#endif  // PHYIRQ_NUM
+
+
+/*
+    Entered at interrupt level
+*/
+static void
+oeth_tx(unsigned long devn)
+{
+    struct net_device *dev = (void *)devn;
+    volatile struct oeth_private *cep;
+    volatile oeth_bd *bdp;
+
+#ifndef TXBUFF_PREALLOC
+    struct  sk_buff *skb;
+#endif
+
+    cep = (struct oeth_private *)netdev_priv(dev);
+
+    // Cycles over the TX BDs, starting at the first one that would've been sent. -TS
+    while (1)
+      {
+        bdp = cep->tx_bd_base + cep->tx_last;
+
+	// Stops once it runs into the first one that's ready for transmit (and thus hasn't been sent yet), or once it has checked all BDs (which would occur if all have been transmitted). -TS 
+        if ((bdp->len_status & OETH_TX_BD_READY) ||
+            ((cep->tx_last == cep->tx_next) && !cep->tx_full))
+            break;
+
+        /* Check status for errors
+         */
+	if (bdp->len_status & 0x1ff) printk("oeth: tx%02d,%08x\n",cep->tx_last,bdp->len_status);
+
+        if (bdp->len_status & OETH_TX_BD_LATECOL)
+            cep->stats.tx_window_errors++;
+            //;dgt - ifconfig doesn't report tx_window_errors ?
+                //;dgt - but we (also) include same in tx_errors.
+
+        if (bdp->len_status & OETH_TX_BD_RETLIM)
+            cep->stats.tx_aborted_errors++;
+            //;dgt - ifconfig doesn't report tx_aborted_errors ?
+                //;dgt - but we (also) include same in tx_errors.
+
+        if (bdp->len_status & OETH_TX_BD_UNDERRUN)
+            cep->stats.tx_fifo_errors++;
+
+        if (bdp->len_status & OETH_TX_BD_CARRIER)
+            cep->stats.tx_carrier_errors++;
+
+        //;dgt - OETH_TX_BD_DEFER neither counted nor ifconfig reported
+
+        if (bdp->len_status & (OETH_TX_BD_LATECOL   |
+                               OETH_TX_BD_RETLIM    |
+                               OETH_TX_BD_UNDERRUN))
+            cep->stats.tx_errors++;
+
+        cep->stats.tx_packets++;
+        cep->stats.tx_bytes += bdp->len_status >> 16;
+        cep->stats.collisions += (bdp->len_status >> 4) & 0x000f;
+
+#ifndef TXBUFF_PREALLOC
+        skb = cep->tx_skbuff[cep->tx_last];
+
+        /* Free the sk buffer associated with this last transmit.
+        */
+        dev_kfree_skb(skb);
+#endif
+
+       if (cep->tx_full)
+            cep->tx_full = 0;
+	cep->tx_last = (cep->tx_last + 1) & OETH_TXBD_NUM_MASK;
+
+      }
+
+        if(((cep->tx_next + 1) & OETH_TXBD_NUM_MASK) != cep->tx_last)
+          {
+            netif_wake_queue(dev);
+          }
+//        else
+//        {
+//          Tx done interrupt but no tx BD's released ?
+//        }
+}
+
+/*
+    Entered at interrupt level
+*/
+static void
+oeth_rx(unsigned long devn)
+{
+    struct net_device *dev = (void *)devn;
+    volatile struct oeth_private *cep;
+    volatile        oeth_bd      *bdp;
+    struct          sk_buff      *skb;
+    int                           pkt_len;
+    int                           bad;                          //;dgt
+    int                           netif_rx_rtnsts;              //;dgt
+  #ifndef RXBUFF_PREALLOC
+    struct          sk_buff      *small_skb;
+  #endif
+
+    cep = (struct oeth_private *)netdev_priv(dev);
+
+    /* First, grab all of the stats for the incoming packet.
+     * These get messed up if we get called due to a busy condition.
+     */
+    for (;;cep->rx_cur = (cep->rx_cur + 1) & OETH_RXBD_NUM_MASK)
+      {
+        bad = 0;                                                //;dgt
+        bdp = cep->rx_bd_base + cep->rx_cur;
+
+  #ifndef RXBUFF_PREALLOC
+        skb = cep->rx_skbuff[cep->rx_cur];
+
+        if (skb == NULL)
+          {
+            skb = dev_alloc_skb(MAX_FRAME_SIZE);
+
+            if (skb != NULL)
+            {
+                bdp->addr = (unsigned long) skb->tail;
+
+                flush_dcache_range (((unsigned long) (bdp->addr)),
+                             ((unsigned long) (bdp->addr)) + MAX_FRAME_SIZE);
+
+                bdp->len_status |= OETH_RX_BD_EMPTY;
+            }
+
+            continue;
+          }
+  #endif
+
+        if (bdp->len_status & OETH_RX_BD_EMPTY)
+            break;
+
+        pkt_len = bdp->len_status >> 16;
+
+#ifdef OETH_SW_CRC_CHECKING
+	int force_crc_err = 0;
+#endif
+
+        /* Check status for errors.
+         */
+	//if (bdp->len_status & 0x1ff) printk("oeth: rx%02d,%08x\n",cep->rx_cur,bdp->len_status);
+
+        if (bdp->len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) {
+            cep->stats.rx_length_errors++;
+            //;dgt - ifconfig doesn't report rx_length_errors ?
+            //;dgt - but we (also) include same in rx_errors.
+            bad = 1;
+        }
+        if (bdp->len_status & OETH_RX_BD_DRIBBLE) {
+            cep->stats.rx_frame_errors++;
+            bad = 1;
+        }
+        if (bdp->len_status & OETH_RX_BD_CRCERR) {
+            cep->stats.rx_crc_errors++;
+            //;dgt - ifconfig doesn't report rx_crc_errors ?
+            //;dgt - but we (also) include same in rx_errors.
+            bad = 1;
+#ifdef OETH_SW_CRC_CHECKING
+        } else {
+            // There is a bug in the OpenCores MAC that very occasionally
+            // corrupts packets by shifting 12 bytes of 4-byte aligned
+            // data (maybe even more aligned?) by 4 bytes, and this happens
+            // after it checks the CRC so we never get told that it's bad
+            // and thus would end up passing the corruption to a
+            // higher-level protocol. As a workaround, we now check the CRC
+            // here too.
+            u32 actual = crc32_le(~0, bdp->addr, pkt_len);
+            if (actual != 0xDEBB20E3) {
+                printk("Pkt corrupted by MAC: %X\n", actual);
+                force_crc_err = 1;
+                cep->stats.rx_crc_errors++;
+                bad = 1;
+            }
+#endif
+        }
+        if (bdp->len_status & OETH_RX_BD_OVERRUN) {
+            cep->stats.rx_crc_errors++;
+            //;dgt - ifconfig doesn't report rx_crc_errors ?
+            //;dgt - but we (also) include same in rx_errors.
+            bad = 1;
+        }
+        if (bdp->len_status & OETH_RX_BD_MISS)
+          {
+            //;dgt - identifies a packet received in promiscuous
+            //;dgt    mode (would not have otherwise been accepted)
+          }
+        if (bdp->len_status & OETH_RX_BD_LATECOL) {
+            cep->stats.rx_frame_errors++;
+            bad = 1;
+        }
+        if (bdp->len_status & OETH_RX_BD_INVSIMB) {             //;dgt
+            cep->stats.rx_frame_errors++;                       //;dgt
+            bad = 1;                                            //;dgt
+        }                                                       //;dgt
+        if (bdp->len_status & (OETH_RX_BD_TOOLONG   |           //;dgt
+                               OETH_RX_BD_SHORT     |           //;dgt
+                               OETH_RX_BD_CRCERR    |           //;dgt
+                               OETH_RX_BD_OVERRUN)              //;dgt
+#ifdef OETH_SW_CRC_CHECKING
+            || force_crc_err
+#endif
+            )
+            cep->stats.rx_errors++;                             //;dgt
+
+        if (bad)
+          {
+            bdp->len_status &= ~OETH_RX_BD_STATS;
+
+            flush_dcache_range (((unsigned long) (bdp->addr)),
+                         ((unsigned long) (bdp->addr)) + OETH_RX_BUFF_SIZE);
+
+            bdp->len_status |= OETH_RX_BD_EMPTY;
+
+            continue;
+          }
+
+        /* Process the incoming frame.
+         */
+
+	/* Strip the CRC. It is not supposed to be passed by Linux Ethernet
+	   drivers. (Many things will work regardless, but not all; e.g.,
+	   802.1d bridging.) */
+	pkt_len -= 4;
+
+#ifdef RXBUFF_PREALLOC
+    #ifdef CONFIG_EXCALIBUR
+//;dgt  skb = dev_alloc_skb(pkt_len);
+        skb = dev_alloc_skb(pkt_len + 2 + 3 + 4);   //;dgt
+          //;dgt Over allocate 2 extra bytes to
+          //;dgt  32 bit align Nios 32 bit
+          //;dgt  IP/TCP fields.
+          //;dgt Over allocate 3 extra bytes to
+          //;dgt  allow packet to be treated as
+          //;dgt  as an even number of bytes or
+          //;dgt  16 bit words if so desired.
+          //;dgt Plus another extra 4 paranoia bytes.
+    #else
+        skb = dev_alloc_skb(pkt_len);
+    #endif
+
+        if (skb == NULL)
+          {
+            printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+            cep->stats.rx_dropped++;
+          }
+        else
+          {
+            skb->dev = dev;
+#if OETH_DEBUG
+            _print("RX\n");
+            oeth_print_packet(bdp->addr, pkt_len);
+#endif
+        #ifdef CONFIG_EXCALIBUR
+          {
+            unsigned short     *dst;
+            unsigned short     *src;
+
+            #ifdef SANCHKEPKT
+              unsigned short   *savddst;
+            #endif // SANCHKEPKT
+
+            skb_reserve( skb, 2 );
+              //;dgt 32 bit align Nios 32 bit IP/TCP fields
+
+            dst = ((unsigned short *) (skb_put(skb, pkt_len)));
+            src = ((unsigned short *) (__va(bdp->addr)));
+
+            #ifdef SANCHKEPKT
+              savddst = dst;
+              DoSanchkEpkt(((const char *) src),
+                           pkt_len,
+                           "DmaRx");
+            #endif // SANCHKEPKT
+
+            //;dgt...FIXME...simple 16 bit copy loop
+            //;dgt... = approx 20% overall throughput
+            //;dgt... improvement over memcpy...
+            //;dgt...A more advanced copy from 32 bit
+            //;dgt... aligned source to 16 bit aligned
+            //;dgt... destination still needed though...
+            //;dgt...Note destination bears enough extra
+            //;dgt... room to hold ((pkt_len + 3) >> 2)
+            //;dgt... longwords...
+            //;dgt;Mar2005;Custom NiosII instruction now
+            //;dgt; available or imminent for a "really"
+            //;dgt; optimized memcpy, even under mismatched
+            //;dgt; src/dst alignments
+            #if 0
+              {
+                unsigned int        uiloop;
+                for(uiloop = 0;
+                    (uiloop < ((pkt_len + 1) >> 1));
+                    uiloop++)
+                  {
+                    *dst++ = *src++;
+                  }
+              }
+            #else
+              memcpy(dst, src, pkt_len);
+            #endif
+
+            #ifdef SANCHKEPKT
+              DoSanchkEpkt(((const char *) savddst),
+                           pkt_len,
+                           "SkbRx");
+            #endif // SANCHKEPKT
+          }
+        #else
+            memcpy(skb_put(skb, pkt_len),
+                   (unsigned char *)__va(bdp->addr),
+                   pkt_len);
+        #endif
+
+            skb->protocol = eth_type_trans(skb,dev);
+
+            netif_rx_rtnsts = netif_rx(skb);                    //;dgt
+
+              switch (netif_rx_rtnsts)                          //;dgt
+                {                                               //;dgt
+                  case NET_RX_DROP:                     // 0x01 //;dgt
+                    cep->stats.rx_dropped++;                    //;dgt
+                    // memo: netif_rx has: kfree_skb(skb);      //;dgt
+                    #if 0                                       //;dgt
+                      printk("%s: netif_rx dropped"             //;dgt
+                               " %d byte packet.\n",            //;dgt
+                             dev->name,                         //;dgt
+                             pkt_len);                          //;dgt
+                    #endif                                      //;dgt
+                    break;                                      //;dgt
+                  #if 0                                         //;dgt
+                    case NET_RX_SUCCESS:                // 0x00 //;dgt
+                      break;                                    //;dgt
+                    default:                                    //;dgt
+//                  case NET_RX_CN_LOW:                 // 0x02 //;dgt
+//                  case NET_RX_CN_MOD:                 // 0x03 //;dgt
+//                  case NET_RX_CN_HIGH:                // 0x04 //;dgt
+//                  case NET_RX_BAD:                    // 0x05 //;dgt
+                      printk("%s: netif_rx rtnsts: %08lX\n",    //;dgt
+                             dev->name,                         //;dgt
+                             netif_rx_rtnsts);                  //;dgt
+                      break;                                    //;dgt
+                  #endif                                        //;dgt
+                }                                               //;dgt
+
+            cep->stats.rx_packets++; // This is the only thing that increments the packet stat if RXBUFF_PREALLOC is defined.
+	    cep->stats.rx_bytes += pkt_len;
+          }
+
+        flush_dcache_range (((unsigned long) (bdp->addr)),
+                     ((unsigned long) (bdp->addr)) + pkt_len);
+
+        bdp->len_status &= ~OETH_RX_BD_STATS;
+        bdp->len_status |= OETH_RX_BD_EMPTY;
+#else
+        if (pkt_len < 128)
+          {
+            small_skb = dev_alloc_skb(pkt_len);
+
+            if (small_skb)
+              {
+                small_skb->dev = dev;
+  #if OETH_DEBUG
+                _print("RX short\n");
+                oeth_print_packet(bdp->addr, bdp->len_status >> 16);
+  #endif
+                memcpy(skb_put(small_skb, pkt_len),
+                       (unsigned char *)__va(bdp->addr),
+                       pkt_len);
+                small_skb->protocol = eth_type_trans(small_skb,dev);
+                netif_rx(small_skb);
+                cep->stats.rx_packets++;
+		cep->stats.rx_bytes += pkt_len;
+              }
+            else
+              {
+                printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+                cep->stats.rx_dropped++;
+              }
+
+            flush_dcache_range (((unsigned long) (bdp->addr)),
+                         ((unsigned long) (bdp->addr)) + pkt_len);
+
+            bdp->len_status &= ~OETH_RX_BD_STATS;
+            bdp->len_status |=  OETH_RX_BD_EMPTY;
+          }
+        else
+          {
+            skb->dev = dev;
+            skb_put(skb, pkt_len);
+            skb->protocol = eth_type_trans(skb,dev);
+            netif_rx(skb);
+            cep->stats.rx_packets++;
+	    cep->stats.rx_bytes += pkt_len;
+  #if OETH_DEBUG
+            _print("RX long\n");
+            oeth_print_packet(bdp->addr, bdp->len_status >> 16);
+  #endif
+            skb = dev_alloc_skb(MAX_FRAME_SIZE);
+
+            bdp->len_status &= ~OETH_RX_BD_STATS;
+
+            if (skb)
+              {
+                cep->rx_skbuff[cep->rx_cur] = skb;
+
+                bdp->addr = (unsigned long)skb->tail;
+
+                flush_dcache_range (((unsigned long) (bdp->addr)),
+                             ((unsigned long) (bdp->addr)) + MAX_FRAME_SIZE);
+
+                bdp->len_status |= OETH_RX_BD_EMPTY;
+              }
+            else
+              {
+                cep->rx_skbuff[cep->rx_cur] = NULL;
+              }
+          }
+#endif
+      }
+}
+
+
+/*-----------------------------------------------------------
+ | Driver entry point
+ |
+ | Entry condition: Cpu interrupts DISabled.
+ */
+static irqreturn_t oeth_interrupt(int             irq,
+                                  void           *dev_id)
+{
+    struct  net_device *dev = dev_id;
+    struct oeth_private *cep;
+    uint    int_events;
+
+    cep = (struct oeth_private *)netdev_priv(dev);
+
+    /* Get the interrupt events that caused us to be here.
+     */
+    int_events = cep->regs->int_src;
+    cep->regs->int_src = int_events;
+
+    /* Handle receive event in its own function.
+     */
+    if (int_events & (OETH_INT_RXF | OETH_INT_RXE | OETH_INT_BUSY))
+        tasklet_schedule(&cep->oeth_rx_tasklet);       
+
+    /* Handle transmit event in its own function.
+     */
+    if (int_events & (OETH_INT_TXB | OETH_INT_TXE))
+        tasklet_schedule(&cep->oeth_tx_tasklet);       
+
+    /* Check for receive busy, i.e. packets coming but no place to
+     * put them.
+     */
+    if (int_events & OETH_INT_BUSY)
+      {
+        cep->stats.rx_dropped++;                                //;dgt
+      }
+
+    return IRQ_HANDLED;
+}
+
+static int
+oeth_open(struct net_device *dev)
+{
+    volatile oeth_regs *regs = (oeth_regs *)dev->base_addr;
+    struct oeth_private *cep = (struct oeth_private *)netdev_priv(dev);
+
+#ifndef RXBUFF_PREALLOC
+    struct  sk_buff *skb;
+    volatile oeth_bd *rx_bd;
+    int i;
+
+    rx_bd = cep->rx_bd_base;
+
+    for(i = 0; i < OETH_RXBD_NUM; i++)
+      {
+        skb = dev_alloc_skb(MAX_FRAME_SIZE);
+
+        if (skb == NULL)
+            rx_bd[i].len_status = (0 << 16) | OETH_RX_BD_IRQ;
+        else
+            flush_dcache_range (((unsigned long) (rx_bd[i].addr)),
+                         ((unsigned long) (rx_bd[i].addr)) + MAX_FRAME_SIZE);
+
+            rx_bd[i].len_status = (0 << 16)         |
+                                  OETH_RX_BD_EMPTY  |
+                                  OETH_RX_BD_IRQ;
+            // FIXME...Should we really let the rx ring
+            //      ... completely fill...?...
+            //      ...Can we actually prevent...?...
+
+        cep->rx_skbuff[i] = skb;
+        rx_bd[i].addr     = (unsigned long)skb->tail;
+      }
+    rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP;
+#endif
+
+    /* Install our interrupt handler.
+     */
+    request_irq(MACIRQ_NUM, oeth_interrupt, 0, "eth", (void *)dev);
+
+    // enable phy interrupts
+    //
+    #if defined(TDK78Q2120PHY)
+      #if defined(PHYIRQ_NUM)
+        request_irq(PHYIRQ_NUM,
+                    oeth_PhyInterrupt,
+                    0, "eth", (void *)dev);
+
+        eth_mdread (dev, PHY_ADDRESS, 17);      // Clear any junk ?
+
+        eth_mdwrite(dev, PHY_ADDRESS, 17, 0xff00);
+          // Enable Jabber     0x8000(0x0080)
+          //        Rxer       0x4000(0x0040)
+          //        Prx        0x2000(0x0020)
+          //        Pfd        0x1000(0x0010)
+          //        Lpack      0x0800(0x0008)
+          //        Lschg      0x0400(0x0004)
+          //        Rfault     0x0200(0x0002)
+          //        Anegcomp   0x0100(0x0001)
+          //  Ints
+
+        (*(volatile unsigned long *)
+             (((unsigned long *)
+                  ((((char *)
+                        (((int) (PHYIRQ_BASE_ADDR)) +
+                         0x0008))))))) =
+                ((unsigned long) (0x0001));
+          // Enable phy interrupt pass thru to PHYIRQ_NUM
+      #endif
+    #endif  /* defined(TDK78Q2120PHY) */
+
+    oeth_phymac_synch(dev,
+                      0);  // Caller = NOT Phy interrupt handler
+
+    /* Enable receiver and transmiter
+     */
+    regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN;
+
+#if OETH_REVISION_DATECODE >= 20040426
+    /* Zero the BD pointers.
+     */
+    cep->rx_cur = 0;
+    cep->tx_next = 0;
+    cep->tx_last = 0;
+    cep->tx_full = 0;
+#endif
+
+    netif_start_queue(dev);
+    tasklet_init(&cep->oeth_rx_tasklet, oeth_rx, (unsigned long)dev);
+    tasklet_init(&cep->oeth_tx_tasklet, oeth_tx, (unsigned long)dev);
+
+    return 0;
+}
+
+static int
+oeth_close(struct net_device *dev)
+{
+    struct oeth_private *cep = (struct oeth_private *)netdev_priv(dev);
+    volatile oeth_regs *regs = (oeth_regs *)dev->base_addr;
+    volatile oeth_bd *bdp;
+    int i;
+
+    netif_stop_queue(dev);
+
+    /* Free phy interrupt handler
+     */
+#if defined(PHYIRQ_NUM)
+        (*(volatile unsigned long *)
+             (((unsigned long *)
+                  ((((char *)
+                        (((int) (PHYIRQ_BASE_ADDR)) +
+                         0x0008))))))) =
+                ((unsigned long) (0x0000));
+          // Disable phy interrupt pass thru to PHYIRQ_NUM
+
+        free_irq(PHYIRQ_NUM, (void *)dev);
+#endif
+
+    /* Free interrupt hadler
+     */
+    free_irq(MACIRQ_NUM, (void *)dev);
+
+    tasklet_kill(&cep->oeth_tx_tasklet);
+    tasklet_kill(&cep->oeth_rx_tasklet);
+
+    /* Disable receiver and transmitesr
+     */
+    regs->moder &= ~(OETH_MODER_RXEN | OETH_MODER_TXEN);
+
+    bdp = cep->rx_bd_base;
+    for (i = 0; i < OETH_RXBD_NUM; i++) {
+        bdp->len_status &= ~(OETH_RX_BD_STATS | OETH_RX_BD_EMPTY);
+        bdp++;
+    }
+
+    bdp = cep->tx_bd_base;
+    for (i = 0; i < OETH_TXBD_NUM; i++) {
+        bdp->len_status &= ~(OETH_TX_BD_STATS | OETH_TX_BD_READY);
+        bdp++;
+    }
+
+#ifndef RXBUFF_PREALLOC
+
+    /* Free all alocated rx buffers
+     */
+    for (i = 0; i < OETH_RXBD_NUM; i++) {
+
+        if (cep->rx_skbuff[i] != NULL)
+            dev_kfree_skb(cep->rx_skbuff[i]);
+
+    }
+#endif  // RXBUFF_PREALLOC
+
+#ifndef TXBUFF_PREALLOC
+
+    /* Free all alocated tx buffers
+     */
+    for (i = 0; i < OETH_TXBD_NUM; i++) {
+
+        if (cep->tx_skbuff[i] != NULL)
+            dev_kfree_skb(cep->tx_skbuff[i]);
+    }
+#endif  // TXBUFF_PREALLOC
+
+    return 0;
+}
+
+// Queues a packet for transmission by the OETH. -TS
+static int
+oeth_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+    volatile struct oeth_private *cep = (struct oeth_private *)netdev_priv(dev);
+    volatile        oeth_bd      *bdp;
+    unsigned        int           lenSkbDataByts;
+
+    netif_stop_queue(dev);
+
+    if (cep->tx_full) {
+        //;dgt-"Impossible", but in any event, queue may have been
+        //;dgt- reawakened by now.
+        /* All transmit buffers are full.  Bail out.
+         */
+        printk("%s: tx queue full!.\n", dev->name);
+        return 1;
+    }
+
+    lenSkbDataByts = skb->len;
+
+    /* Fill in a Tx ring entry
+     */
+    bdp = cep->tx_bd_base + cep->tx_next;
+
+    /* Clear all of the status flags.
+     */
+    bdp->len_status &= ~OETH_TX_BD_STATS;
+
+    /* If the frame is short, tell CPM to pad it.
+     */
+    if (lenSkbDataByts <= ETH_ZLEN)
+        bdp->len_status |= OETH_TX_BD_PAD;
+    else
+        bdp->len_status &= ~OETH_TX_BD_PAD;
+
+#if OETH_DEBUG
+    _print("TX\n");
+    oeth_print_packet(skb->data, lenSkbDataByts);
+#endif  // OETH_DEBUG
+
+#ifdef TXBUFF_PREALLOC
+
+    /* Copy data in preallocated buffer */
+    if (lenSkbDataByts > OETH_TX_BUFF_SIZE)
+      {
+        printk("%s: %d byte tx frame too long (max:%d)!.\n",
+               dev->name,
+               lenSkbDataByts,
+               OETH_TX_BUFF_SIZE);
+
+//;dgt  return 1;                               //;dgt infinite loop!
+        dev_kfree_skb(skb);                     //;dgt
+        netif_wake_queue(dev);
+        return 0;                               //;dgt
+      }
+      else
+      {
+        #ifdef CONFIG_EXCALIBUR
+          #ifdef SANCHKEPKT
+            DoSanchkEpkt(((const char *) (skb->data)),
+                         lenSkbDataByts,
+                         "SkbTx");
+          #endif // SANCHKEPKT
+
+          if((((unsigned long) (skb->data)) & 1) == 0)
+            {
+              unsigned short     *dst;
+              unsigned short     *src;
+
+              dst = ((unsigned short *) (bdp->addr));
+              src = ((unsigned short *) (skb->data));
+
+              //;dgt...FIXME...simple 16 bit copy loop
+              //;dgt... = approx 20% overall throughput
+              //;dgt... improvement...
+              //;dgt...A more advanced copy from 16 bit
+              //;dgt... aligned source to 32 bit aligned
+              //;dgt... destination still needed though...
+              //;dgt;Mar2005;Custom NiosII instruction now
+              //;dgt; available or imminent for a "really"
+              //;dgt; optimized memcpy, even under mismatched
+              //;dgt; src/dst alignments
+              #if 0
+                {
+                  unsigned int        uiloop;
+                  for(uiloop = 0;
+                      (uiloop < (lenSkbDataByts >> 1));
+                      uiloop++)
+                    {
+                      *dst++ = *src++;
+                    }
+
+                  if(((lenSkbDataByts) & 1) != 0)
+                    {
+                      *((unsigned char *) dst) =
+                           *((unsigned char *) src);
+                    }
+                }
+              #else
+                memcpy(dst, src, lenSkbDataByts);
+              #endif
+            }
+            else
+            {
+              memcpy((unsigned char *)bdp->addr,
+                     skb->data,
+                     lenSkbDataByts);
+            }
+
+          #ifdef SANCHKEPKT
+            DoSanchkEpkt(((const char *) (bdp->addr)),
+                         lenSkbDataByts,
+                         "DmaTx");
+          #endif // SANCHKEPKT
+
+        #else
+          memcpy((unsigned char *)bdp->addr, skb->data, lenSkbDataByts);
+        #endif  // CONFIG_EXCALIBUR
+      }
+
+    bdp->len_status =   (bdp->len_status & 0x0000ffff)
+                      | (lenSkbDataByts << 16);
+
+    dev_kfree_skb(skb);
+#else
+    /* Set buffer length and buffer pointer.
+     */
+    bdp->len_status =   (bdp->len_status & 0x0000ffff)
+                      | (lenSkbDataByts << 16);
+    bdp->addr = (uint)__pa(skb->data);
+
+    /* Save skb pointer.
+     */
+    cep->tx_skbuff[cep->tx_next] = skb;
+#endif  // TXBUFF_PREALLOC
+
+//;dgt  cep->tx_next = (cep->tx_next + 1) & OETH_TXBD_NUM_MASK;
+
+    /* Send it on its way.  Tell controller its ready, interrupt when done,
+     * and to put the CRC on the end.
+     */
+    flush_dcache_range (((unsigned long) (bdp->addr)),
+                 ((unsigned long) (bdp->addr)) + lenSkbDataByts);
+
+    local_bh_disable();
+
+    cep->tx_next = (cep->tx_next + 1) & OETH_TXBD_NUM_MASK;     //;dgt
+
+    if (cep->tx_next == cep->tx_last)
+      {
+        cep->tx_full = 1;
+      }
+
+    bdp->len_status |= (  0
+                        | OETH_TX_BD_READY
+                        | OETH_TX_BD_IRQ
+                        | OETH_TX_BD_CRC
+                       );
+
+    dev->trans_start = jiffies;
+
+    if (cep->tx_next != cep->tx_last)
+      {
+        if(((cep->tx_next + 1) & OETH_TXBD_NUM_MASK) != cep->tx_last)
+          {
+            netif_wake_queue(dev);
+          }
+//        else
+//        {
+//          Don't let the tx ring completely fill
+//        }
+      }
+    local_bh_enable();
+
+    return 0;
+}
+
+
+#if 1                                                           //;dgt
+    //                                                          //;dgt
+#else                                                           //;dgt
+static int calc_crc(char *mac_addr)
+{
+    // FIXME....                                                //;dgt
+    // ...must calculate the PRE postconditioned AutoDinII      //;dgt
+    // ... Crc-32 of the 6 bytes pointed to by mac_addr,        //;dgt
+    // ... then extract and reverse bit #'s 3-8 inclusive       //;dgt
+    // ... (with due regard to the varying frames of reference  //;dgt
+    // ... within various crc publications, etc)...             //;dgt
+    // Eg: 01-80-C2-00-00-01 (IEEE 802 Mac control multicast)   //;dgt
+    //   CRC-32:     0x9FC42B70 before Postconditioning         //;dgt
+    //    Last_on_wire_9F    70_First (If were to go onto wire) //;dgt
+    //                       Bits #'s 0-16: 0x2B70              //;dgt
+    //                                 .......98 7654 3210      //;dgt
+    //                                 0010 1011 0111 0000      //;dgt
+    //                       Bits #'s 3-8:  1 0111 0            //;dgt
+    //                        Reversed:     0 1110 1 = 0x1D     //;dgt
+    //   Return multicast hash bit offset: 29 decimal           //;dgt
+    // Eg: 01-00-5E-00-00-09 (IETF Rip2 multicast)              //;dgt
+    //   CRC-32      0xD76F4DCC  before Postconditioning        //;dgt
+    //   Return multicast hash bit offset: 39 decimal           //;dgt
+    // At least it so appears.                                  //;dgt
+
+    int result = 0;
+    return (result & 0x3f);
+}
+#endif                                                      //;dgt
+
+static struct net_device_stats *oeth_get_stats(struct net_device *dev)
+{
+    struct oeth_private *cep = (struct oeth_private *)netdev_priv(dev);
+
+    return &cep->stats;
+}
+
+static void oeth_set_multicast_list(struct net_device *dev)
+{
+    volatile struct oeth_private *cep;
+    volatile oeth_regs *regs;
+
+    cep = (struct oeth_private *)netdev_priv(dev);
+
+    /* Get pointer of controller registers.
+     */
+    regs = (oeth_regs *)dev->base_addr;
+
+    if (dev->flags & IFF_PROMISC) {
+
+        /* Log any net taps.
+         */
+        printk("%s: Promiscuous mode enabled.\n", dev->name);
+        regs->moder |= OETH_MODER_PRO;
+    } else {
+
+        regs->moder &= ~OETH_MODER_PRO;
+
+        if (dev->flags & IFF_ALLMULTI) {
+
+            /* Catch all multicast addresses, so set the
+             * filter to all 1's.
+             */
+            regs->hash_addr0 = 0xffffffff;
+            regs->hash_addr1 = 0xffffffff;
+        }
+        else if (dev->mc_count) {
+
+          #if 1                                         //;dgt
+            // FIXME...for now, until broken            //;dgt
+            //  calc_crc(...) fixed...                  //;dgt
+            regs->hash_addr0 = 0xffffffff;              //;dgt
+            regs->hash_addr1 = 0xffffffff;              //;dgt
+          #else                                         //;dgt
+            struct  dev_mc_list *dmi;
+            int                  i;
+
+            /* Clear filter and add the addresses in the list.
+             */
+            regs->hash_addr0 = 0x00000000;
+//;dgt      regs->hash_addr0 = 0x00000000;
+            regs->hash_addr1 = 0x00000000;              //;dgt
+
+            dmi = dev->mc_list;
+
+            for (i = 0; i < dev->mc_count; i++) {
+
+                int hash_b;
+
+                /* Only support group multicast for now.
+                 */
+                if (!(dmi->dmi_addr[0] & 1))
+                    continue;
+
+                hash_b = calc_crc(dmi->dmi_addr);
+                if(hash_b >= 32)
+                    regs->hash_addr1 |= 1 << (hash_b - 32);
+                else
+                    regs->hash_addr0 |= 1 << hash_b;
+            }
+          #endif                                        //;dgt
+        }
+    }
+}
+
+static int oeth_set_mac_add(struct net_device *dev, void *p)
+{
+    struct sockaddr *addr=p;
+    volatile oeth_regs *regs;
+
+    memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
+
+    regs = (oeth_regs *)dev->base_addr;
+
+    regs->mac_addr1 = (dev->dev_addr[0]) <<  8 |
+                      (dev->dev_addr[1]);
+    regs->mac_addr0 = (dev->dev_addr[2]) << 24 |
+                      (dev->dev_addr[3]) << 16 |
+                      (dev->dev_addr[4]) <<  8 |
+                      (dev->dev_addr[5]);
+    return 0;
+}
+
+#ifdef OETH_SYSFS_MDIO_ACCESS
+int write_in_binary(char *s, int val, int bits) {
+
+	int pos = 0;
+
+	while (bits > 0) {
+		bits--;
+		s[pos++] = '0' + ((val >> bits) & 1);
+	}
+
+	s[pos++] = '\n';
+
+	return pos;
+
+}
+
+int read_in_binary(const char *s, int len) {
+
+	int val = 0;
+
+	while ((len > 0) && (*s == '0' || *s == '1' )) {
+		len--;
+		val = (val << 1) + (*(s++) - '0');
+	}
+
+	return val;
+
+}
+
+#define FIELD_OFFSET(mystruct, myfield) \
+	((unsigned long)&((mystruct *)0)->myfield)
+
+#define CONTAINING_STRUCT(mystruct, myfield, myptr) \
+	((mystruct *)(((const char *)myptr) - FIELD_OFFSET(mystruct, myfield)))
+
+ssize_t show_phy_reg(struct kobject *kobj, struct attribute *attr, 
+                        char *buffer) {
+
+	int phy_num, reg_num;
+	int val;
+	struct net_device *dev = CONTAINING_STRUCT(struct net_device, class_dev.kobj, kobj->parent->parent);
+
+	if (sscanf(kobject_name(kobj), "phy%d", &phy_num) != 1)
+		return -1;
+
+	if (sscanf(attr->name, "reg%d", &reg_num) != 1)
+		return -1;
+
+	val = eth_mdread(dev, phy_num, reg_num);
+
+	return write_in_binary(buffer, val, 16);
+
+}
+
+ssize_t store_phy_reg(struct kobject *kobj, struct attribute *attr, 
+                        const char *buffer, size_t size) {
+
+	int phy_num, reg_num;
+	int val;
+	struct net_device *dev = CONTAINING_STRUCT(struct net_device, class_dev.kobj, kobj->parent->parent);
+
+	if (sscanf(kobject_name(kobj), "phy%d", &phy_num) != 1)
+		return -1;
+	if (sscanf(attr->name, "reg%d", &reg_num) != 1)
+		return -1;
+
+	val = read_in_binary(buffer, size);
+
+	eth_mdwrite(dev, phy_num, reg_num, val);
+
+	return size;
+
+}
+
+struct sysfs_ops phy_ops = {
+	.show = &show_phy_reg,
+	.store = &store_phy_reg
+};
+
+void release_phy(struct kobject *phy) {
+	kfree(phy);
+}
+
+struct kobj_type phy_type = {
+	.release = &release_phy,
+	.sysfs_ops = &phy_ops, // The phys have one attribute for each register
+	.default_attrs = (struct attribute *[]) { 
+		& (struct attribute) { "reg00", NULL, 0640 },
+		& (struct attribute) { "reg01", NULL, 0640 },
+		& (struct attribute) { "reg02", NULL, 0640 },
+		& (struct attribute) { "reg03", NULL, 0640 },
+		& (struct attribute) { "reg04", NULL, 0640 },
+		& (struct attribute) { "reg05", NULL, 0640 },
+		& (struct attribute) { "reg06", NULL, 0640 },
+		& (struct attribute) { "reg07", NULL, 0640 },
+		& (struct attribute) { "reg08", NULL, 0640 },
+		& (struct attribute) { "reg09", NULL, 0640 },
+		& (struct attribute) { "reg10", NULL, 0640 },
+		& (struct attribute) { "reg11", NULL, 0640 },
+		& (struct attribute) { "reg12", NULL, 0640 },
+		& (struct attribute) { "reg13", NULL, 0640 },
+		& (struct attribute) { "reg14", NULL, 0640 },
+		& (struct attribute) { "reg15", NULL, 0640 },
+		& (struct attribute) { "reg16", NULL, 0640 },
+		& (struct attribute) { "reg17", NULL, 0640 },
+		& (struct attribute) { "reg18", NULL, 0640 },
+		& (struct attribute) { "reg19", NULL, 0640 },
+		& (struct attribute) { "reg20", NULL, 0640 },
+		& (struct attribute) { "reg21", NULL, 0640 },
+		& (struct attribute) { "reg22", NULL, 0640 },
+		& (struct attribute) { "reg23", NULL, 0640 },
+		& (struct attribute) { "reg24", NULL, 0640 },
+		& (struct attribute) { "reg25", NULL, 0640 },
+		& (struct attribute) { "reg26", NULL, 0640 },
+		& (struct attribute) { "reg27", NULL, 0640 },
+		& (struct attribute) { "reg28", NULL, 0640 },
+		& (struct attribute) { "reg29", NULL, 0640 },
+		& (struct attribute) { "reg30", NULL, 0640 },
+		& (struct attribute) { "reg31", NULL, 0640 },
+		NULL
+	}
+};
+
+static void init_mdio(struct net_device *dev) {
+
+	int i;
+	// First create the sysfs interface.
+	struct kobject *mdio = kobject_add_dir(&dev->class_dev.kobj, "mdio");
+
+	// Now probe for PHYs.
+	for (i = 0; i < (sizeof(probe_mdio_phys)/sizeof(int)); i++) {
+
+		if (eth_mdread(dev, probe_mdio_phys[i], 0) == 0xFFFF) {
+			// PHY does not exist
+			printk("No PHY found at probe address %d.\n", probe_mdio_phys[i]);
+			continue;
+		}
+
+		struct kobject *phy = kzalloc(sizeof(struct kobject), GFP_KERNEL);
+		kobject_set_name(phy, "phy%02d", probe_mdio_phys[i]);
+		phy->ktype = &phy_type;
+		phy->parent = mdio;
+
+		kobject_register(phy);
+	}
+}
+#endif
+
+static const struct net_device_ops oeth_netdev_ops = {
+	.ndo_open               = oeth_open,
+	.ndo_stop               = oeth_close,
+	.ndo_start_xmit         = oeth_start_xmit,
+	.ndo_set_multicast_list = oeth_set_multicast_list,
+	.ndo_set_mac_address    = oeth_set_mac_add,
+	.ndo_get_stats          = oeth_get_stats,
+	.ndo_do_ioctl           = mii_ioctl,
+};
+
+/*-----------------------------------------------------------
+ | Entry condition: Cpu interrupts ENabled
+ |                   (in SPITE of claims disabled).
+*/
+static int __init oeth_probe(struct net_device *dev)
+{
+    struct          oeth_private  *cep;
+    volatile        oeth_regs     *regs;
+    volatile        oeth_bd       *tx_bd, *rx_bd;
+    int                            i, j, k;
+    unsigned long		   regbase;
+  #ifdef SRAM_BUFF
+    unsigned long mem_addr = SRAM_BUFF_BASE;
+  #else
+    unsigned long mem_addr;
+  #endif    // SRAM_BUFF
+    unsigned bmcr_val;
+
+    PRINTK2("%s:oeth_probe\n", dev->name);
+
+/*     SET_MODULE_OWNER (dev); */
+
+    cep = (struct oeth_private *)netdev_priv(dev);
+
+    if (!request_region(ETH_BASE_ADD,
+                        OETH_IO_EXTENT,
+                        dev->name)) return -EBUSY;
+
+    printk("%s: Open Ethernet Core Version 1.0\n", dev->name);
+
+  #ifdef CONFIG_EXCALIBUR
+    printk("  oeth_probe: %d Khz Nios: %d RX, %d TX",
+           nasys_clock_freq_1000,
+           OETH_RXBD_NUM,
+           OETH_TXBD_NUM);
+  #endif    // CONFIG_EXCALIBUR
+    
+    regbase = (unsigned long)ioremap(ETH_BASE_ADD, OETH_IO_EXTENT);
+
+    if (regbase == 0) {
+	printk(KERN_ERR "%s: " "failed to ioremap mac reg\n", dev->name);
+      	return -EINVAL;
+    }
+
+    __clear_user(cep,sizeof(*cep));
+
+    /* Get pointer ethernet controller configuration registers.
+     */
+    cep->regs = (oeth_regs *)(regbase);
+    regs = (oeth_regs *)(regbase);
+
+    /* Reset the controller.
+     */
+    regs->moder  =  OETH_MODER_RST;     /* Reset ON */
+    regs->moder &= ~OETH_MODER_RST;     /* Reset OFF */
+
+    /* Setting TXBD base to OETH_TXBD_NUM.
+     */
+    regs->tx_bd_num = OETH_TXBD_NUM;
+
+    /* Initialize TXBD pointer
+     */
+    cep->tx_bd_base = (oeth_bd *)(regbase + OETH_BD_OFS);
+    tx_bd =  (volatile oeth_bd *)(regbase + OETH_BD_OFS);
+
+    /* Initialize RXBD pointer
+     */
+    cep->rx_bd_base = ((oeth_bd *)(regbase + OETH_BD_OFS)) + OETH_TXBD_NUM;
+    rx_bd =  ((volatile oeth_bd *)(regbase + OETH_BD_OFS)) + OETH_TXBD_NUM;
+
+#if OETH_REVISION_DATECODE < 20040426
+    /* Initialize transmit pointers.
+     */
+    cep->rx_cur = 0;
+    cep->tx_next = 0;
+    cep->tx_last = 0;
+    cep->tx_full = 0;
+#endif
+
+    /* Set min/max packet length
+     */
+    regs->packet_len = 0x00400600;
+
+//;dgt-see oeth_phymac_synch /* Set IPGT register to recomended value */
+//;dgt-see oeth_phymac_synch regs->ipgt = 0x00000012;
+
+    /* Set IPGR1 register to recomended value
+     */
+    regs->ipgr1 = 0x0000000c;
+
+    /* Set IPGR2 register to recomended value
+     */
+    regs->ipgr2 = 0x00000012;
+
+    /* Set COLLCONF register to recomended value
+     */
+    regs->collconf = 0x000f003f;
+
+    /* Set control module mode
+     */
+  #if 1
+    regs->ctrlmoder = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW;
+  #else
+    regs->ctrlmoder = 0;
+  #endif
+
+    #if defined(TDK78Q2120PHY)
+      // TDK78Q2120 reset values:
+      //
+      //   MR0  (Control):      0x3100:
+      //       0x00100  FullDuplexIfnoneg
+      //       0x01000  AutonegEnabled
+      //       0x02000  100BaseTxIfnoneg
+      //
+      //   MR18 (Diagnostics):  0x0000
+
+      /* TDK78Q2120 LEDs (seven?) NOT configurable?                     */
+    #elif defined(LXT971PHY)
+      ...Intel LXT971A phy...?...
+
+      /* Set PHY to show Tx status, Rx status and Link status */
+      regs->miiaddress = 20<<8;
+      regs->miitx_data = 0x1422;
+      regs->miicommand = OETH_MIICOMMAND_WCTRLDATA;
+    #else
+//      printk("\n*** WARNING : forcing link 10Mbps - autoneg... ***\n");
+//      eth_mdwrite(dev, PHY_ADDRESS, 0, 0x0100);
+    #endif  // TDK78Q2120PHY
+
+#ifdef TXBUFF_PREALLOC
+
+    /* Initialize TXBDs.
+     */
+    for(i = 0, k = 0; i < OETH_TX_BUFF_PAGE_NUM; i++) {
+
+  #ifndef SRAM_BUFF
+        mem_addr = __get_free_page(GFP_KERNEL);
+  #endif    // SRAM_BUFF
+
+        for(j = 0; j < OETH_TX_BUFF_PPGAE; j++, k++) {
+            tx_bd[k].len_status = OETH_TX_BD_PAD |
+                                  OETH_TX_BD_CRC |
+                                  OETH_RX_BD_IRQ;
+            tx_bd[k].addr = __pa(mem_addr);
+            mem_addr += OETH_TX_BUFF_SIZE;
+        }
+    }
+    tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP;
+#else
+
+    /* Initialize TXBDs.
+     */
+    for(i = 0; i < OETH_TXBD_NUM; i++) {
+
+        cep->tx_skbuff[i] = NULL;
+
+        tx_bd[i].len_status = (0 << 16)      |
+                              OETH_TX_BD_PAD |
+                              OETH_TX_BD_CRC |
+                              OETH_RX_BD_IRQ;
+        tx_bd[i].addr = 0;
+    }
+    tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP;
+#endif  // TXBUFF_PREALLOC
+
+#ifdef RXBUFF_PREALLOC
+
+    /* Initialize RXBDs.
+     */
+    for(i = 0, k = 0; i < OETH_RX_BUFF_PAGE_NUM; i++) {
+
+  #ifndef SRAM_BUFF
+        mem_addr = __get_free_page(GFP_KERNEL);
+  #endif    // SRAM_BUFF
+
+        for(j = 0; j < OETH_RX_BUFF_PPGAE; j++, k++)
+          {
+            rx_bd[k].addr = __pa(mem_addr);
+
+            flush_dcache_range (((unsigned long) (rx_bd[k].addr)),
+                         ((unsigned long) (rx_bd[k].addr)) + OETH_RX_BUFF_SIZE);
+
+            rx_bd[k].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ;
+              // FIXME...Should we really let the rx ring
+              //      ... completely fill...?...
+              //      ...Can we actually prevent ?
+
+            mem_addr += OETH_RX_BUFF_SIZE;
+          }
+    }
+    rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP;
+
+#else
+    /* Initialize RXBDs.
+     */
+    for(i = 0; i < OETH_RXBD_NUM; i++)
+      {
+        rx_bd[i].len_status = (0 << 16) | OETH_RX_BD_IRQ;
+        cep->rx_skbuff[i]   = NULL;
+        rx_bd[i].addr       = 0;
+      }
+    rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP;
+
+#endif  // RXBUFF_PREALLOC
+
+    dev->dev_addr[0] = MACADDR0;
+    dev->dev_addr[1] = MACADDR1;
+    dev->dev_addr[2] = MACADDR2;
+    dev->dev_addr[3] = MACADDR3;
+    dev->dev_addr[4] = MACADDR4;
+    dev->dev_addr[5] = MACADDR5;
+
+    regs->mac_addr1 = (dev->dev_addr[0]) <<  8 |
+                      (dev->dev_addr[1]);
+    regs->mac_addr0 = (dev->dev_addr[2]) << 24 |
+                      (dev->dev_addr[3]) << 16 |
+                      (dev->dev_addr[4]) <<  8 |
+                      (dev->dev_addr[5]);
+
+    /* Clear all pending interrupts
+     */
+    regs->int_src = 0xffffffff;
+
+    /* Promisc, IFG, CRCEn
+     */
+    regs->moder |= OETH_MODER_PAD | OETH_MODER_IFG | OETH_MODER_CRCEN;
+
+    /* Enable interrupt sources.
+     */
+    regs->int_mask = OETH_INT_MASK_TXB   |
+                     OETH_INT_MASK_TXE   |
+                     OETH_INT_MASK_RXF   |
+                     OETH_INT_MASK_RXE   |
+                     OETH_INT_MASK_BUSY  |
+                     OETH_INT_MASK_TXC   |
+                     OETH_INT_MASK_RXC;
+
+    /* Fill in the fields of the device structure with ethernet values.
+     */
+    ether_setup(dev);
+
+    dev->base_addr = regbase;
+
+    /* The Open Ethernet specific entries in the device structure.
+     */
+    dev->netdev_ops = &oeth_netdev_ops;
+
+    bmcr_val = eth_mdread(dev, PHY_ADDRESS, MII_BMCR);
+    cep->mii.dev = dev;
+    cep->mii.mdio_read = eth_mdread;
+    cep->mii.mdio_write = eth_mdwrite;
+    cep->mii.phy_id_mask = 0x1f;
+    cep->mii.reg_num_mask = 0x1f;
+    cep->mii.phy_id = PHY_ADDRESS;
+    cep->mii.full_duplex = (bmcr_val & BMCR_FULLDPLX) ? 1 : 0;	/* is full duplex? */
+    cep->mii.force_media = (bmcr_val & BMCR_ANENABLE) ? 1 : 0;	/* is autoneg. disabled? */
+    cep->mii.supports_gmii = 0; /* are GMII registers supported? */
+
+#ifdef CONFIG_EXCALIBUR
+  #ifdef SRAM_BUFF
+    printk(" SRAM @0x%08X",SRAM_BUFF_BASE);
+  #endif
+    printk(" buffs\n");
+    printk("              %s Custom HW ALIGN.\n",
+           #if defined(ALT_CI_ALIGN_32_N)
+             "WITH"
+           #else
+             "NO"
+           #endif
+          );
+    printk("              CONFIG_NIOS2_HW_MULX    %sdefined.\n",
+           #ifdef CONFIG_NIOS2_HW_MULX
+             ""
+           #else
+             "NOT "
+           #endif
+          );
+    printk("              CONFIG_NIOS2_HW_MUL_OFF %sdefined.\n",
+           #ifdef CONFIG_NIOS2_HW_MUL_OFF
+             ""
+           #else
+             "NOT "
+           #endif
+          );
+    printk("              BMCR = %04xh.\n", bmcr_val);
+#endif
+#ifdef SANCHKEPKT
+    printk("              SANCHKEPKT defined.\n");
+#endif
+
+    return 0;
+}
+
+
+/*-----------------------------------------------------------
+ | Driver entry point (called by ethif_probe2()).
+ |
+ | Return:  0   success.
+ |
+ | Entry condition: Cpu interrupts ENabled
+ |                   (in SPITE of claims to contrary).
+*/
+struct net_device * __init oeth_init(int unit)
+{
+    struct net_device *dev = alloc_etherdev(sizeof(struct oeth_private));
+    int                err;
+
+    if (!dev) return ERR_PTR(-ENODEV);
+
+    sprintf(dev->name, "eth%d", unit);
+    netdev_boot_setup_check(dev);
+
+    PRINTK2("%s:oeth_init\n", dev->name);
+
+    if (oeth_probe(dev) != 0)
+      {
+        err = -ENODEV;
+        goto out;
+      }
+
+    err = register_netdev(dev);
+    if (err) {
+      goto out;
+    }
+
+#ifdef OETH_MDC_DIVISOR
+    // Set the MDC divisor.
+    ((volatile oeth_regs *)dev->base_addr)->miimoder = OETH_MDC_DIVISOR;
+#endif
+#ifdef OETH_SYSFS_MDIO_ACCESS
+    init_mdio(dev);
+#endif
+
+    return dev;
+
+out:
+    free_netdev(dev);
+    return ERR_PTR(err);
+}
diff --git a/drivers/net/open_eth.h b/drivers/net/open_eth.h
new file mode 100644
index 0000000..4011c22
--- /dev/null
+++ b/drivers/net/open_eth.h
@@ -0,0 +1,196 @@
+/*--------------------------------------------------------------------
+ * open_eth.c
+ *
+ * Ethernet driver for Open Ethernet Controller (www.opencores.org).
+ *
+ * Copyright (c) 2002 Simon Srot (simons@opencores.org)
+ * Copyright (C) 2004 Microtronix Datacom Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * History:
+ *    Jun/20/2004   DGT Microtronix Datacom NiosII
+ *
+ ---------------------------------------------------------------------*/
+
+/* Core revision's date. Set it to the right thing if you want
+   correct operation. This value is the latest revision as of
+   this writing (2007/08/14). */
+#define OETH_REVISION_DATECODE 20050321
+
+/* Define this to probe these PHY addresses and create user-accessible
+   files for them in /sys/class/net/ethN/mdio. */
+//#define OETH_SYSFS_MDIO_ACCESS {1,2}
+
+/* Define this to set the MDC divisor to this value. If undefined,
+   the divisor will be the core's power-up default of 100. */
+//#define OETH_MDC_DIVISOR 10
+
+/* Define this to do additional CRC checking in software and print debug
+   info when a bad CRC is caught on a packet that the MAC said was good.
+   Useful if you suspect the MAC is silently corrupting packets, which
+   it has been known to do. */
+//#define OETH_SW_CRC_CHECKING
+
+/* Ethernet configuration registers */
+typedef struct _oeth_regs {
+        uint    moder;          /* Mode Register */
+        uint    int_src;        /* Interrupt Source Register */
+        uint    int_mask;       /* Interrupt Mask Register */
+        uint    ipgt;           /* Back to Bak Inter Packet Gap Register */
+        uint    ipgr1;          /* Non Back to Back Inter Packet Gap Register 1 */
+        uint    ipgr2;          /* Non Back to Back Inter Packet Gap Register 2 */
+        uint    packet_len;     /* Packet Length Register (min. and max.) */
+        uint    collconf;       /* Collision and Retry Configuration Register */
+        uint    tx_bd_num;      /* Transmit Buffer Descriptor Number Register */
+        uint    ctrlmoder;      /* Control Module Mode Register */
+        uint    miimoder;       /* MII Mode Register */
+        uint    miicommand;     /* MII Command Register */
+        uint    miiaddress;     /* MII Address Register */
+        uint    miitx_data;     /* MII Transmit Data Register */
+        uint    miirx_data;     /* MII Receive Data Register */
+        uint    miistatus;      /* MII Status Register */
+        uint    mac_addr0;      /* MAC Individual Address Register 0 */
+        uint    mac_addr1;      /* MAC Individual Address Register 1 */
+        uint    hash_addr0;     /* Hash Register 0 */
+        uint    hash_addr1;     /* Hash Register 1 */                           
+} oeth_regs;
+
+/* Ethernet buffer descriptor */
+typedef struct _oeth_bd {
+#if 0
+        ushort  len;            /* Buffer length */
+        ushort  status;         /* Buffer status */
+#else
+        uint    len_status;
+#endif
+        uint    addr;           /* Buffer address */
+} oeth_bd;
+
+#define OETH_BD_OFS             0x400
+#define OETH_TOTAL_BD           128
+#define OETH_MAXBUF_LEN         0x600
+                                
+/* Tx BD */                     
+#define OETH_TX_BD_READY        0x8000 /* Tx BD Ready */
+#define OETH_TX_BD_IRQ          0x4000 /* Tx BD IRQ Enable */
+#define OETH_TX_BD_WRAP         0x2000 /* Tx BD Wrap (last BD) */
+#define OETH_TX_BD_PAD          0x1000 /* Tx BD Pad Enable */
+#define OETH_TX_BD_CRC          0x0800 /* Tx BD CRC Enable */
+                                
+#define OETH_TX_BD_UNDERRUN     0x0100 /* Tx BD Underrun Status */
+#define OETH_TX_BD_RETRY        0x00F0 /* Tx BD Retry Status */
+#define OETH_TX_BD_RETLIM       0x0008 /* Tx BD Retransmission Limit Status */
+#define OETH_TX_BD_LATECOL      0x0004 /* Tx BD Late Collision Status */
+#define OETH_TX_BD_DEFER        0x0002 /* Tx BD Defer Status */
+#define OETH_TX_BD_CARRIER      0x0001 /* Tx BD Carrier Sense Lost Status */
+#define OETH_TX_BD_STATS        (OETH_TX_BD_UNDERRUN            | \
+                                OETH_TX_BD_RETRY                | \
+                                OETH_TX_BD_RETLIM               | \
+                                OETH_TX_BD_LATECOL              | \
+                                OETH_TX_BD_DEFER                | \
+                                OETH_TX_BD_CARRIER)
+                                
+/* Rx BD */                     
+#define OETH_RX_BD_EMPTY        0x8000 /* Rx BD Empty */
+#define OETH_RX_BD_IRQ          0x4000 /* Rx BD IRQ Enable */
+#define OETH_RX_BD_WRAP         0x2000 /* Rx BD Wrap (last BD) */
+                                
+#define OETH_RX_BD_MISS         0x0080 /* Rx BD Miss Status */
+#define OETH_RX_BD_OVERRUN      0x0040 /* Rx BD Overrun Status */
+#define OETH_RX_BD_INVSIMB      0x0020 /* Rx BD Invalid Symbol Status */
+#define OETH_RX_BD_DRIBBLE      0x0010 /* Rx BD Dribble Nibble Status */
+#define OETH_RX_BD_TOOLONG      0x0008 /* Rx BD Too Long Status */
+#define OETH_RX_BD_SHORT        0x0004 /* Rx BD Too Short Frame Status */
+#define OETH_RX_BD_CRCERR       0x0002 /* Rx BD CRC Error Status */
+#define OETH_RX_BD_LATECOL      0x0001 /* Rx BD Late Collision Status */
+#define OETH_RX_BD_STATS        (OETH_RX_BD_MISS                | \
+                                OETH_RX_BD_OVERRUN              | \
+                                OETH_RX_BD_INVSIMB              | \
+                                OETH_RX_BD_DRIBBLE              | \
+                                OETH_RX_BD_TOOLONG              | \
+                                OETH_RX_BD_SHORT                | \
+                                OETH_RX_BD_CRCERR               | \
+                                OETH_RX_BD_LATECOL)
+
+/* MODER Register */
+#define OETH_MODER_RXEN         0x00000001 /* Receive Enable  */
+#define OETH_MODER_TXEN         0x00000002 /* Transmit Enable */
+#define OETH_MODER_NOPRE        0x00000004 /* No Preamble  */
+#define OETH_MODER_BRO          0x00000008 /* Reject Broadcast */
+#define OETH_MODER_IAM          0x00000010 /* Use Individual Hash */
+#define OETH_MODER_PRO          0x00000020 /* Promiscuous (receive all) */
+#define OETH_MODER_IFG          0x00000040 /* Min. IFG not required */
+#define OETH_MODER_LOOPBCK      0x00000080 /* Loop Back */
+#define OETH_MODER_NOBCKOF      0x00000100 /* No Backoff */
+#define OETH_MODER_EXDFREN      0x00000200 /* Excess Defer */
+#define OETH_MODER_FULLD        0x00000400 /* Full Duplex */
+#define OETH_MODER_RST          0x00000800 /* Reset MAC */
+#define OETH_MODER_DLYCRCEN     0x00001000 /* Delayed CRC Enable */
+#define OETH_MODER_CRCEN        0x00002000 /* CRC Enable */
+#define OETH_MODER_HUGEN        0x00004000 /* Huge Enable */
+#define OETH_MODER_PAD          0x00008000 /* Pad Enable */
+#define OETH_MODER_RECSMALL     0x00010000 /* Receive Small */
+ 
+/* Interrupt Source Register */
+#define OETH_INT_TXB            0x00000001 /* Transmit Buffer IRQ */
+#define OETH_INT_TXE            0x00000002 /* Transmit Error IRQ */
+#define OETH_INT_RXF            0x00000004 /* Receive Frame IRQ */
+#define OETH_INT_RXE            0x00000008 /* Receive Error IRQ */
+#define OETH_INT_BUSY           0x00000010 /* Busy IRQ */
+#define OETH_INT_TXC            0x00000020 /* Transmit Control Frame IRQ */
+#define OETH_INT_RXC            0x00000040 /* Received Control Frame IRQ */
+
+/* Interrupt Mask Register */
+#define OETH_INT_MASK_TXB       0x00000001 /* Transmit Buffer IRQ Mask */
+#define OETH_INT_MASK_TXE       0x00000002 /* Transmit Error IRQ Mask */
+#define OETH_INT_MASK_RXF       0x00000004 /* Receive Frame IRQ Mask */
+#define OETH_INT_MASK_RXE       0x00000008 /* Receive Error IRQ Mask */
+#define OETH_INT_MASK_BUSY      0x00000010 /* Busy IRQ Mask */
+#define OETH_INT_MASK_TXC       0x00000020 /* Transmit Control Frame IRQ Mask */
+#define OETH_INT_MASK_RXC       0x00000040 /* Received Control Frame IRQ Mask */
+ 
+/* Control Module Mode Register */
+#define OETH_CTRLMODER_PASSALL  0x00000001 /* Pass Control Frames */
+#define OETH_CTRLMODER_RXFLOW   0x00000002 /* Receive Control Flow Enable */
+#define OETH_CTRLMODER_TXFLOW   0x00000004 /* Transmit Control Flow Enable */
+                               
+/* MII Mode Register */        
+#define OETH_MIIMODER_CLKDIV    0x000000FF /* Clock Divider */
+#define OETH_MIIMODER_NOPRE     0x00000100 /* No Preamble */
+#define OETH_MIIMODER_RST       0x00000200 /* MIIM Reset */
+ 
+/* MII Command Register */
+#define OETH_MIICOMMAND_SCANSTAT  0x00000001 /* Scan Status */
+#define OETH_MIICOMMAND_RSTAT     0x00000002 /* Read Status */
+#define OETH_MIICOMMAND_WCTRLDATA 0x00000004 /* Write Control Data */
+ 
+/* MII Address Register */
+#define OETH_MIIADDRESS_FIAD    0x0000001F /* PHY Address */
+  //;dgt;May2005-note Mx Altera Nios (CONFIG_EXCALIBUR) with
+  //; a TDK78Q2120 phy does NOT use OETH_MIIADDRESS_FIAD, but
+  //; instead uses its own PHY_ADDRESS (0x00 = "broadcast"
+  //; phy address) invention
+  //;dgt:IIRC, Mx Tdk's USED to use address 0x1F but changed some
+  //; undocumented time ago...
+#define OETH_MIIADDRESS_RGAD    0x00001F00 /* RGAD Address */
+ 
+/* MII Status Register */
+#define OETH_MIISTATUS_LINKFAIL 0x00000001 /* Link Fail */
+#define OETH_MIISTATUS_BUSY     0x00000002 /* MII Busy */
+#define OETH_MIISTATUS_NVALID   0x00000004 /* Data in MII Status Register is invalid */
+
+/*----------------------------------------------------------------------*/
+
+    #define OETH_IO_EXTENT      0x800
+
+/*----------------------------------------------------------------------*/
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 03422ce..56133ef 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1458,4 +1458,58 @@ config SERIAL_TIMBERDALE
 	---help---
 	Add support for UART controller on timberdale.
 
+config SERIAL_ALTERA_JTAGUART
+	bool "Altera JTAG UART support"
+	depends on  EMBEDDED
+	select SERIAL_CORE
+	help
+	  This driver supports the Altera JTAG UART port.
+
+config SERIAL_ALTERA_JTAGUART_CONSOLE
+	bool "Altera JTAG UART console support"
+	depends on SERIAL_ALTERA_JTAGUART
+	select SERIAL_CORE_CONSOLE
+	help
+	  Enable a Altera JTAG UART port to be the system console.
+
+config SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS
+	bool "Bypass output when no connection"
+	depends on SERIAL_ALTERA_JTAGUART_CONSOLE
+	select SERIAL_CORE_CONSOLE
+	help
+	  Bypass console output and keep going even if there is no
+	  JTAG terminal connection with PC.
+
+config SERIAL_ALTERA_UART
+	bool "Altera UART support"
+	depends on  EMBEDDED
+	select SERIAL_CORE
+	help
+	  This driver supports the Altera softcore UART port.
+
+config SERIAL_ALTERA_UART_MAXPORTS
+	int "Maximum number of Altera UART ports"
+	depends on SERIAL_ALTERA_UART
+	default 4
+	help
+	  This setting lets you define the maximum number of the Altera
+	  UART ports. The usual default varies from board to board, and
+	  this setting is a way of catering for that.
+
+config SERIAL_ALTERA_UART_BAUDRATE
+	int "Default baudrate for Altera UART ports"
+	depends on SERIAL_ALTERA_UART
+	default 115200
+	help
+	  This setting lets you define what the default baudrate is for the
+	  Altera UART ports. The usual default varies from board to board,
+	  and this setting is a way of catering for that.
+
+config SERIAL_ALTERA_UART_CONSOLE
+	bool "Altera UART console support"
+	depends on SERIAL_ALTERA_UART
+	select SERIAL_CORE_CONSOLE
+	help
+	  Enable a Altera UART port to be the system console.
+
 endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 97f6fcc..8dc3a21 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -80,3 +80,5 @@ obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
 obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
 obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
 obj-$(CONFIG_SERIAL_TIMBERDALE)	+= timbuart.o
+obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altjuart.o
+obj-$(CONFIG_SERIAL_ALTERA_UART) += altuart.o
diff --git a/drivers/serial/altjuart.c b/drivers/serial/altjuart.c
new file mode 100644
index 0000000..b3f2568
--- /dev/null
+++ b/drivers/serial/altjuart.c
@@ -0,0 +1,493 @@
+/*
+ * altjuart.c -- Altera JTAG UART driver
+ *
+ * Based on mcf.c -- Freescale ColdFire UART driver
+ *
+ * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com>
+ * (C) Copyright 2008, Thomas Chou <thomas@wytron.com.tw>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+#include <linux/altjuart.h>
+
+/*
+ * Altera JATG UART reg defs
+ */
+
+#define ALTERA_JTAGUART_SIZE                      8
+
+#define ALTERA_JTAGUART_DATA_REG                  0
+
+#define ALTERA_JTAGUART_DATA_DATA_MSK             (0x000000FF)
+#define ALTERA_JTAGUART_DATA_RVALID_MSK           (0x00008000)
+#define ALTERA_JTAGUART_DATA_RAVAIL_MSK           (0xFFFF0000)
+#define ALTERA_JTAGUART_DATA_RAVAIL_OFST          (16)
+
+#define ALTERA_JTAGUART_CONTROL_REG               4
+
+#define ALTERA_JTAGUART_CONTROL_RE_MSK            (0x00000001)
+#define ALTERA_JTAGUART_CONTROL_WE_MSK            (0x00000002)
+#define ALTERA_JTAGUART_CONTROL_RI_MSK            (0x00000100)
+#define ALTERA_JTAGUART_CONTROL_RI_OFST           (8)
+#define ALTERA_JTAGUART_CONTROL_WI_MSK            (0x00000200)
+#define ALTERA_JTAGUART_CONTROL_AC_MSK            (0x00000400)
+#define ALTERA_JTAGUART_CONTROL_WSPACE_MSK        (0xFFFF0000)
+#define ALTERA_JTAGUART_CONTROL_WSPACE_OFST       (16)
+
+/*
+ * Local per-uart structure.
+ */
+struct altera_jtaguart {
+	struct uart_port port;
+	unsigned int sigs;	/* Local copy of line sigs */
+	unsigned long imr;	/* Local IMR mirror */
+};
+
+static unsigned int altera_jtaguart_tx_empty(struct uart_port *port)
+{
+	return (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) &
+		ALTERA_JTAGUART_CONTROL_WSPACE_MSK) ? TIOCSER_TEMT : 0;
+}
+
+static unsigned int altera_jtaguart_get_mctrl(struct uart_port *port)
+{
+	return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+}
+
+static void altera_jtaguart_set_mctrl(struct uart_port *port, unsigned int sigs)
+{
+}
+
+static void altera_jtaguart_start_tx(struct uart_port *port)
+{
+	struct altera_jtaguart *pp =
+	    container_of(port, struct altera_jtaguart, port);
+
+	pp->imr |= ALTERA_JTAGUART_CONTROL_WE_MSK;
+	writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG);
+}
+
+static void altera_jtaguart_stop_tx(struct uart_port *port)
+{
+	struct altera_jtaguart *pp =
+	    container_of(port, struct altera_jtaguart, port);
+
+	pp->imr &= ~ALTERA_JTAGUART_CONTROL_WE_MSK;
+	writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG);
+}
+
+static void altera_jtaguart_stop_rx(struct uart_port *port)
+{
+	struct altera_jtaguart *pp =
+	    container_of(port, struct altera_jtaguart, port);
+
+	pp->imr &= ~ALTERA_JTAGUART_CONTROL_RE_MSK;
+	writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG);
+}
+
+static void altera_jtaguart_break_ctl(struct uart_port *port, int break_state)
+{
+}
+
+static void altera_jtaguart_enable_ms(struct uart_port *port)
+{
+}
+
+static int altera_jtaguart_startup(struct uart_port *port)
+{
+	struct altera_jtaguart *pp =
+	    container_of(port, struct altera_jtaguart, port);
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	/* Enable RX interrupts now */
+	pp->imr = ALTERA_JTAGUART_CONTROL_RE_MSK;
+	writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	return 0;
+}
+
+static void altera_jtaguart_shutdown(struct uart_port *port)
+{
+	struct altera_jtaguart *pp =
+	    container_of(port, struct altera_jtaguart, port);
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	/* Disable all interrupts now */
+	pp->imr = 0;
+	writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void altera_jtaguart_set_termios(struct uart_port *port,
+					struct ktermios *termios,
+					struct ktermios *old)
+{
+}
+
+static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp)
+{
+	struct uart_port *port = &pp->port;
+	unsigned char ch, flag;
+	unsigned long status;
+
+	while ((status = readl(port->membase + ALTERA_JTAGUART_DATA_REG)) &
+	       ALTERA_JTAGUART_DATA_RVALID_MSK) {
+		ch = status & ALTERA_JTAGUART_DATA_DATA_MSK;
+		flag = TTY_NORMAL;
+		port->icount.rx++;
+
+		if (uart_handle_sysrq_char(port, ch))
+			continue;
+		uart_insert_char(port, 0, 0, ch, flag);
+	}
+
+	tty_flip_buffer_push(port->state->port.tty);
+}
+
+static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp)
+{
+	struct uart_port *port = &pp->port;
+	struct circ_buf *xmit = &port->state->xmit;
+	unsigned int pending, count;
+
+	spin_lock(&port->lock);
+
+	if (port->x_char) {
+		/* Send special char - probably flow control */
+		writel(port->x_char, port->membase + ALTERA_JTAGUART_DATA_REG);
+		port->x_char = 0;
+		port->icount.tx++;
+		spin_unlock(&port->lock);
+		return;
+	}
+
+	pending = uart_circ_chars_pending(xmit);
+	if (pending > 0) {
+		count = (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) &
+				ALTERA_JTAGUART_CONTROL_WSPACE_MSK) >>
+			ALTERA_JTAGUART_CONTROL_WSPACE_OFST;
+		if (count > pending)
+			count = pending;
+		if (count > 0) {
+			pending -= count;
+			while (count--) {
+				writel(xmit->buf[xmit->tail],
+					port->membase + ALTERA_JTAGUART_DATA_REG);
+				xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+				port->icount.tx++;
+			}
+			if (pending < WAKEUP_CHARS)
+				uart_write_wakeup(port);
+		}
+	}
+
+	if (pending == 0) {
+		pp->imr &= ~ALTERA_JTAGUART_CONTROL_WE_MSK;
+		writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG);
+	}
+
+	spin_unlock(&port->lock);
+}
+
+static irqreturn_t altera_jtaguart_interrupt(int irq, void *data)
+{
+	struct uart_port *port = data;
+	struct altera_jtaguart *pp =
+	    container_of(port, struct altera_jtaguart, port);
+	unsigned int isr;
+
+	isr =
+	    (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) >>
+	     ALTERA_JTAGUART_CONTROL_RI_OFST) & pp->imr;
+	if (isr & ALTERA_JTAGUART_CONTROL_RE_MSK)
+		altera_jtaguart_rx_chars(pp);
+	if (isr & ALTERA_JTAGUART_CONTROL_WE_MSK)
+		altera_jtaguart_tx_chars(pp);
+	return IRQ_RETVAL(isr);
+}
+
+static void altera_jtaguart_config_port(struct uart_port *port, int flags)
+{
+	port->type = PORT_ALTERA_JTAGUART;
+
+	/* Clear mask, so no surprise interrupts. */
+	writel(0, port->membase + ALTERA_JTAGUART_CONTROL_REG);
+
+	if (request_irq
+	    (port->irq, altera_jtaguart_interrupt, IRQF_DISABLED,
+	     "JTAGUART", port))
+		printk(KERN_ERR
+		       "ALTERA_JTAGUART: unable to attach Altera JTAG UART %d "
+		       "interrupt vector=%d\n", port->line, port->irq);
+}
+
+static const char *altera_jtaguart_type(struct uart_port *port)
+{
+	return (port->type == PORT_ALTERA_JTAGUART) ? "Altera JTAG UART" : NULL;
+}
+
+static int altera_jtaguart_request_port(struct uart_port *port)
+{
+	/* UARTs always present */
+	return 0;
+}
+
+static void altera_jtaguart_release_port(struct uart_port *port)
+{
+	/* Nothing to release... */
+}
+
+static int altera_jtaguart_verify_port(struct uart_port *port,
+				       struct serial_struct *ser)
+{
+	if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_ALTERA_JTAGUART))
+		return -EINVAL;
+	return 0;
+}
+
+/*
+ *	Define the basic serial functions we support.
+ */
+static struct uart_ops altera_jtaguart_ops = {
+	.tx_empty = altera_jtaguart_tx_empty,
+	.get_mctrl = altera_jtaguart_get_mctrl,
+	.set_mctrl = altera_jtaguart_set_mctrl,
+	.start_tx = altera_jtaguart_start_tx,
+	.stop_tx = altera_jtaguart_stop_tx,
+	.stop_rx = altera_jtaguart_stop_rx,
+	.enable_ms = altera_jtaguart_enable_ms,
+	.break_ctl = altera_jtaguart_break_ctl,
+	.startup = altera_jtaguart_startup,
+	.shutdown = altera_jtaguart_shutdown,
+	.set_termios = altera_jtaguart_set_termios,
+	.type = altera_jtaguart_type,
+	.request_port = altera_jtaguart_request_port,
+	.release_port = altera_jtaguart_release_port,
+	.config_port = altera_jtaguart_config_port,
+	.verify_port = altera_jtaguart_verify_port,
+};
+
+#define ALTERA_JTAGUART_MAXPORTS 1
+static struct altera_jtaguart altera_jtaguart_ports[ALTERA_JTAGUART_MAXPORTS];
+
+#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE)
+
+int __init early_altera_jtaguart_setup(struct altera_jtaguart_platform_uart
+				       *platp)
+{
+	struct uart_port *port;
+	int i;
+
+	for (i = 0; (i < ALTERA_JTAGUART_MAXPORTS) && (platp[i].mapbase); i++) {
+		port = &altera_jtaguart_ports[i].port;
+
+		port->line = i;
+		port->type = PORT_ALTERA_JTAGUART;
+		port->mapbase = platp[i].mapbase;
+		port->membase = ioremap(port->mapbase, ALTERA_JTAGUART_SIZE);
+		port->iotype = SERIAL_IO_MEM;
+		port->irq = platp[i].irq;
+		port->flags = ASYNC_BOOT_AUTOCONF;
+		port->ops = &altera_jtaguart_ops;
+	}
+
+	return 0;
+}
+
+#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
+static void altera_jtaguart_console_putc(struct console *co, const char c)
+{
+	struct uart_port *port = &(altera_jtaguart_ports + co->index)->port;
+	unsigned long status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	while (((status = readl(port->membase + ALTERA_JTAGUART_CONTROL_REG)) &
+		ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) {
+		if ((status & ALTERA_JTAGUART_CONTROL_AC_MSK) == 0) {
+			spin_unlock_irqrestore(&port->lock, flags);
+			return;	/* no connection activity */
+		}
+		spin_unlock_irqrestore(&port->lock, flags);
+		cpu_relax();
+		spin_lock_irqsave(&port->lock, flags);
+	}
+	writel(c, port->membase + ALTERA_JTAGUART_DATA_REG);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+#else
+static void altera_jtaguart_console_putc(struct console *co, const char c)
+{
+	struct uart_port *port = &(altera_jtaguart_ports + co->index)->port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	while ((readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) &
+		ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) {
+		spin_unlock_irqrestore(&port->lock, flags);
+		cpu_relax();
+		spin_lock_irqsave(&port->lock, flags);
+	}
+	writel(c, port->membase + ALTERA_JTAGUART_DATA_REG);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+#endif
+
+static void altera_jtaguart_console_write(struct console *co, const char *s,
+					  unsigned int count)
+{
+	for (; count; count--, s++) {
+		altera_jtaguart_console_putc(co, *s);
+		if (*s == '\n')
+			altera_jtaguart_console_putc(co, '\r');
+	}
+}
+
+static int __init altera_jtaguart_console_setup(struct console *co,
+						char *options)
+{
+	struct uart_port *port;
+
+	if ((co->index >= 0)
+	    && (co->index <= ALTERA_JTAGUART_MAXPORTS))
+		co->index = 0;
+	port = &altera_jtaguart_ports[co->index].port;
+	if (port->membase == 0)
+		return -ENODEV;
+	return 0;
+}
+
+static struct uart_driver altera_jtaguart_driver;
+
+static struct console altera_jtaguart_console = {
+	.name = "ttyJ",
+	.write = altera_jtaguart_console_write,
+	.device = uart_console_device,
+	.setup = altera_jtaguart_console_setup,
+	.flags = CON_PRINTBUFFER,
+	.index = -1,
+	.data = &altera_jtaguart_driver,
+};
+
+static int __init altera_jtaguart_console_init(void)
+{
+	register_console(&altera_jtaguart_console);
+	return 0;
+}
+
+console_initcall(altera_jtaguart_console_init);
+
+#define	ALTERA_JTAGUART_CONSOLE	&altera_jtaguart_console
+
+#else
+
+#define	ALTERA_JTAGUART_CONSOLE	NULL
+
+#endif /* CONFIG_ALTERA_JTAGUART_CONSOLE */
+
+/*
+ *	Define the altera_jtaguart UART driver structure.
+ */
+static struct uart_driver altera_jtaguart_driver = {
+	.owner = THIS_MODULE,
+	.driver_name = "altera_jtaguart",
+	.dev_name = "ttyJ",
+	.major = 232,
+	.minor = 16,
+	.nr = ALTERA_JTAGUART_MAXPORTS,
+	.cons = ALTERA_JTAGUART_CONSOLE,
+};
+
+static int __devinit altera_jtaguart_probe(struct platform_device *pdev)
+{
+	struct altera_jtaguart_platform_uart *platp = pdev->dev.platform_data;
+	struct uart_port *port;
+	int i;
+
+	for (i = 0; (i < ALTERA_JTAGUART_MAXPORTS) && (platp[i].mapbase); i++) {
+		port = &altera_jtaguart_ports[i].port;
+
+		port->line = i;
+		port->type = PORT_ALTERA_JTAGUART;
+		port->mapbase = platp[i].mapbase;
+		port->membase = ioremap(port->mapbase, ALTERA_JTAGUART_SIZE);
+		port->iotype = SERIAL_IO_MEM;
+		port->irq = platp[i].irq;
+		port->ops = &altera_jtaguart_ops;
+		port->flags = ASYNC_BOOT_AUTOCONF;
+
+		uart_add_one_port(&altera_jtaguart_driver, port);
+	}
+
+	return 0;
+}
+
+static int __devexit altera_jtaguart_remove(struct platform_device *pdev)
+{
+	struct uart_port *port;
+	int i;
+
+	for (i = 0; i < ALTERA_JTAGUART_MAXPORTS; i++) {
+		port = &altera_jtaguart_ports[i].port;
+		if (port)
+			uart_remove_one_port(&altera_jtaguart_driver, port);
+	}
+
+	return 0;
+}
+
+static struct platform_driver altera_jtaguart_platform_driver = {
+	.probe = altera_jtaguart_probe,
+	.remove = __devexit_p(altera_jtaguart_remove),
+	.driver = {
+		.name = "altera_jtaguart",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init altera_jtaguart_init(void)
+{
+	int rc;
+
+	rc = uart_register_driver(&altera_jtaguart_driver);
+	if (rc)
+		return rc;
+	rc = platform_driver_register(&altera_jtaguart_platform_driver);
+	if (rc)
+		return rc;
+	return 0;
+}
+
+static void __exit altera_jtaguart_exit(void)
+{
+	platform_driver_unregister(&altera_jtaguart_platform_driver);
+	uart_unregister_driver(&altera_jtaguart_driver);
+}
+
+module_init(altera_jtaguart_init);
+module_exit(altera_jtaguart_exit);
+
+MODULE_DESCRIPTION("Altera JTAG UART Driver");
+MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/altuart.c b/drivers/serial/altuart.c
new file mode 100644
index 0000000..86785d6
--- /dev/null
+++ b/drivers/serial/altuart.c
@@ -0,0 +1,575 @@
+/*
+ * altuart.c -- Altera UART driver
+ *
+ * Based on mcf.c -- Freescale ColdFire UART driver
+ *
+ * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com>
+ * (C) Copyright 2008, Thomas Chou <thomas@wytron.com.tw>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+#include <linux/altuart.h>
+
+/*
+ * Altera UART reg defs
+ */
+
+#define ALTERA_UART_SIZE                  32
+
+#define ALTERA_UART_RXDATA_REG            0
+#define ALTERA_UART_TXDATA_REG            4
+#define ALTERA_UART_STATUS_REG            8
+#define ALTERA_UART_CONTROL_REG           12
+#define ALTERA_UART_DIVISOR_REG           16
+#define ALTERA_UART_EOP_REG               20
+
+#define ALTERA_UART_STATUS_PE_MSK         (0x1)
+#define ALTERA_UART_STATUS_FE_MSK         (0x2)
+#define ALTERA_UART_STATUS_BRK_MSK        (0x4)
+#define ALTERA_UART_STATUS_ROE_MSK        (0x8)
+#define ALTERA_UART_STATUS_TOE_MSK        (0x10)
+#define ALTERA_UART_STATUS_TMT_MSK        (0x20)
+#define ALTERA_UART_STATUS_TRDY_MSK       (0x40)
+#define ALTERA_UART_STATUS_RRDY_MSK       (0x80)
+#define ALTERA_UART_STATUS_E_MSK          (0x100)
+#define ALTERA_UART_STATUS_DCTS_MSK       (0x400)
+#define ALTERA_UART_STATUS_CTS_MSK        (0x800)
+#define ALTERA_UART_STATUS_EOP_MSK        (0x1000)
+
+#define ALTERA_UART_CONTROL_PE_MSK        (0x1)
+#define ALTERA_UART_CONTROL_FE_MSK        (0x2)
+#define ALTERA_UART_CONTROL_BRK_MSK       (0x4)
+#define ALTERA_UART_CONTROL_ROE_MSK       (0x8)
+#define ALTERA_UART_CONTROL_TOE_MSK       (0x10)
+#define ALTERA_UART_CONTROL_TMT_MSK       (0x20)
+#define ALTERA_UART_CONTROL_TRDY_MSK      (0x40)
+#define ALTERA_UART_CONTROL_RRDY_MSK      (0x80)
+#define ALTERA_UART_CONTROL_E_MSK         (0x100)
+#define ALTERA_UART_CONTROL_TRBK_MSK      (0x200)
+#define ALTERA_UART_CONTROL_DCTS_MSK      (0x400)
+#define ALTERA_UART_CONTROL_RTS_MSK       (0x800)
+#define ALTERA_UART_CONTROL_EOP_MSK       (0x1000)
+
+#define ALTERA_UART_EOP_MSK               (0xFF)
+#define ALTERA_UART_EOP_OFST              (0)
+
+/*
+ * Some boards implement the DTR/DCD lines using GPIO lines, most don't. Dummy
+ * out the access macros for those that don't. Those that do should define these
+ * macros somewhere in there board specific inlude files.
+ */
+#if !defined(altera_uart_getppdcd)
+# define altera_uart_getppdcd(p)	(1)
+#endif
+#if !defined(altera_uart_getppdtr)
+# define altera_uart_getppdtr(p)	(1)
+#endif
+#if !defined(altera_uart_setppdtr)
+# define altera_uart_setppdtr(p, v)	do { } while (0)
+#endif
+
+/*
+ * Local per-uart structure.
+ */
+struct altera_uart {
+	struct uart_port port;
+	unsigned int sigs;	/* Local copy of line sigs */
+	unsigned short imr;	/* Local IMR mirror */
+};
+
+static unsigned int altera_uart_tx_empty(struct uart_port *port)
+{
+	return (readl(port->membase + ALTERA_UART_STATUS_REG) &
+		ALTERA_UART_STATUS_TMT_MSK) ? TIOCSER_TEMT : 0;
+}
+
+static unsigned int altera_uart_get_mctrl(struct uart_port *port)
+{
+	struct altera_uart *pp = container_of(port, struct altera_uart, port);
+	unsigned long flags;
+	unsigned int sigs;
+
+	spin_lock_irqsave(&port->lock, flags);
+	sigs =
+	    (readl(port->membase + ALTERA_UART_STATUS_REG) &
+	     ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0;
+	sigs |= (pp->sigs & TIOCM_RTS);
+	sigs |= (altera_uart_getppdcd(port->line) ? TIOCM_CD : 0);
+	sigs |= (altera_uart_getppdtr(port->line) ? TIOCM_DTR : 0);
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	return sigs;
+}
+
+static void altera_uart_set_mctrl(struct uart_port *port, unsigned int sigs)
+{
+	struct altera_uart *pp = container_of(port, struct altera_uart, port);
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	pp->sigs = sigs;
+	altera_uart_setppdtr(port->line, (sigs & TIOCM_DTR));
+	if (sigs & TIOCM_RTS)
+		pp->imr |= ALTERA_UART_CONTROL_RTS_MSK;
+	else
+		pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK;
+	writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void altera_uart_start_tx(struct uart_port *port)
+{
+	struct altera_uart *pp = container_of(port, struct altera_uart, port);
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK;
+	writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void altera_uart_stop_tx(struct uart_port *port)
+{
+	struct altera_uart *pp = container_of(port, struct altera_uart, port);
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
+	writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void altera_uart_stop_rx(struct uart_port *port)
+{
+	struct altera_uart *pp = container_of(port, struct altera_uart, port);
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK;
+	writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void altera_uart_break_ctl(struct uart_port *port, int break_state)
+{
+	struct altera_uart *pp = container_of(port, struct altera_uart, port);
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	if (break_state == -1)
+		pp->imr |= ALTERA_UART_CONTROL_TRBK_MSK;
+	else
+		pp->imr &= ~ALTERA_UART_CONTROL_TRBK_MSK;
+	writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void altera_uart_enable_ms(struct uart_port *port)
+{
+}
+
+static int altera_uart_startup(struct uart_port *port)
+{
+	struct altera_uart *pp = container_of(port, struct altera_uart, port);
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	/* Enable RX interrupts now */
+	pp->imr = ALTERA_UART_CONTROL_RRDY_MSK;
+	writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	return 0;
+}
+
+static void altera_uart_shutdown(struct uart_port *port)
+{
+	struct altera_uart *pp = container_of(port, struct altera_uart, port);
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	/* Disable all interrupts now */
+	pp->imr = 0;
+	writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void altera_uart_set_termios(struct uart_port *port,
+				    struct ktermios *termios,
+				    struct ktermios *old)
+{
+	unsigned long flags;
+	unsigned int baud, baudclk;
+
+	baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
+	baudclk = port->uartclk / baud;
+
+	spin_lock_irqsave(&port->lock, flags);
+	writel(baudclk, port->membase + ALTERA_UART_DIVISOR_REG);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void altera_uart_rx_chars(struct altera_uart *pp)
+{
+	struct uart_port *port = &pp->port;
+	unsigned char ch, flag;
+	unsigned short status;
+
+	while ((status = readl(port->membase + ALTERA_UART_STATUS_REG)) &
+	       ALTERA_UART_STATUS_RRDY_MSK) {
+		ch = readl(port->membase + ALTERA_UART_RXDATA_REG);
+		flag = TTY_NORMAL;
+		port->icount.rx++;
+
+		if (status & ALTERA_UART_STATUS_E_MSK) {
+			writel(status, port->membase + ALTERA_UART_STATUS_REG);
+
+			if (status & ALTERA_UART_STATUS_BRK_MSK) {
+				port->icount.brk++;
+				if (uart_handle_break(port))
+					continue;
+			} else if (status & ALTERA_UART_STATUS_PE_MSK) {
+				port->icount.parity++;
+			} else if (status & ALTERA_UART_STATUS_ROE_MSK) {
+				port->icount.overrun++;
+			} else if (status & ALTERA_UART_STATUS_FE_MSK) {
+				port->icount.frame++;
+			}
+
+			status &= port->read_status_mask;
+
+			if (status & ALTERA_UART_STATUS_BRK_MSK)
+				flag = TTY_BREAK;
+			else if (status & ALTERA_UART_STATUS_PE_MSK)
+				flag = TTY_PARITY;
+			else if (status & ALTERA_UART_STATUS_FE_MSK)
+				flag = TTY_FRAME;
+		}
+
+		if (uart_handle_sysrq_char(port, ch))
+			continue;
+		uart_insert_char(port, status, ALTERA_UART_STATUS_ROE_MSK, ch,
+				 flag);
+	}
+
+	tty_flip_buffer_push(port->state->port.tty);
+}
+
+static void altera_uart_tx_chars(struct altera_uart *pp)
+{
+	struct uart_port *port = &pp->port;
+	struct circ_buf *xmit = &port->state->xmit;
+
+	if (port->x_char) {
+		/* Send special char - probably flow control */
+		writel(port->x_char, port->membase + ALTERA_UART_TXDATA_REG);
+		port->x_char = 0;
+		port->icount.tx++;
+		return;
+	}
+
+	while (readl(port->membase + ALTERA_UART_STATUS_REG) &
+	       ALTERA_UART_STATUS_TRDY_MSK) {
+		if (xmit->head == xmit->tail)
+			break;
+		writel(xmit->buf[xmit->tail],
+		       port->membase + ALTERA_UART_TXDATA_REG);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+	}
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (xmit->head == xmit->tail) {
+		pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
+		writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+	}
+}
+
+static irqreturn_t altera_uart_interrupt(int irq, void *data)
+{
+	struct uart_port *port = data;
+	struct altera_uart *pp = container_of(port, struct altera_uart, port);
+	unsigned int isr;
+
+	isr = readl(port->membase + ALTERA_UART_STATUS_REG) & pp->imr;
+	if (isr & ALTERA_UART_STATUS_RRDY_MSK)
+		altera_uart_rx_chars(pp);
+	if (isr & ALTERA_UART_STATUS_TRDY_MSK)
+		altera_uart_tx_chars(pp);
+	return IRQ_RETVAL(isr);
+}
+
+static void altera_uart_config_port(struct uart_port *port, int flags)
+{
+	port->type = PORT_ALTERA_UART;
+
+	/* Clear mask, so no surprise interrupts. */
+	writel(0, port->membase + ALTERA_UART_CONTROL_REG);
+
+	if (request_irq
+	    (port->irq, altera_uart_interrupt, IRQF_DISABLED,
+	     "UART", port))
+		printk(KERN_ERR "ALTERA_UART: unable to attach Altera UART %d "
+		       "interrupt vector=%d\n", port->line, port->irq);
+}
+
+static const char *altera_uart_type(struct uart_port *port)
+{
+	return (port->type == PORT_ALTERA_UART) ? "Altera UART" : NULL;
+}
+
+static int altera_uart_request_port(struct uart_port *port)
+{
+	/* UARTs always present */
+	return 0;
+}
+
+static void altera_uart_release_port(struct uart_port *port)
+{
+	/* Nothing to release... */
+}
+
+static int altera_uart_verify_port(struct uart_port *port,
+				   struct serial_struct *ser)
+{
+	if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_ALTERA_UART))
+		return -EINVAL;
+	return 0;
+}
+
+/*
+ *	Define the basic serial functions we support.
+ */
+static struct uart_ops altera_uart_ops = {
+	.tx_empty = altera_uart_tx_empty,
+	.get_mctrl = altera_uart_get_mctrl,
+	.set_mctrl = altera_uart_set_mctrl,
+	.start_tx = altera_uart_start_tx,
+	.stop_tx = altera_uart_stop_tx,
+	.stop_rx = altera_uart_stop_rx,
+	.enable_ms = altera_uart_enable_ms,
+	.break_ctl = altera_uart_break_ctl,
+	.startup = altera_uart_startup,
+	.shutdown = altera_uart_shutdown,
+	.set_termios = altera_uart_set_termios,
+	.type = altera_uart_type,
+	.request_port = altera_uart_request_port,
+	.release_port = altera_uart_release_port,
+	.config_port = altera_uart_config_port,
+	.verify_port = altera_uart_verify_port,
+};
+
+static struct altera_uart altera_uart_ports[CONFIG_SERIAL_ALTERA_UART_MAXPORTS];
+
+#if defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE)
+
+int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp)
+{
+	struct uart_port *port;
+	int i;
+
+	for (i = 0;
+	     (i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS) && (platp[i].mapbase);
+	     i++) {
+		port = &altera_uart_ports[i].port;
+
+		port->line = i;
+		port->type = PORT_ALTERA_UART;
+		port->mapbase = platp[i].mapbase;
+		port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE);
+		port->iotype = SERIAL_IO_MEM;
+		port->irq = platp[i].irq;
+		port->uartclk = platp[i].uartclk;
+		port->flags = ASYNC_BOOT_AUTOCONF;
+		port->ops = &altera_uart_ops;
+	}
+
+	return 0;
+}
+
+static void altera_uart_console_putc(struct console *co, const char c)
+{
+	struct uart_port *port = &(altera_uart_ports + co->index)->port;
+	int i;
+
+	for (i = 0; i < 0x10000; i++) {
+		if (readl(port->membase + ALTERA_UART_STATUS_REG) &
+		    ALTERA_UART_STATUS_TRDY_MSK)
+			break;
+	}
+	writel(c, port->membase + ALTERA_UART_TXDATA_REG);
+	for (i = 0; i < 0x10000; i++) {
+		if (readl(port->membase + ALTERA_UART_STATUS_REG) &
+		    ALTERA_UART_STATUS_TRDY_MSK)
+			break;
+	}
+}
+
+static void altera_uart_console_write(struct console *co, const char *s,
+				      unsigned int count)
+{
+	for (; count; count--, s++) {
+		altera_uart_console_putc(co, *s);
+		if (*s == '\n')
+			altera_uart_console_putc(co, '\r');
+	}
+}
+
+static int __init altera_uart_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = CONFIG_SERIAL_ALTERA_UART_BAUDRATE;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	if ((co->index >= 0)
+	    && (co->index <= CONFIG_SERIAL_ALTERA_UART_MAXPORTS))
+		co->index = 0;
+	port = &altera_uart_ports[co->index].port;
+	if (port->membase == 0)
+		return -ENODEV;
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver altera_uart_driver;
+
+static struct console altera_uart_console = {
+	.name = "ttyS",
+	.write = altera_uart_console_write,
+	.device = uart_console_device,
+	.setup = altera_uart_console_setup,
+	.flags = CON_PRINTBUFFER,
+	.index = -1,
+	.data = &altera_uart_driver,
+};
+
+static int __init altera_uart_console_init(void)
+{
+	register_console(&altera_uart_console);
+	return 0;
+}
+
+console_initcall(altera_uart_console_init);
+
+#define	ALTERA_UART_CONSOLE	&altera_uart_console
+
+#else
+
+#define	ALTERA_UART_CONSOLE	NULL
+
+#endif /* CONFIG_ALTERA_UART_CONSOLE */
+
+/*
+ *	Define the altera_uart UART driver structure.
+ */
+static struct uart_driver altera_uart_driver = {
+	.owner = THIS_MODULE,
+	.driver_name = "altera_uart",
+	.dev_name = "ttyS",
+	.major = TTY_MAJOR,
+	.minor = 64,
+	.nr = CONFIG_SERIAL_ALTERA_UART_MAXPORTS,
+	.cons = ALTERA_UART_CONSOLE,
+};
+
+static int __devinit altera_uart_probe(struct platform_device *pdev)
+{
+	struct altera_uart_platform_uart *platp = pdev->dev.platform_data;
+	struct uart_port *port;
+	int i;
+
+	for (i = 0;
+	     (i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS) && (platp[i].mapbase);
+	     i++) {
+		port = &altera_uart_ports[i].port;
+
+		port->line = i;
+		port->type = PORT_ALTERA_UART;
+		port->mapbase = platp[i].mapbase;
+		port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE);
+		port->iotype = SERIAL_IO_MEM;
+		port->irq = platp[i].irq;
+		port->uartclk = platp[i].uartclk;
+		port->ops = &altera_uart_ops;
+		port->flags = ASYNC_BOOT_AUTOCONF;
+
+		uart_add_one_port(&altera_uart_driver, port);
+	}
+
+	return 0;
+}
+
+static int altera_uart_remove(struct platform_device *pdev)
+{
+	struct uart_port *port;
+	int i;
+
+	for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS; i++) {
+		port = &altera_uart_ports[i].port;
+		if (port)
+			uart_remove_one_port(&altera_uart_driver, port);
+	}
+
+	return 0;
+}
+
+static struct platform_driver altera_uart_platform_driver = {
+	.probe = altera_uart_probe,
+	.remove = __devexit_p(altera_uart_remove),
+	.driver = {
+		.name = "altera_uart",
+		.owner = THIS_MODULE,
+		.pm = NULL,
+	},
+};
+
+static int __init altera_uart_init(void)
+{
+	int rc;
+
+	rc = uart_register_driver(&altera_uart_driver);
+	if (rc)
+		return rc;
+	rc = platform_driver_register(&altera_uart_platform_driver);
+	if (rc)
+		return rc;
+	return 0;
+}
+
+static void __exit altera_uart_exit(void)
+{
+	platform_driver_unregister(&altera_uart_platform_driver);
+	uart_unregister_driver(&altera_uart_driver);
+}
+
+module_init(altera_uart_init);
+module_exit(altera_uart_exit);
+
+MODULE_DESCRIPTION("Altera UART Driver");
+MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 4b6f7cb..7f73b68 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -53,6 +53,13 @@ if SPI_MASTER
 
 comment "SPI Master Controller Drivers"
 
+config SPI_ALTERA
+	tristate "Altera SPI Controller"
+	depends on SPI_MASTER && EMBEDDED
+	select SPI_BITBANG
+	help
+	  This is the driver for the Altera Avalon SPI Controller.
+
 config SPI_ATMEL
 	tristate "Atmel SPI Controller"
 	depends on (ARCH_AT91 || AVR32)
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 6d7a3f8..bd58ca4 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -11,6 +11,7 @@ endif
 obj-$(CONFIG_SPI_MASTER)		+= spi.o
 
 # SPI master controller drivers (bus)
+obj-$(CONFIG_SPI_ALTERA)		+= altspi.o
 obj-$(CONFIG_SPI_ATMEL)			+= atmel_spi.o
 obj-$(CONFIG_SPI_BFIN)			+= spi_bfin5xx.o
 obj-$(CONFIG_SPI_BITBANG)		+= spi_bitbang.o
diff --git a/drivers/spi/altspi.c b/drivers/spi/altspi.c
new file mode 100644
index 0000000..10d3fff
--- /dev/null
+++ b/drivers/spi/altspi.c
@@ -0,0 +1,390 @@
+/*
+ * Altera SPI driver
+ *
+ * Based on spi_s3c24xx.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+
+#include <linux/io.h>
+
+#define ALTERA_SPI_RXDATA	0
+#define ALTERA_SPI_TXDATA       4
+#define ALTERA_SPI_STATUS       8
+#define ALTERA_SPI_CONTROL      12
+#define ALTERA_SPI_SLAVE_SEL    20
+
+#define ALTERA_SPI_STATUS_ROE_MSK              (0x8)
+#define ALTERA_SPI_STATUS_TOE_MSK              (0x10)
+#define ALTERA_SPI_STATUS_TMT_MSK              (0x20)
+#define ALTERA_SPI_STATUS_TRDY_MSK             (0x40)
+#define ALTERA_SPI_STATUS_RRDY_MSK             (0x80)
+#define ALTERA_SPI_STATUS_E_MSK                (0x100)
+
+#define ALTERA_SPI_CONTROL_IROE_MSK            (0x8)
+#define ALTERA_SPI_CONTROL_ITOE_MSK            (0x10)
+#define ALTERA_SPI_CONTROL_ITRDY_MSK           (0x40)
+#define ALTERA_SPI_CONTROL_IRRDY_MSK           (0x80)
+#define ALTERA_SPI_CONTROL_IE_MSK              (0x100)
+#define ALTERA_SPI_CONTROL_SSO_MSK             (0x400)
+
+struct altera_spi {
+	/* bitbang has to be first */
+	struct spi_bitbang bitbang;
+	struct completion done;
+
+	unsigned long base;
+	int irq;
+	int len;
+	int count;
+	int bytes_per_word;
+	unsigned long imr;
+
+	/* data buffers */
+	const unsigned char *tx;
+	unsigned char *rx;
+
+	struct resource *ioarea;
+	struct spi_master *master;
+	struct spi_device *curdev;
+	struct device *dev;
+};
+
+static inline struct altera_spi *to_hw(struct spi_device *sdev)
+{
+	return spi_master_get_devdata(sdev->master);
+}
+
+static void altera_spi_chipsel(struct spi_device *spi, int value)
+{
+	struct altera_spi *hw = to_hw(spi);
+
+	if (spi->mode & SPI_CS_HIGH) {
+		switch (value) {
+		case BITBANG_CS_INACTIVE:
+			writel(1 << spi->chip_select,
+			       hw->base + ALTERA_SPI_SLAVE_SEL);
+			hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
+			writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
+			break;
+
+		case BITBANG_CS_ACTIVE:
+			hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
+			writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
+			writel(0, hw->base + ALTERA_SPI_SLAVE_SEL);
+			break;
+		}
+	} else {
+		switch (value) {
+		case BITBANG_CS_INACTIVE:
+			hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
+			writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
+			break;
+
+		case BITBANG_CS_ACTIVE:
+			writel(1 << spi->chip_select,
+			       hw->base + ALTERA_SPI_SLAVE_SEL);
+			hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
+			writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
+			break;
+		}
+	}
+}
+
+static int altera_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
+{
+	struct altera_spi *hw = to_hw(spi);
+
+	spin_lock(&hw->bitbang.lock);
+	if (!hw->bitbang.busy) {
+		hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);
+		/* need to ndelay for 0.5 clocktick ? */
+	}
+	spin_unlock(&hw->bitbang.lock);
+
+	return 0;
+}
+
+/* the spi->mode bits understood by this driver: */
+#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH)
+
+static int altera_spi_setup(struct spi_device *spi)
+{
+	int ret;
+
+	if (!spi->bits_per_word)
+		spi->bits_per_word = 8;
+
+	if (spi->mode & ~MODEBITS) {
+		dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
+			spi->mode & ~MODEBITS);
+		return -EINVAL;
+	}
+
+	ret = altera_spi_setupxfer(spi, NULL);
+	if (ret < 0) {
+		dev_err(&spi->dev, "setupxfer returned %d\n", ret);
+		return ret;
+	}
+
+	dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n",
+		__func__, spi->mode, spi->bits_per_word, spi->max_speed_hz);
+
+	return 0;
+}
+
+static inline unsigned int hw_txbyte(struct altera_spi *hw, int count)
+{
+	if (hw->tx) {
+		switch (hw->bytes_per_word) {
+		case 1:
+			return hw->tx[count];
+		case 2:
+			return (hw->tx[count * 2] | (hw->tx[count * 2 + 1] << 8));
+		}
+	}
+
+	return 0;
+}
+
+static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
+{
+	struct altera_spi *hw = to_hw(spi);
+
+	dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
+		t->tx_buf, t->rx_buf, t->len);
+
+	hw->tx = t->tx_buf;
+	hw->rx = t->rx_buf;
+	hw->count = 0;
+	hw->bytes_per_word = (t->bits_per_word ? : spi->bits_per_word) / 8;
+	hw->len = t->len / hw->bytes_per_word;
+
+	init_completion(&hw->done);
+
+	/* send the first byte */
+	writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA);
+
+	wait_for_completion(&hw->done);
+
+	return hw->count * hw->bytes_per_word;
+}
+
+static irqreturn_t altera_spi_irq(int irq, void *dev)
+{
+	struct altera_spi *hw = dev;
+	unsigned int spsta = readl(hw->base + ALTERA_SPI_STATUS);
+	unsigned int count = hw->count;
+	unsigned int rxd;
+
+	if (spsta & ALTERA_SPI_STATUS_ROE_MSK) {
+		dev_dbg(hw->dev, "data-collision\n");
+		complete(&hw->done);
+		goto irq_done;
+	}
+
+	if (!(spsta & ALTERA_SPI_STATUS_TRDY_MSK)) {
+		dev_dbg(hw->dev, "spi not ready for tx?\n");
+		complete(&hw->done);
+		goto irq_done;
+	}
+
+	hw->count++;
+
+	rxd = readl(hw->base + ALTERA_SPI_RXDATA);
+	if (hw->rx) {
+		switch (hw->bytes_per_word) {
+		case 1:
+			hw->rx[count] = rxd;
+			break;
+		case 2:
+			hw->rx[count * 2] = rxd;
+			hw->rx[count * 2 + 1] = rxd >> 8;
+			break;
+		}
+	}
+
+	count++;
+
+	if (count < hw->len)
+		writel(hw_txbyte(hw, count), hw->base + ALTERA_SPI_TXDATA);
+	else
+		complete(&hw->done);
+
+irq_done:
+	return IRQ_HANDLED;
+}
+
+static int __init altera_spi_probe(struct platform_device *pdev)
+{
+	struct altera_spi *hw;
+	struct spi_master *master;
+	struct resource *res;
+	int err = 0;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(struct altera_spi));
+	if (master == NULL) {
+		dev_err(&pdev->dev, "No memory for spi_master\n");
+		err = -ENOMEM;
+		goto err_nomem;
+	}
+
+	hw = spi_master_get_devdata(master);
+	memset(hw, 0, sizeof(struct altera_spi));
+
+	hw->master = spi_master_get(master);
+	hw->dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, hw);
+	init_completion(&hw->done);
+
+	/* setup the master state. */
+
+	master->bus_num = pdev->id;
+	master->num_chipselect = 16;
+
+	/* setup the state for the bitbang driver */
+
+	hw->bitbang.master = hw->master;
+	hw->bitbang.setup_transfer = altera_spi_setupxfer;
+	hw->bitbang.chipselect = altera_spi_chipsel;
+	hw->bitbang.txrx_bufs = altera_spi_txrx;
+	hw->bitbang.master->setup = altera_spi_setup;
+
+	dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);
+
+	/* find and map our resources */
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
+		err = -ENOENT;
+		goto err_no_iores;
+	}
+
+	hw->ioarea = request_mem_region(res->start, (res->end - res->start) + 1,
+					pdev->name);
+
+	if (hw->ioarea == NULL) {
+		dev_err(&pdev->dev, "Cannot reserve region\n");
+		err = -ENXIO;
+		goto err_no_iores;
+	}
+
+	hw->base =
+	    (unsigned long)ioremap(res->start, (res->end - res->start) + 1);
+	if (hw->base == 0) {
+		dev_err(&pdev->dev, "Cannot map IO\n");
+		err = -ENXIO;
+		goto err_no_iomap;
+	}
+
+	hw->irq = platform_get_irq(pdev, 0);
+	if (hw->irq < 0) {
+		dev_err(&pdev->dev, "No IRQ specified\n");
+		err = -ENOENT;
+		goto err_no_irq;
+	}
+
+	/* program defaults into the registers */
+	hw->imr = 0;		/* disable spi interrupts */
+	writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
+	writel(0, hw->base + ALTERA_SPI_STATUS);	/* clear status reg */
+	if (readl(hw->base + ALTERA_SPI_STATUS) & ALTERA_SPI_STATUS_RRDY_MSK)
+		readl(hw->base + ALTERA_SPI_RXDATA);	/* flush rxdata */
+
+	err = request_irq(hw->irq, altera_spi_irq, 0, pdev->name, hw);
+	if (err) {
+		dev_err(&pdev->dev, "Cannot claim IRQ\n");
+		goto err_no_irq;
+	}
+
+	/* enable receive interrupt */
+	hw->imr |= ALTERA_SPI_CONTROL_IRRDY_MSK;
+	writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
+
+	/* register our spi controller */
+
+	err = spi_bitbang_start(&hw->bitbang);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to register SPI master\n");
+		goto err_register;
+	}
+
+	return 0;
+
+err_register:
+	free_irq(hw->irq, hw);
+err_no_irq:
+	iounmap((void *)hw->base);
+err_no_iomap:
+	release_resource(hw->ioarea);
+	kfree(hw->ioarea);
+err_no_iores:
+	spi_master_put(hw->master);;
+err_nomem:
+	return err;
+}
+
+static int __exit altera_spi_remove(struct platform_device *dev)
+{
+	struct altera_spi *hw = platform_get_drvdata(dev);
+
+	/* disable spi interrupts */
+	hw->imr = 0;
+	writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
+
+	platform_set_drvdata(dev, NULL);
+
+	spi_unregister_master(hw->master);
+
+	free_irq(hw->irq, hw);
+	iounmap((void *)hw->base);
+
+	release_resource(hw->ioarea);
+	kfree(hw->ioarea);
+
+	spi_master_put(hw->master);
+	return 0;
+}
+
+static struct platform_driver altera_spidrv = {
+	.remove = __exit_p(altera_spi_remove),
+	.driver = {
+		.name = "altspi",
+		.owner = THIS_MODULE,
+		.pm = NULL,
+	},
+};
+
+static int __init altera_spi_init(void)
+{
+	return platform_driver_probe(&altera_spidrv, altera_spi_probe);
+}
+
+static void __exit altera_spi_exit(void)
+{
+	platform_driver_unregister(&altera_spidrv);
+}
+
+module_init(altera_spi_init);
+module_exit(altera_spi_exit);
+
+MODULE_DESCRIPTION("Altera SPI Driver");
+MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 2407508..6cc5b35 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -21,6 +21,7 @@ config USB_ARCH_HAS_HCD
 	default y if USB_ARCH_HAS_EHCI
 	default y if PCMCIA && !M32R			# sl811_cs
 	default y if ARM				# SL-811
+	default y if EMBEDDED
 	default y if SUPERH				# r8a66597-hcd
 	default PCI
 
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index be3c9b8..934b502 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_USB_MON)		+= mon/
 obj-$(CONFIG_PCI)		+= host/
 obj-$(CONFIG_USB_EHCI_HCD)	+= host/
 obj-$(CONFIG_USB_ISP116X_HCD)	+= host/
+obj-$(CONFIG_USB_ISP1362_HCD)	+= host/
 obj-$(CONFIG_USB_OHCI_HCD)	+= host/
 obj-$(CONFIG_USB_UHCI_HCD)	+= host/
 obj-$(CONFIG_USB_FHCI_HCD)	+= host/
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 9b43b22..0268b90 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -144,6 +144,18 @@ config USB_ISP116X_HCD
 	  To compile this driver as a module, choose M here: the
 	  module will be called isp116x-hcd.
 
+config USB_ISP1362_HCD
+	tristate "ISP1362 HCD support"
+	depends on USB
+	default N
+	---help---
+	  Supports the Philips ISP1362 chip as a host controller.
+
+	  This driver does not support isochronous transfers.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called isp1362-hcd.
+
 config USB_ISP1760_HCD
 	tristate "ISP 1760 HCD support"
 	depends on USB && EXPERIMENTAL
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 9bbb285..8bebb12 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2160,6 +2160,16 @@ config FB_BROADSHEET
 	  and could also have been called by other names when coupled with
 	  a bridge adapter.
 
+config FB_ALTERA_VGA
+	tristate "Altera framebuffer support"
+	depends on FB && EMBEDDED
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer driver for the VGA controller 
+	  in Altera Nios forum and the video pipeline of NEEK.
+
 source "drivers/video/omap/Kconfig"
 
 source "drivers/video/backlight/Kconfig"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 80232e1..588d6fe 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -126,6 +126,7 @@ obj-$(CONFIG_FB_SH_MOBILE_LCDC)	  += sh_mobile_lcdcfb.o
 obj-$(CONFIG_FB_OMAP)             += omap/
 obj-$(CONFIG_XEN_FBDEV_FRONTEND)  += xen-fbfront.o
 obj-$(CONFIG_FB_CARMINE)          += carminefb.o
+obj-$(CONFIG_FB_ALTERA_VGA)  	  += altfb.o
 obj-$(CONFIG_FB_MB862XX)	  += mb862xx/
 obj-$(CONFIG_FB_MSM)              += msm/
 
diff --git a/drivers/video/altfb.c b/drivers/video/altfb.c
new file mode 100644
index 0000000..8257e2c
--- /dev/null
+++ b/drivers/video/altfb.c
@@ -0,0 +1,394 @@
+/*
+ *  altfb.c -- Altera framebuffer driver
+ *
+ *  Based on vfb.c -- Virtual frame buffer device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+
+#if defined(CONFIG_ALTERA_NEEK_C3)
+#define SGDMABASE LCD_SGDMA_BASE	/* Altera Video Sync Generator */
+#define XRES 800
+#define YRES 480
+#define BPX  32
+#else
+#define VGABASE VGA_CONTROLLER_0_BASE	/* Altera VGA controller */
+#define XRES 640
+#define YRES 480
+#define BPX  16
+#endif
+
+/*
+ *  RAM we reserve for the frame buffer. This defines the maximum screen
+ *  size
+ *
+ *  The default can be overridden if the driver is compiled as a module
+ */
+
+#define VIDEOMEMSIZE	(XRES * YRES * (BPX>>3))
+
+static struct fb_var_screeninfo altfb_default __initdata = {
+	.xres = XRES,
+	.yres = YRES,
+	.xres_virtual = XRES,
+	.yres_virtual = YRES,
+	.bits_per_pixel = BPX,
+#if (BPX == 16)
+	.red = {11, 5, 0},
+	.green = {5, 6, 0},
+	.blue = {0, 5, 0},
+#else /* BXP == 16 or BXP == 32 */
+	.red = {16, 8, 0},
+	.green = {8, 8, 0},
+	.blue = {0, 8, 0},
+#endif
+	.activate = FB_ACTIVATE_NOW,
+	.height = -1,
+	.width = -1,
+	.vmode = FB_VMODE_NONINTERLACED,
+};
+
+static struct fb_fix_screeninfo altfb_fix __initdata = {
+	.id = "altfb",
+	.type = FB_TYPE_PACKED_PIXELS,
+	.visual = FB_VISUAL_TRUECOLOR,
+	.line_length = (XRES * (BPX >> 3)),
+	.accel = FB_ACCEL_NONE,
+};
+
+static int altfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp, struct fb_info *info)
+{
+	/*
+	 *  Set a single color register. The values supplied have a 32/16 bit
+	 *  magnitude.
+	 *  Return != 0 for invalid regno.
+	 */
+
+	if (regno > 255)
+		return 1;
+#if (BPX == 16)
+	red >>= 11;
+	green >>= 10;
+	blue >>= 11;
+
+	if (regno < 255) {
+		((u32 *) info->pseudo_palette)[regno] = ((red & 31) << 11) |
+		    ((green & 63) << 5) | (blue & 31);
+	}
+#else
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+
+	if (regno < 255) {
+		((u32 *) info->pseudo_palette)[regno] = ((red & 255) << 16) |
+		    ((green & 255) << 8) | (blue & 255);
+	}
+#endif
+	return 0;
+}
+
+static struct fb_ops altfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_setcolreg = altfb_setcolreg,
+};
+
+/*
+ *  Initialization
+ */
+
+#ifdef SGDMABASE
+
+#define ALTERA_SGDMA_IO_EXTENT 0x400
+
+#define ALTERA_SGDMA_STATUS 0
+#define ALTERA_SGDMA_STATUS_BUSY_MSK (0x10)
+
+#define ALTERA_SGDMA_CONTROL 16
+#define ALTERA_SGDMA_CONTROL_RUN_MSK  (0x20)
+#define ALTERA_SGDMA_CONTROL_SOFTWARERESET_MSK (0X10000)
+#define ALTERA_SGDMA_CONTROL_PARK_MSK (0X20000)
+
+#define ALTERA_SGDMA_NEXT_DESC_POINTER 32
+
+/* SGDMA can only transfer this many bytes per descriptor */
+#define DISPLAY_BYTES_PER_DESC 0xFF00UL
+#define ALTERA_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK (0x1)
+#define ALTERA_SGDMA_DESCRIPTOR_CONTROL_GENERATE_SOP_MSK (0x4)
+#define ALTERA_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK (0x80)
+#define DISPLAY_DESC_COUNT(len) (((len) + DISPLAY_BYTES_PER_DESC - 1) \
+				/ DISPLAY_BYTES_PER_DESC)
+#define DISPLAY_DESC_SIZE(len) (DISPLAY_DESC_COUNT(len) \
+				* sizeof(struct sgdma_desc))
+
+struct sgdma_desc {
+	u32 read_addr;
+	u32 read_addr_pad;
+
+	u32 write_addr;
+	u32 write_addr_pad;
+
+	u32 next;
+	u32 next_pad;
+
+	u16 bytes_to_transfer;
+	u8 read_burst;
+	u8 write_burst;
+
+	u16 actual_bytes_transferred;
+	u8 status;
+	u8 control;
+
+} __attribute__ ((packed));
+
+static int __init altfb_dma_start(unsigned long start, unsigned long len,
+				  void *descp)
+{
+	unsigned long base =
+	    (unsigned long)ioremap(SGDMABASE, ALTERA_SGDMA_IO_EXTENT);
+	unsigned long first_desc_phys = start + len;
+	unsigned long next_desc_phys = first_desc_phys;
+	struct sgdma_desc *desc = descp;
+	unsigned ctrl = ALTERA_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK;
+
+	writel(ALTERA_SGDMA_CONTROL_SOFTWARERESET_MSK, \
+	       base + ALTERA_SGDMA_CONTROL);	/* halt current transfer */
+	writel(0, base + ALTERA_SGDMA_CONTROL);	/* disable interrupts */
+	writel(0xff, base + ALTERA_SGDMA_STATUS);	/* clear status */
+	writel(first_desc_phys, base + ALTERA_SGDMA_NEXT_DESC_POINTER);
+
+	while (len) {
+		unsigned long cc = min(len, DISPLAY_BYTES_PER_DESC);
+		next_desc_phys += sizeof(struct sgdma_desc);
+		desc->read_addr = start;
+		desc->next = next_desc_phys;
+		desc->bytes_to_transfer = cc;
+		desc->control = ctrl;
+		start += cc;
+		len -= cc;
+		desc++;
+	}
+
+	desc--;
+	desc->next = first_desc_phys;
+	desc->control = ctrl | ALTERA_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK;
+	desc = descp;
+	desc->control = ctrl | ALTERA_SGDMA_DESCRIPTOR_CONTROL_GENERATE_SOP_MSK;
+	writel(ALTERA_SGDMA_CONTROL_RUN_MSK | ALTERA_SGDMA_CONTROL_PARK_MSK, \
+	       base + ALTERA_SGDMA_CONTROL);	/* start */
+	return 0;
+}
+#else
+
+#define DISPLAY_DESC_SIZE(len) 0
+
+static int __init altfb_dma_start(unsigned long start, unsigned long len,
+				  void *descp)
+{
+	unsigned long base = ioremap(VGABASE, 16);
+	writel(0x0, base + 0);	/* Reset the VGA controller */
+	writel(start, base + 4);	/* Where our frame buffer starts */
+	writel(len, base + 8);	/* buffer size */
+	writel(0x1, base + 0);	/* Set the go bit */
+	return 0;
+}
+#endif
+
+	/* R   G   B */
+#define COLOR_WHITE	{204, 204, 204}
+#define COLOR_AMBAR	{208, 208,   0}
+#define COLOR_CIAN	{  0, 206, 206}
+#define	COLOR_GREEN	{  0, 239,   0}
+#define COLOR_MAGENTA	{239,   0, 239}
+#define COLOR_RED	{205,   0,   0}
+#define COLOR_BLUE	{  0,   0, 255}
+#define COLOR_BLACK	{  0,   0,   0}
+
+struct bar_std {
+	u8 bar[8][3];
+};
+
+/* Maximum number of bars are 10 - otherwise, the input print code
+   should be modified */
+static struct bar_std __initdata bars[] = {
+	{			/* Standard ITU-R color bar sequence */
+	 {
+	  COLOR_WHITE,
+	  COLOR_AMBAR,
+	  COLOR_CIAN,
+	  COLOR_GREEN,
+	  COLOR_MAGENTA,
+	  COLOR_RED,
+	  COLOR_BLUE,
+	  COLOR_BLACK,
+	  }
+	 }
+};
+
+#if (BPX == 16)
+static void __init altfb_color_bar(struct fb_info *info)
+{
+	unsigned short *p = (void *)info->screen_base;
+	unsigned xres = info->var.xres;
+	unsigned xbar = xres / 8;
+	unsigned yres = info->var.yres;
+	unsigned x, y, i;
+	for (y = 0; y < yres; y++) {
+		for (i = 0; i < 8; i++) {
+			unsigned short d;
+			d = bars[0].bar[i][2] >> 3;
+			d |= (bars[0].bar[i][1] << 2) & 0x7e0;
+			d |= (bars[0].bar[i][0] << 8) & 0xf800;
+			for (x = 0; x < xbar; x++)
+				*p++ = d;
+		}
+	}
+}
+#else
+static void __init altfb_color_bar(struct fb_info *info)
+{
+	unsigned *p = (void *)info->screen_base;
+	unsigned xres = info->var.xres;
+	unsigned xbar = xres / 8;
+	unsigned yres = info->var.yres;
+	unsigned x, y, i;
+	for (y = 0; y < yres; y++) {
+		for (i = 0; i < 8; i++) {
+			unsigned d;
+			d = bars[0].bar[i][2];
+			d |= bars[0].bar[i][1] << 8;
+			d |= bars[0].bar[i][0] << 16;
+			for (x = 0; x < xbar; x++)
+				*p++ = d;
+		}
+	}
+}
+#endif
+
+static int __init altfb_probe(struct platform_device *dev)
+{
+	struct fb_info *info;
+	int retval = -ENOMEM;
+	void *fbmem_virt;
+	u8 *desc_virt;
+
+	/* sgdma descriptor table is located at the end of display memory */
+	fbmem_virt = dma_alloc_coherent(NULL,
+					VIDEOMEMSIZE +
+					DISPLAY_DESC_SIZE(VIDEOMEMSIZE),
+					(void *)&altfb_fix.smem_start,
+					GFP_KERNEL);
+	if (!fbmem_virt) {
+		printk(KERN_ERR "altfb: unable to allocate %ld Bytes fb memory\n",
+		       VIDEOMEMSIZE + DISPLAY_DESC_SIZE(VIDEOMEMSIZE));
+		return -ENOMEM;
+	}
+	altfb_fix.smem_len = VIDEOMEMSIZE;
+
+	info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev);
+	if (!info)
+		goto err;
+
+	info->screen_base = fbmem_virt;
+	info->fbops = &altfb_ops;
+	info->var = altfb_default;
+	info->fix = altfb_fix;
+	info->pseudo_palette = info->par;
+	info->par = NULL;
+	info->flags = FBINFO_FLAG_DEFAULT;
+
+	retval = fb_alloc_cmap(&info->cmap, 256, 0);
+	if (retval < 0)
+		goto err1;
+
+	retval = register_framebuffer(info);
+	if (retval < 0)
+		goto err2;
+	platform_set_drvdata(dev, info);
+
+	desc_virt = fbmem_virt;
+	desc_virt += altfb_fix.smem_len;
+	if (altfb_dma_start
+	    (altfb_fix.smem_start, altfb_fix.smem_len, desc_virt))
+		goto err2;
+
+	printk(KERN_INFO "fb%d: %s frame buffer device at 0x%x+0x%x\n",
+	       info->node, info->fix.id, (unsigned)altfb_fix.smem_start,
+	       altfb_fix.smem_len);
+	altfb_color_bar(info);
+	return 0;
+err2:
+	fb_dealloc_cmap(&info->cmap);
+err1:
+	framebuffer_release(info);
+err:
+	dma_free_coherent(NULL, altfb_fix.smem_len, fbmem_virt,
+			  altfb_fix.smem_start);
+	return retval;
+}
+
+static int altfb_remove(struct platform_device *dev)
+{
+	struct fb_info *info = platform_get_drvdata(dev);
+
+	if (info) {
+		unregister_framebuffer(info);
+		dma_free_coherent(NULL, info->fix.smem_len, info->screen_base,
+				  info->fix.smem_start);
+		framebuffer_release(info);
+	}
+	return 0;
+}
+
+static struct platform_driver altfb_driver = {
+	.probe = altfb_probe,
+	.remove = altfb_remove,
+	.driver = {
+		   .name = "altfb",
+		   },
+};
+
+static struct platform_device altfb_device = {
+	.name = "altfb",
+	.id = 0,
+};
+
+static int __init altfb_init(void)
+{
+	int ret = 0;
+
+	ret = platform_driver_register(&altfb_driver);
+
+	if (!ret) {
+		ret = platform_device_register(&altfb_device);
+		if (ret)
+			platform_driver_unregister(&altfb_driver);
+	}
+	return ret;
+}
+
+static void __exit altfb_exit(void)
+{
+	platform_device_unregister(&altfb_device);
+	platform_driver_unregister(&altfb_driver);
+}
+
+module_init(altfb_init);
+module_exit(altfb_exit);
+
+MODULE_DESCRIPTION("Altera framebuffer driver");
+MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3711b88..b4e8d1e 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -850,6 +850,18 @@ config TXX9_WDT
 	help
 	  Hardware driver for the built-in watchdog timer on TXx9 MIPS SoCs.
 
+# NIOS Architecture
+
+config ALTERA_REMOTE_UPDATE_WATCHDOG
+	bool "Enable Remote update watchdog"
+	depends on ALTERA_REMOTE_UPDATE
+	default y
+	help
+	  When enable this feature adds a watchdog device to your system which needs to
+	  be serviced in order for the Remote Update component not to time-out.
+	  If unsure say y.
+
+
 # PARISC Architecture
 
 # POWERPC Architecture
diff --git a/drivers/watchdog/avalonwdt.c b/drivers/watchdog/avalonwdt.c
new file mode 100644
index 0000000..ff37447
--- /dev/null
+++ b/drivers/watchdog/avalonwdt.c
@@ -0,0 +1,220 @@
+/*
+ *	WDT driver for the Nios2
+ *
+ *	(c) Copyright 2005 Walter Goossens <walter.goossens@emdes.nl>
+ *	Neither Walter Goossens nor Emdes Embedded Systems admit liability 
+ *  nor provide warranty for any of this software. This material is 
+ *  provided "AS-IS" and at no charge.
+ *
+ *	Based on wdt.c.
+ *	Original copyright messages:
+ *
+ *	(c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ *				http://www.redhat.com
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ *	Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ *	warranty for any of this software. This material is provided
+ *	"AS-IS" and at no charge.
+ *
+ *	(c) Copyright 1995    Alan Cox <alan@redhat.com>
+ */
+
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+// Change this line if you used another name in your PTF file.
+
+#define AVALON_WDT_BASE		na_watchdog
+#define AVALON_WDT_STATUS	AVALON_WDT_BASE
+#define AVALON_WDT_CONTROL	(AVALON_WDT_BASE + 0x04)
+#define AVALON_WDT_PERIODL	(AVALON_WDT_BASE + 0x08)
+#define AVALON_WDT_PERIODH	(AVALON_WDT_BASE + 0x0C)
+#define AVALON_WDT_SIZE		0x18
+
+#define AVALON_WDT_RUN_BIT	0x04
+
+static unsigned long wdt_is_open;
+
+/**
+ *	avalon_wdt_start:
+ *
+ *	Start the watchdog driver.
+ */
+static int avalon_wdt_start(void) {
+	outw_p(inw_p(AVALON_WDT_CONTROL) | AVALON_WDT_RUN_BIT, AVALON_WDT_CONTROL);
+	printk(KERN_INFO "avalonwdt: Starting watchdog timer\n");
+	return 0;
+}
+
+/**
+ *	avalon_wdt_ping:
+ *
+ *	Reload counter one with the watchdog heartbeat.
+ */
+static int avalon_wdt_ping(void) {
+	//It doesn't matter what value we write
+	outw_p(1,AVALON_WDT_PERIODL);
+	return 0;
+}
+
+/**
+ *	avalon_wdt_write:
+ *	@file: file handle to the watchdog
+ *	@buf: buffer to write (unused as data does not matter here
+ *	@count: count of bytes
+ *	@ppos: pointer to the position to write. No seeks allowed
+ *
+ *	A write to a watchdog device is defined as a keepalive signal. Any
+ *	write of data will do, as we we don't define content meaning.
+ */
+
+static ssize_t avalon_wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) {
+	if(count) {
+		avalon_wdt_ping();
+	}
+	return count;
+}
+
+/**
+ *	avalon_wdt_ioctl:
+ *	@inode: inode of the device
+ *	@file: file handle to the device
+ *	@cmd: watchdog command
+ *	@arg: argument pointer
+ *
+ *	The watchdog API defines a common set of functions for all watchdogs
+ *	according to their available features. We only actually usefully support
+ *	querying capabilities and current status.
+ */
+
+static int avalon_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) {
+	void __user *argp = (void __user *)arg;
+
+	static struct watchdog_info ident = {
+		.options =	WDIOF_KEEPALIVEPING,
+		.firmware_version =	1,
+		.identity =		"Nios2_avalon_wdt",
+	};
+
+	switch(cmd) {
+		case WDIOC_GETSUPPORT:
+			return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
+		case WDIOC_KEEPALIVE:
+			avalon_wdt_ping();
+			return 0;
+		default:
+			return -ENOIOCTLCMD;
+	}
+}
+
+/**
+ *	avalon_wdt_open:
+ *	@inode: inode of device
+ *	@file: file handle to device
+ *
+ *	The watchdog device has been opened. The watchdog device is single
+ *	open and on opening we load the counters. 
+ *  The timeout depends on the value you selected in SOPC-builder.
+ */
+static int avalon_wdt_open(struct inode *inode, struct file *file) {
+	if(test_and_set_bit(0, &wdt_is_open))
+		return -EBUSY;
+	avalon_wdt_start();
+	return nonseekable_open(inode, file);
+}
+
+/**
+ *	avalon_wdt_release:
+ *	@inode: inode to board
+ *	@file: file handle to board
+ *
+ */
+static int avalon_wdt_release(struct inode *inode, struct file *file) {
+	clear_bit(0, &wdt_is_open);
+	printk(KERN_CRIT "avalonwdt: WDT device closed unexpectedly.  WDT will (can) not stop!\n");
+	avalon_wdt_ping();
+	return 0;
+}
+
+/*
+ *	Kernel Interfaces
+ */
+
+static struct file_operations avalon_wdt_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= avalon_wdt_write,
+	.ioctl		= avalon_wdt_ioctl,
+	.open		= avalon_wdt_open,
+	.release	= avalon_wdt_release,
+};
+
+static struct miscdevice avalon_wdt_miscdev = {
+	.minor	= WATCHDOG_MINOR,
+	.name	= "watchdog",
+	.fops	= &avalon_wdt_fops,
+};
+
+/**
+ *	cleanup_module:
+ *
+ *	Unload the watchdog. You cannot do this with any file handles open.
+ *	If your watchdog is set to continue ticking on close and you unload
+ *	it, well it keeps ticking. We won't get the interrupt but the board
+ *	will not touch PC memory so all is fine. You just have to load a new
+ *	module in 30 seconds or reboot.
+ */
+
+static void __exit avalon_wdt_exit(void)
+{
+	misc_deregister(&avalon_wdt_miscdev);
+	release_region(AVALON_WDT_BASE,AVALON_WDT_SIZE);
+}
+
+/**
+ * 	avalon_wdt_init:
+ *
+ *	Set up the WDT watchdog board. All we have to do is grab the
+ *	resources we require and bitch if anyone beat us to them.
+ *	The open() function will actually kick the board off.
+ */
+
+static int __init avalon_wdt_init(void)
+{
+	int ret;
+
+	if (!request_region(AVALON_WDT_BASE, AVALON_WDT_SIZE, "Nios2_avalon_wdt")) {
+		printk(KERN_ERR "wdt: I/O address 0x%08x already in use\n", AVALON_WDT_BASE);
+		return -EBUSY;
+	}
+	ret = misc_register(&avalon_wdt_miscdev);
+	if (ret) {
+		printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret);
+		release_region(AVALON_WDT_BASE,AVALON_WDT_SIZE);
+		return ret;
+	}
+	
+	printk(KERN_INFO "Nios2 Avalon Watchdog driver 0.01 at 0x%08x\n", AVALON_WDT_BASE);
+	return 0;
+}
+
+module_init(avalon_wdt_init);
+module_exit(avalon_wdt_exit);
+
+MODULE_AUTHOR("Walter Goossens");
+MODULE_DESCRIPTION("Driver for Nios2 Watchdog");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_LICENSE("GPL");
diff --git a/fs/drop_caches.c b/fs/drop_caches.c
index 31f4b0e..9fedfdc 100644
--- a/fs/drop_caches.c
+++ b/fs/drop_caches.c
@@ -33,7 +33,7 @@ static void drop_pagecache_sb(struct super_block *sb)
 	iput(toput_inode);
 }
 
-static void drop_pagecache(void)
+void drop_pagecache(void)
 {
 	struct super_block *sb;
 
diff --git a/include/linux/altjuart.h b/include/linux/altjuart.h
new file mode 100644
index 0000000..1f1b4d5
--- /dev/null
+++ b/include/linux/altjuart.h
@@ -0,0 +1,17 @@
+/*
+ * altjuart.h -- Altera JTAG UART driver defines.
+ */
+
+#ifndef	__ALTJUART_H
+#define	__ALTJUART_H
+
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+struct altera_jtaguart_platform_uart {
+	unsigned long mapbase;	/* Physical address base */
+	void __iomem *membase;	/* Virtual address if mapped */
+	unsigned int irq;	/* Interrupt vector */
+};
+
+#endif /* __ALTJUART_H */
diff --git a/include/linux/altuart.h b/include/linux/altuart.h
new file mode 100644
index 0000000..9324cfb
--- /dev/null
+++ b/include/linux/altuart.h
@@ -0,0 +1,18 @@
+/*
+ * altuart.h -- Altera UART driver defines.
+ */
+
+#ifndef	__ALTUART_H
+#define	__ALTUART_H
+
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+struct altera_uart_platform_uart {
+	unsigned long mapbase;	/* Physical address base */
+	void __iomem *membase;	/* Virtual address if mapped */
+	unsigned int irq;	/* Interrupt vector */
+	unsigned int uartclk;	/* UART clock rate */
+};
+
+#endif /* __ALTUART_H */
diff --git a/include/linux/elf-em.h b/include/linux/elf-em.h
index 18bea78..8d04fc2 100644
--- a/include/linux/elf-em.h
+++ b/include/linux/elf-em.h
@@ -33,6 +33,7 @@
 #define EM_H8_300	46	/* Renesas H8/300,300H,H8S */
 #define EM_MN10300	89	/* Panasonic/MEI MN10300, AM33 */
 #define EM_BLACKFIN     106     /* ADI Blackfin Processor */
+#define EM_ALTERA_NIOS2 113	/* Altera Nios II soft-core processor */
 #define EM_FRV		0x5441	/* Fujitsu FR-V */
 #define EM_AVR32	0x18ad	/* Atmel AVR32 */
 
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 24c3956..ba1d5fc 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1288,6 +1288,7 @@ int in_gate_area_no_task(unsigned long addr);
 
 int drop_caches_sysctl_handler(struct ctl_table *, int,
 					void __user *, size_t *, loff_t *);
+void drop_pagecache(void);
 unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask,
 			unsigned long lru_pages);
 
diff --git a/include/linux/nios_mmc.h b/include/linux/nios_mmc.h
new file mode 100644
index 0000000..1e54081
--- /dev/null
+++ b/include/linux/nios_mmc.h
@@ -0,0 +1,74 @@
+#ifndef SDIO_HOST_H_
+#define SDIO_HOST_H_
+
+#include <linux/platform_device.h>
+
+struct nios_mmc_platform_mmc {
+	unsigned long mapbase;	/* Physical address base */
+	void __iomem *membase;	/* Virtual address if mapped */
+	unsigned int irq;	/* Interrupt vector */
+	unsigned int clk_src;	/* Source clock rate */
+};
+/******* SDIO Core defines *******/
+typedef volatile struct
+{
+	void __iomem *base;
+	struct mmc_host *mmc;
+	spinlock_t lock;
+	struct resource *res;
+	int irq;
+	unsigned char dat_width;	/* 1=4-bit mode, 0=1-bit */
+	unsigned char prof_en;
+	/* This should point to current cmd we are processing */
+	struct mmc_command *cmd;
+	unsigned int clock_freq;
+} NIOS_MMC_HOST;
+
+#define NIOS_MMC_REG_CTLSTAT 0*4
+#define NIOS_MMC_REG_CLK_CTL 1*4
+#define NIOS_MMC_REG_CMD_ARG0 2*4
+#define NIOS_MMC_REG_CMD_ARG1 3*4
+#define NIOS_MMC_REG_CMD_ARG2 4*4
+#define NIOS_MMC_REG_CMD_ARG3 5*4
+#define NIOS_MMC_REG_DMA_BASE 6*4
+#define NIOS_MMC_REG_XFER_CTL 7*4
+#define NIOS_MMC_REG_MISC 8*4
+#define NIOS_MMC_REG_PROF_CNT0 9*4
+#define NIOS_MMC_REG_PROF_CNT1 10*4
+#define NIOS_MMC_REG_VERSION_INFO 15*4
+
+#define NIOS_MMC_CTLSTAT_BUSY (1<<0)
+#define NIOS_MMC_CTLSTAT_CD (1<<1)
+#define NIOS_MMC_CTLSTAT_WP (1<<2)
+#define NIOS_MMC_CTLSTAT_CD_IF (1<<3)
+#define NIOS_MMC_CTLSTAT_DEV_IF (1<<4)
+#define NIOS_MMC_CTLSTAT_XFER_IF (1<<5)
+#define NIOS_MMC_CTLSTAT_FRMERR_IF (1<<6)
+#define NIOS_MMC_CTLSTAT_CRCERR_IF (1<<7)
+#define NIOS_MMC_CTLSTAT_TIMEOUTERR_IF (1<<8)
+#define NIOS_MMC_CTLSTAT_FIFO_OVERRUN_IF (1<<9)
+#define NIOS_MMC_CTLSTAT_FIFO_UNDERRUN_IF (1<<10)
+#define NIOS_MMC_CTLSTAT_PROF_EN (1<<13)
+#define NIOS_MMC_CTLSTAT_HOST_4BIT (1<<14)
+#define NIOS_MMC_CTLSTAT_CD_IE (1<<16)
+#define NIOS_MMC_CTLSTAT_XFER_IE (1<<18)
+#define NIOS_MMC_CTLSTAT_BLK_PREFETCH (1<<20)
+#define NIOS_MMC_CTLSTAT_SOFT_RST (1<<31)
+
+#define NIOS_MMC_CLK_CTL_CLK_EN (1<<31)
+#define NIOS_MMC_CLK_CTL_DLY_SHIFT 29
+#define NIOS_MMC_CLK_CTL_INV (1<<28)
+
+#define NIOS_MMC_XFER_CTL_XFER_START (1<<0)
+#define NIOS_MMC_XFER_CTL_CMD_IDX_SHIFT (1)
+#define NIOS_MMC_XFER_CTL_DAT_WIDTH (1<<7)
+#define NIOS_MMC_XFER_CTL_RESP_CODE_SHIFT (8)
+#define NIOS_MMC_XFER_CTL_DAT_RWn (1<<10)
+#define NIOS_MMC_XFER_CTL_RESP_NOCRC (1<<11)
+#define NIOS_MMC_XFER_CTL_BYTE_COUNT_SHIFT (12)
+#define NIOS_MMC_XFER_CTL_BLOCK_COUNT_SHIFT (22)
+
+#define NIOS_MMC_MISC_PROF_RESET (1<<0)
+#define NIOS_MMC_MISC_PROF_CNT_SEL_SHIFT (1)
+
+#endif /*SDIO_HOST_H_*/
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index fe661af..0047bfd 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -159,9 +159,6 @@
 
 #define PORT_SC26XX	82
 
-/* SH-SCI */
-#define PORT_SCIFA	83
-
 #define PORT_S3C6400	84
 
 /* NWPSERIAL */
@@ -176,6 +173,10 @@
 /* Qualcomm MSM SoCs */
 #define PORT_MSM	88
 
+/* Altera UARTs */
+#define PORT_ALTERA_JTAGUART	89
+#define PORT_ALTERA_UART	90
+
 #ifdef __KERNEL__
 
 #include <linux/compiler.h>
diff --git a/Makefile b/Makefile
index 00444a8..8af8487 100644
--- a/Makefile
+++ b/Makefile
@@ -895,6 +895,7 @@ endif
 	$(call vmlinux-modpost)
 	$(call if_changed_rule,vmlinux__)
 	$(Q)rm -f .old_version
+	$(Q)cp vmlinux arch/$(SRCARCH)/boot/vmlinux
 
 # build vmlinux.o first to catch section mismatch errors early
 ifdef CONFIG_KALLSYMS
--- a/arch/nios2/include/asm/custom_fpga.h	2009-10-15 10:10:21.000000000 -0400
+++ b/arch/nios2/include/asm/custom_fpga.h	2009-10-07 15:43:48.000000000 -0400
@@ -4,8 +4,8 @@
 /*
  * This file was automatically generated by the swinfo2header utility.
  *
- * Created from SOPC Builder system 'cycloneIII_embedded_evaluation_kit_web_server_sopc' in
- * file './cycloneIII_embedded_evaluation_kit_web_server_sopc.sopcinfo'.
+ * Created from SOPC Builder system 'cycloneIII_embedded_evaluation_kit_standard_sopc' in
+ * file './cycloneIII_embedded_evaluation_kit_standard_sopc.sopcinfo'.
  */
 
 /*
@@ -30,10 +30,10 @@
 #define CPU_FREQ 100000000u
 #define ICACHE_LINE_SIZE 32
 #define ICACHE_LINE_SIZE_LOG2 5
-#define ICACHE_SIZE 4096
+#define ICACHE_SIZE 8192
 #define DCACHE_LINE_SIZE 32
 #define DCACHE_LINE_SIZE_LOG2 5
-#define DCACHE_SIZE 2048
+#define DCACHE_SIZE 4096
 #define INITDA_SUPPORTED 
 #define FLUSHDA_SUPPORTED 
 #define HAS_JMPI_INSTRUCTION 
@@ -47,8 +47,8 @@
 #define TLB_NUM_WAYS_LOG2 4
 #define TLB_PTR_SZ 8
 #define TLB_NUM_ENTRIES 256
-#define FAST_TLB_MISS_EXCEPTION_ADDR 0xc6000800
-#define EXCEPTION_ADDR 0xc5000020
+#define FAST_TLB_MISS_EXCEPTION_ADDR 0xc9000000
+#define EXCEPTION_ADDR 0xc0000020
 #define RESET_ADDR 0xc4000000
 #define BREAK_ADDR 0xc6000020
 #define HAS_DEBUG_STUB 
@@ -61,7 +61,7 @@
 #define HARDWARE_DIVIDE_PRESENT 0
 #define HARDWARE_MULTIPLY_PRESENT 1
 #define HARDWARE_MULX_PRESENT 0
-#define INST_ADDR_WIDTH 27
+#define INST_ADDR_WIDTH 28
 #define DATA_ADDR_WIDTH 28
 
 /*
@@ -83,7 +83,7 @@
 #define LCD_SGDMA_COMPONENT_NAME lcd_sgdma
 #define LCD_SGDMA_BASE 0x2000000
 #define LCD_SGDMA_SPAN 1024u
-#define LCD_SGDMA_IRQ 2
+#define LCD_SGDMA_IRQ 5
 #define LCD_SGDMA_READ_BLOCK_DATA_WIDTH 64
 #define LCD_SGDMA_WRITE_BLOCK_DATA_WIDTH 64
 #define LCD_SGDMA_STREAM_DATA_WIDTH 64
@@ -131,7 +131,7 @@
 #define EXT_FLASH_BASE 0x4000000
 #define EXT_FLASH_SPAN 16777216u
 #define EXT_FLASH_SETUP_VALUE 25
-#define EXT_FLASH_WAIT_VALUE 70
+#define EXT_FLASH_WAIT_VALUE 100
 #define EXT_FLASH_HOLD_VALUE 20
 #define EXT_FLASH_TIMING_UNITS "ns"
 #define EXT_FLASH_SIZE 16777216u
@@ -151,54 +151,52 @@
 #define SSRAM_SSRAM_READ_LATENCY 2
 
 /*
- * Macros for device 'onchip_memory2_0', class 'altera_avalon_onchip_memory2'
- * The macros are prefixed with 'ONCHIP_MEMORY2_0_'.
+ * Macros for device 'igor_mac', class 'eth_ocm'
+ * The macros are prefixed with 'IGOR_MAC_'.
  * The prefix is the slave descriptor.
  */
-#define ONCHIP_MEMORY2_0_COMPONENT_TYPE altera_avalon_onchip_memory2
-#define ONCHIP_MEMORY2_0_COMPONENT_NAME onchip_memory2_0
-#define ONCHIP_MEMORY2_0_BASE 0x6000800
-#define ONCHIP_MEMORY2_0_SPAN 1024u
-#define ONCHIP_MEMORY2_0_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0
-#define ONCHIP_MEMORY2_0_INIT_CONTENTS_FILE "onchip_memory2_0"
-#define ONCHIP_MEMORY2_0_NON_DEFAULT_INIT_FILE_ENABLED 0
-#define ONCHIP_MEMORY2_0_GUI_RAM_BLOCK_TYPE "Automatic"
-#define ONCHIP_MEMORY2_0_WRITABLE 1
-#define ONCHIP_MEMORY2_0_DUAL_PORT 1
-#define ONCHIP_MEMORY2_0_SIZE_VALUE 1024u
-#define ONCHIP_MEMORY2_0_SIZE_MULTIPLE 1
-#define ONCHIP_MEMORY2_0_CONTENTS_INFO ""
-#define ONCHIP_MEMORY2_0_RAM_BLOCK_TYPE "Auto"
-#define ONCHIP_MEMORY2_0_INIT_MEM_CONTENT 1
-#define ONCHIP_MEMORY2_0_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0
-#define ONCHIP_MEMORY2_0_INSTANCE_ID "NONE"
-#define ONCHIP_MEMORY2_0_READ_DURING_WRITE_MODE "DONT_CARE"
+#define IGOR_MAC_COMPONENT_TYPE eth_ocm
+#define IGOR_MAC_COMPONENT_NAME igor_mac
+#define IGOR_MAC_BASE 0x8000000
+#define IGOR_MAC_SPAN 4096u
+#define IGOR_MAC_IRQ 1
 
 /*
- * Macros for device 'mmc_spi', class 'altera_avalon_spi'
- * The macros are prefixed with 'MMC_SPI_'.
+ * Macros for device 'remote_update', class 'altera_avalon_remote_update_cycloneiii'
+ * The macros are prefixed with 'REMOTE_UPDATE_'.
  * The prefix is the slave descriptor.
  */
-#define MMC_SPI_COMPONENT_TYPE altera_avalon_spi
-#define MMC_SPI_COMPONENT_NAME mmc_spi
-#define MMC_SPI_BASE 0x8000000
-#define MMC_SPI_SPAN 256u
-#define MMC_SPI_IRQ 3
-#define MMC_SPI_DATABITS 8
-#define MMC_SPI_DATAWIDTH 16
-#define MMC_SPI_TARGETCLOCK 20000000u
-#define MMC_SPI_CLOCKUNITS "Hz"
-#define MMC_SPI_CLOCKMULT 1
-#define MMC_SPI_NUMSLAVES 1
-#define MMC_SPI_ISMASTER 1
-#define MMC_SPI_CLOCKPOLARITY 0
-#define MMC_SPI_CLOCKPHASE 0
-#define MMC_SPI_LSBFIRST 0
-#define MMC_SPI_EXTRADELAY 0
-#define MMC_SPI_TARGETSSDELAY "0.0"
-#define MMC_SPI_DELAYUNITS "ns"
-#define MMC_SPI_DELAYMULT "1.0E-9"
-#define MMC_SPI_PREFIX "spi_"
+#define REMOTE_UPDATE_COMPONENT_TYPE altera_avalon_remote_update_cycloneiii
+#define REMOTE_UPDATE_COMPONENT_NAME remote_update
+#define REMOTE_UPDATE_BASE 0x8001000
+#define REMOTE_UPDATE_SPAN 512u
+
+/*
+ * Macros for device 'pll', class 'altera_avalon_pll'
+ * The macros are prefixed with 'PLL_'.
+ * The prefix is the slave descriptor.
+ */
+#define PLL_COMPONENT_TYPE altera_avalon_pll
+#define PLL_COMPONENT_NAME pll
+#define PLL_BASE 0x8001200
+#define PLL_SPAN 64u
+#define PLL_ARESET "None"
+#define PLL_PFDENA "None"
+#define PLL_LOCKED "None"
+#define PLL_PLLENA "None"
+#define PLL_SCANCLK "None"
+#define PLL_SCANDATA "None"
+#define PLL_SCANREAD "None"
+#define PLL_SCANWRITE "None"
+#define PLL_SCANCLKENA "None"
+#define PLL_SCANACLR "None"
+#define PLL_SCANDATAOUT "None"
+#define PLL_SCANDONE "None"
+#define PLL_CONFIGUPDATE "None"
+#define PLL_PHASECOUNTERSELECT "None"
+#define PLL_PHASEDONE "None"
+#define PLL_PHASEUPDOWN "None"
+#define PLL_PHASESTEP "None"
 
 /*
  * Macros for device 'sys_clk_timer', class 'altera_avalon_timer'
@@ -207,9 +205,9 @@
  */
 #define SYS_CLK_TIMER_COMPONENT_TYPE altera_avalon_timer
 #define SYS_CLK_TIMER_COMPONENT_NAME sys_clk_timer
-#define SYS_CLK_TIMER_BASE 0x8000100
-#define SYS_CLK_TIMER_SPAN 256u
-#define SYS_CLK_TIMER_IRQ 8
+#define SYS_CLK_TIMER_BASE 0x8001240
+#define SYS_CLK_TIMER_SPAN 64u
+#define SYS_CLK_TIMER_IRQ 0
 #define SYS_CLK_TIMER_ALWAYS_RUN 0
 #define SYS_CLK_TIMER_FIXED_PERIOD 0
 #define SYS_CLK_TIMER_SNAPSHOT 1
@@ -224,37 +222,67 @@
 #define SYS_CLK_TIMER_TICKS_PER_SEC 100u
 
 /*
- * Macros for device 'sysid', class 'altera_avalon_sysid'
- * The macros are prefixed with 'SYSID_'.
+ * Macros for device 'performance_counter', class 'altera_avalon_performance_counter'
+ * The macros are prefixed with 'PERFORMANCE_COUNTER_'.
  * The prefix is the slave descriptor.
  */
-#define SYSID_COMPONENT_TYPE altera_avalon_sysid
-#define SYSID_COMPONENT_NAME sysid
-#define SYSID_BASE 0x8000200
-#define SYSID_SPAN 64u
-#define SYSID_ID 324290607u
-#define SYSID_TIMESTAMP 1245382019u
+#define PERFORMANCE_COUNTER_COMPONENT_TYPE altera_avalon_performance_counter
+#define PERFORMANCE_COUNTER_COMPONENT_NAME performance_counter
+#define PERFORMANCE_COUNTER_BASE 0x8001280
+#define PERFORMANCE_COUNTER_SPAN 64u
+#define PERFORMANCE_COUNTER_HOW_MANY_SECTIONS 1
 
 /*
- * Macros for device 'ps2_0', class 'altera_up_avalon_ps2_classic'
- * The macros are prefixed with 'PS2_0_'.
+ * Macros for device 'touch_panel_spi', class 'altera_avalon_spi'
+ * The macros are prefixed with 'TOUCH_PANEL_SPI_'.
  * The prefix is the slave descriptor.
  */
-#define PS2_0_COMPONENT_TYPE altera_up_avalon_ps2_classic
-#define PS2_0_COMPONENT_NAME ps2_0
-#define PS2_0_BASE 0x8000240
-#define PS2_0_SPAN 8u
-#define PS2_0_IRQ 1
+#define TOUCH_PANEL_SPI_COMPONENT_TYPE altera_avalon_spi
+#define TOUCH_PANEL_SPI_COMPONENT_NAME touch_panel_spi
+#define TOUCH_PANEL_SPI_BASE 0x80012c0
+#define TOUCH_PANEL_SPI_SPAN 64u
+#define TOUCH_PANEL_SPI_IRQ 3
+#define TOUCH_PANEL_SPI_DATABITS 8
+#define TOUCH_PANEL_SPI_DATAWIDTH 16
+#define TOUCH_PANEL_SPI_TARGETCLOCK 32000u
+#define TOUCH_PANEL_SPI_CLOCKUNITS "Hz"
+#define TOUCH_PANEL_SPI_CLOCKMULT 1
+#define TOUCH_PANEL_SPI_NUMSLAVES 1
+#define TOUCH_PANEL_SPI_ISMASTER 1
+#define TOUCH_PANEL_SPI_CLOCKPOLARITY 0
+#define TOUCH_PANEL_SPI_CLOCKPHASE 0
+#define TOUCH_PANEL_SPI_LSBFIRST 0
+#define TOUCH_PANEL_SPI_EXTRADELAY 0
+#define TOUCH_PANEL_SPI_TARGETSSDELAY "0.0"
+#define TOUCH_PANEL_SPI_DELAYUNITS "ns"
+#define TOUCH_PANEL_SPI_DELAYMULT "1.0E-9"
+#define TOUCH_PANEL_SPI_PREFIX "spi_"
 
 /*
- * Macros for device 'gpio_0', class 'gpio'
- * The macros are prefixed with 'GPIO_0_'.
+ * Macros for device 'mmc_spi', class 'altera_avalon_spi'
+ * The macros are prefixed with 'MMC_SPI_'.
  * The prefix is the slave descriptor.
  */
-#define GPIO_0_COMPONENT_TYPE gpio
-#define GPIO_0_COMPONENT_NAME gpio_0
-#define GPIO_0_BASE 0x8000300
-#define GPIO_0_SPAN 256u
+#define MMC_SPI_COMPONENT_TYPE altera_avalon_spi
+#define MMC_SPI_COMPONENT_NAME mmc_spi
+#define MMC_SPI_BASE 0x8001300
+#define MMC_SPI_SPAN 64u
+#define MMC_SPI_IRQ 8
+#define MMC_SPI_DATABITS 8
+#define MMC_SPI_DATAWIDTH 16
+#define MMC_SPI_TARGETCLOCK 20000000u
+#define MMC_SPI_CLOCKUNITS "Hz"
+#define MMC_SPI_CLOCKMULT 1
+#define MMC_SPI_NUMSLAVES 1
+#define MMC_SPI_ISMASTER 1
+#define MMC_SPI_CLOCKPOLARITY 0
+#define MMC_SPI_CLOCKPHASE 0
+#define MMC_SPI_LSBFIRST 0
+#define MMC_SPI_EXTRADELAY 0
+#define MMC_SPI_TARGETSSDELAY "0.0"
+#define MMC_SPI_DELAYUNITS "ns"
+#define MMC_SPI_DELAYMULT "1.0E-9"
+#define MMC_SPI_PREFIX "spi_"
 
 /*
  * Macros for device 'uart', class 'altera_avalon_uart'
@@ -263,9 +291,9 @@
  */
 #define UART_COMPONENT_TYPE altera_avalon_uart
 #define UART_COMPONENT_NAME uart
-#define UART_BASE 0x8000400
-#define UART_SPAN 256u
-#define UART_IRQ 5
+#define UART_BASE 0x8001340
+#define UART_SPAN 64u
+#define UART_IRQ 6
 #define UART_BAUD 115200
 #define UART_DATA_BITS 8
 #define UART_FIXED_BAUD 1
@@ -276,46 +304,7 @@
 #define UART_USE_EOP_REGISTER 0
 #define UART_SIM_TRUE_BAUD 0
 #define UART_SIM_CHAR_STREAM ""
-#define UART_FREQ 60000000u
-
-/*
- * Macros for device 'jtag_uart', class 'altera_avalon_jtag_uart'
- * The macros are prefixed with 'JTAG_UART_'.
- * The prefix is the slave descriptor.
- */
-#define JTAG_UART_COMPONENT_TYPE altera_avalon_jtag_uart
-#define JTAG_UART_COMPONENT_NAME jtag_uart
-#define JTAG_UART_BASE 0x8002000
-#define JTAG_UART_SPAN 64u
-#define JTAG_UART_IRQ 10
-#define JTAG_UART_WRITE_DEPTH 8
-#define JTAG_UART_READ_DEPTH 8
-#define JTAG_UART_WRITE_THRESHOLD 4
-#define JTAG_UART_READ_THRESHOLD 4
-
-/*
- * Macros for device 'button_pio', class 'altera_avalon_pio'
- * The macros are prefixed with 'BUTTON_PIO_'.
- * The prefix is the slave descriptor.
- */
-#define BUTTON_PIO_COMPONENT_TYPE altera_avalon_pio
-#define BUTTON_PIO_COMPONENT_NAME button_pio
-#define BUTTON_PIO_BASE 0x8004000
-#define BUTTON_PIO_SPAN 128u
-#define BUTTON_PIO_IRQ 12
-#define BUTTON_PIO_DO_TEST_BENCH_WIRING 1
-#define BUTTON_PIO_DRIVEN_SIM_VALUE 0xf
-#define BUTTON_PIO_HAS_TRI 0
-#define BUTTON_PIO_HAS_OUT 0
-#define BUTTON_PIO_HAS_IN 1
-#define BUTTON_PIO_CAPTURE 1
-#define BUTTON_PIO_BIT_CLEARING_EDGE_REGISTER 0
-#define BUTTON_PIO_BIT_MODIFYING_OUTPUT_REGISTER 0
-#define BUTTON_PIO_DATA_WIDTH 4
-#define BUTTON_PIO_RESET_VALUE 0x0
-#define BUTTON_PIO_EDGE_TYPE "RISING"
-#define BUTTON_PIO_IRQ_TYPE "EDGE"
-#define BUTTON_PIO_FREQ 60000000u
+#define UART_FREQ 66500000u
 
 /*
  * Macros for device 'touch_panel_pen_irq_n', class 'altera_avalon_pio'
@@ -324,9 +313,9 @@
  */
 #define TOUCH_PANEL_PEN_IRQ_N_COMPONENT_TYPE altera_avalon_pio
 #define TOUCH_PANEL_PEN_IRQ_N_COMPONENT_NAME touch_panel_pen_irq_n
-#define TOUCH_PANEL_PEN_IRQ_N_BASE 0x8010000
-#define TOUCH_PANEL_PEN_IRQ_N_SPAN 128u
-#define TOUCH_PANEL_PEN_IRQ_N_IRQ 14
+#define TOUCH_PANEL_PEN_IRQ_N_BASE 0x80013e0
+#define TOUCH_PANEL_PEN_IRQ_N_SPAN 32u
+#define TOUCH_PANEL_PEN_IRQ_N_IRQ 4
 #define TOUCH_PANEL_PEN_IRQ_N_DO_TEST_BENCH_WIRING 0
 #define TOUCH_PANEL_PEN_IRQ_N_DRIVEN_SIM_VALUE 0x0
 #define TOUCH_PANEL_PEN_IRQ_N_HAS_TRI 0
@@ -342,284 +331,76 @@
 #define TOUCH_PANEL_PEN_IRQ_N_FREQ 60000000u
 
 /*
- * Macros for device 'touch_panel_spi', class 'altera_avalon_spi'
- * The macros are prefixed with 'TOUCH_PANEL_SPI_'.
+ * Macros for device 'sysid', class 'altera_avalon_sysid'
+ * The macros are prefixed with 'SYSID_'.
  * The prefix is the slave descriptor.
  */
-#define TOUCH_PANEL_SPI_COMPONENT_TYPE altera_avalon_spi
-#define TOUCH_PANEL_SPI_COMPONENT_NAME touch_panel_spi
-#define TOUCH_PANEL_SPI_BASE 0x8011000
-#define TOUCH_PANEL_SPI_SPAN 256u
-#define TOUCH_PANEL_SPI_IRQ 16
-#define TOUCH_PANEL_SPI_DATABITS 8
-#define TOUCH_PANEL_SPI_DATAWIDTH 16
-#define TOUCH_PANEL_SPI_TARGETCLOCK 32000u
-#define TOUCH_PANEL_SPI_CLOCKUNITS "Hz"
-#define TOUCH_PANEL_SPI_CLOCKMULT 1
-#define TOUCH_PANEL_SPI_NUMSLAVES 1
-#define TOUCH_PANEL_SPI_ISMASTER 1
-#define TOUCH_PANEL_SPI_CLOCKPOLARITY 0
-#define TOUCH_PANEL_SPI_CLOCKPHASE 0
-#define TOUCH_PANEL_SPI_LSBFIRST 0
-#define TOUCH_PANEL_SPI_EXTRADELAY 0
-#define TOUCH_PANEL_SPI_TARGETSSDELAY "0.0"
-#define TOUCH_PANEL_SPI_DELAYUNITS "ns"
-#define TOUCH_PANEL_SPI_DELAYMULT "1.0E-9"
-#define TOUCH_PANEL_SPI_PREFIX "spi_"
+#define SYSID_COMPONENT_TYPE altera_avalon_sysid
+#define SYSID_COMPONENT_NAME sysid
+#define SYSID_BASE 0x8001400
+#define SYSID_SPAN 16u
+#define SYSID_ID 1597074984u
+#define SYSID_TIMESTAMP 1254740213u
 
 /*
- * Macros for device 'performance_counter', class 'altera_avalon_performance_counter'
- * The macros are prefixed with 'PERFORMANCE_COUNTER_'.
+ * Macros for device 'jtag_uart', class 'altera_avalon_jtag_uart'
+ * The macros are prefixed with 'JTAG_UART_'.
  * The prefix is the slave descriptor.
  */
-#define PERFORMANCE_COUNTER_COMPONENT_TYPE altera_avalon_performance_counter
-#define PERFORMANCE_COUNTER_COMPONENT_NAME performance_counter
-#define PERFORMANCE_COUNTER_BASE 0x8020000
-#define PERFORMANCE_COUNTER_SPAN 256u
-#define PERFORMANCE_COUNTER_HOW_MANY_SECTIONS 1
+#define JTAG_UART_COMPONENT_TYPE altera_avalon_jtag_uart
+#define JTAG_UART_COMPONENT_NAME jtag_uart
+#define JTAG_UART_BASE 0x8001410
+#define JTAG_UART_SPAN 16u
+#define JTAG_UART_IRQ 7
+#define JTAG_UART_WRITE_DEPTH 64
+#define JTAG_UART_READ_DEPTH 64
+#define JTAG_UART_WRITE_THRESHOLD 8
+#define JTAG_UART_READ_THRESHOLD 8
 
 /*
- * Macros for device 'pll', class 'altera_avalon_pll'
- * The macros are prefixed with 'PLL_'.
+ * Macros for device 'ps2_0', class 'altera_up_avalon_ps2_classic'
+ * The macros are prefixed with 'PS2_0_'.
  * The prefix is the slave descriptor.
  */
-#define PLL_COMPONENT_TYPE altera_avalon_pll
-#define PLL_COMPONENT_NAME pll
-#define PLL_BASE 0x8200000
-#define PLL_SPAN 256u
-#define PLL_ARESET "None"
-#define PLL_PFDENA "None"
-#define PLL_LOCKED "None"
-#define PLL_PLLENA "None"
-#define PLL_SCANCLK "None"
-#define PLL_SCANDATA "None"
-#define PLL_SCANREAD "None"
-#define PLL_SCANWRITE "None"
-#define PLL_SCANCLKENA "None"
-#define PLL_SCANACLR "None"
-#define PLL_SCANDATAOUT "None"
-#define PLL_SCANDONE "None"
-#define PLL_CONFIGUPDATE "None"
-#define PLL_PHASECOUNTERSELECT "None"
-#define PLL_PHASEDONE "None"
-#define PLL_PHASEUPDOWN "None"
-#define PLL_PHASESTEP "None"
+#define PS2_0_COMPONENT_TYPE altera_up_avalon_ps2_classic
+#define PS2_0_COMPONENT_NAME ps2_0
+#define PS2_0_BASE 0x8001420
+#define PS2_0_SPAN 8u
+#define PS2_0_IRQ 9
 
 /*
- * Macros for device 'remote_update', class 'altera_avalon_remote_update_cycloneiii'
- * The macros are prefixed with 'REMOTE_UPDATE_'.
+ * Macros for device 'gpio_0', class 'gpio'
+ * The macros are prefixed with 'GPIO_0_'.
  * The prefix is the slave descriptor.
  */
-#define REMOTE_UPDATE_COMPONENT_TYPE altera_avalon_remote_update_cycloneiii
-#define REMOTE_UPDATE_COMPONENT_NAME remote_update
-#define REMOTE_UPDATE_BASE 0x8610000
-#define REMOTE_UPDATE_SPAN 2048u
+#define GPIO_0_COMPONENT_TYPE gpio
+#define GPIO_0_COMPONENT_NAME gpio_0
+#define GPIO_0_BASE 0x8001500
+#define GPIO_0_SPAN 128u
 
 /*
- * Macros for device 'sgdma_rx', class 'altera_avalon_sgdma'
- * The macros are prefixed with 'SGDMA_RX_'.
+ * Macros for device 'onchip_memory2_0', class 'altera_avalon_onchip_memory2'
+ * The macros are prefixed with 'ONCHIP_MEMORY2_0_'.
  * The prefix is the slave descriptor.
  */
-#define SGDMA_RX_COMPONENT_TYPE altera_avalon_sgdma
-#define SGDMA_RX_COMPONENT_NAME sgdma_rx
-#define SGDMA_RX_BASE 0x8702000
-#define SGDMA_RX_SPAN 1024u
-#define SGDMA_RX_IRQ 4
-#define SGDMA_RX_READ_BLOCK_DATA_WIDTH 32
-#define SGDMA_RX_WRITE_BLOCK_DATA_WIDTH 32
-#define SGDMA_RX_STREAM_DATA_WIDTH 32
-#define SGDMA_RX_ADDRESS_WIDTH 32
-#define SGDMA_RX_HAS_READ_BLOCK 0
-#define SGDMA_RX_HAS_WRITE_BLOCK 1
-#define SGDMA_RX_READ_BURSTCOUNT_WIDTH 4
-#define SGDMA_RX_WRITE_BURSTCOUNT_WIDTH 4
-#define SGDMA_RX_BURST_TRANSFER 0
-#define SGDMA_RX_ALWAYS_DO_MAX_BURST 1
-#define SGDMA_RX_DESCRIPTOR_READ_BURST 0
-#define SGDMA_RX_UNALIGNED_TRANSFER 0
-#define SGDMA_RX_CONTROL_SLAVE_DATA_WIDTH 32
-#define SGDMA_RX_CONTROL_SLAVE_ADDRESS_WIDTH 8
-#define SGDMA_RX_DESC_DATA_WIDTH 32
-#define SGDMA_RX_CHAIN_WRITEBACK_DATA_WIDTH 32
-#define SGDMA_RX_STATUS_TOKEN_DATA_WIDTH 24
-#define SGDMA_RX_BYTES_TO_TRANSFER_DATA_WIDTH 16
-#define SGDMA_RX_BURST_DATA_WIDTH 8
-#define SGDMA_RX_CONTROL_DATA_WIDTH 8
-#define SGDMA_RX_ATLANTIC_CHANNEL_DATA_WIDTH 4
-#define SGDMA_RX_COMMAND_FIFO_DATA_WIDTH 104
-#define SGDMA_RX_SYMBOLS_PER_BEAT 4
-#define SGDMA_RX_IN_ERROR_WIDTH 6
-#define SGDMA_RX_OUT_ERROR_WIDTH 0
-
-/*
- * Macros for device 'ddr_sdram', class 'altmemddr'
- * Path to the device is from the master group 'sgdma_rx_m_write'.
- * The macros are prefixed with 'SGDMA_RX_M_WRITE_DDR_SDRAM_'.
- * The prefix is the master group descriptor and the slave descriptor.
- */
-#define SGDMA_RX_M_WRITE_DDR_SDRAM_COMPONENT_TYPE altmemddr
-#define SGDMA_RX_M_WRITE_DDR_SDRAM_COMPONENT_NAME ddr_sdram
-#define SGDMA_RX_M_WRITE_DDR_SDRAM_BASE 0x0
-#define SGDMA_RX_M_WRITE_DDR_SDRAM_SPAN 33554432u
-
-/*
- * Macros for device 'ext_flash', class 'altera_avalon_cfi_flash'
- * Path to the device is from the master group 'sgdma_rx_m_write'.
- * The macros are prefixed with 'SGDMA_RX_M_WRITE_EXT_FLASH_'.
- * The prefix is the master group descriptor and the slave descriptor.
- */
-#define SGDMA_RX_M_WRITE_EXT_FLASH_COMPONENT_TYPE altera_avalon_cfi_flash
-#define SGDMA_RX_M_WRITE_EXT_FLASH_COMPONENT_NAME ext_flash
-#define SGDMA_RX_M_WRITE_EXT_FLASH_BASE 0x4000000
-#define SGDMA_RX_M_WRITE_EXT_FLASH_SPAN 16777216u
-#define SGDMA_RX_M_WRITE_EXT_FLASH_SETUP_VALUE 25
-#define SGDMA_RX_M_WRITE_EXT_FLASH_WAIT_VALUE 70
-#define SGDMA_RX_M_WRITE_EXT_FLASH_HOLD_VALUE 20
-#define SGDMA_RX_M_WRITE_EXT_FLASH_TIMING_UNITS "ns"
-#define SGDMA_RX_M_WRITE_EXT_FLASH_SIZE 16777216u
-
-/*
- * Macros for device 'ssram', class 'altera_avalon_cy7c1380_ssram'
- * Path to the device is from the master group 'sgdma_rx_m_write'.
- * The macros are prefixed with 'SGDMA_RX_M_WRITE_SSRAM_'.
- * The prefix is the master group descriptor and the slave descriptor.
- */
-#define SGDMA_RX_M_WRITE_SSRAM_COMPONENT_TYPE altera_avalon_cy7c1380_ssram
-#define SGDMA_RX_M_WRITE_SSRAM_COMPONENT_NAME ssram
-#define SGDMA_RX_M_WRITE_SSRAM_BASE 0x5000000
-#define SGDMA_RX_M_WRITE_SSRAM_SPAN 1048576u
-#define SGDMA_RX_M_WRITE_SSRAM_SRAM_MEMORY_SIZE 1
-#define SGDMA_RX_M_WRITE_SSRAM_SRAM_MEMORY_UNITS 1048576
-#define SGDMA_RX_M_WRITE_SSRAM_SSRAM_DATA_WIDTH 32
-#define SGDMA_RX_M_WRITE_SSRAM_SSRAM_READ_LATENCY 2
-
-/*
- * Macros for device 'sgdma_tx', class 'altera_avalon_sgdma'
- * The macros are prefixed with 'SGDMA_TX_'.
- * The prefix is the slave descriptor.
- */
-#define SGDMA_TX_COMPONENT_TYPE altera_avalon_sgdma
-#define SGDMA_TX_COMPONENT_NAME sgdma_tx
-#define SGDMA_TX_BASE 0x8702400
-#define SGDMA_TX_SPAN 1024u
-#define SGDMA_TX_IRQ 6
-#define SGDMA_TX_READ_BLOCK_DATA_WIDTH 32
-#define SGDMA_TX_WRITE_BLOCK_DATA_WIDTH 32
-#define SGDMA_TX_STREAM_DATA_WIDTH 32
-#define SGDMA_TX_ADDRESS_WIDTH 32
-#define SGDMA_TX_HAS_READ_BLOCK 1
-#define SGDMA_TX_HAS_WRITE_BLOCK 0
-#define SGDMA_TX_READ_BURSTCOUNT_WIDTH 4
-#define SGDMA_TX_WRITE_BURSTCOUNT_WIDTH 4
-#define SGDMA_TX_BURST_TRANSFER 0
-#define SGDMA_TX_ALWAYS_DO_MAX_BURST 1
-#define SGDMA_TX_DESCRIPTOR_READ_BURST 0
-#define SGDMA_TX_UNALIGNED_TRANSFER 0
-#define SGDMA_TX_CONTROL_SLAVE_DATA_WIDTH 32
-#define SGDMA_TX_CONTROL_SLAVE_ADDRESS_WIDTH 8
-#define SGDMA_TX_DESC_DATA_WIDTH 32
-#define SGDMA_TX_CHAIN_WRITEBACK_DATA_WIDTH 32
-#define SGDMA_TX_STATUS_TOKEN_DATA_WIDTH 24
-#define SGDMA_TX_BYTES_TO_TRANSFER_DATA_WIDTH 16
-#define SGDMA_TX_BURST_DATA_WIDTH 8
-#define SGDMA_TX_CONTROL_DATA_WIDTH 8
-#define SGDMA_TX_ATLANTIC_CHANNEL_DATA_WIDTH 4
-#define SGDMA_TX_COMMAND_FIFO_DATA_WIDTH 104
-#define SGDMA_TX_SYMBOLS_PER_BEAT 4
-#define SGDMA_TX_IN_ERROR_WIDTH 0
-#define SGDMA_TX_OUT_ERROR_WIDTH 1
-
-/*
- * Macros for device 'ddr_sdram', class 'altmemddr'
- * Path to the device is from the master group 'sgdma_tx_m_read'.
- * The macros are prefixed with 'SGDMA_TX_M_READ_DDR_SDRAM_'.
- * The prefix is the master group descriptor and the slave descriptor.
- */
-#define SGDMA_TX_M_READ_DDR_SDRAM_COMPONENT_TYPE altmemddr
-#define SGDMA_TX_M_READ_DDR_SDRAM_COMPONENT_NAME ddr_sdram
-#define SGDMA_TX_M_READ_DDR_SDRAM_BASE 0x0
-#define SGDMA_TX_M_READ_DDR_SDRAM_SPAN 33554432u
-
-/*
- * Macros for device 'ext_flash', class 'altera_avalon_cfi_flash'
- * Path to the device is from the master group 'sgdma_tx_m_read'.
- * The macros are prefixed with 'SGDMA_TX_M_READ_EXT_FLASH_'.
- * The prefix is the master group descriptor and the slave descriptor.
- */
-#define SGDMA_TX_M_READ_EXT_FLASH_COMPONENT_TYPE altera_avalon_cfi_flash
-#define SGDMA_TX_M_READ_EXT_FLASH_COMPONENT_NAME ext_flash
-#define SGDMA_TX_M_READ_EXT_FLASH_BASE 0x4000000
-#define SGDMA_TX_M_READ_EXT_FLASH_SPAN 16777216u
-#define SGDMA_TX_M_READ_EXT_FLASH_SETUP_VALUE 25
-#define SGDMA_TX_M_READ_EXT_FLASH_WAIT_VALUE 70
-#define SGDMA_TX_M_READ_EXT_FLASH_HOLD_VALUE 20
-#define SGDMA_TX_M_READ_EXT_FLASH_TIMING_UNITS "ns"
-#define SGDMA_TX_M_READ_EXT_FLASH_SIZE 16777216u
-
-/*
- * Macros for device 'ssram', class 'altera_avalon_cy7c1380_ssram'
- * Path to the device is from the master group 'sgdma_tx_m_read'.
- * The macros are prefixed with 'SGDMA_TX_M_READ_SSRAM_'.
- * The prefix is the master group descriptor and the slave descriptor.
- */
-#define SGDMA_TX_M_READ_SSRAM_COMPONENT_TYPE altera_avalon_cy7c1380_ssram
-#define SGDMA_TX_M_READ_SSRAM_COMPONENT_NAME ssram
-#define SGDMA_TX_M_READ_SSRAM_BASE 0x5000000
-#define SGDMA_TX_M_READ_SSRAM_SPAN 1048576u
-#define SGDMA_TX_M_READ_SSRAM_SRAM_MEMORY_SIZE 1
-#define SGDMA_TX_M_READ_SSRAM_SRAM_MEMORY_UNITS 1048576
-#define SGDMA_TX_M_READ_SSRAM_SSRAM_DATA_WIDTH 32
-#define SGDMA_TX_M_READ_SSRAM_SSRAM_READ_LATENCY 2
-
-/*
- * Macros for device 'tse_mac', class 'triple_speed_ethernet'
- * The macros are prefixed with 'TSE_MAC_'.
- * The prefix is the slave descriptor.
- */
-#define TSE_MAC_COMPONENT_TYPE triple_speed_ethernet
-#define TSE_MAC_COMPONENT_NAME tse_mac
-#define TSE_MAC_BASE 0x8702800
-#define TSE_MAC_SPAN 1024u
-#define TSE_MAC_TRANSMIT "sgdma_tx"
-#define TSE_MAC_RECEIVE "sgdma_rx"
-#define TSE_MAC_TRANSMIT_FIFO_DEPTH 512
-#define TSE_MAC_RECEIVE_FIFO_DEPTH 512
-#define TSE_MAC_FIFO_WIDTH 32
-#define TSE_MAC_ENABLE_MACLITE 0
-#define TSE_MAC_MACLITE_GIGE 0
-#define TSE_MAC_USE_MDIO 1
-#define TSE_MAC_NUMBER_OF_CHANNEL 1
-#define TSE_MAC_NUMBER_OF_MAC_MDIO_SHARED 1
-#define TSE_MAC_IS_MULTICHANNEL_MAC 0
-#define TSE_MAC_MDIO_SHARED 0
-#define TSE_MAC_REGISTER_SHARED 0
-#define TSE_MAC_PCS 0
-#define TSE_MAC_PCS_SGMII 0
-#define TSE_MAC_PCS_ID 0u
-
-/*
- * Macros for device 'descriptor_memory', class 'altera_avalon_onchip_memory2'
- * The macros are prefixed with 'DESCRIPTOR_MEMORY_'.
- * The prefix is the slave descriptor.
- */
-#define DESCRIPTOR_MEMORY_COMPONENT_TYPE altera_avalon_onchip_memory2
-#define DESCRIPTOR_MEMORY_COMPONENT_NAME descriptor_memory
-#define DESCRIPTOR_MEMORY_BASE 0xb000000
-#define DESCRIPTOR_MEMORY_SPAN 4096u
-#define DESCRIPTOR_MEMORY_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0
-#define DESCRIPTOR_MEMORY_INIT_CONTENTS_FILE "descriptor_memory"
-#define DESCRIPTOR_MEMORY_NON_DEFAULT_INIT_FILE_ENABLED 0
-#define DESCRIPTOR_MEMORY_GUI_RAM_BLOCK_TYPE "Automatic"
-#define DESCRIPTOR_MEMORY_WRITABLE 1
-#define DESCRIPTOR_MEMORY_DUAL_PORT 0
-#define DESCRIPTOR_MEMORY_SIZE_VALUE 4096u
-#define DESCRIPTOR_MEMORY_SIZE_MULTIPLE 1
-#define DESCRIPTOR_MEMORY_CONTENTS_INFO ""
-#define DESCRIPTOR_MEMORY_RAM_BLOCK_TYPE "Auto"
-#define DESCRIPTOR_MEMORY_INIT_MEM_CONTENT 1
-#define DESCRIPTOR_MEMORY_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0
-#define DESCRIPTOR_MEMORY_INSTANCE_ID "NONE"
-#define DESCRIPTOR_MEMORY_READ_DURING_WRITE_MODE "DONT_CARE"
+#define ONCHIP_MEMORY2_0_COMPONENT_TYPE altera_avalon_onchip_memory2
+#define ONCHIP_MEMORY2_0_COMPONENT_NAME onchip_memory2_0
+#define ONCHIP_MEMORY2_0_BASE 0x9000000
+#define ONCHIP_MEMORY2_0_SPAN 512u
+#define ONCHIP_MEMORY2_0_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0
+#define ONCHIP_MEMORY2_0_INIT_CONTENTS_FILE "onchip_memory2_0"
+#define ONCHIP_MEMORY2_0_NON_DEFAULT_INIT_FILE_ENABLED 0
+#define ONCHIP_MEMORY2_0_GUI_RAM_BLOCK_TYPE "Automatic"
+#define ONCHIP_MEMORY2_0_WRITABLE 1
+#define ONCHIP_MEMORY2_0_DUAL_PORT 1
+#define ONCHIP_MEMORY2_0_SIZE_VALUE 512u
+#define ONCHIP_MEMORY2_0_SIZE_MULTIPLE 1
+#define ONCHIP_MEMORY2_0_CONTENTS_INFO ""
+#define ONCHIP_MEMORY2_0_RAM_BLOCK_TYPE "Auto"
+#define ONCHIP_MEMORY2_0_INIT_MEM_CONTENT 1
+#define ONCHIP_MEMORY2_0_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0
+#define ONCHIP_MEMORY2_0_INSTANCE_ID "NONE"
+#define ONCHIP_MEMORY2_0_READ_DURING_WRITE_MODE "DONT_CARE"
 
 
 #endif /* _ALTERA_CPU_H_ */
