aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Ivan Kuten <ivan.kuten@promwad.com>2007-11-09 09:52:26 +0000
committerGravatar Ivan Kuten <ivan.kuten@promwad.com>2007-11-09 09:52:26 +0000
commit3d4957b0dd431b0dd55809a1815abda7e0aa1989 (patch)
tree831461c82018a4b17972817f4fefa2d847b0adaf
parent9a70efaf1b3627d2d2ae4e4a5b17e5e246992ba6 (diff)
downloadbuildroot-3d4957b0dd431b0dd55809a1815abda7e0aa1989.tar.gz
buildroot-3d4957b0dd431b0dd55809a1815abda7e0aa1989.tar.bz2
update kernel-headers nios2 support, thanks atle
-rw-r--r--toolchain/kernel-headers/Config.in2
-rw-r--r--toolchain/kernel-headers/kernel-headers.mk3
-rw-r--r--toolchain/kernel-headers/linux-2.6.23-nios2nommu.patch26567
3 files changed, 26570 insertions, 2 deletions
diff --git a/toolchain/kernel-headers/Config.in b/toolchain/kernel-headers/Config.in
index 28618e6636..15cb496aa2 100644
--- a/toolchain/kernel-headers/Config.in
+++ b/toolchain/kernel-headers/Config.in
@@ -74,7 +74,7 @@ choice
bool "Latest Linux 2.6.22.x kernel headers"
config BR2_KERNEL_HEADERS_2_6_23
- depends !BR2_avr32 && !BR2_nios2
+ depends !BR2_avr32
bool "Latest Linux 2.6.23.x kernel headers"
config BR2_KERNEL_HEADERS_SNAP
diff --git a/toolchain/kernel-headers/kernel-headers.mk b/toolchain/kernel-headers/kernel-headers.mk
index b6fe3e56cf..fef5afd899 100644
--- a/toolchain/kernel-headers/kernel-headers.mk
+++ b/toolchain/kernel-headers/kernel-headers.mk
@@ -18,7 +18,8 @@ KERNEL_ARCH:=$(shell $(SHELL) -c "echo \"$(ARCH)\" | sed -e \"s/-.*//\" \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/powerpc64/powerpc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
- -e s/sh2.*/sh/ -e s/sh3.*/sh/ -e s/sh4.*/sh/")
+ -e s/sh2.*/sh/ -e s/sh3.*/sh/ -e s/sh4.*/sh/ \
+ -e s/nios2.*/nios2nommu/")
# assume old manually sanitized kernel-headers
LINUX_HEADERS_IS_KERNEL=n
diff --git a/toolchain/kernel-headers/linux-2.6.23-nios2nommu.patch b/toolchain/kernel-headers/linux-2.6.23-nios2nommu.patch
new file mode 100644
index 0000000000..6e558fd66c
--- /dev/null
+++ b/toolchain/kernel-headers/linux-2.6.23-nios2nommu.patch
@@ -0,0 +1,26567 @@
+diff --git a/arch/nios2nommu/ChangeLog b/arch/nios2nommu/ChangeLog
+new file mode 100644
+index 0000000..039c010
+--- /dev/null
++++ b/arch/nios2nommu/ChangeLog
+@@ -0,0 +1,4 @@
++2004-06-15 Ken Hill <khill@microtronix.com>
++
++ * Kconfig: Add Microtronix uKit support.
++
+diff --git a/arch/nios2nommu/Kconfig b/arch/nios2nommu/Kconfig
+new file mode 100644
+index 0000000..525c77b
+--- /dev/null
++++ b/arch/nios2nommu/Kconfig
+@@ -0,0 +1,403 @@
++#
++# For a description of the syntax of this configuration file,
++# see the Configure script.
++#
++mainmenu 'uClinux/Nios2 (w/o MMU) Kernel Configuration'
++
++config MMU
++ bool
++ default n
++
++config FPU
++ bool
++ default n
++
++config ZONE_DMA
++ bool
++ default y
++
++config UID16
++ bool
++ default y
++
++config RWSEM_GENERIC_SPINLOCK
++ bool
++ default y
++
++config RWSEM_XCHGADD_ALGORITHM
++ bool
++ default n
++
++config GENERIC_FIND_NEXT_BIT
++ bool
++ default y
++
++config GENERIC_HWEIGHT
++ bool
++ default y
++
++config GENERIC_CALIBRATE_DELAY
++ bool
++ default y
++
++source "init/Kconfig"
++
++menu "Processor type and features"
++
++comment 'Platform dependant setup'
++
++choice
++ prompt "CPU"
++ default NIOS2
++
++config NIOS2
++ bool "NIOS2"
++ help
++ Altera Nios2 softcore processor.
++
++endchoice
++
++choice
++ prompt "Platform"
++ default ALTERA_STRATIX
++
++config MICROTRONIX_UKIT
++ bool "Microtronix uKit board support"
++ depends on NIOS2
++ help
++ Support for the Microtronix uKit development board. Includes support
++ for Sodimm SDRAM/FLASH, soft ethernet MAC & PHY.
++
++config MICROTRONIX_STRATIX
++ bool "Microtronix Stratix board support"
++ depends on NIOS2
++ help
++ Support for the Microtronix Stratix board. Includes support
++ for Sodimm SDRAM/FLASH, soft ethernet MAC & PHY, USB, LVDS
++ & analog/digital converters.
++
++config MICROTRONIX_CYCLONE
++ bool "Microtronix Cyclone board support"
++ depends on NIOS2
++ help
++ Support for the Microtronix Cyclone board. Includes support
++ for SDRAM, FLASH, soft ethernet MAC & PHY, USB,
++ & analog/digital converters.
++
++config MICROTRONIX_PSK
++ bool "Microtronix PSK (Product Starter Kit) support"
++ depends on NIOS2
++ help
++ Support for the Microtronix PSK (Product Starter Kit), which
++ features firefly module (EP1C4 or EP1C12). Includes support
++ for SDRAM, FLASH, and a variety of product expansion kits such
++ as USB, Ethernet etc.
++
++config ALTERA_STRATIX
++ bool "Altera Stratix Development board support"
++ depends on NIOS2
++ help
++ Support for the Altera Stratix Development board. Includes
++ support for 10/100 ethernet, FLASH, SDRAM, compact flash.
++
++config ALTERA_STRATIX_PRO
++ bool "Altera Stratix Pro Development board support"
++ depends on NIOS2
++ help
++ Support for the Altera Stratix 1s40 Development board. Includes
++ support for 10/100 ethernet, FLASH, SDRAM, compact flash.
++
++config ALTERA_STRATIX_II
++ bool "Altera Stratix II Development board support"
++ depends on NIOS2
++ help
++ Support for the Altera Stratix II Development board. Includes
++ support for 10/100 ethernet, FLASH, SDRAM, compact flash.
++
++config ALTERA_CYCLONE
++ bool "Altera Cyclone Development board support"
++ depends on NIOS2
++ help
++ Support for the Altera Cyclone Development board. Includes
++ support for 10/100 ethernet, FLASH, SDRAM, compact flash.
++
++config ALTERA_CYCLONE_1C12_EVAL
++ bool "Altera Cyclone 1C12 Evaluation board support"
++ depends on NIOS2
++ help
++ Support for the Altera Cyclone 1C12 Evaluation board (with the
++ embedded processor module).
++
++config ALTERA_DE2
++ bool "Altera DE2 Development board support"
++ depends on NIOS2
++ help
++ Support for the Altera Cyclone Development board. Includes
++ support for 10/100 ethernet, FLASH, SDRAM, VGA, I2C.
++
++endchoice
++
++choice
++ prompt "Nios II Hardware Multiply Support"
++ default NIOS2_HW_MULX
++ help
++ This option enables various assembler instructions based on your
++ selection. The choice depends on what target hardware you'll be
++ running your applications on. The default is
++ "Enable mulx instruction".
++
++ Here is an explanation of each option:
++ None = -mno-hw-mul -mno-hw-mulx
++ (no mul or mulx instructions used)
++ Enable mul instruction = -mhw-mul -mno-hw-mulx
++ (use mul instructions)
++ Enable mul and mulx instructions = -mhw-mul -mhw-mulx
++ (use mul and mulx instructions)
++
++ If you don't know what to choose, select "Enable mulx instruction".
++
++config NIOS2_HW_MUL_OFF
++ bool "None"
++
++config NIOS2_HW_MUL
++ bool "Enable mul instruction"
++
++config NIOS2_HW_MULX
++ bool "Enable mul and mulx instructions"
++
++endchoice
++
++comment 'Platform drivers Options'
++
++config AVALON_DMA
++ bool "Support of DMA controller with Avalon interface"
++ default y
++ help
++ This enables support of Altera's DMA controller with Avalon
++ interface, so that drivers of DMA-able device can use this
++ interface.
++
++config PIO_DEVICES
++ bool "Enable leds, seven segment display"
++ default y
++ depends on (ALTERA_STRATIX || ALTERA_STRATIX_PRO || ALTERA_CYCLONE)
++ help
++ This enables example code to support leds, and seven segment
++ display as PIO devices. Once enabled, the kernel will show a
++ counter (increas once a second) on these devices.
++
++source "arch/nios2nommu/drivers/Kconfig"
++
++comment 'Miscellaneous Options'
++
++config EXCALIBUR
++ bool
++ default y
++ depends on (NIOS2)
++
++config BREAK_ON_START
++ bool "Include breakpoint trap on kernel startup"
++ help
++ Configures the kernel to trap to the GDB client on startup
++ before the kernel starts initialization. This allows you to
++ debug the kernel startup.
++
++config LARGE_ALLOCS
++ bool "Allow allocating large blocks (> 1MB) of memory"
++ help
++ Allow the slab memory allocator to keep chains for very large
++ memory sizes - upto 32MB. You may need this if your system has
++ a lot of RAM, and you need to able to allocate very large
++ contiguous chunks. If unsure, say N.
++
++choice
++ prompt "Kernel executes from"
++ ---help---
++ Choose the memory type that the kernel will be running in.
++
++config RAMKERNEL
++ bool "RAM"
++ help
++ The kernel will be resident in RAM when running.
++
++#config ROMKERNEL
++# bool "ROM"
++# help
++# The kernel will be resident in FLASH/ROM when running.
++
++#config HIMEMKERNEL
++# bool "HIMEM"
++# help
++# The kernel will be resident in high memory when running.
++
++endchoice
++
++config PREEMPT
++ bool "Preemptible Kernel"
++ help
++ This option reduces the latency of the kernel when reacting to
++ real-time or interactive events by allowing a low priority process to
++ be preempted even if it is in kernel mode executing a system call.
++ This allows applications to run more reliably even when the system is
++ under load.
++
++ Say Y here if you are building a kernel for a desktop, embedded
++ or real-time system. Say N if you are unsure.
++
++config PREEMPT_TIMES
++ bool "Collect preemption latency times"
++ depends on PREEMPT
++ help
++ Allow collection for preemption latency times.
++
++config CMDLINE
++ string "Default kernel command string"
++ default "CONSOLE=/dev/ttyS0 root=/dev/rom0 ro"
++ help
++ On some architectures, there is currently no way
++ for the boot loader to pass arguments to the kernel. For these
++ architectures, you should supply some command-line options at build
++ time by entering them here. As a minimum, you should specify the
++ memory size and the root device (e.g., mem=64M root=/dev/nfs).
++
++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.
++
++source "mm/Kconfig"
++
++config BOOT_LINK_OFFSET
++ hex "Link address offset for booting"
++ default "0x00800000"
++ 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.
++
++endmenu
++
++menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
++
++config PCI
++ bool "PCI support"
++ help
++ Support for PCI bus.
++
++source "drivers/pci/Kconfig"
++
++config HOTPLUG
++ bool "Support for hot-pluggable device"
++ ---help---
++ Say Y here if you want to plug devices into your computer while
++ the system is running, and be able to use them quickly. In many
++ cases, the devices can likewise be unplugged at any time too.
++
++ One well known example of this is PCMCIA- or PC-cards, credit-card
++ size devices such as network cards, modems or hard drives which are
++ plugged into slots found on all modern laptop computers. Another
++ example, used on modern desktops as well as laptops, is USB.
++
++ Enable HOTPLUG and KMOD, and build a modular kernel. Get agent
++ software (at <http://linux-hotplug.sourceforge.net/>) and install it.
++ Then your kernel will automatically call out to a user mode "policy
++ agent" (/sbin/hotplug) to load modules and set up software needed
++ to use devices as you hotplug them.
++
++source "drivers/pcmcia/Kconfig"
++
++source "drivers/pci/hotplug/Kconfig"
++
++endmenu
++
++menu "Executable file formats"
++
++config KCORE_AOUT
++ bool
++ default y
++
++config KCORE_ELF
++ bool
++ default y
++
++source "fs/Kconfig.binfmt"
++
++endmenu
++
++menu "Power management options"
++
++config PM
++ bool "Power Management support"
++ help
++ Support processor power management modes
++
++endmenu
++
++
++source "net/Kconfig"
++
++source "drivers/Kconfig"
++
++source "fs/Kconfig"
++
++source "arch/nios2nommu/Kconfig.debug"
++
++menu "Kernel hacking"
++
++config FULLDEBUG
++ bool "Full Symbolic/Source Debugging support"
++ help
++ Enable debuging symbols on kernel build.
++
++config FRAME_POINTER
++ bool "Compile the kernel with frame pointers"
++ help
++ If you say Y here the resulting kernel image will be slightly larger
++ and slower, but it will give very useful debugging information.
++ If you don't debug the kernel, you can say N, but we may not be able
++ to solve problems without frame pointers.
++
++config MAGIC_SYSRQ
++ bool "Magic SysRq key"
++ help
++ Enables console device to interpret special characters as
++ commands to dump state information.
++
++config HIGHPROFILE
++ bool "Use fast second timer for profiling"
++ depends on COLDFIRE
++ help
++ Use a fast secondary clock to produce profiling information.
++
++config NO_KERNEL_MSG
++ bool "Suppress Kernel BUG Messages"
++ help
++ Do not output any debug BUG messages within the kernel.
++
++config LOG_BUF_SHIFT
++ int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" if DEBUG_KERNEL
++ range 12 21
++ default 17 if ARCH_S390
++ default 16 if X86_NUMAQ || IA64
++ default 15 if SMP
++ default 14
++ help
++ Select kernel log buffer size as a power of 2.
++ Defaults and Examples:
++ 17 => 128 KB for S/390
++ 16 => 64 KB for x86 NUMAQ or IA-64
++ 15 => 32 KB for SMP
++ 14 => 16 KB for uniprocessor
++ 13 => 8 KB
++ 12 => 4 KB
++
++endmenu
++
++source "security/Kconfig"
++
++source "crypto/Kconfig"
++
++source "lib/Kconfig"
+diff --git a/arch/nios2nommu/Kconfig.debug b/arch/nios2nommu/Kconfig.debug
+new file mode 100644
+index 0000000..b188c4a
+--- /dev/null
++++ b/arch/nios2nommu/Kconfig.debug
+@@ -0,0 +1,35 @@
++menu "Kernel hacking"
++
++source "lib/Kconfig.debug"
++
++config FULLDEBUG
++ bool "Full Symbolic/Source Debugging support"
++ help
++ Enable debuging symbols on kernel build.
++
++config FRAME_POINTER
++ bool "Compile the kernel with frame pointers"
++ help
++ If you say Y here the resulting kernel image will be slightly larger
++ and slower, but it will give very useful debugging information.
++ If you don't debug the kernel, you can say N, but we may not be able
++ to solve problems without frame pointers.
++
++config MAGIC_SYSRQ
++ bool "Magic SysRq key"
++ help
++ Enables console device to interpret special characters as
++ commands to dump state information.
++
++config HIGHPROFILE
++ bool "Use fast second timer for profiling"
++ depends on COLDFIRE
++ help
++ Use a fast secondary clock to produce profiling information.
++
++config NO_KERNEL_MSG
++ bool "Suppress Kernel BUG Messages"
++ help
++ Do not output any debug BUG messages within the kernel.
++
++endmenu
+diff --git a/arch/nios2nommu/Makefile b/arch/nios2nommu/Makefile
+new file mode 100644
+index 0000000..ca139b6
+--- /dev/null
++++ b/arch/nios2nommu/Makefile
+@@ -0,0 +1,181 @@
++# arch/niosnommu/Makefile
++#
++# Makefile for the architecture dependent flags and dependencies on the
++# nios.
++#
++# Copyright (C) 2001 Vic Phillips (vic@microtronix.com)
++#
++# based on sparcnommu/Makefile:
++#
++# Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
++#
++KERNELLOAD = ${shell echo `grep "nasys_program_mem " include/asm/nios.h | sed 's/^.*\*)//' | sed 's/)//'`}
++
++HARDWARE_MK = arch/$(ARCH)/hardware.mk
++
++platform-$(CONFIG_NIOS) := NIOS2
++PLATFORM := $(platform-y)
++
++board-$(CONFIG_ALTERA_STRATIX) := altera_stratix
++board-$(CONFIG_ALTERA_STRATIX_PRO) := altera_stratix_pro
++board-$(CONFIG_ALTERA_STRATIX_II) := altera_stratix_ii
++board-$(CONFIG_ALTERA_CYCLONE) := altera_cyclone
++board-$(CONFIG_ALTERA_CYCLONE_1C12_EVAL) := altera_cyclone_1c12_eval
++board-$(CONFIG_MICROTRONIX_STRATIX) := microtronix_stratix
++board-$(CONFIG_MICROTRONIX_CYCLONE) := microtronix_cyclone
++board-$(CONFIG_MICROTRONIX_UKIT) := microtronix_ukit
++board-$(CONFIG_MICROTRONIX_PSK) := microtronix_psk
++BOARD := $(board-y)
++
++model-$(CONFIG_RAMKERNEL) := ram
++model-$(CONFIG_ROMKERNEL) := rom
++model-$(CONFIG_HIMEMKERNEL) := himem
++MODEL := $(model-y)
++
++export PLATFORM BOARD MODEL
++
++CFLAGS += -DNO_MM -pipe -D__linux__ -D__ELF__
++#CFLAGS += -DNO_MM -save-temps -D__linux__ -D__ELF__
++
++# Uncomment this if you are doing gdb source level
++# debugging of the kernel to get the proper debugging information.
++#
++#CFLAGS += -DDEBUG
++
++# Turn on/off various hardware multiply options
++cpu-cflags-$(CONFIG_NIOS2_HW_MUL_OFF) += -mno-hw-mul -mno-hw-mulx
++cpu-cflags-$(CONFIG_NIOS2_HW_MUL) += -mhw-mul -mno-hw-mulx
++cpu-cflags-$(CONFIG_NIOS2_HW_MULX) += -mhw-mul -mhw-mulx
++CFLAGS += $(cpu-cflags-y)
++
++# mulx flags currently cause older version of nios2-elf-gcc to fail
++# The following line ensures that all mulx flags are removed before
++# it is passed to the compiler.
++mulx_help_text:= $(shell $(CC) --target-help | grep mulx)
++ifeq "$(mulx_help_text)" ""
++CFLAGS := $(filter-out -mhw-mulx -mno-hw-mulx, $(CFLAGS))
++endif
++
++# Temporary workaround for nios2-elf-gcc bug
++# First noticed in v3.4.1 (Altera Nios II 1.1 b131)
++# To be removed at a later date when bug is resolved.
++CFLAGS += -fno-optimize-sibling-calls
++
++# This undefines the "__init" type used in defining initialization
++# procedures. When defined, the procedures are put into an 'init' data
++# section that GDB doesn't recognize as source.
++#
++CFLAGS += -DNO_TEXT_SECTIONS
++CFLAGS += -fno-builtin
++CFLAGS += -O2 -g -G 0
++CFLAGS += -DUTS_SYSNAME=\"uClinux\"
++
++CFLAGS_GCC_INC := $(shell $(CC) -print-file-name=include)
++CFLAGS += -I$(CFLAGS_GCC_INC)
++
++AFLAGS += -DNO_MM -g
++#AFLAGS += -DNO_MM -g -save-temps
++
++# vic - add this to get name of nios gcc library
++LIBGCC_CFLAGS = $(if $(CONFIG_NIOS2_HW_MUL_OFF),-mno-hw-mul)
++LIBGCC := `$(CC) --print-libgcc-file-name $(LIBGCC_CFLAGS)`
++
++# add this to avoid multiple '_stack' and '_vecbase' definition errors
++#
++ifdef niosgnu
++# Include the path to the lib directory where the ldscripts are found to fix
++# a problem with the cygwin/bash environment.
++
++#cygwhack: kenw - this following section could be a possible problem
++# due to the O= option on the command line.
++LDSCRIPTS:=$(shell nios2-elf-gcc -print-file-name=ldscripts)
++LDFLAGS += -mnios2elf -L $(LDSCRIPTS)/..
++else
++LDFLAGS += -mnios2elf
++LDLIBS := -L `$(CC) -print-file-name=m32` -l gcc
++endif
++
++head-y := arch/nios2nommu/kernel/head.o arch/nios2nommu/kernel/init_task.o
++
++CLEAN_FILES := include/asm-$(ARCH)/asm-offsets.h \
++ $(HARDWARE_MK) \
++ arch/$(ARCH)/kernel/asm-offsets.s \
++ linux.srec \
++ linux.flash \
++ linux.bin \
++ linux.bin.srec
++
++core-y += arch/nios2nommu/kernel/ \
++ arch/nios2nommu/mm/ \
++ arch/nios2nommu/drivers/
++
++libs-y += arch/nios2nommu/lib/
++
++libs-y += $(LIBGCC)
++####;dgt2;tmp;
++
++# force user to configure hardware before building kernel
++
++pardoned_targets = clean mrproper sgmldocs psdocs pdfdocs \
++ htmldocs mandocs headers_install
++
++-include $(HARDWARE_MK)
++build_targets = $(filter-out $(pardoned_targets), $(MAKECMDGOALS))
++ifneq '$(strip $(build_targets))' ''
++ ifndef SYSPTF
++ ifneq '$(firstword $(MAKECMDGOALS))' 'hwselect'
++ $(error Run "make hwselect SYSPTF=<system.ptf>" first)
++ endif
++ endif
++endif
++
++quiet_cmd_gen_mk = ' RUNNING $@'
++define cmd_gen_mk
++ mkdir -p $(dir $(objtree)/$(HARDWARE_MK)); \
++ perl -I$(TOPDIR)/arch/$(ARCH)/scripts \
++ $(srctree)/arch/$(ARCH)/scripts/hwselect.pl $(SYSPTF) \
++ $(objtree)/$(HARDWARE_MK)
++endef
++
++.PHONY: hwselect
++hwselect:
++ @echo $($(quiet)cmd_gen_mk);
++ @$(cmd_gen_mk)
++
++prepare: include/nios2_system.h
++
++archclean:
++ $(call descend arch/$(ARCH)/boot, subdirclean)
++
++define filechk_nios2_system.h
++ # call perl script that will build nios2_system.h file
++ perl -I$(TOPDIR)/arch/$(ARCH)/scripts \
++ $(TOPDIR)/arch/$(ARCH)/scripts/gen_nios2_system.h.pl $(CPU) $(EXEMEM) $(UPLMEM)
++endef
++
++include/nios2_system.h: $(SYSPTF) FORCE
++ $(call filechk,nios2_system.h)
++
++quiet_cmd_touch = ' TOUCH $@'
++ cmd_touch = touch $(TOPDIR)/$@
++
++arch/$(ARCH)/kernel/vmlinux.lds.S: FORCE
++ @echo $($(quiet)cmd_touch);
++ @$(cmd_touch)
++
++linuxsrec: linux
++ $(OBJCOPY) -O srec $(LINUX) linux.srec
++
++boot := arch/nios2nommu/boot
++
++zImage: vmlinux
++ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
++
++compressed: zImage
++
++CLEAN_FILES += include/nios2_system.h
++
++archmrproper:
++
++archdep:
++
+diff --git a/arch/nios2nommu/boot/Makefile b/arch/nios2nommu/boot/Makefile
+new file mode 100644
+index 0000000..fd25b72
+--- /dev/null
++++ b/arch/nios2nommu/boot/Makefile
+@@ -0,0 +1,17 @@
++#
++# arch/nios2nommu/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.
++
++targets := zImage
++subdir- := compressed
++
++$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
++ $(call if_changed,objcopy)
++ @echo 'Kernel: $@ is ready'
++
++$(obj)/compressed/vmlinux: FORCE
++ $(Q)$(MAKE) $(build)=$(obj)/compressed $@
++
+diff --git a/arch/nios2nommu/boot/compressed/Makefile b/arch/nios2nommu/boot/compressed/Makefile
+new file mode 100644
+index 0000000..2002471
+--- /dev/null
++++ b/arch/nios2nommu/boot/compressed/Makefile
+@@ -0,0 +1,36 @@
++#
++# linux/arch/sh/boot/compressed/Makefile
++#
++# create a compressed vmlinux image from the original vmlinux
++#
++
++targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o \
++ piggy.o vmlinux.lds
++EXTRA_AFLAGS :=
++
++OBJECTS = $(obj)/head.o $(obj)/misc.o
++
++#
++# IMAGE_OFFSET is the load offset of the compression loader
++#
++#IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_MEMORY_START)+0x2000])
++#IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_MEMORY_START)+0x00400000])
++
++LDFLAGS_vmlinux := -T
++
++$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(obj)/piggy.o FORCE
++ $(call if_changed,ld)
++ @:
++
++$(obj)/vmlinux.bin: vmlinux FORCE
++ $(call if_changed,objcopy)
++
++$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
++ $(call if_changed,gzip)
++
++LDFLAGS_piggy.o := -r --format binary --oformat elf32-littlenios2 -T
++
++OBJCOPYFLAGS += -O binary
++
++$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
++ $(call if_changed,ld)
+diff --git a/arch/nios2nommu/boot/compressed/head.S b/arch/nios2nommu/boot/compressed/head.S
+new file mode 100644
+index 0000000..accadd0
+--- /dev/null
++++ b/arch/nios2nommu/boot/compressed/head.S
+@@ -0,0 +1,100 @@
++/*
++ * linux/arch/nios2nommu/boot/compressed/head.S
++ *
++ */
++
++ .text
++ .set noat
++#include <asm/asm-offsets.h>
++#include <asm/asm-macros.h>
++
++ /*
++ * This code can be loaded anywhere, as long as output will not
++ * overlap it.
++ *
++ */
++
++ .global _start
++_start:
++ // disable interrupt
++ wrctl status, r0
++ // flush the instruction cache
++ movia r1,NIOS2_ICACHE_SIZE
++ movi r2,NIOS2_ICACHE_LINE_SIZE
++text_init:
++ initi r1
++ sub r1, r1, r2
++ bgt r1, zero, text_init
++ // then flush the pipeline
++ flushp
++ // flush the data cache
++ movia r1,NIOS2_DCACHE_SIZE
++ movi r2,NIOS2_DCACHE_LINE_SIZE
++data_init:
++ initd (r1)
++ sub r1, r1, r2
++ bgt r1, zero, data_init
++ //------------------------------------------------------
++ // 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
++ 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
++
++flush_cache:
++ // flush all cache after loading
++ // flush the data cache
++ movia r1,NIOS2_DCACHE_SIZE
++ movi r2,NIOS2_DCACHE_LINE_SIZE
++data_flush:
++ flushd (r1)
++ sub r1, r1, r2
++ bgt r1, zero, data_flush
++ // flush the instruction cache
++ movia r1,NIOS2_ICACHE_SIZE
++ movi r2,NIOS2_ICACHE_LINE_SIZE
++text_flush:
++ flushi r1
++ sub r1, r1, r2
++ bgt r1, zero, text_flush
++ // then flush the pipeline
++ flushp
++ // pass saved args to kernel
++ ldw r4,0(sp)
++ ldw r5,4(sp)
++ ldw r6,8(sp)
++ ldw r7,12(sp)
++ movia r1,LINUX_SDRAM_START
++ 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/nios2nommu/boot/compressed/install.sh b/arch/nios2nommu/boot/compressed/install.sh
+new file mode 100644
+index 0000000..6d72e9e
+--- /dev/null
++++ b/arch/nios2nommu/boot/compressed/install.sh
+@@ -0,0 +1,57 @@
++#!/bin/sh
++#
++# arch/sh/boot/install.sh
++#
++# 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 by Linus Torvalds
++#
++# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
++# Adapted from code in arch/i386/boot/install.sh by Russell King
++# Adapted from code in arch/arm/boot/install.sh by Stuart Menefy
++# Adapted from code in arch/sh/boot/install.sh by Takeo Takahashi
++#
++# "make install" script for sh architecture
++#
++# Arguments:
++# $1 - kernel version
++# $2 - kernel image file
++# $3 - kernel map file
++# $4 - default install path (blank if root directory)
++#
++
++# User may have a custom install script
++
++if [ -x /sbin/installkernel ]; then
++ exec /sbin/installkernel "$@"
++fi
++
++if [ "$2" = "zImage" ]; then
++# Compressed install
++ echo "Installing compressed kernel"
++ if [ -f $4/vmlinuz-$1 ]; then
++ mv $4/vmlinuz-$1 $4/vmlinuz.old
++ fi
++
++ if [ -f $4/System.map-$1 ]; then
++ mv $4/System.map-$1 $4/System.old
++ fi
++
++ cat $2 > $4/vmlinuz-$1
++ cp $3 $4/System.map-$1
++else
++# Normal install
++ echo "Installing normal kernel"
++ if [ -f $4/vmlinux-$1 ]; then
++ mv $4/vmlinux-$1 $4/vmlinux.old
++ fi
++
++ if [ -f $4/System.map ]; then
++ mv $4/System.map $4/System.old
++ fi
++
++ cat $2 > $4/vmlinux-$1
++ cp $3 $4/System.map
++fi
+diff --git a/arch/nios2nommu/boot/compressed/misc.c b/arch/nios2nommu/boot/compressed/misc.c
+new file mode 100644
+index 0000000..c513e6e
+--- /dev/null
++++ b/arch/nios2nommu/boot/compressed/misc.c
+@@ -0,0 +1,208 @@
++/*
++ * arch/nios2nommu/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);
++static void gzip_mark(void **);
++static void gzip_release(void **);
++
++extern char input_data[];
++extern int input_len;
++
++static long bytes_out = 0;
++static uch *output_data;
++static unsigned long output_ptr = 0;
++
++#include "nios2_sio.c"
++
++static void *malloc(int size);
++static void free(void *where);
++static void error(char *m);
++static void gzip_mark(void **);
++static void gzip_release(void **);
++
++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"
++
++static void *malloc(int size)
++{
++ void *p;
++
++ if (size <0) error("Malloc error");
++ if (free_mem_ptr == 0) error("Memory error");
++
++ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
++
++ p = (void *)free_mem_ptr;
++ free_mem_ptr += size;
++
++ if (free_mem_ptr >= free_mem_end_ptr)
++ error("Out of memory");
++
++ return p;
++}
++
++static void free(void *where)
++{ /* Don't care */
++}
++
++static void gzip_mark(void **ptr)
++{
++ *ptr = (void *) free_mem_ptr;
++}
++
++static void gzip_release(void **ptr)
++{
++ free_mem_ptr = (long) *ptr;
++}
++
++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 *)nasys_program_mem;
++ output_ptr = 0;
++ free_mem_ptr = (unsigned long)&_end;
++ free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
++
++ makecrc();
++ puts("Uncompressing Linux... ");
++ gunzip();
++ puts("Ok, booting the kernel.\n");
++}
+diff --git a/arch/nios2nommu/boot/compressed/nios2_sio.c b/arch/nios2nommu/boot/compressed/nios2_sio.c
+new file mode 100644
+index 0000000..8630c8f
+--- /dev/null
++++ b/arch/nios2nommu/boot/compressed/nios2_sio.c
+@@ -0,0 +1,57 @@
++
++static int putchar(int ch);
++
++static int puts(const char *s)
++ {
++ while(*s)
++ putchar(*s++);
++ return 0;
++ }
++
++#include <asm/nios.h>
++#include <asm/io.h>
++
++#if defined(CONFIG_SERIAL_AJUART_CONSOLE)
++
++#define IORD_ALTERA_AVALON_JTAG_UART_DATA(base) inl(base)
++#define IOWR_ALTERA_AVALON_JTAG_UART_DATA(base, data) outl(data, base)
++#define IORD_ALTERA_AVALON_JTAG_UART_CONTROL(base) inl(base+4)
++#define IOWR_ALTERA_AVALON_JTAG_UART_CONTROL(base, data) outl(data, base+4)
++#define ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_MSK (0xFFFF0000u)
++#define ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_OFST (16)
++
++static void jtag_putc(int ch)
++{
++ unsigned base = na_jtag_uart;
++ while ((IORD_ALTERA_AVALON_JTAG_UART_CONTROL(base) & ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_MSK) == 0);
++ IOWR_ALTERA_AVALON_JTAG_UART_DATA(base, ch);
++}
++
++static int putchar(int ch)
++{
++ jtag_putc( ch );
++ return ch;
++}
++
++#elif defined(CONFIG_NIOS_SERIAL_CONSOLE)
++
++static void nr_txchar(int ch)
++{
++ while ((na_uart0->np_uartstatus & np_uartstatus_trdy_mask) == 0);
++ na_uart0->np_uarttxdata = ch;
++}
++
++static int putchar(int ch)
++{
++ nr_txchar( ch ); if (ch=='\n') nr_txchar( '\r' );
++ return ch;
++}
++
++#else
++
++static int putchar(int ch)
++{
++ return ch;
++}
++
++#endif
+diff --git a/arch/nios2nommu/boot/compressed/vmlinux.lds.S b/arch/nios2nommu/boot/compressed/vmlinux.lds.S
+new file mode 100644
+index 0000000..08bb3e2
+--- /dev/null
++++ b/arch/nios2nommu/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
++{
++ . =nasys_program_mem + CONFIG_BOOT_LINK_OFFSET;
++
++ _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/nios2nommu/defconfig b/arch/nios2nommu/defconfig
+new file mode 100644
+index 0000000..40629cb
+--- /dev/null
++++ b/arch/nios2nommu/defconfig
+@@ -0,0 +1,690 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.19-uc1
++#
++# CONFIG_MMU is not set
++# CONFIG_FPU is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_LOCK_KERNEL=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++
++#
++# General setup
++#
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++# CONFIG_SYSVIPC is not set
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT 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_RELAY is not set
++CONFIG_INITRAMFS_SOURCE="../romfs ../vendors/Altera/nios2nommu/romfs_list"
++CONFIG_INITRAMFS_ROOT_UID=500
++CONFIG_INITRAMFS_ROOT_GID=500
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_EMBEDDED=y
++# CONFIG_SYSCTL_SYSCALL is not set
++# CONFIG_KALLSYMS is not set
++# CONFIG_HOTPLUG is not set
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++# CONFIG_ELF_CORE is not set
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++# CONFIG_EPOLL is not set
++CONFIG_SLAB=y
++# CONFIG_VM_EVENT_COUNTERS is not set
++CONFIG_RT_MUTEXES=y
++CONFIG_TINY_SHMEM=y
++CONFIG_BASE_SMALL=0
++# CONFIG_SLOB is not set
++
++#
++# Loadable module support
++#
++# CONFIG_MODULES is not set
++
++#
++# Block layer
++#
++CONFIG_BLOCK=y
++# CONFIG_BLK_DEV_IO_TRACE is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++# CONFIG_IOSCHED_AS is not set
++CONFIG_IOSCHED_DEADLINE=y
++# CONFIG_IOSCHED_CFQ is not set
++# CONFIG_DEFAULT_AS is not set
++CONFIG_DEFAULT_DEADLINE=y
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="deadline"
++
++#
++# Processor type and features
++#
++
++#
++# Platform dependant setup
++#
++CONFIG_NIOS2=y
++# CONFIG_MICROTRONIX_UKIT is not set
++# CONFIG_MICROTRONIX_STRATIX is not set
++# CONFIG_MICROTRONIX_CYCLONE is not set
++# CONFIG_MICROTRONIX_PSK is not set
++CONFIG_ALTERA_STRATIX=y
++# CONFIG_ALTERA_STRATIX_PRO is not set
++# CONFIG_ALTERA_STRATIX_II is not set
++# CONFIG_ALTERA_CYCLONE is not set
++# CONFIG_ALTERA_CYCLONE_1C12_EVAL is not set
++# CONFIG_ALTERA_DE2 is not set
++# CONFIG_NIOS2_HW_MUL_OFF is not set
++CONFIG_NIOS2_HW_MUL=y
++# CONFIG_NIOS2_HW_MULX is not set
++
++#
++# Platform drivers Options
++#
++# CONFIG_AVALON_DMA is not set
++# CONFIG_PIO_DEVICES is not set
++# CONFIG_PCI is not set
++# CONFIG_FB_ALTERA is not set
++# CONFIG_SERIO_ALTPS2 is not set
++# CONFIG_I2C_GPIO is not set
++
++#
++# Miscellaneous Options
++#
++CONFIG_EXCALIBUR=y
++# CONFIG_BREAK_ON_START is not set
++CONFIG_LARGE_ALLOCS=y
++CONFIG_RAMKERNEL=y
++CONFIG_PREEMPT=y
++# CONFIG_PREEMPT_TIMES is not set
++CONFIG_CMDLINE=""
++# CONFIG_PASS_CMDLINE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL 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_BOOT_LINK_OFFSET=0x00500000
++
++#
++# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
++#
++
++#
++# PCCARD (PCMCIA/CardBus) support
++#
++
++#
++# PCI Hotplug Support
++#
++
++#
++# Executable file formats
++#
++CONFIG_KCORE_AOUT=y
++CONFIG_KCORE_ELF=y
++CONFIG_BINFMT_FLAT=y
++CONFIG_BINFMT_ZFLAT=y
++# CONFIG_BINFMT_SHARED_FLAT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_NETDEBUG is not set
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# 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_ARPD 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 is not set
++# CONFIG_IPSEC_NAT_TRAVERSAL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_SCTP is not set
++
++#
++# TIPC Configuration (EXPERIMENTAL)
++#
++# CONFIG_TIPC is not set
++# CONFIG_ATM 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
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER 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_KLIPS is not set
++# CONFIG_IEEE80211 is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# 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
++#
++
++#
++# 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 is not set
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++
++#
++# Misc devices
++#
++# CONFIG_TIFM_CORE is not set
++
++#
++# 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 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_OPEN_ETH is not set
++# CONFIG_MTIP1000_ETH is not set
++# CONFIG_NE2000 is not set
++# CONFIG_NET_PCI is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++
++#
++# Ethernet (10000 Mbit)
++#
++
++#
++# Token Ring devices
++#
++
++#
++# Wireless LAN (non-hamradio)
++#
++# CONFIG_NET_RADIO is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE 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 is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_NIOS_LCD_16207 is not set
++# CONFIG_NIOS_BUTTON is not set
++# CONFIG_LEDMAN is not set
++# CONFIG_SNAPDOG is not set
++# CONFIG_FAST_TIMER is not set
++# CONFIG_RESETSWITCH 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_NIOS_SERIAL is not set
++CONFIG_SERIAL_AJUART=y
++CONFIG_SERIAL_AJUART_CONSOLE=y
++# CONFIG_UNIX98_PTYS is not set
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=10
++
++#
++# 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
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_RAW_DRIVER is not set
++
++#
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++# CONFIG_M41T11M6 is not set
++
++#
++# 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_SENSORS_ABITUGURU is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# Digital Video Broadcasting Devices
++#
++# CONFIG_DVB is not set
++
++#
++# Graphics support
++#
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND 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
++#
++# CONFIG_RTC_CLASS is not set
++
++#
++# DMA Engine support
++#
++# CONFIG_DMA_ENGINE is not set
++
++#
++# DMA Clients
++#
++
++#
++# DMA Devices
++#
++
++#
++# File systems
++#
++# CONFIG_EXT2_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_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_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_INOTIFY is not set
++# CONFIG_QUOTA is not set
++# CONFIG_DNOTIFY is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++# CONFIG_DIRECTIO 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_SYSCTL is not set
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_SQUASHFS 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 is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 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
++# CONFIG_AFS_FS is not set
++# CONFIG_9P_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++
++#
++# Native Language Support
++#
++# CONFIG_NLS is not set
++
++#
++# Debug
++#
++# CONFIG_COREDUMP_PRINTK is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_FULLDEBUG is not set
++# CONFIG_FRAME_POINTER is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_NO_KERNEL_MSG is not set
++CONFIG_LOG_BUF_SHIFT=14
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++CONFIG_CRC32=y
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_PLIST=y
+diff --git a/arch/nios2nommu/drivers/Kconfig b/arch/nios2nommu/drivers/Kconfig
+new file mode 100644
+index 0000000..2fde3a8
+--- /dev/null
++++ b/arch/nios2nommu/drivers/Kconfig
+@@ -0,0 +1,45 @@
++# Platfrom drivers configuration
++
++source "arch/nios2nommu/drivers/pci/Kconfig"
++
++config FB_ALTERA
++ tristate "Avalon VGA controller support"
++ default N
++ select FB
++ select FB_CFB_FILLRECT
++ select FB_CFB_COPYAREA
++ select FB_CFB_IMAGEBLIT
++ help
++ This is the frame buffer device driver for the VGA controller
++ in SOPC Builder.
++
++config SERIO_ALTPS2
++ tristate "PS2 controller"
++ select VT
++ default N
++ select SERIO
++
++config I2C_NIOS2_GPIO
++ tristate "GPIO-Based I2C Interface"
++ default N
++ select I2C
++ select I2C_ALGOBIT
++ help
++ Say Y here if you use GPIO lines for an I2C bus.
++
++config BLK_DEV_ALTCF
++ tristate "Altera CF (IDE mode) interface (Avalon bus) support"
++ select IDE
++ select BLK_DEV_IDE
++ default N
++ help
++ This driver provides support for the Altera Compact flash core (with
++ Avalon interface) support. If you have an Altera or Microtronix
++ development board you can build support into the FPGA device for this.
++
++config NIOS_SPI
++ bool "Nios SPI device support"
++ depends on NIOS || NIOS2
++ help
++ This driver supports the Nios softcore SPI device.
++
+diff --git a/arch/nios2nommu/drivers/Makefile b/arch/nios2nommu/drivers/Makefile
+new file mode 100644
+index 0000000..f6a273e
+--- /dev/null
++++ b/arch/nios2nommu/drivers/Makefile
+@@ -0,0 +1,10 @@
++#
++# Makefile for the Linux nios2-specific device drivers.
++#
++
++obj-$(CONFIG_PCI) += pci/
++obj-$(CONFIG_FB_ALTERA) += altfb.o
++obj-$(CONFIG_SERIO_ALTPS2) += altps2.o
++obj-$(CONFIG_I2C_NIOS2_GPIO) += i2c-gpio.o
++obj-$(CONFIG_BLK_DEV_ALTCF) += altcf.o
++obj-$(CONFIG_NIOS_SPI) += spi.o
+diff --git a/arch/nios2nommu/drivers/altcf.c b/arch/nios2nommu/drivers/altcf.c
+new file mode 100644
+index 0000000..80275c6
+--- /dev/null
++++ b/arch/nios2nommu/drivers/altcf.c
+@@ -0,0 +1,266 @@
++/*
++ * linux/drivers/ide/altcf.c
++ * Support for Altera CompactFlash core with Avalon interface.
++ *
++ * 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/mm.h>
++#include <linux/ioport.h>
++#include <linux/blkdev.h>
++#include <linux/hdreg.h>
++#include <linux/ide.h>
++#include <linux/init.h>
++#include <asm/io.h>
++#include <asm/nios.h>
++
++MODULE_AUTHOR("Microtronix Datacom Ltd.");
++MODULE_DESCRIPTION("Driver of Altera CompactFlash core with Avalon interface");
++MODULE_LICENSE("GPL");
++
++#define PDEBUG printk
++/* Altera Avalon Compact Flash core registers */
++#define REG_CFCTL 0
++#define REG_IDECTL 4
++
++/* CFCTL bits */
++#define CFCTL_DET 1 /* detect status */
++#define CFCTL_PWR 2 /* Power */
++#define CFCTL_RST 4 /* Reset */
++#define CFCTL_IDET 8 /* Detect int enable*/
++
++/* IDECTL bits */
++#define IDECTL_IIDE 1 /* IDE int enable */
++
++struct cf_dev {
++ int base;
++ int irq;
++ int ide_base;
++ int ide_irq;
++ int configured;
++ ide_hwif_t *hwif;
++ struct delayed_work wcf;
++};
++
++static struct cf_dev cf_devices[MAX_HWIFS] = {
++#if MAX_HWIFS > 0
++ {na_ide_ctl, na_ide_ctl_irq, na_ide_ide, na_ide_ide_irq, 0, NULL},
++#endif
++#if MAX_HWIFS > 1
++ {na_ctl_base1, na_ctl_irq1, na_ide_base1, na_ide_irq1, 0, NULL},
++#endif
++#if MAX_HWIFS > 2
++ {na_ctl_base2, na_ctl_irq2, na_ide_base2, na_ide_irq2, 0, NULL},
++#endif
++#if MAX_HWIFS > 3
++ {na_ctl_base3, na_ctl_irq3, na_ide_base3, na_ide_irq3, 0, NULL},
++#endif
++};
++
++static inline void cf_init_hwif_ports(hw_regs_t *hw,
++ unsigned long io_addr,
++ unsigned long ctl_addr,
++ int *irq)
++{
++ unsigned int i;
++
++ for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
++ hw->io_ports[i] = io_addr + 4*(i-IDE_DATA_OFFSET);
++
++ hw->io_ports[IDE_CONTROL_OFFSET] = ctl_addr;
++
++ if (irq)
++ *irq = 0;
++
++ hw->io_ports[IDE_IRQ_OFFSET] = 0;
++
++}
++
++static int cf_release(struct cf_dev* dev)
++{
++ if (dev) {
++ if ((dev->configured) && (dev->hwif)) {
++ /* disable IDE interrupts */
++ outl(0, dev->base + REG_IDECTL);
++ /* power off the card */
++ //outl(0, dev->base + REG_CFCTL);
++
++ ide_unregister(dev->hwif->index);
++ dev->configured = 0;
++ dev->hwif = NULL;
++ PDEBUG("CF released\n");
++ return 0;
++ }
++ }
++ return -1;
++}
++
++static int cf_config(struct cf_dev* dev)
++{
++ hw_regs_t hw;
++ int index;
++ ide_hwif_t *hwif;
++
++ if (!dev)
++ return -1;
++
++ if (!dev->configured) {
++ int i;
++ for (i=1; i<=10; i++) {
++ cf_init_hwif_ports(&hw, dev->ide_base, 0, NULL);
++ hw.irq = dev->ide_irq;
++ hw.chipset = ide_generic;
++ outl(IDECTL_IIDE, dev->base + REG_IDECTL);
++ index = ide_register_hw(&hw, 1, &hwif);
++ if (index >=0) {
++ dev->configured = 1;
++ dev->hwif = hwif;
++ return index;
++ }
++
++ set_current_state(TASK_UNINTERRUPTIBLE);
++ schedule_timeout(HZ/10);
++ }
++ /* register fails */
++ PDEBUG("CF:fail to register\n");
++ /* disable IDE interrupt */
++ outl(0, dev->base + REG_IDECTL);
++ return -1;
++ }
++ return -2; /* already configured */
++}
++
++static irqreturn_t cf_intr(int irq, void *dev_id)
++{
++ unsigned int cfctl;
++ struct cf_dev* dev = (struct cf_dev *)dev_id;
++
++ if (!dev)
++ return IRQ_NONE;
++
++ cfctl=inl(dev->base + REG_CFCTL);
++ /* unpower the card */
++ outl((cfctl & ~(CFCTL_PWR)), dev->base + REG_CFCTL);
++
++ if ((cfctl & CFCTL_DET))
++ schedule_delayed_work(&dev->wcf, HZ/2);
++ else
++ schedule_work(&dev->wcf.work);
++ return IRQ_HANDLED;
++}
++
++static void cf_event(struct work_struct *work)
++{
++ struct cf_dev* dev = container_of(work, struct cf_dev, wcf.work);
++
++ if (dev) {
++ unsigned int cfctl;
++
++ cfctl=inl(dev->base + REG_CFCTL);
++ if ((cfctl & CFCTL_DET)) {
++ /* a CF card is inserted, power on the card */
++ outl(((cfctl | CFCTL_PWR) & ~(CFCTL_RST) ), dev->base + REG_CFCTL);
++ set_current_state(TASK_UNINTERRUPTIBLE);
++ schedule_timeout(HZ);
++ cf_config(dev);
++ }
++ else {
++ /* a CF card is removed */
++ cf_release(dev);
++ }
++ }
++}
++
++int __init altcf_init(void)
++{
++ unsigned int cfctl;
++ int i;
++ ide_hwif_t *hwif;
++ hw_regs_t hw;
++ extern ide_hwif_t ide_hwifs[];
++
++ for (i=0; i<MAX_HWIFS; i++) {
++ cfctl=inl(cf_devices[i].base + REG_CFCTL);
++ PDEBUG("CF: ctl=%d\n", cfctl);
++ if (cfctl & CFCTL_DET)
++ {
++ /* power off the card */
++ outl(CFCTL_RST, cf_devices[i].base + REG_CFCTL);
++ mdelay(500);
++ cfctl=inl(cf_devices[i].base + REG_CFCTL);
++
++ /* power on the card */
++ outl(((cfctl | CFCTL_PWR) & ~(CFCTL_RST) ), cf_devices[i].base + REG_CFCTL);
++ mdelay(2000);
++ inl(cf_devices[i].base + REG_CFCTL);
++
++ /* check if card is in right mode */
++ outb(0xa0, cf_devices[i].ide_base+IDE_SELECT_OFFSET*4);
++ mdelay(50);
++ if (inb(cf_devices[i].ide_base+IDE_SELECT_OFFSET*4) == 0xa0) {
++ /* enable IDE interrupt */
++ outl(IDECTL_IIDE, cf_devices[i].base + REG_IDECTL);
++ ide_hwifs[i].chipset = ide_generic;
++ cf_devices[i].hwif = &ide_hwifs[i];
++
++ memset(&hw, 0, sizeof hw);
++ cf_init_hwif_ports(&hw, cf_devices[i].ide_base, 0, NULL);
++ hw.chipset = ide_generic;
++ hw.irq = cf_devices[i].ide_irq;
++ if (ide_register_hw(&hw, 1, &hwif)>=0) {
++ cf_devices[i].configured = 1;
++ cf_devices[i].hwif = hwif;
++ }
++ else
++ printk("CF register fails\n");
++ }
++ else printk("Unable to initialize compact flash card. Please re-insert\n");
++ }
++
++ /* register the detection interrupt */
++ if (request_irq(cf_devices[i].irq, cf_intr, IRQF_DISABLED, "cf", &cf_devices[i])) {
++ PDEBUG("CF: unable to get interrupt %d for detecting inf %d\n",
++ cf_devices[i].irq, i );
++ } else {
++ INIT_DELAYED_WORK(&cf_devices[i].wcf, cf_event);
++ /* enable the detection interrupt */
++ cfctl=inl(cf_devices[i].base + REG_CFCTL);
++ outl(cfctl | CFCTL_IDET, cf_devices[i].base + REG_CFCTL);
++ }
++ }
++
++ return 0;
++}
++
++#ifdef MODULE
++static void __exit altcf_exit(void)
++{
++ unsigned int cfctl;
++ for (i=0; i<MAX_HWIFS; i++) {
++ /* disable detection irq */
++ cfctl=inl(cf_devices[i].base + REG_CFCTL);
++ outl(cfctl & ~CFCTL_IDET, cf_devices[i].base + REG_CFCTL);
++
++ /* free the detection irq */
++ free_irq(cf_devices[i].irq, &cf_devices[i]);
++
++ /* release the device */
++ cf_release(&cf_devices[i]);
++ }
++}
++
++module_init(altcf_init);
++module_exit(altcf_exit);
++#endif
+diff --git a/arch/nios2nommu/drivers/altfb.c b/arch/nios2nommu/drivers/altfb.c
+new file mode 100644
+index 0000000..cebd659
+--- /dev/null
++++ b/arch/nios2nommu/drivers/altfb.c
+@@ -0,0 +1,234 @@
++/*
++ * Altera VGA controller
++ *
++ * linux/drivers/video/vfb.c -- Virtual frame buffer device
++ *
++ * Copyright (C) 2002 James Simmons
++ *
++ * Copyright (C) 1997 Geert Uytterhoeven
++ *
++ * 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/module.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/tty.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/dma-mapping.h>
++#include <linux/platform_device.h>
++
++#include <asm/uaccess.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++
++#define vgabase na_vga_controller_0
++#define XRES 640
++#define YRES 480
++#define BPX 16
++
++ /*
++ * 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 void *videomemory;
++static u_long videomemorysize = VIDEOMEMSIZE;
++module_param(videomemorysize, ulong, 0);
++
++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 // BPX == 24
++ .red = { 16, 8, 0 },
++ .green = { 8, 8, 0 },
++ .blue = { 0, 8, 0 },
++#endif
++ .activate = FB_ACTIVATE_NOW,
++ .height = -1,
++ .width = -1,
++ // timing useless ?
++ .pixclock = 20000,
++ .left_margin = 64,
++ .right_margin = 64,
++ .upper_margin = 32,
++ .lower_margin = 32,
++ .hsync_len = 64,
++ .vsync_len = 2,
++ .vmode = FB_VMODE_NONINTERLACED,
++};
++
++static struct fb_fix_screeninfo altfb_fix __initdata = {
++ .id = "Altera FB",
++ .type = FB_TYPE_PACKED_PIXELS,
++ .visual = FB_VISUAL_TRUECOLOR,
++ .line_length = (XRES * (BPX>>3)),
++ .xpanstep = 0,
++ .ypanstep = 0,
++ .ywrapstep = 0,
++ .accel = FB_ACCEL_NONE,
++};
++
++static int altfb_mmap(struct fb_info *info,
++ struct vm_area_struct *vma);
++
++static struct fb_ops altfb_ops = {
++ .fb_fillrect = cfb_fillrect,
++ .fb_copyarea = cfb_copyarea,
++ .fb_imageblit = cfb_imageblit,
++ .fb_mmap = altfb_mmap,
++};
++
++
++ /*
++ * Most drivers don't need their own mmap function
++ */
++
++static int altfb_mmap(struct fb_info *info,
++ struct vm_area_struct *vma)
++{
++ /* this is uClinux (no MMU) specific code */
++ vma->vm_flags |= (VM_RESERVED | VM_MAYSHARE);
++ vma->vm_start = (unsigned) videomemory;
++ return 0;
++}
++
++ /*
++ * Initialisation
++ */
++
++static void altfb_platform_release(struct device *device)
++{
++ // This is called when the reference count goes to zero.
++ dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n");
++}
++
++static int __init altfb_probe(struct platform_device *dev)
++{
++ struct fb_info *info;
++ int retval = -ENOMEM;
++ dma_addr_t handle;
++
++ /*
++ * For real video cards we use ioremap.
++ */
++ if (!(videomemory = dma_alloc_coherent(&dev->dev, PAGE_ALIGN(videomemorysize), &handle, GFP_KERNEL))) {
++ printk(KERN_ERR "altfb: unable to allocate screen memory\n");
++ return retval;
++ }
++ altfb_fix.smem_start = handle;
++ altfb_fix.smem_len = videomemorysize;
++
++ info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev);
++ if (!info)
++ goto err;
++
++ info->screen_base = (char __iomem *)videomemory;
++ 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);
++
++ outl(0x0,vgabase+0); // Reset the VGA controller
++ outl(videomemory,vgabase+4); // Where our frame buffer starts
++ outl(videomemorysize,vgabase+8); // amount of memory needed
++ outl(0x1,vgabase+0); // Set the go bit
++
++ printk(KERN_INFO
++ "fb%d: Altera frame buffer device, using %ldK of video memory\n",
++ info->node, videomemorysize >> 10);
++ // printk("vga %08x, video %08x+%08x\n",vgabase,videomemory,videomemorysize);
++ return 0;
++err2:
++ fb_dealloc_cmap(&info->cmap);
++err1:
++ framebuffer_release(info);
++err:
++ dma_free_noncoherent(&dev->dev, videomemorysize, videomemory, handle);
++ 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_noncoherent(&dev->dev, videomemorysize, videomemory, altfb_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,
++ .dev = {
++ .release = altfb_platform_release,
++ }
++};
++
++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;
++}
++
++module_init(altfb_init);
++
++#ifdef MODULE
++static void __exit altfb_exit(void)
++{
++ platform_device_unregister(&altfb_device);
++ platform_driver_unregister(&altfb_driver);
++}
++
++module_exit(altfb_exit);
++
++MODULE_LICENSE("GPL");
++#endif /* MODULE */
+diff --git a/arch/nios2nommu/drivers/altps2.c b/arch/nios2nommu/drivers/altps2.c
+new file mode 100644
+index 0000000..4a6523c
+--- /dev/null
++++ b/arch/nios2nommu/drivers/altps2.c
+@@ -0,0 +1,193 @@
++/*
++ * altera DE2 PS/2
++ *
++ * linux/drivers/input/serio/sa1111ps2.c
++ *
++ * Copyright (C) 2002 Russell King
++ *
++ * 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.
++ */
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/input.h>
++#include <linux/serio.h>
++#include <linux/errno.h>
++#include <linux/interrupt.h>
++#include <linux/ioport.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++
++#include <asm/io.h>
++#include <asm/system.h>
++
++
++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. If there was a
++ * framing error, we have to manually clear the status.
++ */
++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. We have to wait for the
++ * port to indicate that the transmitter is empty.
++ */
++static int ps2_write(struct serio *io, unsigned char val)
++{
++ struct ps2if *ps2if = io->port_data;
++ outl(val,ps2if->base);
++ // should check command send error
++ if (inl(ps2if->base+4) & (1<<10))
++ {
++ // printk("ps2 write error %02x\n",val);
++ }
++ 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,
++ "altps2", ps2if);
++ if (ret) {
++ printk(KERN_ERR "altps2: 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;
++ unsigned int status;
++ int ret;
++
++ ps2if = kmalloc(sizeof(struct ps2if), GFP_KERNEL);
++ serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
++ if (!ps2if || !serio) {
++ ret = -ENOMEM;
++ goto free;
++ }
++
++ memset(ps2if, 0, sizeof(struct ps2if));
++ memset(serio, 0, sizeof(struct serio));
++
++ serio->id.type = SERIO_8042;
++ serio->write = ps2_write;
++ serio->open = ps2_open;
++ serio->close = ps2_close;
++ strlcpy(serio->name, dev->dev.bus_id, sizeof(serio->name));
++ strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
++ serio->port_data = ps2if;
++ serio->dev.parent = &dev->dev;
++ ps2if->io = serio;
++ ps2if->dev = dev;
++ platform_set_drvdata(dev, ps2if);
++
++ /*
++ * Request the physical region for this PS2 port.
++ */
++ if (dev->num_resources < 2) {
++ ret = -ENODEV;
++ goto out;
++ }
++ if (!request_mem_region(dev->resource[0].start,
++ 4,
++ "altps2")) {
++ ret = -EBUSY;
++ goto free;
++ }
++ ps2if->base = dev->resource[0].start;
++ ps2if->irq = dev->resource[1].start;
++ printk("altps2 : base %08x irq %d\n",ps2if->base,ps2if->irq);
++ // clear fifo
++ while ((status = inl(ps2if->base)) & 0xffff0000) {
++ }
++
++ serio_register_port(ps2if->io);
++ return 0;
++
++ out:
++ release_mem_region(dev->resource[0].start,4);
++ 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);
++ release_mem_region(dev->resource[0].start,4);
++
++ kfree(ps2if);
++
++ return 0;
++}
++
++/*
++ * Our device driver structure
++ */
++static struct platform_driver ps2_driver = {
++ .probe = ps2_probe,
++ .remove = ps2_remove,
++ .driver = {
++ .name = "altps2",
++ },
++};
++
++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);
+diff --git a/arch/nios2nommu/drivers/i2c-gpio.c b/arch/nios2nommu/drivers/i2c-gpio.c
+new file mode 100644
+index 0000000..3f5e51a
+--- /dev/null
++++ b/arch/nios2nommu/drivers/i2c-gpio.c
+@@ -0,0 +1,166 @@
++/*
++ * drivers/i2c/busses/i2c-gpio.c for Nios2
++ *
++ * drivers/i2c/busses/i2c-ixp2000.c
++ *
++ * I2C adapter for IXP2000 systems using GPIOs for I2C bus
++ *
++ * Author: Deepak Saxena <dsaxena@plexity.net>
++ * Based on IXDP2400 code by: Naeem M. Afzal <naeem.m.afzal@intel.com>
++ * Made generic by: Jeff Daly <jeffrey.daly@intel.com>
++ *
++ * Copyright (c) 2003-2004 MontaVista Software Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2. This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ *
++ * From Jeff Daly:
++ *
++ * I2C adapter driver for Intel IXDP2xxx platforms. This should work for any
++ * IXP2000 platform if it uses the HW GPIO in the same manner. Basically,
++ * SDA and SCL GPIOs have external pullups. Setting the respective GPIO to
++ * an input will make the signal a '1' via the pullup. Setting them to
++ * outputs will pull them down.
++ *
++ * The GPIOs are open drain signals and are used as configuration strap inputs
++ * during power-up so there's generally a buffer on the board that needs to be
++ * 'enabled' to drive the GPIOs.
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/module.h>
++#include <linux/i2c.h>
++#include <linux/i2c-algo-bit.h>
++#include <linux/i2c-id.h>
++
++#include <asm/io.h>
++#include <asm/gpio.h>
++
++static inline int gpio_scl_pin(void *data)
++{
++ return ((struct gpio_i2c_pins*)data)->scl_pin;
++}
++
++static inline int gpio_sda_pin(void *data)
++{
++ return ((struct gpio_i2c_pins*)data)->sda_pin;
++}
++
++
++static void gpio_bit_setscl(void *data, int val)
++{
++ int i = 5000;
++
++ if (val) {
++ outl(3,gpio_scl_pin(data));
++ while(!(inl(gpio_scl_pin(data)) & 1) && i--);
++ } else {
++ outl(2,gpio_scl_pin(data));
++ }
++}
++
++static void gpio_bit_setsda(void *data, int val)
++{
++ if (val) {
++ outl(1,gpio_sda_pin(data));
++ } else {
++ outl(0,gpio_sda_pin(data));
++ }
++}
++
++static int gpio_bit_getscl(void *data)
++{
++ return inl(gpio_scl_pin(data)) & 1;
++}
++
++static int gpio_bit_getsda(void *data)
++{
++ return inl(gpio_sda_pin(data)) & 1;
++}
++
++struct gpio_i2c_data {
++ struct gpio_i2c_pins *gpio_pins;
++ struct i2c_adapter adapter;
++ struct i2c_algo_bit_data algo_data;
++};
++
++static int gpio_i2c_remove(struct platform_device *plat_dev)
++{
++ struct gpio_i2c_data *drv_data = platform_get_drvdata(plat_dev);
++
++ platform_set_drvdata(plat_dev, NULL);
++
++ i2c_del_adapter(&drv_data->adapter);
++
++ kfree(drv_data);
++
++ return 0;
++}
++
++static int gpio_i2c_probe(struct platform_device *plat_dev)
++{
++ int err;
++ struct gpio_i2c_pins *gpio = plat_dev->dev.platform_data;
++ struct gpio_i2c_data *drv_data =
++ kzalloc(sizeof(struct gpio_i2c_data), GFP_KERNEL);
++
++ if (!drv_data)
++ return -ENOMEM;
++ drv_data->gpio_pins = gpio;
++
++ drv_data->algo_data.data = gpio;
++ drv_data->algo_data.setsda = gpio_bit_setsda;
++ drv_data->algo_data.setscl = gpio_bit_setscl;
++ drv_data->algo_data.getsda = gpio_bit_getsda;
++ drv_data->algo_data.getscl = gpio_bit_getscl;
++ drv_data->algo_data.udelay = 6;
++ drv_data->algo_data.timeout = 100;
++
++ drv_data->adapter.id = I2C_HW_B_IXP2000, // borrowed,
++ strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
++ I2C_NAME_SIZE);
++ drv_data->adapter.algo_data = &drv_data->algo_data,
++
++ drv_data->adapter.dev.parent = &plat_dev->dev;
++ drv_data->adapter.class = I2C_CLASS_ALL;
++
++ outl(1,gpio->sda_pin);
++ outl(1,gpio->scl_pin);
++
++ if ((err = i2c_bit_add_bus(&drv_data->adapter)) != 0) {
++ dev_err(&plat_dev->dev, "Could not install, error %d\n", err);
++ kfree(drv_data);
++ return err;
++ }
++
++ platform_set_drvdata(plat_dev, drv_data);
++ printk("i2c-gpio driver at %08x\n",gpio->sda_pin);
++
++ return 0;
++}
++
++static struct platform_driver gpio_i2c_driver = {
++ .probe = gpio_i2c_probe,
++ .remove = gpio_i2c_remove,
++ .driver = {
++ .name = "GPIO-I2C",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init gpio_i2c_init(void)
++{
++ return platform_driver_register(&gpio_i2c_driver);
++}
++
++static void __exit gpio_i2c_exit(void)
++{
++ platform_driver_unregister(&gpio_i2c_driver);
++}
++
++module_init(gpio_i2c_init);
++module_exit(gpio_i2c_exit);
++
+diff --git a/arch/nios2nommu/drivers/pci/Kconfig b/arch/nios2nommu/drivers/pci/Kconfig
+new file mode 100644
+index 0000000..6c3b175
+--- /dev/null
++++ b/arch/nios2nommu/drivers/pci/Kconfig
+@@ -0,0 +1,4 @@
++config PCI_ALTPCI
++ bool "Altera PCI host bridge"
++ select PCI
++ default n
+diff --git a/arch/nios2nommu/drivers/pci/Makefile b/arch/nios2nommu/drivers/pci/Makefile
+new file mode 100644
+index 0000000..b027e1e
+--- /dev/null
++++ b/arch/nios2nommu/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/nios2nommu/drivers/pci/altpci.c b/arch/nios2nommu/drivers/pci/altpci.c
+new file mode 100644
+index 0000000..85959ea
+--- /dev/null
++++ b/arch/nios2nommu/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/nios2nommu/drivers/pci/pci-auto.c b/arch/nios2nommu/drivers/pci/pci-auto.c
+new file mode 100644
+index 0000000..e1cdfdc
+--- /dev/null
++++ b/arch/nios2nommu/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/nios2nommu/drivers/pci/pci.c b/arch/nios2nommu/drivers/pci/pci.c
+new file mode 100644
+index 0000000..83436df
+--- /dev/null
++++ b/arch/nios2nommu/drivers/pci/pci.c
+@@ -0,0 +1,151 @@
++/* arch/sh/kernel/pci.c
++ * $Id: pci.c,v 1.2 2007/01/25 01:26:48 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/nios2nommu/drivers/pci/setup-irq.c b/arch/nios2nommu/drivers/pci/setup-irq.c
+new file mode 100644
+index 0000000..0fa8f98
+--- /dev/null
++++ b/arch/nios2nommu/drivers/pci/setup-irq.c
+@@ -0,0 +1 @@
++#include "../../../../drivers/pci/setup-irq.c"
+diff --git a/arch/nios2nommu/drivers/spi.c b/arch/nios2nommu/drivers/spi.c
+new file mode 100644
+index 0000000..72a2519
+--- /dev/null
++++ b/arch/nios2nommu/drivers/spi.c
+@@ -0,0 +1,315 @@
++#ifdef MODULE
++#include <linux/module.h>
++#include <linux/version.h>
++#else
++#define MOD_INC_USE_COUNT
++#define MOD_DEC_USE_COUNT
++#endif
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/major.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/ioport.h>
++#include <linux/fcntl.h>
++#include <linux/unistd.h>
++#include <linux/init.h>
++
++
++#include <asm/io.h>
++#include <asm/segment.h>
++#include <asm/system.h>
++#include <asm/spi.h>
++
++#if !defined(SEEK_SET)
++#define SEEK_SET 0
++#endif
++
++
++static unsigned int spi_major = 60; /* a local major, can be overwritten */
++static int openflag = 0;
++static np_spi * const spi_ptr = na_spi;
++
++ /*******************************/
++ /* SPI data transfer routines. */
++ /*******************************/
++
++#define SPI_XMIT_READY np_spistatus_trdy_mask
++#define SPI_RECV_READY np_spistatus_rrdy_mask
++
++#define SPI_BUSYPOLL_TIMEOUT 1000
++
++// returns -1 if there is no data present, otherwise returns
++// the value
++inline int SPI_Recv_Byte(char *pdata )
++{
++ if (spi_ptr->np_spistatus & SPI_RECV_READY){
++ *pdata = spi_ptr->np_spirxdata & 0xff;
++ return 0;
++ }
++ return -1;
++}
++
++
++// Sends the 16 bit address+data
++inline int SPI_Send_Byte( unsigned char address, char data )
++{
++ u16 value = ((address & 0xFF) << 8) | (data & 0xFF);
++
++ if ( spi_ptr->np_spistatus & SPI_XMIT_READY ) {
++ spi_ptr->np_spitxdata = value;
++ return 0;
++ }
++
++ return -1;
++}
++
++
++
++ /*************************/
++ /* SPI Driver functions. */
++ /*************************/
++
++int spi_reset( void )
++{
++ // Nothing to do: The Nios does _not_
++ // support burst xfers. Chip Enables
++ // (Selects) are inactive after each xfer.
++ return 0;
++}
++
++
++/***************************************************/
++/* The SPI Write routine. The first 16 bits are */
++/* the device register, and the rest of the buffer */
++/* is data. */
++/***************************************************/
++
++ssize_t spi_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
++{
++ int i;
++ unsigned char addr;
++ int timeout;
++ char temp;
++
++ if ( count < 3 )
++ return -EINVAL; /* Address is 2 bytes: Must have _something_ to send */
++
++ addr = buf[0]; /* chip register address. */
++ spi_ptr->np_spistatus=0;
++
++ for ( i = sizeof(u16); i<count; i++ )
++ {
++ timeout=SPI_BUSYPOLL_TIMEOUT;
++ while (SPI_Send_Byte(addr, buf[i])==-1)
++ {
++ if (--timeout==0)
++ {
++ printk("spi_write time out\n");
++ return i; /* return the number of bytes sent */
++ }
++ }
++ /* read the data */
++ timeout=SPI_BUSYPOLL_TIMEOUT;
++ while (SPI_Recv_Byte(&temp)==-1)
++ {
++ if (--timeout==0)
++ break;
++ }
++ }
++ return i;
++// unsigned char *temp; /* Our pointer to the buffer */
++// int i;
++// int addr;
++//
++// if ( count < 3 )
++// return -EINVAL; /* Address is 2 bytes: Must have _something_ to send */
++//
++// temp = (char *)buf;
++// addr = (int)*((u16 *)temp); /* chip register address. */
++// temp += sizeof(u16);
++//
++// for ( i = count - sizeof(u16); i; i--, temp++ )
++// *temp = (unsigned char)SPI_Transfer( addr, (int)*temp );
++//
++//
++// return count; /* we can always send all data */
++}
++
++//int spi_read( struct inode *inode, struct file *file, char *buf, int count )
++ssize_t spi_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
++{
++ int i;
++ unsigned char addr;
++ int timeout;
++ char temp;
++
++ if ( count < 3 )
++ return -EINVAL; /* Address is 2 bytes: Must have _something_ to send */
++
++ addr = buf[0]; /* chip register address. */
++ spi_ptr->np_spistatus=0;
++
++ /* empty the np_spirxdata register */
++ SPI_Recv_Byte(&temp);
++
++ for ( i = sizeof(u16); i<count; i++ )
++ {
++ /* send the address */
++ timeout=SPI_BUSYPOLL_TIMEOUT;
++ while (SPI_Send_Byte(addr, 0)==-1)
++ {
++ if (--timeout==0)
++ {
++ printk("spi_read write address time out\n");
++ return i;
++ }
++ }
++
++ /* read the data */
++ timeout=SPI_BUSYPOLL_TIMEOUT;
++ while (SPI_Recv_Byte(&buf[i])==-1)
++ {
++ if (--timeout==0)
++ {
++ printk("spi_read read data time out\n");
++ return i;
++ }
++ }
++#if 0
++ printk("spi_read time left %d\n", timeout);
++#endif
++ }
++ return i;
++}
++
++loff_t spi_lseek(struct file *filp, loff_t offset, int origin)
++{
++#if 0
++ int bit_count, i;
++#endif
++
++ if ( origin != SEEK_SET || offset != (offset & 0xFFFF) )
++ {
++ errno = -EINVAL;
++ return -1;
++ }
++
++#if 0
++ /****************************************/
++ /* Nios SPI implementation safeguard: */
++ /* It is possible to have more than */
++ /* one CS active at a time. Check that */
++ /* the given address is a power of two. */
++ /****************************************/
++ bit_count = 0;
++ for ( i = 0; i < sizeof(u16); i++ )
++ {
++ if ( (1 << i) & offset )
++ {
++ if ( ++bit_count > 1 )
++ {
++ errno = -EINVAL;
++ return -1;
++ }
++ }
++ }
++#endif
++ spi_ptr->np_spislaveselect = offset;
++ return 0;
++}
++
++int spi_open(struct inode *inode, struct file *filp)
++{
++ preempt_disable();
++ if (openflag) {
++ preempt_enable();
++ return -EBUSY;
++ }
++
++ MOD_INC_USE_COUNT;
++ openflag = 1;
++ preempt_enable();
++
++ return 0;
++}
++
++int spi_release(struct inode *inode, struct file *filp)
++{
++ openflag = 0;
++ MOD_DEC_USE_COUNT;
++ return 0;
++}
++
++
++/* static struct file_operations spi_fops */
++
++static struct file_operations spi_fops = {
++ llseek: spi_lseek, /* Set chip-select line. The offset is used as an address. */
++ read: spi_read,
++ write: spi_write,
++ open: spi_open,
++ release: spi_release,
++};
++
++
++int register_NIOS_SPI( void )
++{
++ int result = register_chrdev( spi_major, "spi", &spi_fops );
++ if ( result < 0 )
++ {
++ printk( "SPI: unable to get major %d for SPI bus \n", spi_major );
++ return result;
++ }/*end-if*/
++
++ if ( spi_major == 0 )
++ spi_major = result; /* here we got our major dynamically */
++
++ /* reserve our port, but check first if free */
++ if ( check_region( (unsigned int)na_spi, sizeof(np_spi) ) )
++ {
++ printk( "SPI: port at adr 0x%08x already occupied\n", (unsigned int)na_spi );
++ unregister_chrdev( spi_major, "spi" );
++
++ return result;
++ }/*end-if*/
++
++ return 0;
++}
++
++void unregister_NIOS_SPI( void )
++{
++ if ( spi_major > 0 )
++ unregister_chrdev( spi_major, "spi" );
++
++ release_region( (unsigned int)na_spi, sizeof(np_spi) );
++}
++
++
++#ifdef MODULE
++void cleanup_module( void )
++{
++ unregister_NIOS_SPI();
++}
++
++
++
++int init_module( void )
++{
++ return register_NIOS_SPI();
++}
++#endif
++
++
++static int __init nios_spi_init(void)
++{
++ printk("SPI: Nios SPI bus device version 0.1\n");
++ return register_NIOS_SPI();
++// if ( register_NIOS_SPI() )
++// printk("*** Cannot initialize SPI device.\n");
++}
++
++__initcall(nios_spi_init);
+diff --git a/arch/nios2nommu/kernel/ChangeLog b/arch/nios2nommu/kernel/ChangeLog
+new file mode 100644
+index 0000000..7f1449d
+--- /dev/null
++++ b/arch/nios2nommu/kernel/ChangeLog
+@@ -0,0 +1,27 @@
++2004-06-17 Ken Hill <khill@microtronix.com>
++
++ * process.c (machine_restart): Add code to disable interrups and
++ jump to the cpu reset address.
++ (machine_halt): Add code to disable interrupts and spinlock.
++ (machine_power_off): Add code to disable interrupts and spinlock.
++
++2004-06-16 Ken Hill <khill@microtronix.com>
++
++ * nios2_ksyms.c: Remove hard_reset_now.
++
++2004-06-10 Ken Hill <khill@microtronix.com>
++
++ * nios2_ksyms.c: Add EXPORT_SYMBOL_NOVERS(__down) to solve insmod for
++ some modules.
++
++2004-06-02 Ken Hill <khill@microtronix.com>
++
++ * entry.S (software_exception): Add a safety catch for old applications that may
++ have been linked against an older library. This does not add any overhead to
++ system call processing.
++
++2004-04-15 Ken Hill <khill@microtronix.com>
++
++ * setup.c (setup_arch): Remove ROMFS message from debug printk kernel message.
++ Add copyright and GNU license notice.
++
+diff --git a/arch/nios2nommu/kernel/Makefile b/arch/nios2nommu/kernel/Makefile
+new file mode 100644
+index 0000000..a056ff1
+--- /dev/null
++++ b/arch/nios2nommu/kernel/Makefile
+@@ -0,0 +1,22 @@
++#
++# 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 init_task.o vmlinux.lds
++
++obj-y := entry.o traps.o irq.o syscalltable.o \
++ process.o signal.o setup.o sys_nios2.o \
++ semaphore.o io.o usb.o\
++ time.o ptrace.o start.o nios2_ksyms.o
++
++obj-$(CONFIG_MODULES) += module.o
++obj-$(CONFIG_CONSOLE) += console.o
++obj-$(CONFIG_PIO_DEVICES) += pio.o
++obj-$(CONFIG_AVALON_DMA) += dma.o
++
++
+diff --git a/arch/nios2nommu/kernel/asm-offsets.c b/arch/nios2nommu/kernel/asm-offsets.c
+new file mode 100644
+index 0000000..4877eba
+--- /dev/null
++++ b/arch/nios2nommu/kernel/asm-offsets.c
+@@ -0,0 +1,201 @@
++/*
++ * 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/bootinfo.h>
++#include <asm/irq.h>
++#include <asm/hardirq.h>
++#include <asm/nios.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 kernel_stat struct */
++ DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
++
++ /* offsets into the irq_cpustat_t struct */
++ DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
++
++ /* offsets into the irq_node struct */
++ DEFINE(IRQ_HANDLER, offsetof(struct irq_hand, handler));
++ DEFINE(IRQ_FLAGS, offsetof(struct irq_hand, flags));
++ DEFINE(IRQ_DEV_ID, offsetof(struct irq_hand, dev_id));
++ DEFINE(IRQ_DEVNAME, offsetof(struct irq_hand, devname));
++
++ /* offsets into the thread struct */
++ DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
++ DEFINE(THREAD_KPSR, offsetof(struct thread_struct, kpsr));
++ DEFINE(THREAD_KESR, offsetof(struct thread_struct, kesr));
++ 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_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_STATUS_EXTENSION, offsetof(struct pt_regs, status_extension));
++ 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(PS_S_ASM, PS_S);
++
++ 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 into the kernel_stat struct */
++ DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
++
++ /* 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_NOTIFY_RESUME_ASM, TIF_NOTIFY_RESUME);
++ 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_NOTIFY_RESUME_ASM, _TIF_NOTIFY_RESUME);
++ 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);
++
++#if defined(na_flash_kernel) && defined(na_flash_kernel_end)
++ /* the flash chip */
++ DEFINE(NIOS_FLASH_START, na_flash_kernel);
++ DEFINE(NIOS_FLASH_END, na_flash_kernel_end);
++
++ /* the kernel placement in the flash*/
++ DEFINE(KERNEL_FLASH_START, na_flash_kernel);
++ DEFINE(KERNEL_FLASH_LEN, 0x200000);
++
++ /* the romdisk placement in the flash */
++ DEFINE(LINUX_ROMFS_START, na_flash_kernel+0x200000);
++ DEFINE(LINUX_ROMFS_END, na_flash_kernel_end);
++#else
++#error Sorry,you dont have na_flash_kernel or na_flash_kernel_end defined in the core.
++#endif
++
++#if defined(nasys_program_mem) && defined(nasys_program_mem_end)
++ /* the sdram */
++ DEFINE(LINUX_SDRAM_START, nasys_program_mem);
++ DEFINE(LINUX_SDRAM_END, nasys_program_mem_end);
++#else
++#error Sorry,you dont have nasys_program_mem or nasys_program_mem_end defined in the core.
++#endif
++
++ DEFINE(NIOS2_ICACHE_SIZE, nasys_icache_size);
++ DEFINE(NIOS2_ICACHE_LINE_SIZE, nasys_icache_line_size);
++ DEFINE(NIOS2_DCACHE_SIZE, nasys_dcache_size);
++ DEFINE(NIOS2_DCACHE_LINE_SIZE, nasys_dcache_line_size);
++
++#if defined(na_enet)
++ DEFINE(NA_ENET_ASM, na_enet);
++#endif
++
++#if defined(na_enet_reset)
++ DEFINE(NA_ENET_RESET_ASM, na_enet_reset);
++#endif
++
++#if defined(na_enet_reset_n)
++ DEFINE(NA_ENET_RESET_N_ASM, na_enet_reset_n);
++#endif
++
++#if defined(na_ide_interface)
++ DEFINE(NA_IDE_INTERFACE_ASM, na_ide_interface);
++#endif
++
++#if defined(na_timer0)
++ DEFINE(NA_TIMER0_ASM, na_timer0);
++ DEFINE(NP_TIMERCONTROL_ASM, offsetof(np_timer, np_timercontrol));
++ DEFINE(NP_TIMERSTATUS_ASM, offsetof(np_timer, np_timerstatus));
++#endif
++
++#if defined(na_uart0)
++ DEFINE(NA_UART0_ASM, na_uart0);
++ DEFINE(NP_UARTCONTROL_ASM, offsetof(np_uart, np_uartcontrol));
++ DEFINE(NP_UARTSTATUS_ASM, offsetof(np_uart, np_uartstatus));
++#endif
++
++#if defined(na_uart1)
++ DEFINE(NA_UART1_ASM, na_uart1);
++#endif
++
++#if defined(na_uart2)
++ DEFINE(NA_UART2_ASM, na_uart2);
++#endif
++
++#if defined(na_uart3)
++ DEFINE(NA_UART3_ASM, na_uart3);
++#endif
++
++ return 0;
++}
+diff --git a/arch/nios2nommu/kernel/dma.c b/arch/nios2nommu/kernel/dma.c
+new file mode 100644
+index 0000000..f23323b
+--- /dev/null
++++ b/arch/nios2nommu/kernel/dma.c
+@@ -0,0 +1,342 @@
++/*
++ * 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 sizeof(dma_channels)/sizeof(struct dma_channel)
++
++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 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)
++{
++ struct proc_dir_entry *e;
++
++ e = create_proc_entry("dma", 0, NULL);
++ if (e)
++ e->proc_fops = &proc_dma_operations;
++
++ return 0;
++}
++
++__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/nios2nommu/kernel/entry.S b/arch/nios2nommu/kernel/entry.S
+new file mode 100644
+index 0000000..7f71a01
+--- /dev/null
++++ b/arch/nios2nommu/kernel/entry.S
+@@ -0,0 +1,898 @@
++/*
++ * linux/arch/nios2nommu/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>
++
++.text
++.set noat
++.set nobreak
++
++ENTRY(system_call)
++/* SAVE_ALL */
++ rdctl r10,status /* enable intrs again */
++ ori r10,r10,0x0001
++ wrctl status,r10
++
++ movi r2,-LENOSYS
++ stw r2,PT_R2(sp) /* default return value in r2 */
++ /* original r2 is in orig_r2 */
++
++ movui r1,NR_syscalls
++ bgtu r3,r1,ret_from_exception
++ slli r1,r3,2
++ movhi r11,%hiadj(sys_call_table)
++ add r1,r1,r11
++ ldw r1,%lo(sys_call_table)(r1)
++ beq r1,r0,ret_from_exception
++
++ movi r11,%lo(0xffffe000) /* Get thread info pointer */
++ and r11,sp,r11
++ ldw r11,TI_FLAGS(r11)
++ BTBNZ r11,r11,TIF_SYSCALL_TRACE_ASM,1f
++
++ callr r1
++ stw r2,PT_R2(sp) /* save the return value */
++ br ret_from_exception
++1:
++ SAVE_SWITCH_STACK
++ call syscall_trace
++ RESTORE_SWITCH_STACK
++ /* wentao: restore r4-9, since they are trashed by syscall_trace */
++ 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)
++ callr r1
++ stw r2,PT_R2(sp) /* save the return value */
++ SAVE_SWITCH_STACK
++ call syscall_trace
++ RESTORE_SWITCH_STACK
++
++ret_from_exception:
++ ldw r1,PT_STATUS_EXTENSION(sp) /* check if returning to kernel */
++ TSTBZ r1,r1,PS_S_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
++
++Luser_return:
++ GET_THREAD_INFO r24 /* get thread_info pointer */
++ ldw r10,TI_FLAGS(r24) /* 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 */
++ call do_signal
++ RESTORE_SWITCH_STACK
++ br restore_all
++
++/*
++ * Handle software exceptions. Put here so external interrupts
++ * can fall throught to ret_from_interrupt.
++ */
++
++software_exception:
++ ldw r24,-4(ea) // instruction that caused the exception
++ xorhi r24,r24,0x003b // upper half of trap opcode
++ xori r24,r24,0x683a // lower half of trap opcode
++ bne r24,r0,instruction_trap /* N - check for instruction trap */
++ cmpeqi r11,r2,TRAP_ID_SYSCALL /* ? Is this a syscall */
++ bne r11,r0,system_call /* Y - handle syscall */
++ cmpeqi r11,r2,TRAP_ID_APPDEBUG /* ? Is this an application debug */
++ bne r11,r0,app_debug /* Y - handle app_debug */
++ cmpeqi r11,r2,63 /* ? Is this the old syscall number */
++ bne r11,r0,system_call /* Y - handle syscall to catch older apps*/
++ br restore_all /* N - everything else is ignored for now */
++
++app_debug:
++ GET_THREAD_INFO r24 /* get thread_info */
++ ldw r1,TI_TASK(r24) /* get thread_info->task */
++ ldw r24,(TASK_THREAD + THREAD_FLAGS)(r1) /* get thread_info->task->thread.flags */
++ ORI32 r24, r24, NIOS2_FLAG_DEBUG /* set the debug flag */
++ stw r24,(TASK_THREAD + THREAD_FLAGS)(r1) /* save thread_info->task->thread.flags */
++ br restore_all
++
++/*
++ * 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.
++ */
++ENTRY(inthandler)
++ SAVE_ALL
++ /*
++ * Test to see if the exception was a software exception or caused by an
++ * external interrupt, and vector accordingly.
++ */
++
++ rdctl r24,estatus
++ andi r24,r24,1
++ beq r24,r0,software_exception
++ rdctl r12,ipending
++ beq r12,r0,software_exception
++
++ 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)
++ rdctl r9,ienable /* Isolate possible interrupts */
++ and r12,r12,r9
++ beq r12,r0,ret_from_interrupt /* No one to service done */
++ movi r4,%lo(-1) /* Start from bit position 0, highest priority */
++ /* This is the IRQ # for handler call */
++1: addi r4,r4,1
++ srl r10,r12,r4
++ andi r10,r10,1 /* Isolate bit we are interested in */
++ cmpeqi r11,r4,32 /* ? End of the register */
++ bne r11,r0,ret_from_interrupt /* Y - out of here */
++ beq r10,r0,1b
++ mov r5,sp /* Setup pt_regs pointer for handler call */
++ PUSH r4 /* Save state for return */
++ PUSH r12
++ call process_int
++ POP r12
++ POP r4
++ br 1b /* Check for other interrupts while here */
++
++ENTRY(ret_from_interrupt)
++ ldw r4,PT_STATUS_EXTENSION(sp)
++ TSTBZ r4,r4,PS_S_ASM,Luser_return // Returning to user
++
++#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
++
++
++/*
++ * 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
++
++ movia r8,status_extension /* save status extension */
++ ldw r7,0(r8)
++ stw r7,TASK_THREAD+THREAD_KESR(r4)
++
++ 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_KESR(r5) /* restore extended status reg */
++ stw r7,0(r8)
++
++ 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
++
++ENTRY(sys_fork)
++ mov r4,sp
++ SAVE_SWITCH_STACK
++ call nios2_vfork
++ 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
++ 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
++ call do_rt_sigreturn
++ RESTORE_SWITCH_STACK
++ ret
++
++/******************************************************************************
++* *
++* 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. *
++* *
++******************************************************************************/
++
++ /*
++ * This is the software exception handler for Nios2.
++ */
++
++ /*
++ * 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/nios2nommu/kernel/head.S b/arch/nios2nommu/kernel/head.S
+new file mode 100644
+index 0000000..f1cba65
+--- /dev/null
++++ b/arch/nios2nommu/kernel/head.S
+@@ -0,0 +1,228 @@
++/*
++ * 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 <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 status_extension
++status_extension:
++ .long 0
++
++ .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).
++ */
++ .text
++ .global _start
++_start:
++ 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
++ */
++
++ movia r24,inthandler
++ jmp r24
++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
++
++NR_MoveStart:
++#ifdef CONFIG_BREAK_ON_START
++ break
++#endif //CONFIG_BREAK_ON_START
++ 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:
++
++ //------------------------------------
++ // Disable interrupts on known devices
++ //
++#ifdef NA_ENET_ASM
++#ifdef NA_ENET_RESET_ASM
++ movia r1,NA_ENET_RESET_ASM // ethernet reset address
++ stwio r0,0(r1) // reset
++#endif
++#ifdef NA_ENET_RESET_N_ASM
++ movia r1,NA_ENET_RESET_N_ASM // ethernet reset address
++ stwio r0,0(r1) // reset
++#endif
++ nop // give it some time
++ nop //
++ nop //
++ nop //
++#endif
++#ifdef NA_TIMER0_ASM
++ movia r1,NA_TIMER0_ASM // get timer address
++ stwio r0,NP_TIMERCONTROL_ASM(r1) // clear interrupt enable
++ stwio r0,NP_TIMERSTATUS_ASM(r1) // clear interrupt condition
++#endif
++#ifdef NA_UART0_ASM
++ movia r1,NA_UART0_ASM
++ stwio r0,NP_UARTCONTROL_ASM(r1) // clear interrupt enable
++ stwio r0,NP_UARTSTATUS_ASM(r1) // clear interrupt status
++#endif
++#ifdef NA_UART1_ASM
++ movia r1,NA_UART1_ASM
++ stwio r0,NP_UARTCONTROL_ASM(r1) // clear interrupt enable
++ stwio r0,NP_UARTSTATUS_ASM(r1) // clear interrupt status
++#endif
++#ifdef NA_UART2_ASM
++ movia r1,NA_UART2_ASM
++ stwio r0,NP_UARTCONTROL_ASM(r1) // clear interrupt enable
++ stwio r0,NP_UARTSTATUS_ASM(r1) // clear interrupt status
++#endif
++#ifdef NA_UART3_ASM
++ movia r1,NA_UART3_ASM
++ stwio r0,NP_UARTCONTROL_ASM(r1) // clear interrupt enable
++ stwio r0,NP_UARTSTATUS_ASM(r1) // clear interrupt status
++#endif
++#ifdef NA_IDE_INTERFACE_ASM
++ movia r1,NA_IDE_INTERFACE_ASM // ATA reset
++ stwio r0,0(r1) // write to control register
++#endif
++#ifdef NA_ENET_ASM
++#ifdef NA_ENET_RESET_ASM
++ movia r1,NA_ENET_RESET_ASM // ethernet reset address
++ movui r2,1 // reset
++ stwio r2,0(r1) //
++#endif
++#ifdef NA_ENET_RESET_N_ASM
++ movia r1,NA_ENET_RESET_N_ASM // ethernet reset address
++ movui r2,1 // reset
++ stwio r2,0(r1) //
++#endif
++#endif
++ wrctl ienable,r0 // Mask off all possible interrupts
++
++ //------------------------------------------------------
++ // 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
++
++ //------------------------------------------------------
++ // Call main() with interrupts disabled
++ //
++ movia r1,status_extension // get the STATUS extension address
++ movi r2,PS_S_ASM // set initial mode = supervisor
++ stw r2,0(r1)
++
++ 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/nios2nommu/kernel/init_task.c b/arch/nios2nommu/kernel/init_task.c
+new file mode 100644
+index 0000000..867e8fb
+--- /dev/null
++++ b/arch/nios2nommu/kernel/init_task.c
+@@ -0,0 +1,69 @@
++/*--------------------------------------------------------------------
++ *
++ * 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 fs_struct init_fs = INIT_FS;
++static struct files_struct init_files = INIT_FILES;
++static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
++static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
++struct mm_struct init_mm = INIT_MM(init_mm);
++
++EXPORT_SYMBOL(init_mm);
++
++/*
++ * 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
++ __attribute__((__section__(".data.init_task"))) =
++ { INIT_THREAD_INFO(init_task) };
++
+diff --git a/arch/nios2nommu/kernel/io.c b/arch/nios2nommu/kernel/io.c
+new file mode 100644
+index 0000000..e1b0b12
+--- /dev/null
++++ b/arch/nios2nommu/kernel/io.c
+@@ -0,0 +1,143 @@
++/*--------------------------------------------------------------------
++ *
++ * Optimized IO string functions.
++ *
++ * 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/io.h>
++
++void insl(unsigned long port, void *dst, unsigned long count)
++{
++ unsigned long read32;
++
++ if ((unsigned long)dst & 2){
++ /* Unaligned destination pointer, need to do
++ * two 16 bit writes for each read.
++ */
++ unsigned short *p=(unsigned short*)dst;
++ while (count--){
++ read32 = inl(port);
++ *p++ = read32 & 0xFFFF;
++ *p++ = read32 >> 16;
++ }
++ }
++ else {
++ unsigned long *p=(unsigned long*)dst;
++ while (count--)
++ *p++ = inl(port);
++ }
++}
++
++void insw(unsigned long port, void *dst, unsigned long count)
++{
++ unsigned long dst1=(unsigned long)dst;
++ if (count > 8) {
++ /* Long word align buffer ptr */
++ if (dst1 & 2) {
++ *(unsigned short*)dst1 = inw(port);
++ dst1 += sizeof(unsigned short);
++ count--;
++ }
++
++ /* Input pairs of short and store as longs */
++ while (count >= 8) {
++ *((unsigned long *)dst1) = inw(port) + (inw(port) << 16); dst1+=sizeof(unsigned long);
++ *((unsigned long *)dst1) = inw(port) + (inw(port) << 16); dst1+=sizeof(unsigned long);
++ *((unsigned long *)dst1) = inw(port) + (inw(port) << 16); dst1+=sizeof(unsigned long);
++ *((unsigned long *)dst1) = inw(port) + (inw(port) << 16); dst1+=sizeof(unsigned long);
++ count -= 8;
++ }
++ }
++
++ /* Input remaining shorts */
++ while (count--) {
++ *((unsigned short *)dst1) = inw(port);
++ dst1 += sizeof(unsigned short);
++ }
++}
++
++
++void outsl(unsigned long port, void *src, unsigned long count)
++{
++ unsigned long src1=(unsigned long)src;
++ unsigned long write32;
++
++ if (src1 & 2){
++ /* Unaligned source pointer, need to read
++ * two 16 bit shorts before writing to register.
++ */
++ while (count--){
++ write32 = *(unsigned short *)src1;
++ src1+=sizeof(unsigned short);
++ write32 |= *((unsigned short *)src1) << 16;
++ src1+=sizeof(unsigned short);
++ outl(write32,port);
++ }
++ }
++ else {
++ while (count--) {
++ outl(*(unsigned long *)src1,port);
++ src1+=sizeof(unsigned long);
++ }
++ }
++}
++
++void outsw(unsigned long port, void *src, unsigned long count)
++{
++ unsigned int lw;
++ unsigned long src1=(unsigned long)src;
++
++ if (count > 8) {
++ /* Long word align buffer ptr */
++ if (src1 & 2) {
++ outw( *(unsigned short *)src1, port );
++ count--;
++ src1 += sizeof(unsigned short);
++ }
++
++ /* Read long words and output as pairs of short */
++ while (count >= 8) {
++ lw = *(unsigned long *)src1;
++ src1+=sizeof(unsigned long);
++ outw(lw, port);
++ outw((lw >> 16), port);
++ lw = *(unsigned long *)src1;
++ src1+=sizeof(unsigned long);
++ outw(lw, port);
++ outw((lw >> 16), port);
++ lw = *(unsigned long *)src1;
++ src1+=sizeof(unsigned long);
++ outw(lw, port);
++ outw((lw >> 16), port);
++ lw = *(unsigned long *)src1;
++ src1+=sizeof(unsigned long);
++ outw(lw, port);
++ outw((lw >> 16), port);
++ count -= 8;
++ }
++ }
++
++ /* Output remaining shorts */
++ while (count--) {
++ outw( *(unsigned short *)src1, port );
++ src1 += sizeof(unsigned short);
++ }
++}
+diff --git a/arch/nios2nommu/kernel/irq.c b/arch/nios2nommu/kernel/irq.c
+new file mode 100644
+index 0000000..f1b2347
+--- /dev/null
++++ b/arch/nios2nommu/kernel/irq.c
+@@ -0,0 +1,245 @@
++/*
++ * linux/arch/$(ARCH)/irq.c -- general exception handling code
++ *
++ * Cloned from Linux/m68k.
++ *
++ * No original Copyright holder listed,
++ * Probabily original (C) Roman Zippel (assigned DJD, 1999)
++ *
++ * Copyright 1999-2000 D. Jeff Dionne, <jeff@rt-control.com>
++ *
++ * 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/module.h>
++#include <linux/sched.h>
++#include <linux/kernel_stat.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/seq_file.h>
++
++#include <asm/system.h>
++#include <asm/irq.h>
++#include <asm/page.h>
++#include <asm/nios.h>
++#include <asm/hardirq.h>
++
++/* table for system interrupt handlers */
++irq_hand_t irq_list[NR_IRQS];
++
++/* The number of spurious interrupts */
++volatile unsigned int num_spurious;
++
++#define NUM_IRQ_NODES 16
++static irq_node_t nodes[NUM_IRQ_NODES];
++
++void __init init_irq_proc(void)
++{
++ /* Insert /proc/irq driver here */
++}
++
++static irqreturn_t default_irq_handler(int irq, void *ptr)
++{
++#if 1
++ printk(KERN_INFO "%s(%d): default irq handler vec=%d [0x%x]\n",
++ __FILE__, __LINE__, irq, irq);
++#endif
++ disable_irq(irq);
++ return(IRQ_NONE);
++}
++
++/*
++ * void init_IRQ(void)
++ *
++ * Parameters: None
++ *
++ * Returns: Nothing
++ *
++ * This function should be called during kernel startup to initialize
++ * the IRQ handling routines.
++ */
++
++void __init init_IRQ(void)
++{
++ int i;
++
++ for (i = 0; i < NR_IRQS; i++) {
++ irq_list[i].handler = default_irq_handler;
++ irq_list[i].flags = IRQ_FLG_STD;
++ irq_list[i].dev_id = NULL;
++ irq_list[i].devname = NULL;
++ }
++
++ for (i = 0; i < NUM_IRQ_NODES; i++)
++ nodes[i].handler = NULL;
++
++ /* turn off all interrupts */
++ clrimr(0);
++
++#ifdef DEBUG
++ printk("init_IRQ done\n");
++#endif
++}
++
++irq_node_t *new_irq_node(void)
++{
++ irq_node_t *node;
++ short i;
++
++ for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
++ if (!node->handler)
++ return node;
++
++ printk (KERN_INFO "new_irq_node: out of nodes\n");
++ return NULL;
++}
++
++int request_irq(unsigned int irq,
++ irq_handler_t handler,
++ unsigned long flags,
++ const char *devname,
++ void *dev_id)
++{
++ if (irq >= NR_IRQS) {
++ printk (KERN_ERR "%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
++ return -ENXIO;
++ }
++
++ if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
++ if (irq_list[irq].flags & IRQ_FLG_LOCK) {
++ printk(KERN_ERR "%s: IRQ %d from %s is not replaceable\n",
++ __FUNCTION__, irq, irq_list[irq].devname);
++ return -EBUSY;
++ }
++ if (flags & IRQ_FLG_REPLACE) {
++ printk(KERN_ERR "%s: %s can't replace IRQ %d from %s\n",
++ __FUNCTION__, devname, irq, irq_list[irq].devname);
++ return -EBUSY;
++ }
++ }
++ irq_list[irq].handler = handler;
++ irq_list[irq].flags = flags;
++ irq_list[irq].dev_id = dev_id;
++ irq_list[irq].devname = devname;
++
++ setimr(1<<irq);
++
++ return 0;
++}
++
++void free_irq(unsigned int irq, void *dev_id)
++{
++ if (irq >= NR_IRQS) {
++ printk (KERN_ERR "%s: Unknown IRQ %d\n", __FUNCTION__, irq);
++ return;
++ }
++
++ if (irq_list[irq].dev_id != dev_id)
++ printk(KERN_ERR "%s: Removing probably wrong IRQ %d from %s\n",
++ __FUNCTION__, irq, irq_list[irq].devname);
++
++ irq_list[irq].handler = default_irq_handler;
++ irq_list[irq].flags = IRQ_FLG_STD;
++ irq_list[irq].dev_id = NULL;
++ irq_list[irq].devname = NULL;
++
++ clrimr(~(1<<irq));
++}
++
++/* usually not useful in embedded systems */
++unsigned long probe_irq_on (void)
++{
++ return 0;
++}
++
++int probe_irq_off (unsigned long irqs)
++{
++ return 0;
++}
++
++void enable_irq(unsigned int irq)
++{
++ setimr(1<<irq);
++}
++
++void disable_irq(unsigned int irq)
++{
++ clrimr(~(1<<irq));
++}
++
++int show_interrupts(struct seq_file *p, void *v)
++{
++ int i = *(loff_t *) v;
++
++ if (i == 0) {
++ seq_printf(p, " : %10u spurious\n", num_spurious);
++ }
++
++ if ((i < NR_IRQS) && (!(irq_list[i].flags & IRQ_FLG_STD))) {
++ seq_printf(p, "%3d: %10u ", i, kstat_cpu(0).irqs[i]);
++ if (irq_list[i].flags & IRQ_FLG_LOCK)
++ seq_printf(p, "L ");
++ else
++ seq_printf(p, " ");
++ seq_printf(p, "%s\n", irq_list[i].devname);
++ }
++
++ return 0;
++}
++
++#ifdef CONFIG_PREEMPT_TIMES
++extern void latency_cause(int,int);
++#else
++#define latency_cause(a, b)
++#endif
++asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
++{
++
++ /* give the machine specific code a crack at it first */
++ irq_enter();
++ kstat_cpu(0).irqs[vec]++;
++ latency_cause(-99,~vec);
++
++ if (irq_list[vec].handler) {
++ if ((irq_list[vec].handler(vec, irq_list[vec].dev_id))==IRQ_NONE)
++ ;
++ } else
++#ifdef DEBUG
++ {
++ printk(KERN_ERR "No interrupt handler for level %ld\n", vec);
++//// asm("trap 5");
++ }
++#else
++ #if 1
++ printk(KERN_ERR "Ignoring interrupt %ld: no handler\n", vec);
++ #else
++ panic("No interrupt handler for level %ld\n", vec);
++ #endif
++#endif
++
++ irq_exit();
++}
++
++int get_irq_list(char *buf)
++{
++ int i, len = 0;
++
++ /* autovector interrupts */
++ for (i = 0; i < NR_IRQS; i++) {
++ if (irq_list[i].handler) {
++ len += sprintf(buf+len, "auto %2d: %10u ", i,
++ i ? kstat_cpu(0).irqs[i] : num_spurious);
++ if (irq_list[i].flags & IRQ_FLG_LOCK)
++ len += sprintf(buf+len, "L ");
++ else
++ len += sprintf(buf+len, " ");
++ len += sprintf(buf+len, "%s\n", irq_list[i].devname);
++ }
++ }
++ return len;
++}
++EXPORT_SYMBOL(request_irq);
++EXPORT_SYMBOL(free_irq);
+diff --git a/arch/nios2nommu/kernel/module.c b/arch/nios2nommu/kernel/module.c
+new file mode 100644
+index 0000000..99b270f
+--- /dev/null
++++ b/arch/nios2nommu/kernel/module.c
+@@ -0,0 +1,173 @@
++/* 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>
++
++#if 0
++#define DEBUGP printk
++#else
++#define DEBUGP(fmt , ...)
++#endif
++
++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. */
++}
++
++/* 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;
++
++ 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/nios2nommu/kernel/nios2_ksyms.c b/arch/nios2nommu/kernel/nios2_ksyms.c
+new file mode 100644
+index 0000000..720f007
+--- /dev/null
++++ b/arch/nios2nommu/kernel/nios2_ksyms.c
+@@ -0,0 +1,113 @@
++/*--------------------------------------------------------------------
++ *
++ * 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/semaphore.h>
++#include <asm/checksum.h>
++#include <asm/hardirq.h>
++#include <asm/current.h>
++
++extern void dump_thread(struct pt_regs *, struct user *);
++/* platform dependent support */
++
++EXPORT_SYMBOL(__ioremap);
++EXPORT_SYMBOL(iounmap);
++EXPORT_SYMBOL(dump_fpu);
++EXPORT_SYMBOL(dump_thread);
++
++EXPORT_SYMBOL(kernel_thread);
++
++/* Networking helper routines. */
++EXPORT_SYMBOL(csum_partial_copy);
++
++EXPORT_SYMBOL(memcpy);
++EXPORT_SYMBOL(memset);
++EXPORT_SYMBOL(memmove);
++
++EXPORT_SYMBOL(__down);
++EXPORT_SYMBOL(__down_interruptible);
++EXPORT_SYMBOL(__down_trylock);
++EXPORT_SYMBOL(__up);
++
++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/nios2nommu/kernel/nios_gdb_stub.c b/arch/nios2nommu/kernel/nios_gdb_stub.c
+new file mode 100644
+index 0000000..103925b
+--- /dev/null
++++ b/arch/nios2nommu/kernel/nios_gdb_stub.c
+@@ -0,0 +1,1456 @@
++// Modified for uClinux - Vic - Apr 2002
++// From:
++
++// File: nios_gdb_stub.c
++// Date: 2000 June 20
++// Author dvb \ Altera Santa Cruz
++
++#ifndef __KERNEL__
++#include "nios.h"
++#else
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <asm/nios.h>
++#endif
++
++#include "nios_gdb_stub.h"
++
++#define na_debug_peripheral_irq 8
++
++enum
++{
++ na_BreakpointTrap = 3,
++ na_SingleStepTrap = 4,
++ na_StartGDBTrap = 5
++};
++
++
++#ifdef __KERNEL__
++
++extern int _etext;
++
++static void puts( unsigned char *s )
++{
++ while(*s) {
++ while (!(nasys_printf_uart->np_uartstatus & np_uartstatus_trdy_mask));
++ nasys_printf_uart->np_uarttxdata = *s++;
++ }
++}
++
++#endif // __KERNEL__
++
++// --------------------------------
++// Local Prototypes
++
++#if GDB_DEBUG_PRINT
++
++static void StringFit(char *s,int w);
++
++// --------------------------------
++// Debugging The Debugger
++
++void GDB_RawMessage(char *s)
++ {
++ StringFit(s,32);
++ nr_pio_lcdwritescreen(s);
++ }
++#else
++ #define GDB_RawMessage(a,b,c) // define away to nothing
++#endif
++
++#if GDB_DEBUG_PRINT
++void GDB_Print2(char *s,int n1,int n2)
++ {
++ char st[1000];
++
++ sprintf(st,s,n1,n2);
++ GDB_RawMessage(st);
++ }
++#else
++ #define GDB_Print2(a,b,c) // define away to nothing
++#endif
++
++// If string is longer than w, cut out the middle.
++
++#if GDB_DEBUG_PRINT
++int StringLen(char *s)
++ {
++ int l = 0;
++
++ while(*s++)
++ l++;
++ return l;
++ }
++
++static void StringFit(char *s,int w)
++ {
++ if(StringLen(s) > w)
++ {
++ int i;
++
++
++ w = w / 2;
++
++ for(i = 0; i < w; i++)
++ {
++ s[i + w] = s[StringLen(s) - w + i];
++ }
++ s[w + w] = 0;
++ }
++ }
++#endif
++
++// ---------------------------------------------
++// Generic routines for dealing with
++// hex input, output, and parsing
++// (Adapted from other stubs.)
++
++NiosGDBGlobals gdb = {0}; // not static: the ISR uses it!
++
++static char dHexChars[16] = "0123456789abcdef";
++
++/*
++ * HexCharToValue -- convert a characters
++ * to its hex value, or -1 if not.
++ */
++char HexCharToValue(char c)
++{
++ char result=0;
++
++ if(c >= '0' && c <= '9')
++ result = c - '0';
++ else if(c >= 'a' && c <= 'f')
++ result = c - 'a' + 10;
++ else if(c >= 'A' && c <= 'F')
++ result = c - 'A' + 10;
++ else
++ result = -1;
++ return result;
++}
++
++/*
++ * HexStringToValue -- convert a 2*byte_width string of characters
++ * to its little endian hex value,
++ * or -1 if not.
++ * This routine is for strings of hex values
++ */
++unsigned long HexStringToValue(char *c, int byte_width)
++{
++ unsigned long result=0;
++ unsigned char a,b;
++ int i=0;
++
++ while (i < byte_width)
++ {
++ a = HexCharToValue(*c++);
++ if (a & 0x80) return a;
++ b = HexCharToValue(*c++);
++ if (b & 0x80) return b;
++ b = (a<<4) | (b&0x0f);
++ result |= b << (i*8);
++ i++;
++ }
++ return result;
++}
++
++/*
++ * Hex2Value -- convert a non-hex char delimited string
++ * to its big endian hex value.
++ * This routine is for address and byte count values
++ */
++
++char *Hex2Value(char *hexIn, int *valueOut)
++ {
++ char c;
++ int digitValue;
++ int value = 0;
++
++ while(1)
++ {
++ c = *hexIn;
++ digitValue = HexCharToValue(c);
++ if(digitValue < 0)
++ {
++ *valueOut = value;
++ return hexIn;
++ }
++ hexIn++;
++ value = (value << 4) + digitValue;
++ }
++ }
++
++/*
++ * HexToMem -- convert a string to a specified
++ * number of bytes in memory.
++ *
++ * JMB -- make this thing a bit smarter so
++ * that it selects the byte width to
++ * write based on the number of bytes
++ * and the destination address alignment.
++ * This is to support writes to non-byte enabled
++ * peripheral registers...I don't like it.
++ * Beware! there are cases where it wont work
++ */
++char *HexToMem(char *hexIn, char *memOut, int memByteCount)
++{
++ int i;
++ unsigned long x;
++ short *memOutS=0;
++ long *memOutL=0;
++ int byte_width;
++
++ //determine maximum byte width
++ if (((memByteCount%2) != 0) || (((unsigned int)memOut%2) != 0))
++ byte_width = 1;
++ else if (((memByteCount % 4) != 0) || (((unsigned int)memOut % 4) != 0))
++ {
++ byte_width = 2;
++ memOutS = (short *)memOut;
++ }
++ else
++ {
++ byte_width = 4;
++ memOutL = (long *)memOut;
++ }
++ for(i = 0; i < memByteCount; i+=byte_width)
++ {
++ x = HexStringToValue(hexIn,byte_width);
++ hexIn += byte_width*2;
++ switch (byte_width)
++ {
++ case 1:
++ *memOut++ = (unsigned char) 0x000000ff & x;
++ break;
++ case 2:
++ *memOutS++ = (unsigned short) 0x0000ffff & x;
++ break;
++ case 4:
++ *memOutL++ = x;
++ break;
++ default:
++ //How could this ever happen???
++ break;
++ }
++ }
++
++ return hexIn;
++}
++
++char *MemToHex(char *memIn, char *hexOut, int memByteCount)
++{
++ int i,j;
++ int byte_width;
++ unsigned long x=0;
++ unsigned short *memInS=0;
++ unsigned long *memInL=0;
++
++ //determine maximum byte width
++ if (((memByteCount % 2) != 0) || (((unsigned int)memIn % 2) != 0))
++ byte_width = 1;
++ else if (((memByteCount % 4) != 0) || (((unsigned int)memIn % 4) != 0))
++ {
++ byte_width = 2;
++ memInS = (short *)memIn;
++ }
++ else
++ {
++ byte_width = 4;
++ memInL = (long *)memIn;
++ }
++
++ for(i = 0; i < memByteCount; i+=byte_width)
++ {
++ switch (byte_width)
++ {
++ case 1:
++ x = *memIn++;
++ break;
++ case 2:
++ x = *memInS++;
++ break;
++ case 4:
++ x = *memInL++;
++ break;
++ default:
++ //How would we get here?
++ break;
++ }
++
++ for (j=0; j<byte_width; j++)
++ {
++ *hexOut++ = dHexChars[(x&0x000000f0)>>4];
++ *hexOut++ = dHexChars[x&0x0000000f];
++ x = x>>8;
++ }
++ }
++
++ *hexOut = 0;
++
++ return hexOut;
++}
++
++//Send just the + or - to indicate
++//ACK or NACK
++void GDBPutAck (char ack)
++{
++ if (gdb.comlink == ne_gdb_serial)
++ GDBPutChar (ack);
++#ifdef ETHER_DEBUG
++#ifdef ethernet_exists
++ else
++ {
++ if (gdb.host_ip_address != 0)
++ nr_plugs_send_to (gdb.gdb_eth_plug, &ack, 1, 0,
++ gdb.host_ip_address,
++ gdb.host_port_number);
++ }
++#endif
++#endif
++}
++
++/*
++ * Once a $ comes in, use GetGDBPacket to
++ * retrieve a full gdb packet, and verify
++ * checksum, and reply + or -.
++ */
++int GetGDBPacket(char *aBuffer)
++{
++ int checksum=0;
++ int length=0;
++ char c;
++ int x=0;
++
++ if (gdb.comlink == ne_gdb_serial)
++ {
++ while ((c = GDBGetChar ()) != '$') ;
++
++startPacket:
++ length = 0;
++ checksum = 0;
++ while(((c = GDBGetChar()) != '#') && (length < kTextBufferSize))
++ {
++ if(c == '$')
++ goto startPacket;
++ checksum += c;
++ aBuffer[length++] = c;
++ aBuffer[length] = 0;
++ }
++
++ c = GDBGetChar();
++ x = HexCharToValue(c) << 4;
++ c = GDBGetChar();
++ x += HexCharToValue(c);
++
++
++ checksum &= 0xff;
++
++ GDB_Print2("GetPacket %d",length,0);
++ }
++#ifdef ETHER_DEBUG
++#ifdef ethernet_exists
++ else
++ {
++ int srcidx;
++ // wait till beginning of packet
++ while (gdb.textBuffer[0] != '$') nr_plugs_idle();
++startEPacket:
++ length = 0;
++ checksum = 0;
++ srcidx = 1;
++
++ //loop until packet terminator
++ //leave enough room for the checksum at the end
++ while (((c = gdb.textBuffer[srcidx++]) != '#') && (srcidx < kTextBufferSize-2))
++ {
++ if (c == '$')
++ goto startEPacket;
++
++ checksum += c;
++ aBuffer[length++] = c;
++ }
++
++ c = gdb.textBuffer[srcidx++];
++ x = HexCharToValue(c) << 4;
++ c = gdb.textBuffer[srcidx++];
++ x += HexCharToValue (c);
++
++ aBuffer[length++] = 0;
++
++ checksum &= 0xff;
++
++ GDB_Print2("GetPacket %d",length,0);
++ }
++#endif
++#endif
++
++ if(checksum != x)
++ {
++ GDBPutAck('-');
++ length = 0;
++ }
++ else
++ {
++ GDBPutAck('+');
++ }
++ return length;
++}
++
++//Wait for acknowledgement
++//Should we have some way of timing out???
++//return TRUE if ACK
++//return FALSE if NACK
++int GDBGetACK (void)
++{
++ char c;
++ if (gdb.comlink == ne_gdb_serial)
++ {
++ while (1)
++ {
++ c = GDBGetChar ();
++ if (c == '+') return (1);
++ else if (c == '-') return (0);
++ }
++
++ }
++#ifdef ETHER_DEBUG
++#ifdef ethernet_exists
++ else
++ {
++ gdb.ACKstatus = ne_gdb_ack_waiting;
++ while (1)
++ {
++ nr_plugs_idle ();
++ if (gdb.ACKstatus == ne_gdb_ack_acked)
++ {
++ gdb.ACKstatus = ne_gdb_ack_notwaiting;
++ return (1);
++ }
++ else if (gdb.ACKstatus == ne_gdb_ack_nacked)
++ {
++ gdb.ACKstatus = ne_gdb_ack_notwaiting;
++ return (0);
++ }
++ }
++ }
++#endif
++#endif
++ return(0);
++}
++
++/*
++ * Send a packet, preceded by $,
++ * and followed by #checksum.
++ */
++void PutGDBPacket(char *aBuffer)
++{
++ int checksum;
++ char c;
++ char *origPtr;
++ int cnt=0;
++
++ origPtr = aBuffer; // Remember in case we get a NACK
++ if (gdb.comlink == ne_gdb_serial)
++ {
++startPutSerial:
++ GDBPutChar('$');
++ checksum = 0;
++ while((c = *aBuffer++) != 0)
++ {
++ checksum += c;
++ GDBPutChar(c);
++ }
++ GDBPutChar('#');
++ GDBPutChar(dHexChars[(checksum >> 4) & 15]);
++ GDBPutChar(dHexChars[checksum & 15]);
++
++ if (!GDBGetACK ())
++ {
++ aBuffer = origPtr;
++ if (++cnt < GDB_RETRY_CNT) goto startPutSerial;
++ }
++ }
++#ifdef ETHER_DEBUG
++#ifdef ethernet_exists
++ else
++ {
++ if (gdb.host_ip_address != 0)
++ {
++ int i;
++ int result;
++ char c1;
++
++ i = 0;
++ c = aBuffer[i];
++ if (c==0) return; //there is no data in packet, so why bother sending
++ aBuffer[i++] = '$';
++ checksum = 0;
++ do
++ {
++ checksum += c;
++ c1 = aBuffer[i];
++ aBuffer[i++] = c;
++ c = c1;
++ } while (c != 0);
++
++ aBuffer[i++] = '#';
++ aBuffer[i++] = dHexChars[(checksum >> 4) & 15];
++ aBuffer[i++] = dHexChars[checksum & 15];
++ aBuffer[i++] = 0;
++startPutEth:
++ result = nr_plugs_send_to (gdb.gdb_eth_plug, aBuffer, i, 0,
++ gdb.host_ip_address,
++ gdb.host_port_number);
++
++ if (!GDBGetACK ())
++ {
++ if (++cnt < GDB_RETRY_CNT) goto startPutEth;
++ }
++ aBuffer[0] = 0; //clear packet to
++ }
++ }
++#endif
++#endif
++}
++
++int PutTracePacket(char *aBuffer, int size)
++{
++ int checksum;
++#ifdef ethernet_exists
++ char c;
++#endif
++ int i;
++ int cnt=0;
++
++ if (gdb.comlink == ne_gdb_serial)
++ {
++startPutSerial:
++ GDBPutChar('$');
++ checksum = 0;
++ for (i=0; i<size; i++)
++ {
++ checksum += aBuffer[i];
++ GDBPutChar (aBuffer[i]);
++ }
++ GDBPutChar('#');
++ GDBPutChar(dHexChars[(checksum >> 4) & 15]);
++ GDBPutChar(dHexChars[checksum & 15]);
++
++ if (!GDBGetACK ())
++ {
++ if (++cnt < GDB_RETRY_CNT) goto startPutSerial;
++ }
++ }
++#ifdef ETHER_DEBUG
++#ifdef ethernet_exists
++ else
++ {
++ int result;
++ char c1;
++
++ checksum = 0;
++ c = '$';
++ for (i=0; i<size; i++)
++ {
++ checksum += aBuffer[i];
++ c1 = aBuffer[i];
++ aBuffer[i] = c;
++ c = c1;
++ }
++ aBuffer[i++] = c;
++
++ aBuffer[i++] = '#';
++ aBuffer[i++] = dHexChars[(checksum >> 4) & 15];
++ aBuffer[i++] = dHexChars[checksum & 15];
++ aBuffer[i++] = 0;
++ethResend:
++ if (gdb.host_ip_address != 0)
++ {
++ result = nr_plugs_send_to (gdb.gdb_eth_plug, aBuffer, i, 0,
++ gdb.host_ip_address,
++ gdb.host_port_number);
++ }
++ if (!GDBGetACK ())
++ {
++ if (++cnt < GDB_RETRY_CNT) goto ethResend;
++ }
++ aBuffer[0]=0;
++ }
++#endif
++#endif
++ if (cnt < GDB_RETRY_CNT) return 1;
++ else return 0;
++}
++
++void PutGDBOKPacket(char *aBuffer)
++ {
++ aBuffer[0] = 'O';
++ aBuffer[1] = 'K';
++ aBuffer[2] = 0;
++ PutGDBPacket(aBuffer);
++ }
++
++#if nasys_debug_core
++
++//some defines used exclusively for TRACE data xfer
++//stepsize is the ascii hex step value i.e. twice the binary length
++#define stepsize (2*(2*sizeof(int) + sizeof (char)))
++#define MAX_TRACE_BYTES (((int)((2*MAX_DATA_SIZE-2)/stepsize))*stepsize)
++
++int Trace_Read_Intercept (char *aBuffer)
++{
++ int cnt=0;
++ unsigned int data;
++ unsigned char code;
++ int byteCount;
++ unsigned char *w;
++ unsigned short dataAccumulate;
++ int status;
++
++ w = aBuffer;
++ w++; //skip past the m
++ if (*w++ == 't') //see if this is a special "memory trace" packet
++ {
++ w = Hex2Value(w,&byteCount); //get the number of bytes to transfer
++
++ //turn byteCount to a multiple of stepsize
++ byteCount = ((int)(byteCount/stepsize))*stepsize;
++
++ //wait until fifo empties
++ nm_debug_get_reg(status, np_debug_write_status);
++ while (status&np_debug_write_status_writing_mask) nm_debug_get_reg(status,np_debug_write_status);
++
++ // loop through total size
++ while (byteCount > 0)
++ {
++ w=aBuffer; //reset w to beginning of buffer
++
++ //calculate the number of bytes in this packet
++ if (byteCount > MAX_TRACE_BYTES) dataAccumulate = MAX_TRACE_BYTES;
++ else dataAccumulate = byteCount;
++
++ //insert data size at beginning of packet
++ w = MemToHex((char *)&dataAccumulate, w, sizeof (dataAccumulate));
++
++ byteCount -= dataAccumulate; //decrement byteCount
++
++ // accumulate a full buffer
++ for (cnt=0; cnt<dataAccumulate; cnt+=stepsize)
++ {
++ int valid;
++ nm_debug_set_reg (1, np_debug_read_sample); //begin transaction
++
++ //wait until data is ready
++ nm_debug_get_reg (valid, np_debug_data_valid);
++ while (!valid) nm_debug_get_reg(valid,np_debug_data_valid) ;
++
++ nm_debug_get_reg (data, np_debug_trace_address);
++ w = MemToHex ((char *)&data, w, sizeof (int));
++
++ nm_debug_get_reg (data, np_debug_trace_data);
++ w = MemToHex ((char *)&data, w, sizeof (int));
++
++ nm_debug_get_reg (data, np_debug_trace_code);
++ w = MemToHex ((char *)&data, w, sizeof (char));
++ }
++
++ //if one of our data packets doesn't make it, stop sending them
++ //if (PutTracePacket (aBuffer,dataAccumulate+4) != 1) //+4 for size filed
++ // byteCount = 0;
++ /* kenw - My module can't handle the incoming data fast enough. So
++ * send this one packet, and wait for another mt command.
++ */
++ PutTracePacket (aBuffer,dataAccumulate+4);
++ byteCount = 0;
++ }
++ return 1;
++ }
++ return 0;
++}
++
++/*
++#undef stepsize
++#undef MAX_TRACE_BYTES
++*/
++
++#endif
++
++void DoGDBCommand_m(char *aBuffer)
++ {
++ char *w;
++ int startAddr,byteCount;
++
++#if nasys_debug_core
++ /* intercept some access to the dbg peripheral */
++ if (Trace_Read_Intercept (aBuffer)) return;
++#endif
++
++ w = aBuffer;
++ w++; // past 'm'
++ w = Hex2Value(w,&startAddr);
++ w++; // past ','
++ w = Hex2Value(w,&byteCount);
++
++ if (byteCount > MAX_DATA_SIZE) byteCount = MAX_DATA_SIZE;
++
++ // mA,L -- request memory
++ w = aBuffer;
++ w = MemToHex((char *)startAddr,w,byteCount);
++ PutGDBPacket(aBuffer);
++ }
++
++void DoGDBCommand_M(char *aBuffer)
++ {
++ char *w;
++ int startAddr,byteCount;
++
++ w = aBuffer;
++ w++; // past 'M'
++ w = Hex2Value(w,&startAddr);
++ w++; // past ','
++ w = Hex2Value(w,&byteCount);
++ w++; // past ':'
++
++ GDB_Print2("M from %x to %x",startAddr,byteCount);
++
++ // MA,L:values -- write to memory
++
++ w = HexToMem(w,(char *)startAddr,byteCount);
++
++ // Send "OK"
++ PutGDBOKPacket(aBuffer);
++ }
++
++int Debug_Read_Intercept (char *aBuffer)
++{
++ unsigned int data;
++ int index;
++ unsigned char *w;
++
++ w = aBuffer;
++ w++; //skip past the g
++ if (*w++ == 'g') //see if this is a special "register read" packet
++ {
++ w = Hex2Value(w,&index); //get the index of the register to be read
++
++ nm_debug_get_reg (data, index);
++
++ //assemble the output packet
++ w=aBuffer; //reset w to beginning of buffer
++ w = MemToHex((char *)&data, w, sizeof (data));
++ *w++ = 0;
++
++ //now send it
++ PutTracePacket (aBuffer,sizeof (data) * 2);
++
++ return 1;
++ }
++ return 0;
++}
++
++// Return the values of all the registers
++void DoGDBCommand_g(NiosGDBGlobals *g)
++ {
++ char *w;
++
++ if (Debug_Read_Intercept (g->textBuffer)) return;
++
++ w = g->textBuffer;
++
++ w = MemToHex((char *)(&g->registers),w,sizeof(g->registers));
++ PutGDBPacket(g->textBuffer);
++ GDB_Print2("Sent Registers",0,0);
++ }
++
++int Debug_Write_Intercept (char *aBuffer)
++{
++ unsigned int data;
++ int index;
++ unsigned char *w;
++
++ w = aBuffer;
++ w++; //skip past the g
++ if (*w++ == 'g') //see if this is a special "register read" packet
++ {
++ w = Hex2Value(w,&index); //get the index of the register to be written
++ w++; // past ','
++ w = Hex2Value(w,&data);
++
++ nm_debug_set_reg (data, index);
++
++ //now send it
++ // Send "OK"
++ PutGDBOKPacket(aBuffer);
++
++ return 1;
++ }
++ return 0;
++}
++
++void DoGDBCommand_G(NiosGDBGlobals *g)
++ {
++ char *w;
++
++ if (Debug_Write_Intercept (g->textBuffer)) return;
++
++ w = g->textBuffer;
++ w++; // skip past 'G'
++ w = HexToMem(w,(char *)(&g->registers), sizeof(g->registers) );
++
++ // Send "OK"
++ PutGDBOKPacket(g->textBuffer);
++
++ GDB_Print2("Received Registers",0,0);
++ }
++
++// Return last signal value
++void DoGDBCommand_qm(NiosGDBGlobals *g)
++ {
++ char *w;
++
++ w = g->textBuffer;
++
++ *w++ = 'S';
++ *w++ = '2';
++ *w++ = '3'; // make up a signal for now...
++ *w++ = 0;
++ PutGDBPacket(g->textBuffer);
++ }
++
++void DoGDBCommand_q(NiosGDBGlobals *g)
++{
++#ifdef na_ssram_detect_in
++ short int* ssram_exists;
++#endif
++ char *w;
++ w = g->textBuffer;
++
++ w++; /* skip past the q */
++ switch (*w) {
++ case ('A'):
++ w = g->textBuffer;
++
++ /* handle intialization information */
++ /* is nios_ocd available? */
++#ifdef nasys_debug_core
++ *w++ = nasys_debug_core + '0';
++#else
++ *w++ = '0';
++#endif
++ *w++ = ',';
++
++ /* determine if the SSRAM debugger board is
++ * physically present */
++#ifdef na_ssram_detect_in
++ ssram_exists = (short int*) na_ssram_detect_in;
++ *w++ = !(*ssram_exists) + '0';
++#else
++ *w++ = '0';
++#endif
++ *w++ = ',';
++
++ /* print out the max size of a trace packet */
++#if nasys_debug_core
++ sprintf (w, "%04x", MAX_TRACE_BYTES);
++#else
++ sprintf (w, "0000");
++#endif
++
++ break;
++ case ('B'):
++ w = g->textBuffer;
++
++ /* returns 1 if it was an OCD interrupt
++ * returns 0 if it was software breakpoint */
++ if (gdb.trapNumber == nasys_debug_core_irq) {
++ *w++ = '1';
++ } else {
++ *w++ = '0';
++ }
++
++ *w++ = 0;
++ break;
++ default:
++ w = g->textBuffer;
++
++ *w = 0;
++ break;
++ }
++
++ PutGDBPacket(g->textBuffer);
++}
++
++
++void GDBInsertBreakpoint(NiosGDBGlobals *g,short *address)
++ {
++ NiosGDBBreakpoint *b;
++
++ GDB_Print2("breakpoint 0x%x",(int)address,0);
++ if(g->breakpointCount < kMaximumBreakpoints)
++ {
++ b = &g->breakpoint[g->breakpointCount++];
++ b->address = address;
++ b->oldContents = *b->address;
++ *b->address = 0x7904;
++ }
++ }
++
++void GDBRemoveBreakpoints(NiosGDBGlobals *g)
++ {
++ NiosGDBBreakpoint *b;
++ int i;
++
++ for(i = 0; i < g->breakpointCount; i++)
++ {
++ b = &g->breakpoint[i];
++ *b->address = b->oldContents;
++ b->address = 0;
++ }
++
++ g->breakpointCount = 0;
++ }
++
++int NiosInstructionIsTrap5(unsigned short instruction)
++ {
++ return instruction == 0x7905;
++ }
++
++int NiosInstructionIsPrefix(unsigned short instruction)
++ {
++ return (instruction >> 11) == 0x13;
++ }
++
++int NiosInstructionIsSkip(unsigned short instruction)
++ {
++ int op6;
++ int op11;
++
++ op6 = (instruction >> 10);
++ op11 = (instruction >> 5);
++
++ return (op6 == 0x14 // SKP0
++ || op6 == 0x15 // SKP1
++ || op11 == 0x3f6 // SKPRz
++ || op11 == 0x3f7 // SKPS
++ || op11 == 0x3fa); // SKPRnz
++ }
++
++int NiosInstructionIsBranch(unsigned short instruction,short *pc,short **branchTargetOut)
++ {
++ int op4;
++ int op7;
++ int op10;
++ short *branchTarget = 0;
++ int result = 0;
++
++ op4 = (instruction >> 12);
++ op7 = (instruction >> 9);
++ op10 = (instruction >> 6);
++
++ if(op4 == 0x08) // BR, BSR
++ {
++ int offset;
++
++ result = 1;
++ offset = instruction & 0x07ff;
++ if(offset & 0x400) // sign extend
++ offset |= 0xffffF800;
++ branchTarget = pc + offset + 1; // short * gets x2 scaling automatically
++ }
++ else if(op10 == 0x1ff) // JMP, CALL
++ {
++ result = 1;
++ branchTarget = (short *)(gdb.registers.r[instruction & 31] * 2);
++ }
++ else if(op7 == 0x3d) // JMPC, CALLC
++ {
++ result = 1;
++ branchTarget = pc + 1 + (instruction & 0x0ffff);
++#ifdef __nios32__
++ branchTarget = (short *)((int)branchTarget & 0xffffFFFc); // align 32...
++#else
++ branchTarget = (short *)((int)branchTarget & 0xFFFe); // align 16...
++#endif
++ branchTarget = (short *)(*(int *)branchTarget);
++ }
++
++ if(branchTargetOut)
++ *branchTargetOut = branchTarget;
++
++ return result;
++ }
++
++// -------------------------
++// Step at address
++//
++// "stepping" involves inserting a
++// breakpoint at some reasonable
++// spot later than the current program
++// counter
++//
++// On the Nios processor, this is
++// nontrivial. For example, we should
++// not break up a PFX instruction.
++
++void DoGDBCommand_s(NiosGDBGlobals *g)
++ {
++ char *w;
++ int x;
++ short *pc;
++ short *branchTarget;
++ unsigned short instruction;
++ int stepType;
++
++ /*
++ * First, if there's an argument to the packet,
++ * set the new program-counter value
++ */
++
++ w = g->textBuffer;
++ w++;
++ if(HexCharToValue(*w) >= 0)
++ {
++ w = Hex2Value(w,&x);
++ g->registers.pc = x;
++ }
++
++ /*
++ * Scan forward to see what the
++ * most appropriate location(s) for
++ * a breakpoint will be.
++ *
++ * The rules are:
++ * 1. If *pc == PFX, break after modified instruction.
++ * 2. If *pc == BR,BSR,JMP,CALL, break at destination
++ * 3. If *pc == SKIP, break right after SKIP AND after optional instruction,
++ which might, of course, be prefixed.
++ * 4. Anything else, just drop in the breakpoint.
++ */
++
++ pc = (short *)(int)g->registers.pc;
++
++ instruction = *pc;
++ stepType = 0;
++
++ if(NiosInstructionIsPrefix(instruction))
++ {
++ /*
++ * PFX instruction: skip til after it
++ */
++ while(NiosInstructionIsPrefix(instruction))
++ {
++ pc++;
++ instruction = *pc;
++ }
++
++ GDBInsertBreakpoint(g,pc + 1);
++ stepType = 1;
++ }
++ else if(NiosInstructionIsBranch(instruction,pc,&branchTarget))
++ {
++ GDBInsertBreakpoint(g,branchTarget);
++ stepType = 2;
++ }
++ else if(NiosInstructionIsSkip(instruction))
++ {
++ short *pc2;
++ stepType = 3;
++
++ /*
++ * Skip gets to breaks: one after the skippable instruction,
++ * and the skippable instruction itself.
++ *
++ * Since Skips know how to skip over PFX's, we have to, too.
++ */
++ pc2 = pc; // the Skip instruction
++ do
++ {
++ pc2++;
++ } while(NiosInstructionIsPrefix(*pc2));
++ // pc2 now points to first non-PFX after Skip
++ GDBInsertBreakpoint(g,pc2+1);
++ GDBInsertBreakpoint(g,pc+1);
++ }
++ else
++ GDBInsertBreakpoint(g,pc+1); // the genericest case
++
++ GDB_Print2("Program Steppingat 0x%x (%d)",g->registers.pc,stepType);
++ }
++
++// -----------------------------
++// Continue at address
++
++void DoGDBCommand_c(NiosGDBGlobals *g)
++ {
++ char *w;
++ int x;
++ w = g->textBuffer;
++
++ w++; // past command
++
++ // Anything in the packet? if so,
++ // use it to set the PC value
++
++ if(HexCharToValue(*w) >= 0)
++ {
++ w = Hex2Value(w,&x);
++ g->registers.pc = x;
++ }
++
++ GDB_Print2("Program Running at 0x%x",g->registers.pc,0);
++ }
++
++// ----------------------
++// Kill
++
++void DoGDBCommand_k(NiosGDBGlobals *g)
++ {
++ return;
++ }
++
++
++/*
++ * If we've somehow skidded
++ * to a stop just after a PFX instruction
++ * back up the program counter by one.
++ *
++ * That way, we can't end up with an accidentally-unprefixed
++ * instruction.
++ *
++ * We do this just before we begin running
++ * again, so that when the host queries our
++ * registers, we report the place we actually
++ * stopped.
++ */
++
++void MaybeAdjustProgramCounter(NiosGDBGlobals *g)
++ {
++ short instruction;
++ if(g->registers.pc)
++ {
++ instruction = *(short *)(int)(g->registers.pc - 2);
++ if(NiosInstructionIsPrefix(instruction))
++ g->registers.pc -= 2;
++ else
++ {
++ // If the *current* instruction is Trap5, we must skip it!
++ instruction = *(short *)(int)(g->registers.pc);
++ if(NiosInstructionIsTrap5(instruction))
++ g->registers.pc += 2;
++ }
++ }
++ }
++
++/*
++ * GDBMainLoop - this is the main processing loop
++ * for the GDB stub.
++ */
++void GDBMainLoop (void)
++{
++ while(1)
++ {
++ if (GetGDBPacket(gdb.textBuffer) > 0)
++ {
++
++ GDB_Print2(gdb.textBuffer,0,0);
++ switch(gdb.textBuffer[0])
++ {
++ case 's':
++ DoGDBCommand_s(&gdb);
++ goto startRunning;
++ break;
++
++ case 'c': // continue
++ DoGDBCommand_c(&gdb);
++
++ // if the PC is something other than 0, it's
++ // probably ok to exit and go there
++
++ startRunning:
++ if(gdb.registers.pc)
++ {
++ MaybeAdjustProgramCounter(&gdb);
++ return;
++ }
++ break;
++
++ case 'm': // memory read
++ DoGDBCommand_m(gdb.textBuffer);
++ break;
++
++ case 'M': // memory set
++ DoGDBCommand_M(gdb.textBuffer);
++ break;
++
++ case 'g': // registers read
++ DoGDBCommand_g(&gdb);
++ break;
++
++ case 'G': //registers set
++ DoGDBCommand_G(&gdb);
++ break;
++
++ case 'k': //kill process
++ DoGDBCommand_k(&gdb);
++ break;
++
++ case '?': // last exception value
++ DoGDBCommand_qm(&gdb);
++ break;
++
++ case 'q':
++ DoGDBCommand_q(&gdb);
++ break;
++
++ default: // return empty packet, means "yeah yeah".
++ gdb.textBuffer[0] = 0;
++ PutGDBPacket(gdb.textBuffer);
++ break;
++ }
++ }
++ }
++
++}
++
++// ----------main------------
++void GDBMain(void)
++{
++ int i;
++
++ for(i = 0; i < kTextBufferSize; i++)
++ gdb.textBuffer[i] = i;
++
++ GDBRemoveBreakpoints(&gdb);
++
++#ifdef __KERNEL__
++/*
++ * Inform the user that they need to add the symbol file for the application
++ * that is just starting up. Display the .text .data .bss regions.
++ */
++ if (gdb.trapNumber == 5) {
++ extern struct task_struct *_current_task;
++ sprintf(gdb.textBuffer,
++ "\r\n\nGDB: trap 5 at 0x%08lX", gdb.registers.pc);
++ puts(gdb.textBuffer);
++ if (_current_task) {
++ if ( _current_task->mm->start_code > _etext )
++ sprintf(gdb.textBuffer,
++ "\r\nGDB: Enter the following command in the nios-elf-gdb Console Window:"
++ "\r\nGDB: add-symbol-file %s.abself 0x%08lX 0x%08lX 0x%08lX\r\n\n",
++ _current_task->comm,
++ (unsigned long)_current_task->mm->start_code,
++ (unsigned long)_current_task->mm->start_data,
++ (unsigned long)_current_task->mm->end_data );
++ else
++ sprintf(gdb.textBuffer,
++ ", kernel process: %s\r\n", _current_task->comm );
++ } else
++ sprintf(gdb.textBuffer,
++ ", kernel process unknown\r\n" );
++ puts(gdb.textBuffer);
++ }
++#endif
++
++ // Send trapnumber for breakpoint encountered. No other signals.
++
++ gdb.textBuffer[0] = 'S';
++ gdb.textBuffer[1] = '0';
++
++#if nasys_debug_core
++ if (gdb.trapNumber == nasys_debug_core_irq)
++ {
++ /* gdb.textBuffer[2] = '8'; */
++ gdb.textBuffer[2] = '5';
++ }
++ else
++ {
++ gdb.textBuffer[2] = '5';
++ }
++#else
++ gdb.textBuffer[2] = '5';
++#endif
++ gdb.textBuffer[3] = 0;
++ PutGDBPacket(gdb.textBuffer);
++
++ GDB_Print2("Trap %2d At 0x%x",
++ gdb.trapNumber,gdb.registers.pc);
++// printf ("Trap %d at 0x%x\n",gdb.trapNumber,gdb.registers.pc);
++// for (i=0;i<32;i++) printf (" register[%d] = 0x%x\n",i,gdb.registers.r[i]);
++
++ GDBMainLoop ();
++}
++
++// +----------------------------------
++// | gdb_eth_proc -- gets called for udp packets
++// | from the host bound for gdb stub
++#ifdef ETHER_DEBUG
++#ifdef ethernet_exists
++int gdb_eth_proc(int plug_handle,
++ void *context,
++ ns_plugs_packet *p,
++ void *payload,
++ int payload_length)
++{
++ int i;
++ char *buf = (char *)payload;
++ // if this is a stop request, set a flag to stop after nr_plugs_idle
++ // leave it up to the host to prevent stops from being sent while stub is running???
++
++ if (*buf == 3) gdb.stop = 1;
++
++ // if we're waiting for an ack, check that here
++ if (gdb.ACKstatus == ne_gdb_ack_waiting)
++ {
++ if (buf[0] == '+')
++ {
++ gdb.ACKstatus = ne_gdb_ack_acked;
++ return 0;
++ }
++ else if (buf[0] == '-')
++ {
++ gdb.ACKstatus = ne_gdb_ack_nacked;
++ return 0;
++ }
++ }
++ strcpy (gdb.textBuffer, buf); //all commands should be zero terminated strings
++
++ gdb.textBuffer[payload_length] = 0; //terminate string
++
++ gdb.host_ip_address=((ns_plugs_ip_packet *)(p[ne_plugs_ip].header))->source_ip_address;
++ gdb.host_port_number=((ns_plugs_udp_packet *)(p[ne_plugs_udp].header))->source_port;
++
++ return 0;
++}
++
++int nr_dbg_plugs_idle (void)
++{
++ int result;
++
++ result = nr_plugs_idle ();
++ if (gdb.stop)
++ {
++ gdb.stop = 0;
++//;dgt2;tmp; asm ("TRAP #5");
++ }
++ return result;
++}
++#endif
++#endif
++
++
++/*
++ * int main(void)
++ *
++ * All we really do here is install our trap # 3,
++ * and call it once, so that we're living down in
++ * the GDBMain, trap handler.
++ */
++
++extern int StubBreakpointHandler;
++extern int StubHarmlessHandler;
++#if nasys_debug_core
++extern int StubHWBreakpointHandler;
++#endif
++#ifdef nasys_debug_uart
++extern int StubUartHandler;
++#endif
++
++void gdb_local_install(int active)
++{
++ unsigned int *vectorTable;
++ unsigned int stubBreakpointHandler;
++ unsigned int stubHarmlessHandler;
++#if nasys_debug_core
++ unsigned int stubHWBreakpointHandler;
++#endif
++
++ gdb.breakpointCount = 0;
++ gdb.textBuffer[0] = 0;
++
++ vectorTable = (int *)nasys_vector_table;
++ stubBreakpointHandler = ( (unsigned int)(&StubBreakpointHandler) ) >> 1;
++ stubHarmlessHandler = ( (unsigned int)(&StubHarmlessHandler) ) >> 1;
++#if nasys_debug_core
++ stubHWBreakpointHandler = ( (unsigned int)(&StubHWBreakpointHandler) ) >> 1;
++#endif
++
++ /*
++ * Breakpoint & single step both go here
++ */
++ vectorTable[na_BreakpointTrap] = stubBreakpointHandler;
++ vectorTable[na_SingleStepTrap] = stubBreakpointHandler;
++ vectorTable[na_StartGDBTrap] = active ? stubBreakpointHandler : stubHarmlessHandler;
++ /*
++ * If it exists, Hardware Breakpoint has a different entry point
++ */
++#if nasys_debug_core
++ vectorTable[na_debug_peripheral_irq] = stubHWBreakpointHandler;
++#endif
++
++#ifndef __KERNEL__
++#ifdef nasys_debug_uart
++ if (gdb.comlink == ne_gdb_serial)
++ {
++ np_uart *uart = (np_uart *)nasys_debug_uart;
++ unsigned int stubUartHandler = ((unsigned int)(&StubUartHandler)) >> 1;
++
++ vectorTable[nasys_debug_uart_irq] = stubUartHandler; //set Uart int vector
++ uart->np_uartcontrol = np_uartcontrol_irrdy_mask; //enable Rx intr
++ }
++#endif
++#endif
++}
++
++void nios_gdb_install(int active)
++{
++ gdb.comlink = ne_gdb_serial;
++ gdb_local_install (active);
++}
++
++#ifdef ETHER_DEBUG
++#ifdef ethernet_exists
++void nios_gdb_install_ethernet (int active)
++{
++ int result;
++ host_16 host_port = GDB_ETH_PORT;
++
++ gdb.comlink = ne_gdb_ethernet;
++ gdb_local_install (active);
++
++ result = nr_plugs_create (&gdb.gdb_eth_plug, ne_plugs_udp, host_port, gdb_eth_proc, 0, 0);
++ //if unabled to open ethernet plug, switch back to default serial interface
++ if (result)
++ {
++ printf ("nr_plugs_create failed %d\n",result);
++ gdb.comlink = ne_gdb_serial;
++ return;
++ }
++ result = nr_plugs_connect (gdb.gdb_eth_plug, 0, -1, -1);
++ if (result)
++ {
++ printf ("nr_plugs_connect fialed %d\n",result);
++ gdb.comlink = ne_gdb_serial;
++ return;
++ }
++}
++#endif
++#endif
++
++#ifdef nios_gdb_breakpoint
++ #undef nios_gdb_breakpoint
++#endif
++
++void nios_gdb_breakpoint(void)
++ {
++ /*
++ * If you arrived here, you didn't include
++ * the file "nios_peripherals.h", which
++ * defines nios_gdb_breakpoint as a
++ * macro that expands to TRAP 5.
++ *
++ * (No problem, you can step out
++ * of this routine.)
++ */
++//;dgt2;tmp; asm("TRAP 5");
++ }
++
++// end of file
+diff --git a/arch/nios2nommu/kernel/nios_gdb_stub.h b/arch/nios2nommu/kernel/nios_gdb_stub.h
+new file mode 100644
+index 0000000..3900109
+--- /dev/null
++++ b/arch/nios2nommu/kernel/nios_gdb_stub.h
+@@ -0,0 +1,105 @@
++// file: nios_gdb_stub.h
++// Author: Altera Santa Cruz \ 2000
++//
++// You can modify this header file to
++// enable some features useful for
++// debugging the debugger. They're
++// good features also to just show
++// signs of life on your Nios board.
++// But they consume valuable peripherals!
++//
++// The 'GDB_DEBUG_PRINT' option ties
++// up the LCD living on the 5v port,
++// showing useful internals of the stub.
++//
++// dvb@altera.com
++//
++
++#ifdef ETHER_DEBUG
++#ifdef na_enet
++#define ethernet_exists
++#endif
++#endif
++
++#ifdef ETHER_DEBUG
++#ifdef ethernet_exists
++#include "plugs.h"
++#endif
++#endif
++
++#define MAX_DATA_SIZE 650
++#define kTextBufferSize ((2*MAX_DATA_SIZE)+4)
++#define kMaximumBreakpoints 4
++#define GDB_ETH_PORT 7070
++#define GDB_WHOLE_PACKET 0
++#define GDB_SKIP_FIRST 1
++#define GDB_RETRY_CNT 3
++
++/*
++ * This register structure must match
++ * its counterpart in the GDB host, since
++ * it is blasted across in byte notation.
++ */
++typedef struct
++ {
++ int r[32];
++ long pc;
++ short ctl0;
++ short ctl1;
++ short ctl2;
++ short ctl3;
++ } NiosGDBRegisters;
++
++typedef struct
++ {
++ short *address;
++ short oldContents;
++ } NiosGDBBreakpoint;
++
++typedef struct
++ {
++ NiosGDBRegisters registers;
++ int trapNumber; // stashed by ISR, to distinguish types
++ char textBuffer[kTextBufferSize];
++ int breakpointCount; // breakpoints used for stepping
++ int comlink;
++ int stop;
++ int gdb_eth_plug;
++ NiosGDBBreakpoint breakpoint[kMaximumBreakpoints];
++#ifdef ETHER_DEBUG
++#ifdef ethernet_exists
++ volatile int ACKstatus;
++ net_32 host_ip_address;
++ net_16 host_port_number;
++#endif
++#endif
++ } NiosGDBGlobals;
++
++#ifdef ETHER_DEBUG
++#ifdef ethernet_exists
++enum
++{
++ ne_gdb_ack_notwaiting,
++ ne_gdb_ack_waiting,
++ ne_gdb_ack_acked,
++ ne_gdb_ack_nacked
++};
++#endif
++#endif
++
++enum
++{
++ ne_gdb_serial,
++ ne_gdb_ethernet
++};
++
++#ifndef GDB_DEBUG_PRINT
++ #define GDB_DEBUG_PRINT 0
++#endif
++
++void GDB_Main(void); // initialize gdb and begin.
++
++char GDBGetChar(void);
++void GDBPutChar(char c);
++void GDB_Print2(char *s,int v1,int v2);
++
+diff --git a/arch/nios2nommu/kernel/nios_gdb_stub_io.c b/arch/nios2nommu/kernel/nios_gdb_stub_io.c
+new file mode 100644
+index 0000000..e0d8f82
+--- /dev/null
++++ b/arch/nios2nommu/kernel/nios_gdb_stub_io.c
+@@ -0,0 +1,39 @@
++// Modified for uClinux - Vic - Apr 2002
++// From:
++
++// file: nios_gdb_stub_IO.c
++//
++// Single character I/O for Nios GDB Stub
++
++#ifndef __KERNEL__
++#include "nios.h"
++#else
++#include <asm/nios.h>
++#endif
++
++#include "nios_gdb_stub.h"
++
++#ifdef nasys_debug_uart
++ #define GDB_UART nasys_debug_uart
++#endif
++
++char GDBGetChar(void)
++{
++ char c = 0;
++
++#ifdef GDB_UART
++ while( (c = (char)nr_uart_rxchar(GDB_UART)) < 0 )
++ ;
++#endif
++
++ return c;
++}
++
++void GDBPutChar(char c)
++{
++#ifdef GDB_UART
++ nr_uart_txchar(c, GDB_UART);
++#endif
++}
++
++// End of file
+diff --git a/arch/nios2nommu/kernel/nios_gdb_stub_isr.S b/arch/nios2nommu/kernel/nios_gdb_stub_isr.S
+new file mode 100644
+index 0000000..c4af09a
+--- /dev/null
++++ b/arch/nios2nommu/kernel/nios_gdb_stub_isr.S
+@@ -0,0 +1,99 @@
++/*--------------------------------------------------------------------
++ *
++ * Assembly language portions of Nios GDB Stub
++ *
++ * arch\nios2nommu\kernel\switch.S
++ *
++ * 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.
++ *
++ * Modified for uClinux - Vic - Apr 2002
++ * Jan/20/2004 dgt NiosII
++ *
++ ---------------------------------------------------------------------*/
++
++
++//;dgt2;tmp;
++
++ .equ ethernet_exists, 1
++
++
++ .equ gdbRegistersGeneral,0
++ .equ gdbRegistersPC,32
++ .equ gdbRegistersCtl0Ctl1,33
++ .equ gdbRegistersCtl2Ctl3,34
++ .equ gdbTrapNumber,35 ; ISR can report trap number here
++
++
++ .text
++
++ .global StubBreakpointHandler
++ .global StubHarmlessHandler
++ .global StubButtonHandler
++ .global StubHWBreakpointHandler
++ .global GDBMain
++
++ .comm _gdb_stub_stack,1024,4 ; Local stack, statically allocated.
++ .equ gdbStubStacktop,_gdb_stub_stack+992
++
++
++StubHarmlessHandler:
++//;dgt2;tmp
++
++ .equ gdbBreakChar,0x3
++ .global StubUartHandler
++
++StubUartHandler:
++//;dgt2;tmp
++
++StubUartRx:
++//;dgt2;tmp
++
++StubHWBreakpointHandler:
++//;dgt2;tmp
++
++StubBreakpointHandler:
++//;dgt2;tmp
++
++#ifdef __KERNEL__
++;----------------------------------------
++; Name: nr_uart_rxchar
++; Description: Read character if available
++; Input: %o0: UART base to use
++; Output: %o0 = character 0-0xff, or -1 if none present
++; Side Effects: %g0 & %g1 altered
++; CWP Depth: 0
++;
++
++ .global nr_uart_rxchar
++nr_uart_rxchar:
++//;dgt2;tmp
++
++
++;----------------------------------------
++; Name: nr_uart_txchar
++; Description: Send a single byte out the UART
++; Input: %o0 = A character
++; %o1 = the UART to use, 0 for default
++; Output: none
++; Side Effects: %g0 & %g1 altered, CPU waits for UART
++; CWP Depth: 0
++;
++
++; nr_uart_txchar
++ .global nr_uart_txchar
++nr_uart_txchar:
++//;dgt2;tmp
++
++#endif
+diff --git a/arch/nios2nommu/kernel/pio.c b/arch/nios2nommu/kernel/pio.c
+new file mode 100644
+index 0000000..013a64b
+--- /dev/null
++++ b/arch/nios2nommu/kernel/pio.c
+@@ -0,0 +1,154 @@
++/*
++ * 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>
++
++MODULE_AUTHOR("Microtronix Datacom Ltd.");
++MODULE_DESCRIPTION("Drivers of PIO devices (LEDs and 7 seg) on Nios kit");
++MODULE_LICENSE("GPL");
++
++#undef CONFIG_PIO_SEG
++#ifdef na_seven_seg_pio
++#define CONFIG_PIO_SEG
++#define PIO_SEG_IO na_seven_seg_pio
++#endif
++
++#undef CONFIG_PIO_LED
++#ifdef na_led_pio
++#define CONFIG_PIO_LED
++#define PIO_LED_IO na_led_pio
++#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
++void pio_led_write(int value)
++{
++ np_pio *pio=(np_pio *)(PIO_LED_IO);
++
++ //outl(-1, &pio->np_piodirection);
++ outl(value, &pio->np_piodata);
++}
++
++static void __init pio_led_init(void)
++{
++ np_pio *pio=(np_pio *)(PIO_LED_IO);
++
++ outl(-1, &pio->np_piodirection);
++ outl(0x0, &pio->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)
++{
++#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));
++#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/nios2nommu/kernel/process.c b/arch/nios2nommu/kernel/process.c
+new file mode 100644
+index 0000000..4cd353c
+--- /dev/null
++++ b/arch/nios2nommu/kernel/process.c
+@@ -0,0 +1,578 @@
++/*--------------------------------------------------------------------
++ *
++ * 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/a.out.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>
++
++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 code in head.S take care of disabling peripherals.
++ */
++
++void machine_restart(char * __unused)
++{
++ local_irq_disable();
++ __asm__ __volatile__ (
++ "jmp %0\n\t"
++ :
++ : "r" (CPU_RESET_ADDRESS)
++ : "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 statusx: %08lx\n",
++ regs->ea, regs->estatus, regs->status_extension);
++}
++
++/*
++ * Create a kernel thread
++ */
++int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
++{
++ long retval;
++ long clone_arg = flags | CLONE_VM;
++ mm_segment_t fs;
++
++ fs = get_fs();
++ set_fs(KERNEL_DS);
++
++ __asm__ __volatile(
++
++ " movi r2, %6\n\t" /* TRAP_ID_SYSCALL */
++ " movi r3, %1\n\t" /* __NR_clone */
++ " mov r4, %5\n\t" /* (clone_arg */
++ /* (flags | CLONE_VM)) */
++ " movia r5, -1\n\t" /* usp: -1 */
++ " trap\n\t" /* sys_clone */
++ "\n\t"
++ " cmpeq r4, r3, zero\n\t"/*2nd return valu in r3 */
++ " bne r4, zero, 1f\n\t"/* 0: parent, just return. */
++ /* See copy_thread, called */
++ /* by do_fork, called by */
++ /* nios2_clone, called by */
++ /* sys_clone, called by */
++ /* syscall trap handler. */
++
++ " mov r4, %4\n\t" /* fn's parameter (arg) */
++ "\n\t"
++ "\n\t"
++ " callr %3\n\t" /* Call function (fn) */
++ "\n\t"
++ " mov r4, r2\n\t" /* fn's rtn code//;dgt2;tmp;*/
++ " movi r2, %6\n\t" /* TRAP_ID_SYSCALL */
++ " movi r3, %2\n\t" /* __NR_exit */
++ " trap\n\t" /* sys_exit() */
++
++ /* Not reached by child. */
++ "1:\n\t"
++ " mov %0, r2\n\t" /* error rtn code (retval) */
++
++ : "=r" (retval) /* %0 */
++
++ : "i" (__NR_clone) /* %1 */
++ , "i" (__NR_exit) /* %2 */
++ , "r" (fn) /* %3 */
++ , "r" (arg) /* %4 */
++ , "r" (clone_arg) /* %5 (flags | CLONE_VM) */
++ , "i" (TRAP_ID_SYSCALL) /* %6 */
++
++ : "r2" /* Clobbered */
++ , "r3" /* Clobbered */
++ , "r4" /* Clobbered */
++ , "r5" /* Clobbered */
++ , "ra" /* Clobbered //;mex1 */
++ );
++
++ set_fs(fs);
++ return retval;
++}
++
++void flush_thread(void)
++{
++ /* Now, this task is no longer a kernel thread. */
++ current->thread.flags &= ~NIOS2_FLAG_KTHREAD;
++
++#ifdef CONFIG_FPU
++ unsigned long zero = 0;
++#endif
++ set_fs(USER_DS);
++#ifdef CONFIG_FPU
++ if (!FPU_IS_EMU)
++...;dgt2;
++ asm volatile (".chip 68k/68881\n\t"
++ "frestore %0@\n\t"
++ ".chip 68k" : : "a" (&zero));
++#endif
++}
++
++/*
++ * "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)
++{
++ /* fork almost works, enough to trick you into looking elsewhere :-( */
++ return(-EINVAL);
++}
++
++/*
++ * 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)
++{
++ /* r4: clone_flags, r5: child_stack (usp) */
++
++ unsigned long clone_flags;
++ unsigned long newsp;
++
++ clone_flags = regs->r4;
++ newsp = regs->r5;
++ if (!newsp)
++ newsp = regs->sp;
++ return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
++}
++
++int copy_thread(int nr, 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;
++ unsigned long stack_offset, *retp;
++
++ stack_offset = THREAD_SIZE - sizeof(struct pt_regs);
++ childregs = (struct pt_regs *) ((unsigned long) p->stack + stack_offset);
++ p->thread.kregs = childregs;
++
++ *childregs = *regs;
++ childregs->r2 = 0; //;dgt2;...redundant?...see "rtnvals" below
++
++ retp = ((unsigned long *) regs);
++ stack = ((struct switch_stack *) retp) - 1;
++
++ childstack = ((struct switch_stack *) childregs) - 1;
++ *childstack = *stack;
++ childstack->ra = (unsigned long)ret_from_fork;
++
++ if (usp == -1)
++ p->thread.kregs->sp = (unsigned long) childstack;
++ else
++ p->thread.kregs->sp = usp;
++
++ p->thread.ksp = (unsigned long)childstack;
++
++#ifdef CONFIG_FPU
++ if (!FPU_IS_EMU) {
++ /* Copy the current fpu state */
++...;dgt2;
++ asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
++
++ if (p->thread.fpstate[0])
++ asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
++ "fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
++ : : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0])
++ : "memory");
++ /* Restore the state in case the fpu was busy */
++ asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
++ }
++#endif
++
++ /* Set the return value for the child. */
++ childregs->r2 = 0; //;dgt2;...redundant?...see childregs->r2 above
++ childregs->r3 = 1; //;dgt2;...eg: kernel_thread parent test
++
++ /* Set the return value for the parent. */
++ regs->r2 = p->pid; // Return child pid to parent
++ regs->r3 = 0; //;dgt2;...eg: kernel_thread parent test
++
++ return 0;
++}
++
++/* Fill in the fpu structure for a core dump. */
++
++int dump_fpu(struct pt_regs *regs, struct user_m68kfp_struct *fpu)
++{
++#ifdef CONFIG_FPU
++ char fpustate[216];
++
++ if (FPU_IS_EMU) {
++ int i;
++
++ memcpy(fpu->fpcntl, current->thread.fpcntl, 12);
++ memcpy(fpu->fpregs, current->thread.fp, 96);
++ /* Convert internal fpu reg representation
++ * into long double format
++ */
++ for (i = 0; i < 24; i += 3)
++ fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |
++ ((fpu->fpregs[i] & 0x0000ffff) << 16);
++ return 1;
++ }
++
++ /* First dump the fpu context to avoid protocol violation. */
++...;dgt2;tmp;
++ asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
++ if (!fpustate[0])
++ return 0;
++
++ asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
++ :: "m" (fpu->fpcntl[0])
++ : "memory");
++ asm volatile ("fmovemx %/fp0-%/fp7,%0"
++ :: "m" (fpu->fpregs[0])
++ : "memory");
++#endif
++ return 1;
++}
++
++/*
++ * fill in the user structure for a core dump..
++ */
++void dump_thread(struct pt_regs * regs, struct user * dump)
++{
++ struct switch_stack *sw;
++
++ /* changed the size calculations - should hopefully work better. lbt */
++ dump->magic = CMAGIC;
++ dump->start_code = 0;
++ dump->start_stack = regs->sp & ~(PAGE_SIZE - 1);
++ dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
++ dump->u_dsize = ((unsigned long) (current->mm->brk +
++ (PAGE_SIZE-1))) >> PAGE_SHIFT;
++ dump->u_dsize -= dump->u_tsize;
++ dump->u_ssize = 0;
++
++ if (dump->start_stack < TASK_SIZE)
++ dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
++
++ dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
++ sw = ((struct switch_stack *)regs) - 1;
++ dump->regs.r1 = regs->r1;
++ dump->regs.r2 = regs->r2;
++ dump->regs.r3 = regs->r3;
++ dump->regs.r4 = regs->r4;
++ dump->regs.r5 = regs->r5;
++ dump->regs.r6 = regs->r6;
++ dump->regs.r7 = regs->r7;
++ dump->regs.r8 = regs->r8;
++ dump->regs.r9 = regs->r9;
++ dump->regs.r10 = regs->r10;
++ dump->regs.r11 = regs->r11;
++ dump->regs.r12 = regs->r12;
++ dump->regs.r13 = regs->r13;
++ dump->regs.r14 = regs->r14;
++ dump->regs.r15 = regs->r15;
++ dump->regs.r16 = sw->r16;
++ dump->regs.r17 = sw->r17;
++ dump->regs.r18 = sw->r18;
++ dump->regs.r19 = sw->r19;
++ dump->regs.r20 = sw->r20;
++ dump->regs.r21 = sw->r21;
++ dump->regs.r22 = sw->r22;
++ dump->regs.r23 = sw->r23;
++ dump->regs.ra = sw->ra;
++ dump->regs.fp = sw->fp;
++ dump->regs.gp = sw->gp;
++ dump->regs.sp = regs->sp;
++ dump->regs.orig_r2 = regs->orig_r2;
++ dump->regs.estatus = regs->estatus;
++ dump->regs.ea = regs->ea;
++ /* dump floating point stuff */
++ // dump->u_fpvalid = dump_fpu (regs, &dump->m68kfp);
++}
++
++/*
++ * 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 "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 "\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; // No user mode setting, at least not for now
++ 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_icache_range(pc, pc+4);
++ }
++ }
++}
+diff --git a/arch/nios2nommu/kernel/ptrace.c b/arch/nios2nommu/kernel/ptrace.c
+new file mode 100644
+index 0000000..e6ff3b3
+--- /dev/null
++++ b/arch/nios2nommu/kernel/ptrace.c
+@@ -0,0 +1,352 @@
++/*
++ * linux/arch/m68knommu/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/smp_lock.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>
++
++/*
++ * 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. Notice that usp has no stack-slot and needs to be treated
++ specially (see get_reg/put_reg below). */
++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), 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), -1, -1, PT_REG(ra), -1,
++ PT_REG(estatus), -1, -1, -1
++};
++
++/*
++ * Get contents of register REGNO in task TASK.
++ */
++static inline long get_reg(struct task_struct *task, int regno)
++{
++ unsigned long *addr;
++
++ if (regno == PTR_R0)
++ return 0;
++ else if (regno == PTR_BA)
++ return 0;
++ else if (regno == PTR_STATUS)
++ return 0;
++ else if (regno == PTR_IENABLE)
++ return 0;
++ else if (regno == PTR_IPENDING)
++ return 0;
++ else if (regno < sizeof(regoff)/sizeof(regoff[0]))
++ addr = (unsigned long *)(task->thread.kregs + regoff[regno]);
++ else
++ return 0;
++ 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 == PTR_R0)
++ return -1;
++ else if (regno == PTR_BA)
++ return -1;
++ else if (regno == PTR_STATUS)
++ return -1;
++ else if (regno == PTR_IENABLE)
++ return -1;
++ else if (regno == PTR_IPENDING)
++ return -1;
++ else if (regno < sizeof(regoff)/sizeof(regoff[0]))
++ addr = (unsigned long *) (task->thread.kregs + regoff[regno]);
++ else
++ return -1;
++ *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: {
++ unsigned long tmp;
++ int copied;
++
++ copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
++ ret = -EIO;
++ if (copied != sizeof(tmp))
++ break;
++ ret = put_user(tmp,(unsigned long *) 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;
++
++ tmp = 0; /* Default return condition */
++ addr = addr >> 2; /* temporary hack. */
++ ret = -EIO;
++ if (addr < 19) {
++ tmp = get_reg(child, addr);
++#if 0 // No FPU stuff
++ } else if (addr >= 21 && addr < 49) {
++ tmp = child->thread.fp[addr - 21];
++#ifdef CONFIG_M68KFPU_EMU
++ /* Convert internal fpu reg representation
++ * into long double format
++ */
++ if (FPU_IS_EMU && (addr < 45) && !(addr % 3))
++ tmp = ((tmp & 0xffff0000) << 15) |
++ ((tmp & 0x0000ffff) << 16);
++#endif
++#endif
++ } else if (addr == 49) {
++ tmp = child->mm->start_code;
++ } else if (addr == 50) {
++ tmp = child->mm->start_data;
++ } else if (addr == 51) {
++ tmp = child->mm->end_code;
++ } else
++ break;
++ ret = put_user(tmp,(unsigned long *) data);
++ 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 = 0;
++ if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
++ break;
++ ret = -EIO;
++ break;
++
++ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
++ 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 < 19) {
++ if (put_reg(child, addr, data))
++ break;
++ ret = 0;
++ break;
++ }
++#if 0 // No FPU stuff
++ if (addr >= 21 && addr < 48)
++ {
++#ifdef CONFIG_M68KFPU_EMU
++ /* Convert long double format
++ * into internal fpu reg representation
++ */
++ if (FPU_IS_EMU && (addr < 45) && !(addr % 3)) {
++ data = (unsigned long)data << 15;
++ data = (data & 0xffff0000) |
++ ((data & 0x0000ffff) >> 1);
++ }
++#endif
++ child->thread.fp[addr - 21] = data;
++ ret = 0;
++ }
++#endif
++ break;
++
++ case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
++ case PTRACE_CONT: { /* restart after signal. */
++
++ 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;
++ 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: {
++
++ ret = 0;
++ if (child->state == EXIT_ZOMBIE) /* already dead */
++ break;
++ child->exit_code = SIGKILL;
++ wake_up_process(child);
++ break;
++ }
++
++ /*
++ * Single stepping requires placing break instructions in
++ * the code to break back. If you are stepping through a
++ * conditional branch you need to decode the test and put
++ * the break in the correct location.
++ */
++ case PTRACE_SINGLESTEP: { /* set the trap flag. */
++
++ ret = -EIO;
++ if ((unsigned long) data > _NSIG)
++ break;
++ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
++
++ child->exit_code = data;
++ /* give it a chance to run. */
++ wake_up_process(child);
++ ret = 0;
++ break;
++ }
++
++ case PTRACE_DETACH: /* detach a process that was attached. */
++ ret = ptrace_detach(child, data);
++ break;
++
++ case PTRACE_GETREGS: { /* Get all gp regs from the child. */
++ int i;
++ unsigned long tmp;
++ for (i = 0; i < 19; 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;
++ for (i = 0; i < 19; 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;
++ }
++
++#ifdef PTRACE_GETFPREGS
++ case PTRACE_GETFPREGS: { /* Get the child FPU state. */
++ ret = 0;
++ if (copy_to_user((void *)data, &child->thread.fp,
++ sizeof(struct user_m68kfp_struct)))
++ ret = -EFAULT;
++ break;
++ }
++#endif
++
++#ifdef PTRACE_SETFPREGS
++ case PTRACE_SETFPREGS: { /* Set the child FPU state. */
++ ret = 0;
++ if (copy_from_user(&child->thread.fp, (void *)data,
++ sizeof(struct user_m68kfp_struct)))
++ ret = -EFAULT;
++ break;
++ }
++#endif
++
++ default:
++ 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/nios2nommu/kernel/semaphore.c b/arch/nios2nommu/kernel/semaphore.c
+new file mode 100644
+index 0000000..0c7d11b
+--- /dev/null
++++ b/arch/nios2nommu/kernel/semaphore.c
+@@ -0,0 +1,155 @@
++/*--------------------------------------------------------------------
++ *
++ * arch/nios2nommu/kernel/semaphore.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
++ *
++ ---------------------------------------------------------------------*/
++
++/*
++ * Generic semaphore code. Buyer beware. Do your own
++ * specific changes in <asm/semaphore-helper.h>
++ */
++
++#include <linux/sched.h>
++#include <linux/err.h>
++#include <asm/semaphore-helper.h>
++
++#ifndef CONFIG_RMW_INSNS
++spinlock_t semaphore_wake_lock;
++#endif
++
++/*
++ * Semaphores are implemented using a two-way counter:
++ * The "count" variable is decremented for each process
++ * that tries to sleep, while the "waking" variable is
++ * incremented when the "up()" code goes to wake up waiting
++ * processes.
++ *
++ * Notably, the inline "up()" and "down()" functions can
++ * efficiently test if they need to do any extra work (up
++ * needs to do something only if count was negative before
++ * the increment operation.
++ *
++ * waking_non_zero() (from asm/semaphore.h) must execute
++ * atomically.
++ *
++ * When __up() is called, the count was negative before
++ * incrementing it, and we need to wake up somebody.
++ *
++ * This routine adds one to the count of processes that need to
++ * wake up and exit. ALL waiting processes actually wake up but
++ * only the one that gets to the "waking" field first will gate
++ * through and acquire the semaphore. The others will go back
++ * to sleep.
++ *
++ * Note that these functions are only called when there is
++ * contention on the lock, and as such all this is the
++ * "non-critical" part of the whole semaphore business. The
++ * critical part is the inline stuff in <asm/semaphore.h>
++ * where we want to avoid any extra jumps and calls.
++ */
++asmlinkage void __up(struct semaphore *sem)
++{
++ wake_one_more(sem);
++ wake_up(&sem->wait);
++}
++
++/*
++ * Perform the "down" function. Return zero for semaphore acquired,
++ * return negative for signalled out of the function.
++ *
++ * If called from __down, the return is ignored and the wait loop is
++ * not interruptible. This means that a task waiting on a semaphore
++ * using "down()" cannot be killed until someone does an "up()" on
++ * the semaphore.
++ *
++ * If called from __down_interruptible, the return value gets checked
++ * upon return. If the return value is negative then the task continues
++ * with the negative value in the return register (it can be tested by
++ * the caller).
++ *
++ * Either form may be used in conjunction with "up()".
++ *
++ */
++
++
++#define DOWN_HEAD(task_state) \
++ \
++ \
++ current->state = (task_state); \
++ add_wait_queue(&sem->wait, &wait); \
++ \
++ /* \
++ * Ok, we're set up. sem->count is known to be less than zero \
++ * so we must wait. \
++ * \
++ * We can let go the lock for purposes of waiting. \
++ * We re-acquire it after awaking so as to protect \
++ * all semaphore operations. \
++ * \
++ * If "up()" is called before we call waking_non_zero() then \
++ * we will catch it right away. If it is called later then \
++ * we will have to go through a wakeup cycle to catch it. \
++ * \
++ * Multiple waiters contend for the semaphore lock to see \
++ * who gets to gate through and who has to wait some more. \
++ */ \
++ for (;;) {
++
++#define DOWN_TAIL(task_state) \
++ current->state = (task_state); \
++ } \
++ current->state = TASK_RUNNING; \
++ remove_wait_queue(&sem->wait, &wait);
++
++void __sched __down(struct semaphore * sem)
++{
++ DECLARE_WAITQUEUE(wait, current);
++
++ DOWN_HEAD(TASK_UNINTERRUPTIBLE)
++ if (waking_non_zero(sem))
++ break;
++ schedule();
++ DOWN_TAIL(TASK_UNINTERRUPTIBLE)
++}
++
++int __sched __down_interruptible(struct semaphore * sem)
++{
++ DECLARE_WAITQUEUE(wait, current);
++ int ret = 0;
++
++ DOWN_HEAD(TASK_INTERRUPTIBLE)
++
++ ret = waking_non_zero_interruptible(sem, current);
++ if (ret)
++ {
++ if (ret == 1)
++ /* ret != 0 only if we get interrupted -arca */
++ ret = 0;
++ break;
++ }
++ schedule();
++ DOWN_TAIL(TASK_INTERRUPTIBLE)
++ return ret;
++}
++
++int __down_trylock(struct semaphore * sem)
++{
++ return waking_non_zero_trylock(sem);
++}
+diff --git a/arch/nios2nommu/kernel/setup.c b/arch/nios2nommu/kernel/setup.c
+new file mode 100644
+index 0000000..1f1627b
+--- /dev/null
++++ b/arch/nios2nommu/kernel/setup.c
+@@ -0,0 +1,663 @@
++/*
++ 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/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>
++
++#include <asm/irq.h>
++#include <asm/byteorder.h>
++#include <asm/asm-offsets.h>
++#include <asm/pgtable.h>
++
++#ifdef CONFIG_BLK_DEV_INITRD
++#include <linux/blk.h>
++#endif
++
++#ifdef CONFIG_NIOS_SPI
++#include <asm/spi.h>
++extern ssize_t spi_write(struct file *filp, const char *buf, size_t count, loff_t *ppos);
++extern ssize_t spi_read (struct file *filp, char *buf, size_t count, loff_t *ppos);
++extern loff_t spi_lseek (struct file *filp, loff_t offset, int origin);
++extern int spi_open (struct inode *inode, struct file *filp);
++extern int spi_release (struct inode *inode, struct file *filp);
++#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_CMDLINE
++#define CONFIG_CMDLINE "CONSOLE=/dev/ttyS0 root=/dev/rom0 ro"
++#endif
++
++#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, 0};
++
++#define CPU "NIOS2"
++
++#if defined (CONFIG_CS89x0) || defined (CONFIG_SMC91111) || defined (CONFIG_OPEN_ETH) || defined (CONFIG_MTIP1000_ETH) || defined (CONFIG_DM9000_ETH) || defined (CONFIG_SMC91X) || defined (CONFIG_DM9000) || defined (CONFIG_DM9KS)
++ #if defined (CONFIG_MTIP1000_ETH) //;dgt3;
++ #include <../drivers/net/mtip1000.h> //;dgt3;
++ #endif //;dgt3;
++
++ unsigned char *excalibur_enet_hwaddr;
++ unsigned char excalibur_enet_hwaddr_array[6];
++#endif
++
++// save args passed from u-boot, called from head.S
++void nios2_boot_init(unsigned r4,unsigned r5,unsigned r6,unsigned r7)
++{
++#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
++}
++
++inline void flash_command(int base, int offset, short data)
++{
++ volatile unsigned short * ptr=(unsigned short*) (base);
++
++ ptr[0x555]=0xaa;
++ ptr[0x2aa]=0x55;
++ ptr[offset]=data;
++}
++
++inline void exit_se_flash(int base)
++{
++ flash_command(base, 0x555, 0x90);
++ *(unsigned short*)base=0;
++}
++
++void __init setup_arch(char **cmdline_p)
++{
++ int bootmap_size;
++ extern int _stext, _etext;
++ extern int _edata, _end;
++#ifdef DEBUG
++ extern int _sdata, _sbss, _ebss;
++#ifdef CONFIG_BLK_DEV_BLKMEM
++ extern int *romarray;
++#endif
++#endif
++#if 0 // krh
++ unsigned char *psrc=(unsigned char *)((NIOS_FLASH_START + NIOS_FLASH_END)>>1);
++ int i=0;
++#endif // krh
++
++ memory_start = PAGE_ALIGN((unsigned long)&_end);
++ memory_end = (unsigned long) nasys_program_mem_end;
++
++#if 0 //;kenw;
++ /* copy the command line from booting paramter region */
++ #if defined (nasys_am29lv065d_flash_0) //;dgt;
++ { //;dgt;
++ // ...TBA... //;dgt;
++ } //;dgt;
++ #else //;dgt;
++ flash_command((int)psrc, 0x555, 0x88);
++ while ((*psrc!=0xFF) && (i<sizeof(command_line))) {
++ command_line[i++]=*psrc++;
++ }
++ command_line[i]=0;
++ exit_se_flash(((NIOS_FLASH_START + NIOS_FLASH_END)>>1) );
++ if (command_line[0]==0)
++ #endif //;dgt;
++#endif //;kenw;
++#ifndef CONFIG_PASS_CMDLINE
++ memcpy(command_line, default_command_line, sizeof(default_command_line));
++#endif
++
++ printk("\x0F\r\n\nuClinux/Nios II\n");
++ printk("Altera Nios II support (C) 2004 Microtronix Datacom Ltd.\n");
++
++#ifdef DEBUG
++ printk("KERNEL -> TEXT=0x%08x-0x%08x DATA=0x%08x-0x%08x "
++ "BSS=0x%08x-0x%08x\n", (int) &_stext, (int) &_etext,
++ (int) &_sdata, (int) &_edata,
++ (int) &_sbss, (int) &_ebss);
++ printk("KERNEL -> MEM=0x%06x-0x%06x STACK=0x%06x-0x%06x\n",
++ (int) memory_start, (int) memory_end,
++ (int) memory_end, (int) nasys_program_mem_end);
++#endif
++
++ 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) 0;
++ init_task.thread.kregs = &fake_regs;
++
++#if 0
++ ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
++#endif
++
++ /* Keep a copy of command line */
++ *cmdline_p = &command_line[0];
++
++ memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
++ saved_command_line[COMMAND_LINE_SIZE-1] = 0;
++
++#ifdef DEBUG
++ if (strlen(*cmdline_p))
++ printk("Command line: '%s'\n", *cmdline_p);
++ else
++ printk("No Command line passed\n");
++#endif
++
++
++#if defined (CONFIG_CS89x0) || defined (CONFIG_SMC91111) || defined (CONFIG_OPEN_ETH) || defined (CONFIG_MTIP1000_ETH) || defined (CONFIG_DM9000_ETH) || defined (CONFIG_SMC91X) || defined (CONFIG_DM9000) || defined (CONFIG_DM9KS)
++
++ #if defined (CONFIG_MTIP1000_ETH) //;dgt3;
++ (*((np_mtip_mac *) //;dgt3;
++ (na_mtip_mac_control_port))). //;dgt3;
++ COMMAND_CONFIG = 0; //;dgt3;
++ #endif //;dgt3;
++
++ /* now read the hwaddr of the ethernet --wentao*/
++
++ #if 1 //;dgt2;
++// #if defined (nasys_am29lv065d_flash_0) //;dgt;
++ { //;dgt;
++ unsigned char *flashptr = //;dgt;
++ ((unsigned char *) //;dgt;
++ (( //;dgt;
++ #if defined (na_flash_kernel_end) //;dgt2;
++ na_flash_kernel_end //;dgt2;
++ #else //;dgt2;
++ #if defined (na_flash_kernel_base) //;dgt2;
++ na_flash_kernel_base + //;dgt;
++ #else //;dgt2;
++ na_flash_kernel + //;dgt2;
++ #endif //;dgt2;
++ na_flash_kernel_size //;dgt2;
++ #endif //;dgt2;
++ - 0x00010000))); //;dgt;
++ // last 64K of Altera stratix/cyclone flash //;dgt;
++ //;dgt;
++ if((*((unsigned long *) flashptr)) == 0x00005AFE) //;dgt;
++ { //;dgt;
++ memcpy(excalibur_enet_hwaddr_array, //;dgt;
++ ((void*) (flashptr+4)),6); //;dgt;
++ } //;dgt;
++ else //;dgt;
++ { //;dgt;
++ printk("\nsetup_arch: No persistant network" //;dgt;
++ " settings signature at %08lX\n", //;dgt;
++ ((unsigned long) flashptr)); //;dgt;
++ *((unsigned long *) //;dgt;
++ (&(excalibur_enet_hwaddr_array[0]))) = //;dgt;
++ 0x00ED0700; //;dgt2;
++ /* 0x00-07-ED: Altera Corporation. //;dgt; */
++ *((unsigned short *) //;dgt;
++ (&(excalibur_enet_hwaddr_array[4]))) = //;dgt;
++ 0x0000; //;dgt;
++ /* Should be: 0x-00-07-ED-0A-03-(Random# 0-256) //;dgt2; */
++ /* 0x-00-07-ED-0A-xx-yy Vermont boards //;dgt2; */
++ /* 0x-00-07-ED-0B-xx-yy Rhode Island boards //;dgt2; */
++ /* 0x-00-07-ED-0C-xx-yy Delaware boards //;dgt2; */
++ /* 00 Internal Altera //;dgt2; */
++ /* 01 Beta, pre-production//;dgt2; */
++ /* 02 Beta, pre-production//;dgt2; */
++ /* 03 Customer use //;dgt2; */
++ } //;dgt;
++ } //;dgt;
++ #else //;dgt;
++ flash_command(NIOS_FLASH_START, 0x555, 0x88);
++ memcpy(excalibur_enet_hwaddr_array,(void*)NIOS_FLASH_START,6);
++ exit_se_flash(NIOS_FLASH_START);;
++ #endif //;dgt;
++
++ /* now do the checking, make sure we got a valid addr */
++ if (excalibur_enet_hwaddr_array[0] & (unsigned char)1)
++ {
++ printk("Ethernet hardware address:Clearing invalid bit #0\n");
++ excalibur_enet_hwaddr_array[0] ^= (unsigned char)1;
++ }
++ excalibur_enet_hwaddr=excalibur_enet_hwaddr_array;
++#ifdef DEBUG
++ printk("Setup the hardware addr for ethernet\n\t %02x %02x %02x %02x %02x %02x\n",
++ excalibur_enet_hwaddr[0],excalibur_enet_hwaddr[1],
++ excalibur_enet_hwaddr[2],excalibur_enet_hwaddr[3],
++ excalibur_enet_hwaddr[4],excalibur_enet_hwaddr[5]);
++#endif
++#endif
++
++
++ /*
++ * give all the memory to the bootmap allocator, tell it to put the
++ * boot mem_map at the start of memory
++ */
++ bootmap_size = init_bootmem_node(
++ NODE_DATA(0),
++ memory_start >> PAGE_SHIFT, /* map goes here */
++ PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */
++ memory_end >> PAGE_SHIFT);
++ /*
++ * free the usable memory, we have to make sure we do not free
++ * the bootmem bitmap so we then reserve it after freeing it :-)
++ */
++ free_bootmem(memory_start, memory_end - memory_start);
++ reserve_bootmem(memory_start, bootmap_size);
++#ifdef CONFIG_BLK_DEV_INITRD
++ if (initrd_start) reserve_bootmem(virt_to_phys((void *)initrd_start), initrd_end - initrd_start);
++#endif /* CONFIG_BLK_DEV_INITRD */
++ /*
++ * get kmalloc into gear
++ */
++ paging_init();
++#ifdef CONFIG_VT
++#if defined(CONFIG_DUMMY_CONSOLE)
++ conswitchp = &dummy_con;
++#endif
++#endif
++
++#ifdef DEBUG
++ printk("Done setup_arch\n");
++#endif
++
++}
++
++int get_cpuinfo(char * buffer)
++{
++ char *cpu, *mmu, *fpu;
++ u_long clockfreq;
++
++ cpu = CPU;
++ mmu = "none";
++ fpu = "none";
++
++ clockfreq = nasys_clock_freq;
++
++ return(sprintf(buffer, "CPU:\t\t%s\n"
++ "MMU:\t\t%s\n"
++ "FPU:\t\t%s\n"
++ "Clocking:\t%lu.%1luMHz\n"
++ "BogoMips:\t%lu.%02lu\n"
++ "Calibration:\t%lu loops\n",
++ cpu, mmu, fpu,
++ clockfreq/1000000,(clockfreq/100000)%10,
++ (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
++ (loops_per_jiffy*HZ)));
++
++}
++
++/*
++ * Get CPU information for use by the procfs.
++ */
++
++static int show_cpuinfo(struct seq_file *m, void *v)
++{
++ char *cpu, *mmu, *fpu;
++ u_long clockfreq;
++
++ cpu = CPU;
++ mmu = "none";
++ fpu = "none";
++
++ clockfreq = nasys_clock_freq;
++
++ seq_printf(m, "CPU:\t\t%s\n"
++ "MMU:\t\t%s\n"
++ "FPU:\t\t%s\n"
++ "Clocking:\t%lu.%1luMHz\n"
++ "BogoMips:\t%lu.%02lu\n"
++ "Calibration:\t%lu loops\n",
++ cpu, mmu, fpu,
++ clockfreq/1000000,(clockfreq/100000)%10,
++ (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
++ (loops_per_jiffy*HZ));
++
++ return 0;
++}
++
++#ifdef CONFIG_NIOS_SPI
++
++static int bcd2char( int x )
++{
++ if ( (x & 0xF) > 0x90 || (x & 0x0F) > 0x09 )
++ return 99;
++
++ return (((x & 0xF0) >> 4) * 10) + (x & 0x0F);
++}
++
++#endif // CONFIG_NIOS_SPI
++
++
++void arch_gettod(int *year, int *month, int *date, int *hour, int *min, int *sec)
++{
++#ifdef CONFIG_NIOS_SPI
++ /********************************************************************/
++ /* Read the CMOS clock on the Microtronix Datacom O/S Support card. */
++ /* Use the SPI driver code, but circumvent the file system by using */
++ /* its internal functions. */
++ /********************************************************************/
++ int hr;
++
++ struct /*********************************/
++ { /* The SPI payload. Warning: the */
++ unsigned short register_addr; /* sizeof() operator will return */
++ unsigned char value; /* a length of 4 instead of 3! */
++ } spi_data; /*********************************/
++
++
++ if ( spi_open( NULL, NULL ) )
++ {
++ printk( "Cannot open SPI driver to read system CMOS clock.\n" );
++ *year = *month = *date = *hour = *min = *sec = 0;
++ return;
++ }
++
++ spi_lseek( NULL, clockCS, 0 /* == SEEK_SET */ );
++
++ spi_data.register_addr = clock_write_control;
++ spi_data.value = 0x40; // Write protect
++ spi_write( NULL, (const char *)&spi_data, 3, NULL );
++
++ spi_data.register_addr = clock_read_sec;
++ spi_data.value = 0;
++ spi_read( NULL, (char *)&spi_data, 3, NULL );
++ *sec = (int)bcd2char( spi_data.value );
++
++ spi_data.register_addr = clock_read_min;
++ spi_data.value = 0;
++ spi_read( NULL, (char *)&spi_data, 3, NULL );
++ *min = (int)bcd2char( spi_data.value );
++
++ spi_data.register_addr = clock_read_hour;
++ spi_data.value = 0;
++ spi_read( NULL, (char *)&spi_data, 3, NULL );
++ hr = (int)bcd2char( spi_data.value );
++ if ( hr & 0x40 ) // Check 24-hr bit
++ hr = (hr & 0x3F) + 12; // Convert to 24-hr
++
++ *hour = hr;
++
++
++
++ spi_data.register_addr = clock_read_date;
++ spi_data.value = 0;
++ spi_read( NULL, (char *)&spi_data, 3, NULL );
++ *date = (int)bcd2char( spi_data.value );
++
++ spi_data.register_addr = clock_read_month;
++ spi_data.value = 0;
++ spi_read( NULL, (char *)&spi_data, 3, NULL );
++ *month = (int)bcd2char( spi_data.value );
++
++ spi_data.register_addr = clock_read_year;
++ spi_data.value = 0;
++ spi_read( NULL, (char *)&spi_data, 3, NULL );
++ *year = (int)bcd2char( spi_data.value );
++
++
++ spi_release( NULL, NULL );
++#else
++ *year = *month = *date = *hour = *min = *sec = 0;
++
++#endif
++}
++
++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)
++{
++}
++
++struct seq_operations cpuinfo_op = {
++ start: cpuinfo_start,
++ next: cpuinfo_next,
++ stop: cpuinfo_stop,
++ show: show_cpuinfo
++};
++
++
++// adapted from linux/arch/arm/mach-versatile/core.c and mach-bast
++// note, hardware MAC address is still undefined
++
++#if defined(CONFIG_SMC91X) && defined(na_enet)
++
++#ifndef LAN91C111_REGISTERS_OFFSET
++#define LAN91C111_REGISTERS_OFFSET 0x300
++#endif
++
++static struct resource smc91x_resources[] = {
++ [0] = {
++ .start = na_enet + LAN91C111_REGISTERS_OFFSET,
++ .end = na_enet + LAN91C111_REGISTERS_OFFSET + 0x100 - 1, // 32bits,64k, LAN91C111_REGISTERS_OFFSET 0x0300 ?
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = na_enet_irq,
++ .end = na_enet_irq,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++static struct platform_device smc91x_device = {
++ .name = "smc91x",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(smc91x_resources),
++ .resource = smc91x_resources,
++};
++static int __init smc91x_device_init(void)
++{
++ /* customizes platform devices, or adds new ones */
++ platform_device_register(&smc91x_device);
++ return 0;
++}
++arch_initcall(smc91x_device_init);
++#endif // CONFIG_SMC91X
++
++
++#if defined(na_DM9000A) && !defined(na_dm9000) // defs for DE2
++#define na_dm9000 na_DM9000A
++#define na_dm9000_irq na_DM9000A_irq
++#endif
++
++#if defined(CONFIG_DM9000) && defined(na_dm9000)
++#include <linux/dm9000.h>
++static struct resource dm9k_resource[] = {
++ [0] = {
++ .start = na_dm9000,
++ .end = na_dm9000 + 3,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = na_dm9000 + 4,
++ .end = na_dm9000 + 4 + 3,
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .start = na_dm9000_irq,
++ .end = na_dm9000_irq,
++ .flags = IORESOURCE_IRQ,
++ }
++
++};
++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,
++ }
++};
++static int __init dm9k_device_init(void)
++{
++ /* customizes platform devices, or adds new ones */
++ platform_device_register(&dm9k_device);
++ return 0;
++}
++arch_initcall(dm9k_device_init);
++#endif // CONFIG_DM9000
++
++
++#if defined(CONFIG_SERIO_ALTPS2) && defined(na_ps2_0)
++
++static struct resource altps2_0_resources[] = {
++ [0] = {
++ .start = na_ps2_0,
++ .end = na_ps2_0 + 0x8 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = na_ps2_0_irq,
++ .end = na_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(na_ps2_1)
++static struct resource altps2_1_resources[] = {
++ [0] = {
++ .start = na_ps2_1,
++ .end = na_ps2_1 + 0x8 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = na_ps2_1_irq,
++ .end = na_ps2_1_irq,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++static struct platform_device altps2_1_device = {
++ .name = "altps2",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(altps2_1_resources),
++ .resource = altps2_1_resources,
++};
++#endif // na_ps2_1
++
++static int __init altps2_device_init(void)
++{
++ /* customizes platform devices, or adds new ones */
++ platform_device_register(&altps2_0_device);
++#if defined(na_ps2_1)
++ platform_device_register(&altps2_1_device);
++#endif // na_ps2_1
++ return 0;
++}
++arch_initcall(altps2_device_init);
++#endif // CONFIG_SERIO_ALTPS2
++
++#if defined(CONFIG_I2C_NIOS2_GPIO) && defined(na_gpio_0)
++#include <asm/gpio.h>
++
++static struct gpio_i2c_pins i2c_gpio_0_pins = {
++ .sda_pin = (na_gpio_0+(0<<2)),
++ .scl_pin = (na_gpio_0+(1<<2)),
++};
++
++static struct platform_device i2c_gpio_0_controller = {
++ .name = "GPIO-I2C",
++ .id = 0,
++ .dev = {
++ .platform_data = &i2c_gpio_0_pins,
++ },
++ .num_resources = 0
++};
++
++static int __init i2c_gpio_device_init(void)
++{
++ /* customizes platform devices, or adds new ones */
++ platform_device_register(&i2c_gpio_0_controller);
++ return 0;
++}
++arch_initcall(i2c_gpio_device_init);
++
++#endif // CONFIG_I2C_NIOS2_GPIO
+diff --git a/arch/nios2nommu/kernel/signal.c b/arch/nios2nommu/kernel/signal.c
+new file mode 100644
+index 0000000..d8c30dc
+--- /dev/null
++++ b/arch/nios2nommu/kernel/signal.c
+@@ -0,0 +1,738 @@
++/*
++ * 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 Macdonald
++ *
++ * 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 <asm/setup.h>
++#include <asm/uaccess.h>
++#include <asm/pgtable.h>
++#include <asm/traps.h>
++#include <asm/ucontext.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);
++
++/*
++ * 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;
++ while (1) {
++ current->state = TASK_INTERRUPTIBLE;
++ schedule();
++ if (do_signal(&saveset, regs))
++ 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;
++ while (1) {
++ current->state = TASK_INTERRUPTIBLE;
++ schedule();
++ if (do_signal(&saveset, regs))
++ 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 (verify_area(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 (verify_area(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);
++
++ *pr2 = regs->r2;
++ regs->orig_r2 = -1; /* disable syscall checks */
++
++#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 */
++ 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(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(usp, &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);
++ err |= __get_user(regs->status_extension,
++ &uc->uc_mcontext.status_extension);
++ 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 (verify_area(VERIFY_READ, 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))))
++ 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))
++ 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 (verify_area(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;
++}
++
++#ifdef CONFIG_FPU
++/*
++ * Set up a signal frame.
++ *
++ * Not converted, no FPU support at moment.
++ */
++
++static inline int save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
++{
++ int err = 0;
++
++ if (FPU_IS_EMU) {
++ /* save registers */
++ err |= copy_to_user(&sc->sc_fpcntl, current->thread.fpcntl, 12);
++ err |= copy_to_user(&sc->sc_fpregs, current->thread.fp, 24);
++ return err;
++ }
++
++ __asm__ volatile ("Nios II FPUt"
++ : : );
++
++ if (sc->sc_fpstate[0]) {
++ fpu_version = sc->sc_fpstate[0];
++ __asm__ volatile ("Nios II FPU"
++ : /* no outputs */
++ :
++ : );
++ }
++ return err;
++}
++
++static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs)
++{
++ unsigned char fpstate[FPCONTEXT_SIZE];
++ int context_size = 0;
++ int err = 0;
++
++ if (FPU_IS_EMU) {
++ /* save fpu control register */
++ err |= copy_to_user(&uc->uc_mcontext.fpregs.f_pcr,
++ current->thread.fpcntl, 12);
++ /* save all other fpu register */
++ err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
++ current->thread.fp, 96);
++ return err;
++ }
++
++ __asm__ volatile ("Nios II FPU"
++ : : : );
++
++ err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate);
++ if (fpstate[0]) {
++ fpregset_t fpregs;
++ context_size = fpstate[1];
++ fpu_version = fpstate[0];
++ __asm__ volatile ("Nios II FPU"
++ : /* no outputs */
++ :
++ : );
++ err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
++ sizeof(fpregs));
++ }
++ if (context_size)
++ err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4,
++ context_size);
++ return err;
++}
++
++#endif
++
++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));
++#ifdef CONFIG_FPU
++ err |= save_fpu_state(sc, regs);
++#endif
++ 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->status_extension,
++ &uc->uc_mcontext.status_extension);
++ 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(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->sp, &gregs[23]);
++ err |= __put_user(sw->fp, &gregs[24]);
++ err |= __put_user(sw->gp, &gregs[25]);
++#ifdef CONFIG_FPU
++ err |= rt_save_fpu_state(uc, regs);
++#endif
++ return err;
++}
++
++extern void cache_push_v (unsigned long vaddr, int len);
++
++static inline void push_cache (unsigned long vaddr)
++{
++ cache_push_v(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) {
++ 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 r3,__NR_sigreturn */
++ err |= __put_user(0x00c00004 + (__NR_sigreturn << 6), (long *)(frame->retcode));
++ /* mov r2,r0 */
++ err |= __put_user(0x0005883a, (long *)(frame->retcode + 4));
++ /* trap */
++ err |= __put_user(0x003b683a, (long *)(frame->retcode + 8));
++
++ 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 r3,__NR_rt_sigreturn */
++ err |= __put_user(0x00c00004 + (__NR_rt_sigreturn << 6), (long *)(frame->retcode));
++ /* mov r2,r0 */
++ err |= __put_user(0x0005883a, (long *)(frame->retcode + 4));
++ /* trap */
++ err |= __put_user(0x003b683a, (long *)(frame->retcode + 8));
++
++ 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 -ERESTARTNOHAND:
++ if (!has_handler)
++ goto do_restart;
++ regs->r2 = -EINTR;
++ break;
++
++ case -ERESTARTSYS:
++ if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
++ regs->r2 = -EINTR;
++ break;
++ }
++ /* fallthrough */
++ case -ERESTARTNOINTR:
++ do_restart:
++ regs->r2 = regs->orig_r2;
++ 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)
++{
++ /* are we from a system call? */
++ if (regs->orig_r2 >= 0)
++ /* 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)
++{
++ 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);
++ return 1;
++ }
++
++ /* Did we come from a system call? */
++ if (regs->orig_r2 >= 0){
++ /* Restart the system call - no handlers present */
++ if (regs->r2 == -ERESTARTNOHAND
++ || regs->r2 == -ERESTARTSYS
++ || regs->r2 == -ERESTARTNOINTR) {
++ regs->r2 = regs->orig_r2;
++ regs->ea -= 4;
++ } else if (regs->r2 == -ERESTART_RESTARTBLOCK) {
++ regs->r2 = __NR_restart_syscall;
++ regs->ea -= 4;
++ }
++ }
++ return 0;
++}
+diff --git a/arch/nios2nommu/kernel/start.c b/arch/nios2nommu/kernel/start.c
+new file mode 100644
+index 0000000..bca81fc
+--- /dev/null
++++ b/arch/nios2nommu/kernel/start.c
+@@ -0,0 +1,502 @@
++/*--------------------------------------------------------------------
++ *
++ * 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>
++
++ #ifdef CONFIG_SERIAL_AJUART //;dgt;20may05;
++ #ifdef CONFIG_SERIAL_AJUART_CONSOLE //;dgt;20may05;
++
++ #include <linux/console.h> //;dgt;20may05;
++ #include <asm/altera_juart.h> //;dgt;20may05;
++
++ extern struct console juart_console; //;dgt;20may05;
++
++ #endif // CONFIG_SERIAL_AJUART //;dgt;20may05;
++ #endif // CONFIG_SERIAL_AJUART_CONSOLE //;dgt;20may05;
++
++//;dgt;20may05; #ifdef CONFIG_CRC_CHECK
++
++// #if defined(CONFIG_NIOS_SERIAL) //;dgt;20may05;
++// #if defined(CONFIG_NIOS_SERIAL_CONSOLE) //;dgt;20may05;
++ #if defined(nasys_printf_uart) //;dgt;20may05;
++ static void putsNoNewLine( unsigned char *s )
++ {
++ while(*s) {
++ while (!(nasys_printf_uart->np_uartstatus &
++ np_uartstatus_trdy_mask));
++ nasys_printf_uart->np_uarttxdata = *s++;
++ }
++ }
++
++ #define NL "\r\n"
++ static void puts(unsigned char *s)
++ {
++ putsNoNewLine( s );
++ putsNoNewLine( NL );
++ }
++ #endif // nasys_printf_uart //;dgt;20may05;
++// #endif // CONFIG_NIOS_SERIAL_CONSOLE) //;dgt;20may05;
++// #endif // CONFIG_NIOS_SERIAL) //;dgt;20may05;
++
++#ifdef CONFIG_CRC_CHECK //;dgt;20may05;
++
++#if 1
++#define outchar(X) { \
++ while (!(nasys_printf_uart->np_uartstatus & np_uartstatus_trdy_mask)); \
++ nasys_printf_uart->np_uarttxdata = (X); }
++#else
++#define outchar(X) putchar(X)
++#endif
++#define outhex(X,Y) { \
++ unsigned long __w; \
++ __w = ((X) >> (Y)) & 0xf; \
++ __w = __w > 0x9 ? 'A' + __w - 0xa : '0' + __w; \
++ outchar(__w); }
++#define outhex8(X) { \
++ outhex(X,4); \
++ outhex(X,0); }
++#define outhex16(X) { \
++ outhex(X,12); \
++ outhex(X,8); \
++ outhex(X,4); \
++ outhex(X,0); }
++#define outhex32(X) { \
++ outhex(X,28); \
++ outhex(X,24); \
++ outhex(X,20); \
++ outhex(X,16); \
++ outhex(X,12); \
++ outhex(X,8); \
++ outhex(X,4); \
++ outhex(X,0); }
++#endif
++
++#if 0
++static unsigned long testvar = 0xdeadbeef;
++#endif
++
++#ifdef CONFIG_CRC_CHECK
++
++
++/******************************************************/
++
++
++extern unsigned long __CRC_Table_Begin;
++
++typedef unsigned char U8;
++typedef unsigned long U32;
++
++/* Table of CRC-32's of all single byte values */
++const U32 crc_32_tab[] = {
++ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
++ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
++ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
++ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
++ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
++ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
++ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
++ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
++ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
++ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
++ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
++ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
++ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
++ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
++ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
++ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
++ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
++ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
++ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
++ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
++ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
++ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
++ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
++ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
++ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
++ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
++ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
++ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
++ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
++ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
++ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
++ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
++ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
++ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
++ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
++ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
++ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
++ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
++ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
++ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
++ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
++ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
++ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
++ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
++ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
++ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
++ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
++ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
++ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
++ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
++ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
++ 0x2d02ef8dL
++};
++
++U32 Calc_CRC( const U8 *p, U32 len )
++{
++ U32 crc = (U32)~0L;
++ while (len--)
++ crc = crc_32_tab[0xFF & (crc ^ *p++)] ^ (crc >> 8);
++
++ return crc ^ (U32)~0L;
++}
++
++
++
++/******************************************************/
++
++
++/* hjz: Following time stuff is hacked and modified from uC-libc (various files), which in turn was... */
++/* This is adapted from glibc */
++/* Copyright (C) 1991, 1993 Free Software Foundation, Inc */
++
++#define SECS_PER_HOUR 3600L
++#define SECS_PER_DAY 86400L
++typedef unsigned long time_t;
++
++
++static const unsigned short int __mon_lengths[2][12] = {
++ /* Normal years. */
++ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
++ /* Leap years. */
++ {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
++};
++/* This global is exported to the wide world in keeping
++ * with the interface in time.h */
++long int timezone = 0;
++
++static const char *dayOfWeek[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
++static const char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
++ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
++
++/* Nonzero if YEAR is a leap year (every 4 years,
++ except every 100th isn't, and every 400th is). */
++# define __isleap(year) ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
++
++struct tm
++{
++ int tm_sec; /* Seconds. [0-60] (1 leap second) */
++ int tm_min; /* Minutes. [0-59] */
++ int tm_hour; /* Hours. [0-23] */
++ int tm_mday; /* Day. [1-31] */
++ int tm_mon; /* Month. [0-11] */
++ int tm_year; /* Year - 1900. */
++ int tm_wday; /* Day of week. [0-6] */
++ int tm_yday; /* Days in year.[0-365] */
++ int tm_isdst; /* DST. [-1/0/1]*/
++
++# ifdef __USE_BSD
++ long int tm_gmtoff; /* Seconds east of UTC. */
++ __const char *tm_zone; /* Timezone abbreviation. */
++# else
++ long int __tm_gmtoff; /* Seconds east of UTC. */
++ __const char *__tm_zone; /* Timezone abbreviation. */
++# endif
++};
++
++void __tm_conv(struct tm *tmbuf, time_t *t, time_t offset)
++{
++ long days, rem;
++ register int y;
++ register const unsigned short int *ip;
++
++ timezone = -offset;
++
++ days = *t / SECS_PER_DAY;
++ rem = *t % SECS_PER_DAY;
++ rem += offset;
++ while (rem < 0)
++ {
++ rem += SECS_PER_DAY;
++ days--;
++ }
++ while (rem >= SECS_PER_DAY)
++ {
++ rem -= SECS_PER_DAY;
++ days++;
++ }
++
++ tmbuf->tm_hour = rem / SECS_PER_HOUR;
++ rem %= SECS_PER_HOUR;
++ tmbuf->tm_min = rem / 60;
++ tmbuf->tm_sec = rem % 60;
++
++ /* January 1, 1970 was a Thursday. */
++ tmbuf->tm_wday = (4 + days) % 7;
++ if (tmbuf->tm_wday < 0)
++ tmbuf->tm_wday += 7;
++
++ y = 1970;
++ while (days >= (rem = __isleap(y) ? 366 : 365))
++ {
++ y++;
++ days -= rem;
++ }
++
++ while (days < 0)
++ {
++ y--;
++ days += __isleap(y) ? 366 : 365;
++ }
++
++ tmbuf->tm_year = y - 1900;
++ tmbuf->tm_yday = days;
++
++ ip = __mon_lengths[__isleap(y)];
++ for (y = 0; days >= ip[y]; ++y)
++ days -= ip[y];
++
++ tmbuf->tm_mon = y;
++ tmbuf->tm_mday = days + 1;
++ tmbuf->tm_isdst = -1;
++}
++
++
++
++/* hjz: NOT your traditional ctime: This one includes timezone */
++/* (UTC) and excludes the traditional trailing newline. */
++char *CTime( time_t *t )
++{
++ static char theTime[29];
++ struct tm tm;
++
++ __tm_conv( &tm, t, 0 );
++ sprintf( theTime, "%s %s %02d %02d:%02d:%02d UTC %04d",
++ dayOfWeek[tm.tm_wday], month[tm.tm_mon], tm.tm_mday,
++ tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year + 1900 );
++
++ return theTime;
++}
++
++/******************************************************/
++
++
++/* hjz: polled-I/O: Get a char if one is ready, or return -1 */
++int getc( void )
++{
++ if ( nasys_printf_uart->np_uartstatus & np_uartstatus_rrdy_mask )
++ return nasys_printf_uart->np_uartrxdata;
++ else
++ return -1;
++}
++
++
++typedef unsigned long off_t;
++typedef struct
++{
++ U8 *startAddr;
++ U8 *endAddr;
++ U32 CRC;
++ time_t mtime;
++ off_t size; // File size
++ char id[44]; // Filename. If path exceeds available size, name is "..." + last 40 chars of given filename
++ char host[32]; // hostname. If name exceeds available size name is first 28 chars of hostname + "..."
++} FLASH_REGION_DESC;
++
++
++int Test_Flash_Regions(void)
++{
++ FLASH_REGION_DESC *pRegion = (FLASH_REGION_DESC *)&__CRC_Table_Begin;
++ U32 crc;
++ char cBuff[256];
++ int nrFailedRegions = 0;
++ int regionStatus;
++ int i;
++ unsigned int startAddr = (int) pRegion->startAddr;
++ unsigned int endAddr = (int) pRegion->endAddr;
++
++ puts( "***Checking flash CRC's" );
++ if ( (startAddr == -1) || (startAddr >= endAddr)
++ || !( ((startAddr >= (int) NIOS_FLASH_START) && (endAddr < (int) NIOS_FLASH_END))
++ || ((startAddr >= (int) na_flash) && (endAddr < (int) na_flash_end)) ) )
++ {
++ puts( " No Flash regions defined." );
++ return -1;
++ }
++
++
++ for ( i = 0; pRegion->startAddr && pRegion->startAddr != (U8 *)~0L; pRegion++, i++ )
++ {
++ crc = Calc_CRC( pRegion->startAddr, pRegion->endAddr - pRegion->startAddr );
++ if ( crc != pRegion->CRC )
++ {
++ regionStatus = 1;
++ nrFailedRegions++;
++ }
++ else
++ regionStatus = 0;
++
++ sprintf( cBuff, " Region %d: 0x%08lX - 0x%08lX, CRC = 0x%08lX --> %s" NL
++ " From file `%s' on host `%s'" NL
++ " Dated %s, size = %lu bytes",
++ i, (U32)pRegion->startAddr, (U32)pRegion->endAddr, pRegion->CRC,
++ regionStatus ? "***Failed" : "Passed",
++ pRegion->id, pRegion->host, CTime( &pRegion->mtime ), pRegion->size
++ );
++ puts( cBuff );
++ }
++
++ return nrFailedRegions;
++}
++#endif /* CONFIG_CRC_CHECK */
++
++
++int main(void) {
++
++#ifdef DEBUG
++ puts("MAIN: starting c\n");
++#endif
++
++#ifdef CONFIG_KGDB /* builtin GDB stub */
++
++/* Set up GDB stub, and make the first trap into it */
++ nios_gdb_install(1);
++#ifdef CONFIG_BREAK_ON_START
++ puts( "MAIN: trapping to debugger - make sure nios-elf-gdb is running on host." );
++ nios_gdb_breakpoint();
++ nop();
++#endif
++
++#endif /* CONFIG_KGDB */
++
++#ifdef CONFIG_CRC_CHECK
++ #ifdef CONFIG_PROMPT_ON_MISSING_CRC_TABLES
++ if ( Test_Flash_Regions() )
++ #else
++ if ( Test_Flash_Regions() > 0 )
++ #endif
++ {
++ int c;
++ char tmp[3];
++ while ( getc() != -1 ) // flush input
++ ;
++
++ putsNoNewLine( " Do you wish to continue (Y/N) ? " );
++ while ( 1 )
++ {
++ c = getc();
++ if ( c == -1 )
++ continue;
++
++ if ( !isprint( c ) )
++ c = '?';
++
++ sprintf( tmp, "\b%c", c );
++ putsNoNewLine( tmp );
++ c = toupper( c );
++ if ( c == 'Y' )
++ {
++ puts( "" );
++ break;
++ }
++
++ if ( c == 'N' )
++ {
++ puts( NL "***Trapping to monitor..." );
++ return -1;
++ }
++ }
++ }
++ puts( "***Starting kernel..." );
++
++#endif
++
++ // Altera NiosII Custom shift instr(s) possibly //;dgt;
++ // assumed by memcpy, etc; ensure "correct" core //;dgt;
++ // loaded therefore if so. //;dgt;
++
++ #if defined(ALT_CI_ALIGN_32_N) //;dgt;
++ if(ALT_CI_ALIGN_32(1, 0xA9876543, //;dgt;
++ 0xB210FEDC) != 0x10FEDCA9) //;dgt;
++ { //;dgt;
++ goto badshiftci_label; //;dgt;
++ } //;dgt;
++ if(ALT_CI_ALIGN_32(2, 0xA9876543, //;dgt;
++ 0xB210FEDC) != 0xFEDCA987) //;dgt;
++ { //;dgt;
++ goto badshiftci_label; //;dgt;
++ } //;dgt;
++ if(ALT_CI_ALIGN_32(3, 0xA9876543, //;dgt;
++ 0xB210FEDC) != 0xDCA98765) //;dgt;
++ { //;dgt;
++ goto badshiftci_label; //;dgt;
++ } //;dgt;
++ #endif //;dgt;
++ goto gudshiftci_label; //;dgt;
++badshiftci_label: //;dgt;
++ { //;dgt;
++ unsigned char BadCImsg[] = //;dgt;
++ "?...ALT_CI_ALIGNn_321() NOT expected" //;dgt;
++ " NiosII custom instruction\n"; //;dgt;
++ unsigned char CIabortMsg[] = //;dgt;
++ " ...aborting uClinux startup..."; //;dgt;
++
++ #ifdef CONFIG_SERIAL_AJUART //;dgt;
++ #ifdef CONFIG_SERIAL_AJUART_CONSOLE //;dgt;
++ juart_console.index = 0; //;dgt;
++ jtaguart_console_write(&(juart_console), //;dgt;
++ BadCImsg, //;dgt;
++ strlen(BadCImsg)); //;dgt;
++ jtaguart_console_write(&(juart_console), //;dgt;
++ CIabortMsg, //;dgt;
++ strlen(CIabortMsg)); //;dgt;
++ #endif // CONFIG_SERIAL_AJUART //;dgt;
++ #endif // CONFIG_SERIAL_AJUART_CONSOLE //;dgt;
++
++// #if defined(CONFIG_NIOS_SERIAL) //;dgt;
++// #if defined(CONFIG_NIOS_SERIAL_CONSOLE) //;dgt;
++ #if defined(nasys_printf_uart) //;dgt;
++ puts(BadCImsg); //;dgt;
++ puts(CIabortMsg); //;dgt;
++ #endif // nasys_printf_uart //;dgt;
++// #endif // CONFIG_NIOS_SERIAL_CONSOLE) //;dgt;
++// #endif // CONFIG_NIOS_SERIAL) //;dgt;
++
++ panic(" ...wrong fpga core?..."); //;dgt;
++ } //;dgt;
++
++gudshiftci_label: //;dgt;
++
++ start_kernel();
++ return 0;
++}
+diff --git a/arch/nios2nommu/kernel/sys_nios2.c b/arch/nios2nommu/kernel/sys_nios2.c
+new file mode 100644
+index 0000000..8018fb0
+--- /dev/null
++++ b/arch/nios2nommu/kernel/sys_nios2.c
+@@ -0,0 +1,248 @@
++/*
++ * 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/smp_lock.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/fs.h>
++#include <linux/uaccess.h>
++#include <linux/ipc.h>
++#include <linux/unistd.h>
++
++#include <asm/setup.h>
++#include <asm/cachectl.h>
++#include <asm/traps.h>
++#include <asm/ipc.h>
++#include <asm/cacheflush.h>
++
++/*
++ * sys_pipe() is the normal C calling standard for creating
++ * a pipe. It's not the way unix traditionally does this, though.
++ */
++asmlinkage int sys_pipe(unsigned long * fildes)
++{
++ int fd[2];
++ int error;
++
++ error = do_pipe(fd);
++ if (!error) {
++ if (copy_to_user(fildes, fd, 2*sizeof(int)))
++ error = -EFAULT;
++ }
++ return error;
++}
++
++/* 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);
++}
++
++/*
++ * 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;
++};
++
++asmlinkage int old_mmap(struct mmap_arg_struct *arg)
++{
++ struct mmap_arg_struct a;
++ int error = -EFAULT;
++
++ if (copy_from_user(&a, arg, sizeof(a)))
++ goto out;
++
++ error = -EINVAL;
++ if (a.offset & ~PAGE_MASK)
++ goto out;
++
++ a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++
++ error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
++out:
++ return error;
++}
++
++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 (uint call, int first, int second,
++ int third, void *ptr, long fifth)
++{
++ int version;
++
++ version = call >> 16; /* hack for backward compatibility */
++ call &= 0xffff;
++
++ if (call <= SEMCTL)
++ switch (call) {
++ case SEMOP:
++ return sys_semop (first, (struct sembuf *)ptr, second);
++ case SEMGET:
++ return sys_semget (first, second, third);
++ case SEMCTL: {
++ union semun fourth;
++ if (!ptr)
++ return -EINVAL;
++ if (get_user(fourth.__pad, (void **) ptr))
++ return -EFAULT;
++ return sys_semctl (first, second, third, fourth);
++ }
++ default:
++ return -EINVAL;
++ }
++ if (call <= MSGCTL)
++ switch (call) {
++ case MSGSND:
++ return sys_msgsnd (first, (struct msgbuf *) 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 *)ptr,
++ sizeof (tmp)))
++ return -EFAULT;
++ return sys_msgrcv (first, tmp.msgp, second,
++ tmp.msgtyp, third);
++ }
++ default:
++ return sys_msgrcv (first,
++ (struct msgbuf *) ptr,
++ second, fifth, third);
++ }
++ case MSGGET:
++ return sys_msgget ((key_t) first, second);
++ case MSGCTL:
++ return sys_msgctl (first, second,
++ (struct msqid_ds *) ptr);
++ default:
++ return -EINVAL;
++ }
++
++ return -EINVAL;
++}
++
++/* sys_cacheflush -- flush the processor cache. */
++asmlinkage int
++sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
++{
++ flush_cache_all();
++ 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") = TRAP_ID_SYSCALL;
++ register long __sc __asm__ ("r3") = __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" (__res), "r" (__sc), "r" (__a), "r" (__b), "r" (__c)
++ : "memory");
++
++ return __res;
++}
+diff --git a/arch/nios2nommu/kernel/syscalltable.S b/arch/nios2nommu/kernel/syscalltable.S
+new file mode 100644
+index 0000000..3507e24
+--- /dev/null
++++ b/arch/nios2nommu/kernel/syscalltable.S
+@@ -0,0 +1,362 @@
++/*--------------------------------------------------------------------
++ *
++ * 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_ni_syscall /* 0 - old "setup()" system call*/
++ .long sys_exit
++ .long sys_fork
++ .long sys_read
++ .long sys_write
++ .long sys_open /* 5 */
++ .long sys_close
++ .long sys_waitpid
++ .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_chown16
++ .long sys_ni_syscall /* old break syscall holder */
++ .long sys_stat
++ .long sys_lseek
++ .long sys_getpid /* 20 */
++ .long sys_mount
++ .long sys_oldumount
++ .long sys_setuid16
++ .long sys_getuid16
++ .long sys_stime /* 25 */
++ .long sys_ptrace
++ .long sys_alarm
++ .long sys_fstat
++ .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_setgid16
++ .long sys_getgid16
++ .long sys_signal
++ .long sys_geteuid16
++ .long sys_getegid16 /* 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_sgetmask
++ .long sys_ssetmask
++ .long sys_setreuid16 /* 70 */
++ .long sys_setregid16
++ .long sys_sigsuspend
++ .long sys_sigpending
++ .long sys_sethostname
++ .long sys_setrlimit /* 75 */
++ .long sys_old_getrlimit
++ .long sys_getrusage
++ .long sys_gettimeofday
++ .long sys_settimeofday
++ .long sys_getgroups16 /* 80 */
++ .long sys_setgroups16
++ .long old_select
++ .long sys_symlink
++ .long sys_lstat
++ .long sys_readlink /* 85 */
++ .long sys_uselib
++ .long sys_ni_syscall /* sys_swapon */
++ .long sys_reboot
++ .long old_readdir
++ .long old_mmap /* 90 */
++ .long sys_munmap
++ .long sys_truncate
++ .long sys_ftruncate
++ .long sys_fchmod
++ .long sys_fchown16 /* 95 */
++ .long sys_getpriority
++ .long sys_setpriority
++ .long sys_ni_syscall /* old profil syscall holder */
++ .long sys_statfs
++ .long sys_fstatfs /* 100 */
++ .long sys_ni_syscall /* was 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
++ .long sys_ni_syscall /* iopl for i386 */ /* 110 */
++ .long sys_vhangup
++ .long sys_ni_syscall /* obsolete idle() syscall */
++ .long sys_ni_syscall /* vm86old for i386 */
++ .long sys_wait4
++ .long sys_ni_syscall /* 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_ni_syscall /* 125 */ /* sys_mprotect */
++ .long sys_sigprocmask
++ .long sys_ni_syscall /* old "creat_module" */
++ .long sys_init_module
++ .long sys_delete_module
++ .long sys_ni_syscall /* 130: old "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 /* for afs_syscall */
++ .long sys_setfsuid16
++ .long sys_setfsgid16
++ .long sys_llseek /* 140 */
++ .long sys_getdents
++ .long sys_select
++ .long sys_flock
++ .long sys_ni_syscall /* sys_msync */
++ .long sys_readv /* 145 */
++ .long sys_writev
++ .long sys_getsid
++ .long sys_fdatasync
++ .long sys_sysctl
++ .long sys_ni_syscall /* 150 */ /* sys_mlock */
++ .long sys_ni_syscall /* sys_munlock */
++ .long sys_ni_syscall /* sys_mlockall */
++ .long sys_ni_syscall /* 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_ni_syscall /* sys_mremap */
++ .long sys_setresuid16
++ .long sys_getresuid16 /* 165 */
++ .long sys_getpagesize /* sys_getpagesize */
++ .long sys_ni_syscall /* old "query_module" */
++ .long sys_poll
++ .long sys_ni_syscall /* sys_nfsservctl */
++ .long sys_setresgid16 /* 170 */
++ .long sys_getresgid16
++ .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_lchown16
++ .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_mmap2
++ .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_ni_syscall /* sys_mincore */
++ .long sys_ni_syscall /* 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_ni_syscall /* 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_ni_syscall /* Reserved for pselect6 */
++ .long sys_ni_syscall /* Reserved for 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
++ .long sys_eventfd
++ .long sys_pread64
++ .long sys_pwrite64 /* 321 */
++
++ .rept NR_syscalls - 322
++ .long sys_ni_syscall
++ .endr
++
+diff --git a/arch/nios2nommu/kernel/time.c b/arch/nios2nommu/kernel/time.c
+new file mode 100644
+index 0000000..3b536fe
+--- /dev/null
++++ b/arch/nios2nommu/kernel/time.c
+@@ -0,0 +1,219 @@
++/*--------------------------------------------------------------------
++ *
++ * arch/nios2nommu/kernel/time.c
++ *
++ * Architecture specific time handling details.
++ *
++ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al
++ *
++ * Most of the stuff is located in the machine specific files.
++ *
++ * Copyright (C) 2004 Microtronix Datacom Ltd
++ * Copyright (C) 1998-2000 D. Jeff Dionne <jeff@lineo.ca>,
++ * Kenneth Albanowski <kjahds@kjahds.com>,
++ * Copyright (C) 1991, 1992, 1995 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/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 <asm/segment.h>
++#include <asm/io.h>
++#include <asm/nios.h>
++
++#define TICK_SIZE (tick_nsec / 1000)
++
++unsigned long cpu_khz;
++static inline int set_rtc_mmss(unsigned long nowtime)
++{
++ return 0;
++}
++
++/* Timer timeout status */
++#define nios2_timer_TO (inw(&na_timer0->np_timerstatus) & np_timerstatus_to_mask)
++
++/* Timer snapshot */
++static inline unsigned long nios2_read_timercount(void)
++{
++ unsigned long count;
++
++ outw(0, &na_timer0->np_timersnapl);
++ count = inw(&na_timer0->np_timersnaph) << 16 | inw(&na_timer0->np_timersnapl);
++
++ return count;
++}
++
++/*
++ * Should return useconds since last timer tick
++ */
++static unsigned long gettimeoffset(void)
++{
++ unsigned long offset;
++ unsigned long count;
++
++ count = nios2_read_timercount();
++ offset = ((nasys_clock_freq/HZ)-1 - nios2_read_timercount()) \
++ / (nasys_clock_freq / USEC_PER_SEC);
++
++ /* Check if we just wrapped the counters and maybe missed a tick */
++ if (nios2_timer_TO && (offset < (100000 / HZ / 2)))
++ offset += (USEC_PER_SEC / HZ);
++
++ return offset;
++}
++
++/*
++ * 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;
++
++ write_seqlock(&xtime_lock);
++ na_timer0->np_timerstatus = 0; /* Clear the interrupt condition */
++
++ do_timer(1);
++#ifndef CONFIG_SMP
++ update_process_times(user_mode(get_irq_regs()));
++#endif
++ profile_tick(CPU_PROFILING);
++ /*
++ * 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);
++ return(IRQ_HANDLED);
++}
++
++void __init time_init(void)
++{
++ unsigned int year, mon, day, hour, min, sec;
++ int err;
++
++ extern void arch_gettod(int *year, int *mon, int *day, int *hour,
++ int *min, int *sec);
++
++ cpu_khz=nasys_clock_freq_1000;
++ 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;
++
++ err = request_irq(na_timer0_irq, timer_interrupt, IRQ_FLG_LOCK, "timer", NULL);
++ if(err)
++ printk(KERN_ERR "%s() failed - errno = %d\n", __FUNCTION__, -err);
++ na_timer0->np_timerperiodl = (nasys_clock_freq/HZ)-1;
++ na_timer0->np_timerperiodh = ((nasys_clock_freq/HZ)-1) >> 16;
++
++ /* interrupt enable + continuous + start */
++ na_timer0->np_timercontrol = np_timercontrol_start_mask
++ + np_timercontrol_cont_mask
++ + np_timercontrol_ito_mask;
++}
++
++/*
++ * This version of gettimeofday has near microsecond resolution.
++ */
++void do_gettimeofday(struct timeval *tv)
++{
++ unsigned long flags;
++ unsigned long seq;
++ unsigned long usec, sec;
++
++ do {
++ seq = read_seqbegin_irqsave(&xtime_lock, flags);
++ usec = gettimeoffset();
++ sec = xtime.tv_sec;
++ usec += (xtime.tv_nsec / 1000);
++ } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
++
++ while (usec >= 1000000) {
++ usec -= 1000000;
++ sec++;
++ }
++
++ tv->tv_sec = sec;
++ tv->tv_usec = usec;
++}
++EXPORT_SYMBOL(do_gettimeofday);
++
++int do_settimeofday(struct timespec *tv)
++{
++ time_t wtm_sec, sec = tv->tv_sec;
++ long wtm_nsec, nsec = tv->tv_nsec;
++
++ if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
++ return -EINVAL;
++
++ write_seqlock_irq(&xtime_lock);
++ /*
++ * This is revolting. We need to set "xtime" correctly. However, the
++ * value in this location is the value at the last tick.
++ * Discover what correction gettimeofday() would have
++ * made, and then undo it!
++ */
++ nsec -= gettimeoffset() * NSEC_PER_USEC;
++
++ wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
++ wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
++
++ set_normalized_timespec(&xtime, sec, nsec);
++ set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
++
++ ntp_clear();
++
++ write_sequnlock_irq(&xtime_lock);
++ clock_was_set();
++
++ return 0;
++}
++EXPORT_SYMBOL(do_settimeofday);
++
++/*
++ * Scheduler clock - returns current time in nanosec units.
++ */
++unsigned long long sched_clock(void)
++{
++ return (unsigned long long)jiffies * (1000000000 / HZ);
++}
+diff --git a/arch/nios2nommu/kernel/traps.c b/arch/nios2nommu/kernel/traps.c
+new file mode 100644
+index 0000000..14b7e4c
+--- /dev/null
++++ b/arch/nios2nommu/kernel/traps.c
+@@ -0,0 +1,178 @@
++/*
++ * 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 <asm/delay.h>
++#include <asm/system.h>
++#include <asm/ptrace.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/unistd.h>
++
++#include <asm/nios.h>
++
++/* #define TRAP_DEBUG */
++
++#if 0
++void dumpit(unsigned long l1, unsigned long l2)
++{
++ printk("0x%08x l1 0x%08x l2\n");
++ while(1);
++}
++
++struct trap_trace_entry {
++ unsigned long pc;
++ unsigned long type;
++};
++
++int trap_curbuf = 0;
++struct trap_trace_entry trapbuf[1024];
++
++void syscall_trace_entry(struct pt_regs *regs)
++{
++ printk("%s[%d]: ", current->comm, current->pid);
++ printk("scall<%d> (could be %d)\n", (int) regs->r3,
++ (int) regs->r4);
++}
++
++void syscall_trace_exit(struct pt_regs *regs)
++{
++}
++#endif
++
++/*
++ * 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);
++ if(pregs->status_extension & PS_S)
++ 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);
++ }
++}
++
++#if 0
++void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long psr)
++{
++#ifdef TRAP_DEBUG
++ printk("Watchpoint detected at PC %08lx PSR %08lx\n", pc, psr);
++#endif
++ if(psr & PSR_SUPERVISOR)
++ panic("Tell me what a watchpoint trap is, and I'll then deal "
++ "with such a beast...");
++}
++#endif
++
++void trap_init(void)
++{
++#ifdef DEBUG
++ printk("trap_init reached\n");
++#endif
++}
+diff --git a/arch/nios2nommu/kernel/usb.c b/arch/nios2nommu/kernel/usb.c
+new file mode 100644
+index 0000000..65655b6
+--- /dev/null
++++ b/arch/nios2nommu/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/nios2nommu/kernel/vmlinux.lds.S b/arch/nios2nommu/kernel/vmlinux.lds.S
+new file mode 100644
+index 0000000..491901c
+--- /dev/null
++++ b/arch/nios2nommu/kernel/vmlinux.lds.S
+@@ -0,0 +1,141 @@
++#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 */
++
++jiffies = jiffies_64;
++
++SECTIONS
++{
++ . = nasys_program_mem;
++ /* read-only */
++ _stext = . ;
++ _text = .; /* Text and read-only data */
++ .text : {
++ TEXT_TEXT
++ SCHED_TEXT
++ LOCK_TEXT
++ *(.fixup)
++ *(.gnu.warning)
++ } =0
++
++ . = ALIGN(4) ;
++ _etext = .; /* End of text section */
++
++ . = ALIGN(32); /* Exception table */
++ __start___ex_table = .;
++ __ex_table : { *(__ex_table) }
++ __stop___ex_table = .;
++
++ RODATA
++
++ /* writeable */
++ .data : { /* Data */
++ /*
++ * This ALIGN is needed as a workaround for a bug a gcc bug upto 4.1 which
++ * limits the maximum alignment to at most 32kB and results in the following
++ * warning:
++ *
++ * CC arch/mips/kernel/init_task.o
++ * arch/mips/kernel/init_task.c:30: warning: alignment of ‘init_thread_union’
++ * is greater than maximum object file alignment. Using 32768
++ */
++ . = ALIGN(4096);
++ *(.data.init_task)
++
++ *(.data)
++
++ CONSTRUCTORS
++ }
++
++ .lit8 : { *(.lit8) }
++ .lit4 : { *(.lit4) }
++ /* We want the small data sections together, so single-instruction offsets
++ can access them all, and initialized data all before uninitialized, so
++ we can shorten the on-disk segment size. */
++ .sdata : { *(.sdata) }
++
++ . = ALIGN(4096);
++ __nosave_begin = .;
++ .data_nosave : { *(.data.nosave) }
++ . = ALIGN(4096);
++ __nosave_end = .;
++
++ . = ALIGN(32);
++ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
++
++ _edata = .; /* End of data section */
++
++ /* will be freed after init */
++ . = ALIGN(4096); /* Init code and data */
++ __init_begin = .;
++ .init.text : {
++ _sinittext = .;
++ *(.init.text)
++ _einittext = .;
++ }
++ .init.data : { *(.init.data) }
++ . = ALIGN(16);
++ __setup_start = .;
++ .init.setup : { *(.init.setup) }
++ __setup_end = .;
++
++ __initcall_start = .;
++ .initcall.init : {
++ INITCALLS
++ }
++ __initcall_end = .;
++
++ __con_initcall_start = .;
++ .con_initcall.init : { *(.con_initcall.init) }
++ __con_initcall_end = .;
++ SECURITY_INIT
++ /* .exit.text is discarded at runtime, not link time, to deal with
++ references from .rodata */
++ .exit.text : { *(.exit.text) }
++ .exit.data : { *(.exit.data) }
++ . = ALIGN(4096);
++ __initramfs_start = .;
++ .init.ramfs : { *(.init.ramfs) }
++ __initramfs_end = .;
++ . = ALIGN(32);
++ __per_cpu_start = .;
++ .data.percpu : { *(.data.percpu) }
++ __per_cpu_end = .;
++ . = ALIGN(4096);
++ __init_end = .;
++ /* freed after init ends here */
++
++ __bss_start = .; /* BSS */
++ .sbss : {
++ *(.sbss)
++ *(.scommon)
++ }
++ .bss : {
++ *(.bss)
++ *(COMMON)
++ }
++ __bss_stop = .;
++
++ _end = . ;
++
++ /* Sections to be discarded */
++ /DISCARD/ : {
++ *(.exit.text)
++ *(.exit.data)
++ *(.exitcall.exit)
++ }
++
++
++ STABS_DEBUG
++
++ DWARF_DEBUG
++
++ /* These must appear regardless of . */
++ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
++ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
++ .note : { *(.note) }
++}
+diff --git a/arch/nios2nommu/lib/Makefile b/arch/nios2nommu/lib/Makefile
+new file mode 100644
+index 0000000..1315c57
+--- /dev/null
++++ b/arch/nios2nommu/lib/Makefile
+@@ -0,0 +1,17 @@
++#
++# 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 =checksum.o string.o memcpy.o
+diff --git a/arch/nios2nommu/lib/checksum.c b/arch/nios2nommu/lib/checksum.c
+new file mode 100644
+index 0000000..475f1a3
+--- /dev/null
++++ b/arch/nios2nommu/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
++ */
++
++unsigned int csum_partial(const unsigned char * buff, int len, unsigned int 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
++ */
++
++unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum)
++{
++ memcpy(dst, src, len);
++ return csum_partial(dst, len, sum);
++
++}
+diff --git a/arch/nios2nommu/lib/memcpy.c b/arch/nios2nommu/lib/memcpy.c
+new file mode 100644
+index 0000000..6586b99
+--- /dev/null
++++ b/arch/nios2nommu/lib/memcpy.c
+@@ -0,0 +1,62 @@
++/*--------------------------------------------------------------------
++ *
++ * arch/nios2nommu/lib/memcpy.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.
++ *
++ *
++ * Jun/09/2004 dgt Split out separate source file from string.c
++ *
++ ---------------------------------------------------------------------*/
++
++#include <linux/types.h>
++#include <linux/autoconf.h>
++#include <asm/nios.h>
++#include <asm/string.h>
++
++#ifdef __HAVE_ARCH_MEMCPY
++ void * memcpy(void * d, const void * s, size_t count)
++ {
++ unsigned long dst, src;
++ 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++;
++
++ return d;
++ }
++#endif
+diff --git a/arch/nios2nommu/lib/string.c b/arch/nios2nommu/lib/string.c
+new file mode 100644
+index 0000000..b87c195
+--- /dev/null
++++ b/arch/nios2nommu/lib/string.c
+@@ -0,0 +1,180 @@
++/*--------------------------------------------------------------------
++ *
++ * 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 <linux/autoconf.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/nios2nommu/mm/Makefile b/arch/nios2nommu/mm/Makefile
+new file mode 100644
+index 0000000..b007a11
+--- /dev/null
++++ b/arch/nios2nommu/mm/Makefile
+@@ -0,0 +1,12 @@
++# $Id: Makefile,v 1.1 2006/07/05 06:23:18 gerg Exp $
++# Makefile for the linux Sparc-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 extable.o memory.o
++obj-y += dma-noncoherent.o
++
+diff --git a/arch/nios2nommu/mm/dma-noncoherent.c b/arch/nios2nommu/mm/dma-noncoherent.c
+new file mode 100644
+index 0000000..5649940
+--- /dev/null
++++ b/arch/nios2nommu/mm/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/nios2nommu/mm/extable.c b/arch/nios2nommu/mm/extable.c
+new file mode 100644
+index 0000000..e23778f
+--- /dev/null
++++ b/arch/nios2nommu/mm/extable.c
+@@ -0,0 +1,29 @@
++/*
++ * linux/arch/niosnommu/mm/extable.c
++ */
++
++#include <linux/module.h>
++#include <linux/spinlock.h>
++#include <asm/uaccess.h>
++
++/* Simple binary search */
++const struct exception_table_entry *
++search_extable(const struct exception_table_entry *first,
++ const struct exception_table_entry *last,
++ unsigned long value)
++{
++ while (first <= last) {
++ const struct exception_table_entry *mid;
++ long diff;
++
++ mid = (last - first) / 2 + first;
++ diff = mid->insn - value;
++ if (diff == 0)
++ return mid;
++ else if (diff < 0)
++ first = mid+1;
++ else
++ last = mid-1;
++ }
++ return NULL;
++}
+diff --git a/arch/nios2nommu/mm/init.c b/arch/nios2nommu/mm/init.c
+new file mode 100644
+index 0000000..21fe61b
+--- /dev/null
++++ b/arch/nios2nommu/mm/init.c
+@@ -0,0 +1,231 @@
++/*
++ * 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>
++//;dgt2;#include <asm/machdep.h>
++//;dgt2;#include <asm/shglcore.h>
++
++#undef 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;
++
++extern unsigned long rom_length;
++
++void show_mem(void)
++{
++ unsigned long i;
++ int free = 0, total = 0, reserved = 0, shared = 0;
++ int cached = 0;
++
++ printk(KERN_INFO "\nMem-info:\n");
++ show_free_areas();
++ i = max_mapnr;
++ while (i-- > 0) {
++ total++;
++ if (PageReserved(mem_map+i))
++ reserved++;
++ else if (PageSwapCache(mem_map+i))
++ cached++;
++ else if (!page_count(mem_map+i))
++ free++;
++ else
++ shared += page_count(mem_map+i) - 1;
++ }
++ printk(KERN_INFO "%d pages of RAM\n",total);
++ printk(KERN_INFO "%d free pages\n",free);
++ printk(KERN_INFO "%d reserved pages\n",reserved);
++ printk(KERN_INFO "%d pages shared\n",shared);
++ printk(KERN_INFO "%d pages swap cached\n",cached);
++}
++
++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.
++ */
++#ifdef DEBUG
++ unsigned long start_mem = PAGE_ALIGN(memory_start);
++#endif
++ unsigned long end_mem = memory_end & PAGE_MASK;
++
++#ifdef DEBUG
++ printk (KERN_DEBUG "start_mem is %#lx\nvirtual_end is %#lx\n",
++ start_mem, end_mem);
++#endif
++
++ /*
++ * 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(PAGE_SIZE);
++ memset((void *)empty_zero_page, 0, PAGE_SIZE);
++
++ /*
++ * Set up SFC/DFC registers (user data space).
++ */
++ set_fs (USER_DS);
++
++#ifdef DEBUG
++ printk (KERN_DEBUG "before free_area_init\n");
++
++ printk (KERN_DEBUG "free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
++ start_mem, end_mem);
++#endif
++
++ {
++ unsigned long zones_size[MAX_NR_ZONES] = {0, };
++
++ zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> 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 = (void *) end_mem;
++
++ start_mem = PAGE_ALIGN(start_mem);
++ max_mapnr = num_physpages = MAP_NR(high_memory);
++
++ /* 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
++}
++
+diff --git a/arch/nios2nommu/mm/ioremap.c b/arch/nios2nommu/mm/ioremap.c
+new file mode 100644
+index 0000000..1c8b172
+--- /dev/null
++++ b/arch/nios2nommu/mm/ioremap.c
+@@ -0,0 +1,65 @@
++/* 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>
++
++/*
++ * Map some physical address range into the kernel address space.
++ */
++
++void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
++{
++ return (void *)physaddr;
++}
++
++/*
++ * Unmap a ioremap()ed region again
++ */
++void iounmap(void *addr)
++{
++}
++
++/*
++ * __iounmap unmaps nearly everything, so be careful
++ * it doesn't free currently pointer/page tables anymore but it
++ * wans't used anyway and might be added later.
++ */
++void __iounmap(void *addr, unsigned long size)
++{
++}
++
+diff --git a/arch/nios2nommu/mm/memory.c b/arch/nios2nommu/mm/memory.c
+new file mode 100644
+index 0000000..76d60d9
+--- /dev/null
++++ b/arch/nios2nommu/mm/memory.c
+@@ -0,0 +1,212 @@
++/*
++ * 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 <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>
++
++/*
++ * cache_clear() semantics: Clear any cache entries for the area in question,
++ * without writing back dirty entries first. This is useful if the data will
++ * be overwritten anyway, e.g. by DMA to memory. The range is defined by a
++ * _physical_ address.
++ */
++
++void cache_clear (unsigned long paddr, int len)
++{
++}
++
++
++/*
++ * Define cache invalidate functions. The instruction and data cache
++ * will need to be flushed. Write back the dirty data cache and invalidate
++ * the instruction cache for the range.
++ *
++ */
++
++static __inline__ void cache_invalidate_inst(unsigned long paddr, int len)
++{
++ unsigned long sset, eset;
++
++ sset = (paddr & (nasys_icache_size - 1)) & (~(nasys_icache_line_size - 1));
++ eset = (((paddr & (nasys_icache_size - 1)) + len) & (~(nasys_icache_line_size - 1))) + nasys_icache_line_size;
++
++ __asm__ __volatile__ (
++ "1:\n\t"
++ "flushi %0\n\t"
++ "add %0,%0,%2\n\t"
++ "blt %0,%1,1b\n\t"
++ "flushp\n\t"
++ : : "r" (sset), "r" (eset), "r" (nasys_icache_line_size));
++
++}
++
++static __inline__ void cache_invalidate_data(unsigned long paddr, int len)
++{
++ unsigned long sset, eset;
++
++ sset = (paddr & (nasys_dcache_size - 1)) & (~(nasys_dcache_line_size - 1));
++ eset = (((paddr & (nasys_dcache_size - 1)) + len) & (~(nasys_dcache_line_size - 1))) + nasys_dcache_line_size;
++
++ __asm__ __volatile__ (
++ "1:\n\t"
++ "flushd 0(%0)\n\t"
++ "add %0,%0,%2\n\t"
++ "blt %0,%1,1b\n\t"
++ : : "r" (sset),"r" (eset), "r" (nasys_dcache_line_size));
++
++}
++
++static __inline__ void cache_invalidate_lines(unsigned long paddr, int len)
++{
++ unsigned long sset, eset;
++
++ sset = (paddr & (nasys_dcache_size - 1)) & (~(nasys_dcache_line_size - 1));
++ eset = (((paddr & (nasys_dcache_size - 1)) + len) & (~(nasys_dcache_line_size - 1))) + nasys_dcache_line_size;
++
++ __asm__ __volatile__ (
++ "1:\n\t"
++ "flushd 0(%0)\n\t"
++ "add %0,%0,%2\n\t"
++ "blt %0,%1,1b\n\t"
++ : : "r" (sset),"r" (eset), "r" (nasys_dcache_line_size));
++
++ sset = (paddr & (nasys_icache_size - 1)) & (~(nasys_icache_line_size - 1));
++ eset = (((paddr & (nasys_icache_size - 1)) + len) & (~(nasys_icache_line_size - 1))) + nasys_icache_line_size;
++
++ __asm__ __volatile__ (
++ "1:\n\t"
++ "flushi %0\n\t"
++ "add %0,%0,%2\n\t"
++ "blt %0,%1,1b\n\t"
++ "flushp\n\t"
++ : : "r" (sset), "r" (eset), "r" (nasys_icache_line_size));
++
++}
++
++/*
++ * cache_push() semantics: Write back any dirty cache data in the given area,
++ * and invalidate the range in the instruction cache. It needs not (but may)
++ * invalidate those entries also in the data cache. The range is defined by a
++ * _physical_ address.
++ */
++
++void cache_push (unsigned long paddr, int len)
++{
++ cache_invalidate_lines(paddr, len);
++}
++
++
++/*
++ * cache_push_v() semantics: Write back any dirty cache data in the given
++ * area, and invalidate those entries at least in the instruction cache. This
++ * is intended to be used after data has been written that can be executed as
++ * code later. The range is defined by a _user_mode_ _virtual_ address.
++ */
++
++void cache_push_v (unsigned long vaddr, int len)
++{
++ cache_invalidate_lines(vaddr, len);
++}
++
++/*
++ * cache_push_all() semantics: Invalidate instruction cache and write back
++ * dirty data cache & invalidate.
++ */
++void cache_push_all (void)
++{
++ __asm__ __volatile__ (
++ "1:\n\t"
++ "flushd 0(%0)\n\t"
++ "sub %0,%0,%1\n\t"
++ "bgt %0,r0,1b\n\t"
++ : : "r" (nasys_dcache_size), "r" (nasys_dcache_line_size));
++
++ __asm__ __volatile__ (
++ "1:\n\t"
++ "flushi %0\n\t"
++ "sub %0,%0,%1\n\t"
++ "bgt %0,r0,1b\n\t"
++ "flushp\n\t"
++ : : "r" (nasys_icache_size), "r" (nasys_icache_line_size));
++
++}
++
++/*
++ * dcache_push() semantics: Write back and dirty data cache and invalidate
++ * the range.
++ */
++void dcache_push (unsigned long vaddr, int len)
++{
++ cache_invalidate_data(vaddr, len);
++}
++
++/*
++ * icache_push() semantics: Invalidate instruction cache in the range.
++ */
++void icache_push (unsigned long vaddr, int len)
++{
++ cache_invalidate_inst(vaddr, len);
++}
++
++/* Map some physical address range into the kernel address space. The
++ * code is copied and adapted from map_chunk().
++ */
++
++unsigned long kernel_map(unsigned long paddr, unsigned long size,
++ int nocacheflag, unsigned long *memavailp )
++{
++ return paddr;
++}
++
++
++int is_in_rom(unsigned long addr)
++{
++ /* Default case, not in ROM */
++ return(0);
++}
++
++int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
++ unsigned long address, int write_access)
++{
++ BUG();
++ return VM_FAULT_OOM;
++}
+diff --git a/arch/nios2nommu/scripts/PTF/PTFParser.pm b/arch/nios2nommu/scripts/PTF/PTFParser.pm
+new file mode 100644
+index 0000000..c243c7b
+--- /dev/null
++++ b/arch/nios2nommu/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/nios2nommu/scripts/PTF/PTFParser.yp b/arch/nios2nommu/scripts/PTF/PTFParser.yp
+new file mode 100644
+index 0000000..e105e6a
+--- /dev/null
++++ b/arch/nios2nommu/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/nios2nommu/scripts/PTF/PTFSection.pm b/arch/nios2nommu/scripts/PTF/PTFSection.pm
+new file mode 100644
+index 0000000..a88d340
+--- /dev/null
++++ b/arch/nios2nommu/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/nios2nommu/scripts/PTF/SystemPTF.pm b/arch/nios2nommu/scripts/PTF/SystemPTF.pm
+new file mode 100644
+index 0000000..9f44cfe
+--- /dev/null
++++ b/arch/nios2nommu/scripts/PTF/SystemPTF.pm
+@@ -0,0 +1,149 @@
++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);
++}
++
++sub getClockFreq () {
++ my ($self) = @_;
++
++ my $wsa = $self->{root}->getSection ('WIZARD_SCRIPT_ARGUMENTS', '');
++ $wsa or return;
++
++ my $result = $wsa->getAssignment ('clock_freq');
++ 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/nios2nommu/scripts/PTF/SystemPTF/Board.pm b/arch/nios2nommu/scripts/PTF/SystemPTF/Board.pm
+new file mode 100644
+index 0000000..fe2bbc8
+--- /dev/null
++++ b/arch/nios2nommu/scripts/PTF/SystemPTF/Board.pm
+@@ -0,0 +1,2 @@
++1;
++
+diff --git a/arch/nios2nommu/scripts/PTF/SystemPTF/CPU.pm b/arch/nios2nommu/scripts/PTF/SystemPTF/CPU.pm
+new file mode 100644
+index 0000000..ea10598
+--- /dev/null
++++ b/arch/nios2nommu/scripts/PTF/SystemPTF/CPU.pm
+@@ -0,0 +1,89 @@
++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 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/nios2nommu/scripts/PTF/SystemPTF/Module.pm b/arch/nios2nommu/scripts/PTF/SystemPTF/Module.pm
+new file mode 100644
+index 0000000..48d246b
+--- /dev/null
++++ b/arch/nios2nommu/scripts/PTF/SystemPTF/Module.pm
+@@ -0,0 +1,267 @@
++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 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 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');
++
++ if ($data_width == 8) {
++ $size = 1 << $addr_width;
++ } elsif ($data_width == 16) {
++ $size = 1 << ($addr_width + 1);
++ } elsif ($data_width == 32) {
++ $size = 1 << ($addr_width + 2);
++ } elsif ($data_width == 64) {
++ $size = 1 << ($addr_width + 3);
++ } elsif ($data_width == 128) {
++ $size = 1 << ($addr_width + 4);
++ } else {
++ return;
++ }
++
++ $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');
++ 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/nios2nommu/scripts/gen_nios2_system.h.pl b/arch/nios2nommu/scripts/gen_nios2_system.h.pl
+new file mode 100644
+index 0000000..b7bcff5
+--- /dev/null
++++ b/arch/nios2nommu/scripts/gen_nios2_system.h.pl
+@@ -0,0 +1,314 @@
++# 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> \
++# <upload location>
++#
++
++use PTF::SystemPTF;
++use strict;
++use integer;
++
++my $target_cpu;
++my $exec_location;
++my $upload_location;
++
++if (scalar (@ARGV) != 3) {
++ 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];
++ $upload_location = $ARGV[2];
++}
++
++#
++# 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_system.h
++#
++print <<ENDOFHEADER;
++#ifndef __NIOS2_SYSTEM_H__
++#define __NIOS2_SYSTEM_H__
++
++/*
++ * This file contains hardware information about the target platform.
++ * The nios2_system.h file is being phased out and will be removed in a
++ * later release.
++ *
++ * All base addresses for non memory devices have their high bit turned on to
++ * bypass the cache.
++ *
++ * This file is automatically generated. Do not modify.
++ */
++
++ENDOFHEADER
++
++#
++# generate contents for nios2_system.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 $upload_module = $system->getModule ($upload_location);
++if (! $upload_module) {
++ print STDERR "ERROR: $upload_location is not a valid module in the system: " . $system->getName() . ".\n";
++ print "#error $upload_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 (! $module->isMemoryDevice () && ! $module->isCustomInstruction ()) {
++ # turn on high bit for base address
++ $mask = 0x80000000;
++ }
++
++ if (scalar (@module_ports) == 1) {
++ 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;
++ }
++
++ } else {
++ # 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_system.h/$class_name.pm") {
++ print "/* Executing ...scripts/nios2_system.h/$class_name.pm */\n";
++ $code .= "require \"$dir/nios2_system.h/BasicModule.pm\";";
++ $code .= "require \"$dir/nios2_system.h/$class_name.pm\";";
++ $code .= $class_name . "::run(\$system, \@{\$found_classes{\$class_name}});";
++ eval $code;
++ if ($@) {
++ print "#warning Could not execute ...scripts/nios2_system.h/$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/$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";
++
++if ($upload_location eq "flash_kernel") {
++ # nothing to do
++ print ("/* Redefinition of CFI flash memory unecessary */\n");
++} else {
++ my $module = $system->getModule ("flash_kernel");
++ if ($module) {
++ # there is a conflicting module in the system, error.
++ print STDERR "Error, a SOPC module named flash_kernel already exists but is not the upload location.\n";
++ print "#error The module name \"flash_kernel\" already exists but isn't the upload location.\n";
++ print "#error This will break the kernel.\n";
++ print "#error Please rename the module to something else in SOPC Builder.\n\n";
++ exit 1;
++ } else {
++ print ("/*\n");
++ print (" * Redefining upload location ($upload_location) to flash_kernel.\n");
++ print (" */\n\n");
++ # undefine the original module names and re-define them here.
++ print ("#undef na_${upload_location}\n");
++ print ("#undef na_${upload_location}_size\n");
++ print ("#undef na_${upload_location}_end\n");
++
++ my $base_address = $upload_module->getBaseAddress ();
++ printf ("#define %-33s %30s\n",
++ ("na_flash_kernel", $base_address));
++
++ my $mem_size = $upload_module->getSize();
++ printf ("#define %-33s %30s\n",
++ ("na_flash_kernel_size", $mem_size));
++
++ my $mem_end = hex ($base_address) + hex ($mem_size);
++ printf ("#define %-53s %#010x\n",
++ ("na_flash_kernel_end", $mem_end));
++ }
++}
++
++print "\n";
++
++printf ("#define %-33s %30s\n",
++ ("nasys_clock_freq", $system->getClockFreq()));
++printf ("#define %-33s %30s\n",
++ ("nasys_clock_freq_1000", int ($system->getClockFreq()) / 1000));
++
++{
++ 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));
++}
++
++print "\n";
++
++#
++# print footer for nios2_system.h
++#
++print <<ENDOFFOOTER;
++#endif /* __NIOS2_SYSTEM_H__ */
++ENDOFFOOTER
+diff --git a/arch/nios2nommu/scripts/hwselect.pl b/arch/nios2nommu/scripts/hwselect.pl
+new file mode 100644
+index 0000000..8181bee
+--- /dev/null
++++ b/arch/nios2nommu/scripts/hwselect.pl
+@@ -0,0 +1,166 @@
++# This script generates arch/nios2nommu/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 %cfiinfo;
++my %meminfo;
++foreach my $module_name (@modulelist) {
++ my $module = $system->getModule ($module_name);
++ my $class = $module->getClass ();
++
++ if ($module->isEnabled ()) {
++ if ($class eq 'altera_avalon_cfi_flash') {
++ $cfiinfo{$module_name}{class} = $class;
++ $cfiinfo{$module_name}{size} = $module->getSize();
++ }
++
++ if ($module->isMemoryDevice()) {
++ $meminfo{$module_name}{class} = $class;
++ $meminfo{$module_name}{size} = $module->getSize();
++ }
++ }
++}
++
++#
++# Select an upload device:
++#
++print "\n--- Please select a device to upload the kernel to:\n\n";
++
++$index = 1;
++foreach my $name (keys (%cfiinfo)) {
++ my $size = hex ($cfiinfo{$name}{size});
++ print "($index) $name\n\tClass: $cfiinfo{$name}{class}\n\tSize: $size bytes\n\n";
++ $index += 1;
++}
++
++my @cfilist = keys (%cfiinfo);
++my $cfi_selected = $cfilist[request_answer (1, $index - 1) - 1];
++
++delete $meminfo{$cfi_selected};
++
++#
++# 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 "Device to upload to: $cfi_selected\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 "UPLMEM = $cfi_selected\n";
++print HWMK "EXEMEM = $mem_selected\n";
++
++close (HWMK);
++
++print "\n--- Settings written to $target_filename\n\n";
+\ No newline at end of file
+diff --git a/arch/nios2nommu/scripts/nios2_system.h/BasicModule.pm b/arch/nios2nommu/scripts/nios2_system.h/BasicModule.pm
+new file mode 100644
+index 0000000..e15c26b
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.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) | 0x80000000;
++
++ 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) | 0x80000000;
++ $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/nios2nommu/scripts/nios2_system.h/altera_avalon_cf.pm b/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_cf.pm
+new file mode 100644
+index 0000000..dada452
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_cf.pm
+@@ -0,0 +1,18 @@
++package altera_avalon_cf;
++
++use base qw(BasicModule);
++use strict;
++
++sub required_module_names {
++ "ide"
++}
++
++sub required_class_name {
++ "altera_avalon_cf"
++}
++
++sub run {
++ altera_avalon_cf->run2(@_);
++}
++
++1;
+diff --git a/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_jtag_uart.pm b/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_jtag_uart.pm
+new file mode 100644
+index 0000000..22bb9c9
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.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/nios2nommu/scripts/nios2_system.h/altera_avalon_lan91c111.pm b/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_lan91c111.pm
+new file mode 100644
+index 0000000..5a29b7e
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.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/nios2nommu/scripts/nios2_system.h/altera_avalon_pio.pm b/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_pio.pm
+new file mode 100644
+index 0000000..afdbcae
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.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) | 0x80000000;
++ 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/nios2nommu/scripts/nios2_system.h/altera_avalon_spi.pm b/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_spi.pm
+new file mode 100644
+index 0000000..719a22c
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_spi.pm
+@@ -0,0 +1,30 @@
++package altera_avalon_spi;
++
++use base qw(BasicModule);
++use strict;
++
++sub required_module_names {
++ "spi"
++}
++
++sub required_class_name {
++ "altera_avalon_spi"
++}
++
++sub base_address_cast {
++ "np_spi"
++}
++
++sub print_prefix {
++ my ($class, $system) = @_;
++
++ print "#ifndef __ASSEMBLY__\n";
++ print "#include <asm/spi_struct.h>\n";
++ print "#endif\n\n";
++}
++
++sub run {
++ altera_avalon_spi->run2 (@_);
++}
++
++1;
+diff --git a/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_sysid.pm b/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_sysid.pm
+new file mode 100644
+index 0000000..deb9826
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.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/nios2nommu/scripts/nios2_system.h/altera_avalon_timer.pm b/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_timer.pm
+new file mode 100644
+index 0000000..495ccdc
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_timer.pm
+@@ -0,0 +1,46 @@
++package altera_avalon_timer;
++
++use base qw(BasicModule);
++use strict;
++
++sub required_class_name {
++ "altera_avalon_timer";
++}
++
++sub required_module_names {
++ "timer0"
++}
++
++sub print_prefix {
++ my ($class, $system) = @_;
++
++ print "\n";
++ print "#ifndef __ASSEMBLY__\n";
++ print "#include <asm/timer_struct.h>\n";
++ print "#endif\n";
++ print "\n";
++}
++
++sub base_address_cast {
++ "np_timer"
++}
++
++# 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') {
++ return 1;
++ } else {
++ return 0;
++ }
++}
++
++sub run {
++ altera_avalon_timer->run2 (@_);
++}
++
++1;
+diff --git a/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_uart.pm b/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_uart.pm
+new file mode 100644
+index 0000000..abf48d7
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.h/altera_avalon_uart.pm
+@@ -0,0 +1,44 @@
++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 {
++ "np_uart"
++}
++
++sub print_prefix {
++ my ($class, $system) = @_;
++
++ print "#ifndef __ASSEMBLY__\n";
++ print "#include <asm/uart_struct.h>\n";
++ print "#endif\n\n";
++}
++
++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/nios2nommu/scripts/nios2_system.h/mtip_avalon_10_100_mac.pm b/arch/nios2nommu/scripts/nios2_system.h/mtip_avalon_10_100_mac.pm
+new file mode 100644
+index 0000000..fdd727b
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.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/nios2nommu/scripts/nios2_system.h/mtx_avalon_dm9000.pm b/arch/nios2nommu/scripts/nios2_system.h/mtx_avalon_dm9000.pm
+new file mode 100644
+index 0000000..5985c2f
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.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/nios2nommu/scripts/nios2_system.h/mtx_avalon_isp1161a1.pm b/arch/nios2nommu/scripts/nios2_system.h/mtx_avalon_isp1161a1.pm
+new file mode 100644
+index 0000000..e70ffa3
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.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/nios2nommu/scripts/nios2_system.h/opencores_ethernet_mac.pm b/arch/nios2nommu/scripts/nios2_system.h/opencores_ethernet_mac.pm
+new file mode 100644
+index 0000000..7b580b5
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.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/nios2nommu/scripts/nios2_system.h/opencores_i2c.pm b/arch/nios2nommu/scripts/nios2_system.h/opencores_i2c.pm
+new file mode 100644
+index 0000000..512d12c
+--- /dev/null
++++ b/arch/nios2nommu/scripts/nios2_system.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/include/asm-nios2nommu/ChangeLog b/include/asm-nios2nommu/ChangeLog
+new file mode 100644
+index 0000000..94aaa27
+--- /dev/null
++++ b/include/asm-nios2nommu/ChangeLog
+@@ -0,0 +1,14 @@
++2004-06-29 Ken Hill <khill@microtronix.com>
++
++ * bitops.h (find_next_zero_bit): Fix problem with with masking for found_first
++ handling. The masking of the upper bits for size < 32 bits would set all
++ the bits to 1. Removing any zero's there may have been.
++
++2004-06-02 Ken Hill <khill@microtronix.com>
++
++ * processor.h (TASK_SIZE): Change na_sdram_end to nasys_program_mem_end to remove
++ dependancy on quartus memory component name.
++
++ * page.h (PAGE_OFFSET): Change na_sdram to nasys_program_mem to remove
++ dependancy on quartus memory component name.
++
+diff --git a/include/asm-nios2nommu/Kbuild b/include/asm-nios2nommu/Kbuild
+new file mode 100644
+index 0000000..abf0368
+--- /dev/null
++++ b/include/asm-nios2nommu/Kbuild
+@@ -0,0 +1,4 @@
++include include/asm-generic/Kbuild.asm
++
++header-y += traps.h
++header-y += io.h
+diff --git a/include/asm-nios2nommu/a.out.h b/include/asm-nios2nommu/a.out.h
+new file mode 100644
+index 0000000..8297687
+--- /dev/null
++++ b/include/asm-nios2nommu/a.out.h
+@@ -0,0 +1,85 @@
++/* $Id: a.out.h,v 1.1 2006/07/05 06:20:25 gerg Exp $ */
++/*
++ * 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 __NIOS2NOMMU_A_OUT_H__
++#define __NIOS2NOMMU_A_OUT_H__
++
++#define SPARC_PGSIZE 0x1000 /* Thanks to the sun4 architecture... */
++#define SEGMENT_SIZE SPARC_PGSIZE /* whee... */
++
++struct exec {
++ unsigned char a_dynamic:1; /* A __DYNAMIC is in this image */
++ unsigned char a_toolversion:7;
++ unsigned char a_machtype;
++ unsigned short a_info;
++ unsigned long a_text; /* length of text, in bytes */
++ unsigned long a_data; /* length of data, in bytes */
++ unsigned long a_bss; /* length of bss, in bytes */
++ unsigned long a_syms; /* length of symbol table, in bytes */
++ unsigned long a_entry; /* where program begins */
++ unsigned long a_trsize;
++ unsigned long a_drsize;
++};
++
++#define INIT_EXEC { \
++ .a_dynamic = 0, \
++ .a_toolversion = 0, \
++ .a_machtype = 0, \
++ .a_info = 0, \
++ .a_text = 0, \
++ .a_data = 0, \
++ .a_bss = 0, \
++ .a_syms = 0, \
++ .a_entry = 0, \
++ .a_trsize = 0, \
++ .a_drsize = 0, \
++}
++
++/* Where in the file does the text information begin? */
++#define N_TXTOFF(x) (N_MAGIC(x) == ZMAGIC ? 0 : sizeof (struct exec))
++
++/* Where do the Symbols start? */
++#define N_SYMOFF(x) (N_TXTOFF(x) + (x).a_text + \
++ (x).a_data + (x).a_trsize + \
++ (x).a_drsize)
++
++/* Where does text segment go in memory after being loaded? */
++#define N_TXTADDR(x) (((N_MAGIC(x) == ZMAGIC) && \
++ ((x).a_entry < SPARC_PGSIZE)) ? \
++ 0 : SPARC_PGSIZE)
++
++/* And same for the data segment.. */
++#define N_DATADDR(x) (N_MAGIC(x)==OMAGIC ? \
++ (N_TXTADDR(x) + (x).a_text) \
++ : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
++
++#define N_TRSIZE(a) ((a).a_trsize)
++#define N_DRSIZE(a) ((a).a_drsize)
++#define N_SYMSIZE(a) ((a).a_syms)
++
++#ifdef __KERNEL__
++
++#define STACK_TOP TASK_SIZE
++
++#endif
++
++#endif /* __NIOS2NOMMU_A_OUT_H__ */
+diff --git a/include/asm-nios2nommu/altera_juart.h b/include/asm-nios2nommu/altera_juart.h
+new file mode 100644
+index 0000000..da6320d
+--- /dev/null
++++ b/include/asm-nios2nommu/altera_juart.h
+@@ -0,0 +1,36 @@
++/*------------------------------------------------------------------------
++ *
++ * linux/drivers/serial/altera_juart.h
++ *
++ * Driver for Altera JTAG UART core with Avalon interface
++ *
++ * 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/2005 DGT Microtronix Datacom NiosII
++ *
++ -----------------------------------------------------------------------*/
++
++#ifndef _ALTERA_JUART_H_
++ #define _ALTERA_JUART_H_
++
++ /* jtag uart details needed outside of the driver itself: */
++ /* by: arch/kernel/start.c - boot time error message(s) */
++
++ void jtaguart_console_write
++ ( struct console *co,
++ const char *s,
++ unsigned int count);
++
++#endif /* _ALTERA_JUART_H_ */
+diff --git a/include/asm-nios2nommu/asm-macros.h b/include/asm-nios2nommu/asm-macros.h
+new file mode 100644
+index 0000000..9dda7cd
+--- /dev/null
++++ b/include/asm-nios2nommu/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/include/asm-nios2nommu/atomic.h b/include/asm-nios2nommu/atomic.h
+new file mode 100644
+index 0000000..fb627de
+--- /dev/null
++++ b/include/asm-nios2nommu/atomic.h
+@@ -0,0 +1,146 @@
++#ifndef __ASM_SH_ATOMIC_H
++#define __ASM_SH_ATOMIC_H
++
++/*
++ * Atomic operations that C can't guarantee us. Useful for
++ * resource counting etc..
++ *
++ */
++
++typedef struct { volatile int counter; } atomic_t;
++
++#define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
++
++#define atomic_read(v) ((v)->counter)
++#define atomic_set(v,i) ((v)->counter = (i))
++
++#include <asm/system.h>
++
++/*
++ * To get proper branch prediction for the main line, we must branch
++ * forward to code at the end of this object's .text section, then
++ * branch back to restart the operation.
++ */
++
++static __inline__ void atomic_add(int i, atomic_t * v)
++{
++ unsigned long flags;
++
++ local_irq_save(flags);
++ *(long *)v += i;
++ local_irq_restore(flags);
++}
++
++static __inline__ void atomic_sub(int i, atomic_t *v)
++{
++ unsigned long flags;
++
++ local_irq_save(flags);
++ *(long *)v -= i;
++ local_irq_restore(flags);
++}
++
++static __inline__ int atomic_add_return(int i, atomic_t * v)
++{
++ unsigned long temp, flags;
++
++ local_irq_save(flags);
++ temp = *(long *)v;
++ temp += i;
++ *(long *)v = temp;
++ local_irq_restore(flags);
++
++ return temp;
++}
++
++#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
++
++static __inline__ int atomic_sub_return(int i, atomic_t * v)
++{
++ unsigned long temp, flags;
++
++ local_irq_save(flags);
++ temp = *(long *)v;
++ temp -= i;
++ *(long *)v = temp;
++ local_irq_restore(flags);
++
++ return temp;
++}
++
++#define atomic_dec_return(v) atomic_sub_return(1,(v))
++#define atomic_inc_return(v) atomic_add_return(1,(v))
++
++/*
++ * atomic_inc_and_test - increment and test
++ * @v: pointer of type atomic_t
++ *
++ * Atomically increments @v by 1
++ * and returns true if the result is zero, or false for all
++ * other cases.
++ */
++#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
++
++#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
++#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
++
++#define atomic_inc(v) atomic_add(1,(v))
++#define atomic_dec(v) atomic_sub(1,(v))
++
++static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
++{
++ int ret;
++ unsigned long flags;
++
++ local_irq_save(flags);
++ ret = v->counter;
++ if (likely(ret == old))
++ v->counter = new;
++ local_irq_restore(flags);
++
++ return ret;
++}
++
++#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
++
++static inline int atomic_add_unless(atomic_t *v, int a, int u)
++{
++ int ret;
++ unsigned long flags;
++
++ local_irq_save(flags);
++ ret = v->counter;
++ if (ret != u)
++ v->counter += a;
++ local_irq_restore(flags);
++
++ return ret != u;
++}
++#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
++
++static __inline__ void atomic_clear_mask(unsigned int mask, atomic_t *v)
++{
++ unsigned long flags;
++
++ local_irq_save(flags);
++ *(long *)v &= ~mask;
++ local_irq_restore(flags);
++}
++
++static __inline__ void atomic_set_mask(unsigned int mask, atomic_t *v)
++{
++ unsigned long flags;
++
++ local_irq_save(flags);
++ *(long *)v |= mask;
++ local_irq_restore(flags);
++}
++
++/* Atomic operations are already serializing on SH */
++#define smp_mb__before_atomic_dec() barrier()
++#define smp_mb__after_atomic_dec() barrier()
++#define smp_mb__before_atomic_inc() barrier()
++#define smp_mb__after_atomic_inc() barrier()
++
++#include <asm-generic/atomic.h>
++#endif /* __ASM_SH_ATOMIC_H */
+diff --git a/include/asm-nios2nommu/auxvec.h b/include/asm-nios2nommu/auxvec.h
+new file mode 100644
+index 0000000..fc21e4d
+--- /dev/null
++++ b/include/asm-nios2nommu/auxvec.h
+@@ -0,0 +1,4 @@
++#ifndef __ASM_SH_AUXVEC_H
++#define __ASM_SH_AUXVEC_H
++
++#endif /* __ASM_SH_AUXVEC_H */
+diff --git a/include/asm-nios2nommu/bitops.h b/include/asm-nios2nommu/bitops.h
+new file mode 100644
+index 0000000..7bf1862
+--- /dev/null
++++ b/include/asm-nios2nommu/bitops.h
+@@ -0,0 +1,11 @@
++#ifndef __ASM_NIOS2NOMMU_BITOPS_H
++#define __ASM_NIOS2NOMMU_BITOPS_H
++
++#ifdef __KERNEL__
++#include <asm/system.h>
++#include <asm-generic/bitops.h>
++#define smp_mb__before_clear_bit() barrier()
++#define smp_mb__after_clear_bit() barrier()
++#endif /* __KERNEL__ */
++
++#endif /* __ASM_NIOS2NOMMU_BITOPS_H */
+diff --git a/include/asm-nios2nommu/bootinfo.h b/include/asm-nios2nommu/bootinfo.h
+new file mode 100644
+index 0000000..ee8c39e
+--- /dev/null
++++ b/include/asm-nios2nommu/bootinfo.h
+@@ -0,0 +1,2 @@
++
++/* Nothing for nios2nommu */
+diff --git a/include/asm-nios2nommu/bug.h b/include/asm-nios2nommu/bug.h
+new file mode 100644
+index 0000000..d99ab08
+--- /dev/null
++++ b/include/asm-nios2nommu/bug.h
+@@ -0,0 +1,4 @@
++#ifndef _MNIOS2NOMMU_BUG_H
++#define _MNIOS2NOMMU_BUG_H
++#include <asm-generic/bug.h>
++#endif
+diff --git a/include/asm-nios2nommu/bugs.h b/include/asm-nios2nommu/bugs.h
+new file mode 100644
+index 0000000..a0753eb
+--- /dev/null
++++ b/include/asm-nios2nommu/bugs.h
+@@ -0,0 +1,40 @@
++#ifndef __ASM_NIOS_BUGS_H
++#define __ASM_NIOS_BUGS_H
++
++/*--------------------------------------------------------------------
++ *
++ * include/asm-nios2nommu/bugs.h
++ *
++ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al
++ *
++ * Copyright (C) 1994 Linus Torvalds
++ * 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
++ *
++ ---------------------------------------------------------------------*/
++
++
++/*
++ * This is included by init/main.c to check for architecture-dependent bugs.
++ *
++ * Needs:
++ * void check_bugs(void);
++ */
++
++static void check_bugs(void)
++{
++}
++
++#endif
+diff --git a/include/asm-nios2nommu/byteorder.h b/include/asm-nios2nommu/byteorder.h
+new file mode 100644
+index 0000000..960b6d3
+--- /dev/null
++++ b/include/asm-nios2nommu/byteorder.h
+@@ -0,0 +1,38 @@
++#ifndef __ASM_NIOS_BYTEORDER_H
++#define __ASM_NIOS_BYTEORDER_H
++
++/*--------------------------------------------------------------------
++ *
++ * include/asm-nios2nommu/byteorder.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/types.h>
++
++#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
++# define __BYTEORDER_HAS_U64__
++# define __SWAB_64_THRU_32__
++#endif
++
++#include <linux/byteorder/little_endian.h>
++
++#endif
++
+diff --git a/include/asm-nios2nommu/cache.h b/include/asm-nios2nommu/cache.h
+new file mode 100644
+index 0000000..82bbd14
+--- /dev/null
++++ b/include/asm-nios2nommu/cache.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 __ARCH_NIOS2NOMMU_CACHE_H
++#define __ARCH_NIOS2NOMMU_CACHE_H
++
++#include <asm/nios.h>
++
++/* bytes per L1 cache line */
++#define L1_CACHE_BYTES nasys_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 5
++
++
++#define __cacheline_aligned
++#define ____cacheline_aligned
++
++#endif
+diff --git a/include/asm-nios2nommu/cachectl.h b/include/asm-nios2nommu/cachectl.h
+new file mode 100644
+index 0000000..39d7d9d
+--- /dev/null
++++ b/include/asm-nios2nommu/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 _NIOS2NOMMU_CACHECTL_H
++#define _NIOS2NOMMU_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 /* _NIOS2NOMMU_CACHECTL_H */
+diff --git a/include/asm-nios2nommu/cacheflush.h b/include/asm-nios2nommu/cacheflush.h
+new file mode 100644
+index 0000000..4543201
+--- /dev/null
++++ b/include/asm-nios2nommu/cacheflush.h
+@@ -0,0 +1,59 @@
++#ifndef _NIOS2NOMMU_CACHEFLUSH_H
++#define _NIOS2NOMMU_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>
++
++extern void cache_push (unsigned long vaddr, int len);
++extern void dcache_push (unsigned long vaddr, int len);
++extern void icache_push (unsigned long vaddr, int len);
++extern void cache_push_all (void);
++extern void cache_clear (unsigned long paddr, int len);
++
++#define flush_cache_all() __flush_cache_all()
++#define flush_cache_mm(mm) do { } while (0)
++#define flush_cache_range(vma, start, end) cache_push(start, end - start)
++#define flush_cache_page(vma, vmaddr) do { } while (0)
++#define flush_dcache_range(start,end) dcache_push(start, end - start)
++#define flush_dcache_page(page) do { } while (0)
++#define flush_dcache_mmap_lock(mapping) do { } while (0)
++#define flush_dcache_mmap_unlock(mapping) do { } while (0)
++#define flush_icache_range(start,end) cache_push(start, end - start)
++#define flush_icache_page(vma,pg) do { } while (0)
++#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++ memcpy(dst, src, len)
++
++
++extern inline void __flush_cache_all(void)
++{
++ cache_push_all();
++}
++
++#endif /* _NIOS2NOMMU_CACHEFLUSH_H */
+diff --git a/include/asm-nios2nommu/checksum.h b/include/asm-nios2nommu/checksum.h
+new file mode 100644
+index 0000000..1f6879e
+--- /dev/null
++++ b/include/asm-nios2nommu/checksum.h
+@@ -0,0 +1,320 @@
++#ifndef __NIOS2_CHECKSUM_H
++#define __NIOS2_CHECKSUM_H
++
++/* checksum.h: IP/UDP/TCP checksum routines on the NIOS.
++ *
++ * Copyright(C) 1995 Linus Torvalds
++ * Copyright(C) 1995 Miguel de Icaza
++ * Copyright(C) 1996 David S. Miller
++ * Copyright(C) 2001 Ken Hill
++ * Copyright(C) 2004 Microtronix Datacom Ltd.
++ *
++ * derived from:
++ * Alpha checksum c-code
++ * ix86 inline assembly
++ * Spar nommu
++ *
++ * 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.
++ *
++ */
++
++
++/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
++
++/*
++ * computes the checksum of the TCP/UDP pseudo-header
++ * returns a 16-bit checksum, already complemented
++ */
++
++extern inline unsigned short csum_tcpudp_magic(unsigned long saddr,
++ unsigned long daddr,
++ unsigned short len,
++ unsigned short proto,
++ unsigned int sum)
++{
++ barrier();
++ __asm__ __volatile__(
++" add %0, %3, %0\n"
++" bgeu %0, %3, 1f\n"
++" addi %0, %0, 1\n"
++"1: add %0, %4, %0\n"
++" bgeu %0, %4, 1f\n"
++" addi %0, %0, 1\n"
++"1: add %0, %5, %0\n"
++" bgeu %0, %5, 1f\n"
++" addi %0, %0, 1\n"
++"1:\n"
++/*
++ We need the carry from the addition of 16-bit
++ significant addition, so we zap out the low bits
++ in one half, zap out the high bits in another,
++ shift them both up to the top 16-bits of a word
++ and do the carry producing addition, finally
++ shift the result back down to the low 16-bits.
++
++ Actually, we can further optimize away two shifts
++ because we know the low bits of the original
++ value will be added to zero-only bits so cannot
++ affect the addition result nor the final carry
++ bit.
++*/
++" slli %1,%0, 16\n" /* Need a copy to fold with */
++ /* Bring the LOW 16 bits up */
++" add %0, %1, %0\n" /* add and set carry, neat eh? */
++" cmpltu r15, %0, %1\n" /* get remaining carry bit */
++" srli %0, %0, 16\n" /* shift back down the result */
++" add %0, %0, r15\n"
++" nor %0, %0, %0\n" /* negate */
++ : "=&r" (sum), "=&r" (saddr)
++ : "0" (sum), "1" (saddr), "r" (ntohl(len+proto)), "r" (daddr)
++ : "r15");
++ return ((unsigned short) sum);
++ barrier();
++}
++
++
++/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
++
++
++ extern inline unsigned short from32to16(unsigned long x)
++ {
++ barrier();
++ __asm__ __volatile__(
++ "add %0, %1, %0\n"
++ "cmpltu r15, %0, %1\n"
++ "srli %0, %0, 16\n"
++ "add %0, %0, r15\n"
++ : "=r" (x)
++ : "r" (x << 16), "0" (x)
++ : "r15");
++ return x;
++ barrier();
++ }
++
++
++/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
++
++
++extern inline unsigned long do_csum(const unsigned char * buff, int len)
++{
++ int odd, count;
++ unsigned long result = 0;
++
++ barrier();
++ if (len <= 0)
++ goto out;
++ odd = 1 & (unsigned long) buff;
++ if (odd) {
++////result = *buff; // dgt: Big endian
++ result = *buff << 8; // dgt: Little endian
++
++ len--;
++ buff++;
++ }
++ count = len >> 1; /* nr of 16-bit words.. */
++ if (count) {
++ if (2 & (unsigned long) buff) {
++ result += *(unsigned short *) buff;
++ count--;
++ len -= 2;
++ buff += 2;
++ }
++ count >>= 1; /* nr of 32-bit words.. */
++ if (count) {
++ unsigned long carry = 0;
++ do {
++ unsigned long w = *(unsigned long *) buff;
++ count--;
++ buff += 4;
++ result += carry;
++ result += w;
++ carry = (w > result);
++ } while (count);
++ result += carry;
++ result = (result & 0xffff) + (result >> 16);
++ }
++ if (len & 2) {
++ result += *(unsigned short *) buff;
++ buff += 2;
++ }
++ }
++ if (len & 1)
++ result += *buff; /* This is little machine, byte is right */
++ result = from32to16(result);
++ if (odd)
++ result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
++out:
++ return result;
++ barrier();
++ }
++
++
++/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
++
++
++/* ihl is always 5 or greater, almost always is 5, iph is always word
++ * aligned but can fail to be dword aligned very often.
++ */
++
++ extern inline unsigned short ip_fast_csum(const unsigned char *iph, unsigned int ihl)
++ {
++ unsigned int sum;
++
++ barrier();
++ __asm__ __volatile__(
++" andi r8, %1, 2\n" /* Remember original alignment */
++" ldw %0, (%1)\n" /* 16 or 32 bit boundary */
++" beq r8, r0, 1f\n" /* Aligned on 32 bit boundary, go */
++" srli %0, %0, 16\n" /* Get correct 16 bits */
++" addi %2, %2, -1\n" /* Take off for 4 bytes, pickup last 2 at end */
++" addi %1, %1, 2\n" /* Adjust pointer to 32 bit boundary */
++" br 2f\n"
++"1:\n"
++" addi %2, %2, -1\n"
++" addi %1, %1, 4\n" /* Bump ptr a long word */
++"2:\n"
++" ldw r9, (%1)\n"
++"1:\n"
++" add %0, r9, %0\n"
++" bgeu %0, r9, 2f\n"
++" addi %0, %0, 1\n"
++"2:\n"
++" addi %1, %1, 4\n"
++" addi %2, %2, -1\n"
++" ldw r9, (%1)\n"
++" bne %2, r0, 1b\n"
++" beq r8, r0, 1f\n" /* 32 bit boundary time to leave */
++" srli r9, r9, 16\n" /* 16 bit boundary, get correct 16 bits */
++" add %0, r9, %0\n"
++" bgeu %0, r9, 1f\n"
++" addi %0, %0, 1\n"
++"1:\n"
++" slli %2, %0, 16\n"
++" add %0, %2, %0\n"
++" cmpltu r8, %0, %2\n"
++" srli %0, %0, 16\n"
++" add %0, %0, r8\n"
++" nor %0, %0, %0\n"
++ : "=&r" (sum), "=&r" (iph), "=&r" (ihl)
++ : "1" (iph), "2" (ihl)
++ : "r8", "r9");
++ return sum;
++ barrier();
++ }
++
++/*these 2 functions are now in checksum.c */
++unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
++unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
++
++/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
++
++/*
++ * the same as csum_partial_copy, but copies from user space.
++ *
++ * here even more important to align src and dst on a 32-bit (or even
++ * better 64-bit) boundary
++ */
++extern inline unsigned int
++csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
++{
++ barrier();
++ if (csum_err) *csum_err = 0;
++ memcpy(dst, src, len);
++ return csum_partial(dst, len, sum);
++ barrier();
++}
++
++#define csum_partial_copy_nocheck(src, dst, len, sum) \
++ csum_partial_copy ((src), (dst), (len), (sum))
++
++
++/*
++ * this routine is used for miscellaneous IP-like checksums, mainly
++ * in icmp.c
++ */
++
++extern inline unsigned short ip_compute_csum(unsigned char * buff, int len)
++{
++ barrier();
++ return ~from32to16(do_csum(buff,len));
++ barrier();
++}
++
++
++/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
++
++
++#define csum_partial_copy_fromuser(s, d, l, w) \
++ csum_partial_copy((char *) (s), (d), (l), (w))
++
++
++/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
++
++
++/*
++ * Fold a partial checksum without adding pseudo headers
++ */
++extern __inline__ unsigned int csum_fold(unsigned int sum)
++{
++ barrier();
++ __asm__ __volatile__(
++ "add %0, %1, %0\n"
++ "cmpltu r8, %0, %1\n"
++ "srli %0, %0, 16\n"
++ "add %0, %0, r8\n"
++ "nor %0, %0, %0\n"
++ : "=r" (sum)
++ : "r" (sum << 16), "0" (sum)
++ : "r8");
++ return sum;
++ barrier();
++}
++
++
++/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
++
++
++extern __inline__ unsigned long csum_tcpudp_nofold(unsigned long saddr,
++ unsigned long daddr,
++ unsigned short len,
++ unsigned short proto,
++ unsigned int sum)
++{
++ barrier();
++ __asm__ __volatile__(
++ "add %0, %1, %0\n"
++ "cmpltu r8, %0, %1\n"
++ "add %0, %0, r8\n" /* add carry */
++ "add %0, %2, %0\n"
++ "cmpltu r8, %0, %2\n"
++ "add %0, %0, r8\n" /* add carry */
++ "add %0, %3, %0\n"
++ "cmpltu r8, %0, %3\n"
++ "add %0, %0, r8\n" /* add carry */
++ : "=r" (sum), "=r" (saddr)
++ : "r" (daddr), "r" ( (ntohs(len)<<16) + (proto*256) ),
++ "0" (sum),
++ "1" (saddr)
++ : "r8");
++
++ return sum;
++ barrier();
++}
++
++
++#endif /* (__NIOS2_CHECKSUM_H) */
+diff --git a/include/asm-nios2nommu/cprefix.h b/include/asm-nios2nommu/cprefix.h
+new file mode 100644
+index 0000000..4983211
+--- /dev/null
++++ b/include/asm-nios2nommu/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 __NIOS2_CPREFIX_H
++#define __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 /* !(__NIOS2_CPREFIX_H) */
+diff --git a/include/asm-nios2nommu/cpumask.h b/include/asm-nios2nommu/cpumask.h
+new file mode 100644
+index 0000000..86fb365
+--- /dev/null
++++ b/include/asm-nios2nommu/cpumask.h
+@@ -0,0 +1,28 @@
++/*
++ * All rights reserved.
++ *
++ * 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, 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_NIOS2NOMMU_CPUMASK_H
++#define _ASM_NIOS2NOMMU_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_NIOS2NOMMU_CPUMASK_H */
+diff --git a/include/asm-nios2nommu/cputime.h b/include/asm-nios2nommu/cputime.h
+new file mode 100644
+index 0000000..370e4f2
+--- /dev/null
++++ b/include/asm-nios2nommu/cputime.h
+@@ -0,0 +1,31 @@
++/*
++ * cputime.h
++ * (C) Copyright 2004, Microtronix Datacom Ltd.
++ *
++ * Taken from m68knommu
++ *
++ * 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 __NIOS2NOMMU_CPUTIME_H
++#define __NIOS2NOMMU_CPUTIME_H
++
++#include <asm-generic/cputime.h>
++
++#endif /* __NIOS@NOMMU_CPUTIME_H */
+diff --git a/include/asm-nios2nommu/current.h b/include/asm-nios2nommu/current.h
+new file mode 100644
+index 0000000..5ac1dbc
+--- /dev/null
++++ b/include/asm-nios2nommu/current.h
+@@ -0,0 +1,39 @@
++#ifndef _NIOS2NOMMU_CURRENT_H
++#define _NIOS2NOMMU_CURRENT_H
++/*
++ * current.h
++ * (C) Copyright 2000, Lineo, David McCullough <davidm@uclinux.org>
++ * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
++ * (C) Copyright 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.
++ *
++ */
++
++#include <linux/thread_info.h>
++
++struct task_struct;
++
++static inline struct task_struct *get_current(void)
++{
++ return(current_thread_info()->task);
++}
++
++#define current get_current()
++
++#endif /* _NIOS2NOMMU_CURRENT_H */
+diff --git a/include/asm-nios2nommu/delay.h b/include/asm-nios2nommu/delay.h
+new file mode 100644
+index 0000000..da0a184
+--- /dev/null
++++ b/include/asm-nios2nommu/delay.h
+@@ -0,0 +1,96 @@
++#ifndef _NIOS_DELAY_H
++#define _NIOS_DELAY_H
++
++/*--------------------------------------------------------------------
++ *
++ * include/asm-nios2nommu/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;
++
++ __asm__("mulxuu %0,%1,%2" : "=r" (loops) :
++ "r" (x), "r" (loops_per_jiffy * 226));
++ __delay(loops);
++}
++
++extern __inline__ void __ndelay(unsigned int x)
++{
++ unsigned int loops;
++
++ __asm__("mulxuu %0,%1,%2" : "=r" (loops) :
++ "r" (x), "r" (loops_per_jiffy * 5));
++ __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/include/asm-nios2nommu/device.h b/include/asm-nios2nommu/device.h
+new file mode 100644
+index 0000000..d8f9872
+--- /dev/null
++++ b/include/asm-nios2nommu/device.h
+@@ -0,0 +1,7 @@
++/*
++ * Arch specific extensions to struct device
++ *
++ * This file is released under the GPLv2
++ */
++#include <asm-generic/device.h>
++
+diff --git a/include/asm-nios2nommu/div64.h b/include/asm-nios2nommu/div64.h
+new file mode 100644
+index 0000000..68d72e4
+--- /dev/null
++++ b/include/asm-nios2nommu/div64.h
+@@ -0,0 +1,31 @@
++#ifndef __ASMNIOS_DIV64_H
++#define __ASMNIOS_DIV64_H
++
++/*--------------------------------------------------------------------
++ *
++ * include/asm-nios2nommu/div64.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-generic/div64.h>
++
++#endif
++
+diff --git a/include/asm-nios2nommu/dma-mapping.h b/include/asm-nios2nommu/dma-mapping.h
+new file mode 100644
+index 0000000..6289370
+--- /dev/null
++++ b/include/asm-nios2nommu/dma-mapping.h
+@@ -0,0 +1,79 @@
++#ifndef _ASM_DMA_MAPPING_H
++#define _ASM_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(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_DMA_MAPPING_H */
+diff --git a/include/asm-nios2nommu/dma.h b/include/asm-nios2nommu/dma.h
+new file mode 100644
+index 0000000..ea098d5
+--- /dev/null
++++ b/include/asm-nios2nommu/dma.h
+@@ -0,0 +1,63 @@
++/* $Id: dma.h,v 1.1 2006/07/05 06:20:25 gerg Exp $
++ *
++ * Copyright 2004 (C) 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_DMA_H
++#define _ASM_NIOS2_DMA_H
++
++#include <linux/kernel.h>
++#include <asm/asm-offsets.h>
++
++#define MAX_DMA_ADDRESS (LINUX_SDRAM_END)
++
++int request_dma(unsigned int, const char *);
++void free_dma(unsigned int);
++void enable_dma(unsigned int dmanr);
++void disable_dma(unsigned int dmanr);
++void set_dma_count(unsigned int dmanr, unsigned int count);
++int get_dma_residue(unsigned int dmanr);
++void nios2_set_dma_data_width(unsigned int dmanr, unsigned int width);
++
++void nios2_set_dma_handler(unsigned int dmanr, int (*handler)(void*, int), void* user);
++int nios2_request_dma(const char *);
++
++void nios2_set_dma_mode(unsigned int dmanr, unsigned int mode);
++void nios2_set_dma_rcon(unsigned int dmanr, unsigned int set);
++void nios2_set_dma_wcon(unsigned int dmanr, unsigned int set);
++void nios2_set_dma_raddr(unsigned int dmanr, unsigned int a);
++void nios2_set_dma_waddr(unsigned int dmanr, unsigned int a);
++
++static inline unsigned long claim_dma_lock(void)
++{
++}
++
++static inline void release_dma_lock(unsigned long flags)
++{
++}
++
++#ifdef CONFIG_PCI
++extern int isa_dma_bridge_buggy;
++#else
++#define isa_dma_bridge_buggy (0)
++#endif
++
++#endif /* !(_ASM_NIOS2_DMA_H) */
+diff --git a/include/asm-nios2nommu/elf.h b/include/asm-nios2nommu/elf.h
+new file mode 100644
+index 0000000..94b2ac0
+--- /dev/null
++++ b/include/asm-nios2nommu/elf.h
+@@ -0,0 +1,140 @@
++#ifndef __NIOS2_ELF_H
++#define __NIOS2_ELF_H
++
++/*--------------------------------------------------------------------
++ *
++ * include/asm-nios2nommu/elf.h
++ *
++ * Nio2 ELF relocation types
++ *
++ * 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
++ * Mar/18/2004 xwt NiosII relocation types added
++ *
++ ---------------------------------------------------------------------*/
++
++#include <asm/ptrace.h>
++#include <asm/user.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
++
++typedef unsigned long elf_greg_t;
++
++#define ELF_NGREG (sizeof (struct user_regs_struct) / 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) _r->a1 = 0
++
++#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->r1; \
++ pr_reg[1] = regs->r2; \
++ pr_reg[2] = regs->r3; \
++ pr_reg[3] = regs->r4; \
++ pr_reg[4] = regs->r5; \
++ pr_reg[5] = regs->r6; \
++ pr_reg[6] = regs->r7; \
++ pr_reg[7] = regs->r8; \
++ pr_reg[8] = regs->r9; \
++ pr_reg[9] = regs->r10; \
++ pr_reg[10] = regs->r11; \
++ pr_reg[11] = regs->r12; \
++ pr_reg[12] = regs->r13; \
++ pr_reg[13] = regs->r14; \
++ pr_reg[14] = regs->r15; \
++ pr_reg[23] = regs->sp; \
++ pr_reg[26] = regs->estatus; \
++ { \
++ struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \
++ pr_reg[15] = sw->r16; \
++ pr_reg[16] = sw->r17; \
++ pr_reg[17] = sw->r18; \
++ pr_reg[18] = sw->r19; \
++ pr_reg[19] = sw->r20; \
++ pr_reg[20] = sw->r21; \
++ pr_reg[21] = sw->r22; \
++ pr_reg[22] = sw->r23; \
++ pr_reg[24] = sw->fp; \
++ pr_reg[25] = sw->gp; \
++ }
++
++/* 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)
++
++#ifdef __KERNEL__
++#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
++#endif
++
++#endif
+diff --git a/include/asm-nios2nommu/emergency-restart.h b/include/asm-nios2nommu/emergency-restart.h
+new file mode 100644
+index 0000000..108d8c4
+--- /dev/null
++++ b/include/asm-nios2nommu/emergency-restart.h
+@@ -0,0 +1,6 @@
++#ifndef _ASM_EMERGENCY_RESTART_H
++#define _ASM_EMERGENCY_RESTART_H
++
++#include <asm-generic/emergency-restart.h>
++
++#endif /* _ASM_EMERGENCY_RESTART_H */
+diff --git a/include/asm-nios2nommu/entry.h b/include/asm-nios2nommu/entry.h
+new file mode 100644
+index 0000000..4b1773f
+--- /dev/null
++++ b/include/asm-nios2nommu/entry.h
+@@ -0,0 +1,187 @@
++/*
++ * 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 __NIOS2NOMMU_ENTRY_H
++#define __NIOS2NOMMU_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
++ * 54(sp) - status_extension
++ * 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
++ movia r24,status_extension // Read status extension
++ ldw r24,0(r24)
++ andi r24,r24,PS_S_ASM
++ bne 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 ra,PT_RA(sp)
++ stw fp,PT_FP(sp)
++ stw gp,PT_GP(sp)
++ rdctl r24,estatus
++ stw r24,PT_ESTATUS(sp)
++ movia r24,status_extension // Read status extension
++ ldw r1,0(r24)
++ stw r1,PT_STATUS_EXTENSION(sp) // Store user/supervisor status
++ ORI32 r1,r1,PS_S_ASM // Set supervisor mode
++ stw r1,0(r24)
++ stw ea,PT_EA(sp)
++.endm
++
++.macro RESTORE_ALL
++ ldw r1,PT_STATUS_EXTENSION(sp) // Restore user/supervisor status
++ movia r24,status_extension
++ stw r1,0(r24)
++ 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 /* __NIOS2NOMMU_ENTRY_H */
+diff --git a/include/asm-nios2nommu/errno.h b/include/asm-nios2nommu/errno.h
+new file mode 100644
+index 0000000..c2caf21
+--- /dev/null
++++ b/include/asm-nios2nommu/errno.h
+@@ -0,0 +1,6 @@
++#ifndef _NIOS2NOMMU_ERRNO_H
++#define _NIOS2NOMMU_ERRNO_H
++
++#include <asm-generic/errno.h>
++
++#endif /* _NIOS2NOMMU_ERRNO_H */
+diff --git a/include/asm-nios2nommu/fcntl.h b/include/asm-nios2nommu/fcntl.h
+new file mode 100644
+index 0000000..9d98af2
+--- /dev/null
++++ b/include/asm-nios2nommu/fcntl.h
+@@ -0,0 +1,11 @@
++#ifndef _NIOS2_FCNTL_H
++#define _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 /* _NIOS2_FCNTL_H */
+diff --git a/include/asm-nios2nommu/flat.h b/include/asm-nios2nommu/flat.h
+new file mode 100644
+index 0000000..681329a
+--- /dev/null
++++ b/include/asm-nios2nommu/flat.h
+@@ -0,0 +1,129 @@
++/*
++ * include/asm-nios2nommu/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 __NIOS2_FLAT_H__
++#define __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 /* __NIOS2_FLAT_H__ */
+diff --git a/include/asm-nios2nommu/futex.h b/include/asm-nios2nommu/futex.h
+new file mode 100644
+index 0000000..6a332a9
+--- /dev/null
++++ b/include/asm-nios2nommu/futex.h
+@@ -0,0 +1,6 @@
++#ifndef _ASM_FUTEX_H
++#define _ASM_FUTEX_H
++
++#include <asm-generic/futex.h>
++
++#endif
+diff --git a/include/asm-nios2nommu/gpio.h b/include/asm-nios2nommu/gpio.h
+new file mode 100644
+index 0000000..b91937b
+--- /dev/null
++++ b/include/asm-nios2nommu/gpio.h
+@@ -0,0 +1,11 @@
++#ifndef _ASM_GPIO_H_
++#define _ASM_GPIO_H_ 1
++
++
++struct gpio_i2c_pins {
++ unsigned sda_pin;
++ unsigned scl_pin;
++};
++
++#endif /*_ASM_GPIO_*/
++
+diff --git a/include/asm-nios2nommu/hardirq.h b/include/asm-nios2nommu/hardirq.h
+new file mode 100644
+index 0000000..0041f51
+--- /dev/null
++++ b/include/asm-nios2nommu/hardirq.h
+@@ -0,0 +1,43 @@
++/*
++ * Ported from m68knommu
++ *
++ * Copyright (C) 2003, Microtronix Datacom Ltd.
++ * 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 __NIOS2_HARDIRQ_H
++#define __NIOS2_HARDIRQ_H
++
++#include <linux/cache.h>
++#include <linux/threads.h>
++
++typedef struct {
++ unsigned int __softirq_pending;
++} ____cacheline_aligned irq_cpustat_t;
++
++#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
++
++#define HARDIRQ_BITS 8
++
++#ifdef CONFIG_SMP
++# error nios2nommu SMP is not available
++#endif /* CONFIG_SMP */
++
++#endif /* __NIOS2_HARDIRQ_H */
+diff --git a/include/asm-nios2nommu/hdreg.h b/include/asm-nios2nommu/hdreg.h
+new file mode 100644
+index 0000000..b4d910a
+--- /dev/null
++++ b/include/asm-nios2nommu/hdreg.h
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (C) 1994-1996 Linus Torvalds & authors
++ * Copyright (C) 2002 Wentau Xu (www.microtronix.com)
++ * 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 __NIOS2_HDREG_H
++#define __NIOS2_HDREG_H
++
++typedef unsigned long ide_ioreg_t;
++
++#endif /* __NIOS2_HDREG_H */
+diff --git a/include/asm-nios2nommu/hw_irq.h b/include/asm-nios2nommu/hw_irq.h
+new file mode 100644
+index 0000000..d2fd3be
+--- /dev/null
++++ b/include/asm-nios2nommu/hw_irq.h
+@@ -0,0 +1,16 @@
++#ifndef _ASM_HW_IRQ_H
++#define _ASM_HW_IRQ_H
++
++/*
++ * linux/include/asm/hw_irq.h
++ *
++ * (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
++ *
++ * moved some of the old arch/i386/kernel/irq.h to here. VY
++ *
++ * IRQ/IPI changes taken from work by Thomas Radke
++ * <tomsoft@informatik.tu-chemnitz.de>
++ */
++
++
++#endif /* _ASM_HW_IRQ_H */
+diff --git a/include/asm-nios2nommu/ide.h b/include/asm-nios2nommu/ide.h
+new file mode 100644
+index 0000000..f8ef9ad
+--- /dev/null
++++ b/include/asm-nios2nommu/ide.h
+@@ -0,0 +1,40 @@
++/*
++ * linux/include/asm-niosnommu2/ide.h
++ *
++ * Copyright (C) 1994-1996 Linus Torvalds & authors
++ * 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 __ASMNIOS2_IDE_H
++#define __ASMNIOS2_IDE_H
++
++#ifdef __KERNEL__
++#undef MAX_HWIFS /* we're going to force it */
++
++#ifndef MAX_HWIFS
++#define MAX_HWIFS 1
++#endif
++
++#include <asm-generic/ide_iops.h>
++
++#endif /* __KERNEL__ */
++
++#endif /* __ASMNIOS2_IDE_H */
+diff --git a/include/asm-nios2nommu/init.h b/include/asm-nios2nommu/init.h
+new file mode 100644
+index 0000000..8641f4f
+--- /dev/null
++++ b/include/asm-nios2nommu/init.h
+@@ -0,0 +1,22 @@
++/*
++ * 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.
++ *
++ */
++#error "<asm/init.h> should never be used - use <linux/init.h> instead"
+diff --git a/include/asm-nios2nommu/io.h b/include/asm-nios2nommu/io.h
+new file mode 100644
+index 0000000..d0e3741
+--- /dev/null
++++ b/include/asm-nios2nommu/io.h
+@@ -0,0 +1,277 @@
++/*
++ * 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 __NIOS2_IO_H
++#define __NIOS2_IO_H
++
++#ifdef __KERNEL__
++
++#include <linux/kernel.h>
++
++#include <asm/page.h> /* IO address mapping routines need this */
++#include <asm/system.h>
++#include <asm/unaligned.h>
++
++extern void insw(unsigned long port, void *dst, unsigned long count);
++extern void outsw(unsigned long port, void *src, unsigned long count);
++extern void insl(unsigned long port, void *dst, unsigned long count);
++extern void outsl(unsigned long port, void *src, unsigned long count);
++
++#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)
++#ifndef irq_canonicalize
++#define irq_canonicalize(i) (i)
++#endif
++
++#endif /* __KERNEL__ */
++/* IO macros are needed by userspace programs */
++
++/*
++ * readX/writeX() are used to access memory mapped devices. On some
++ * architectures the memory mapped IO stuff needs to be accessed
++ * differently. On the Nios architecture, we just read/write the
++ * memory location directly.
++ */
++
++#define readb(addr) \
++({ \
++ unsigned char __res;\
++ __asm__ __volatile__( \
++ "ldbuio %0, 0(%1)" \
++ : "=r"(__res) \
++ : "r" (addr)); \
++ __res; \
++})
++
++#define readw(addr) \
++({ \
++ unsigned short __res;\
++ __asm__ __volatile__( \
++ "ldhuio %0, 0(%1)" \
++ : "=r"(__res) \
++ : "r" (addr)); \
++ __res; \
++})
++
++#define readl(addr) \
++({ \
++ unsigned int __res;\
++ __asm__ __volatile__( \
++ "ldwio %0, 0(%1)" \
++ : "=r"(__res) \
++ : "r" (addr)); \
++ __res; \
++})
++
++#define writeb(b,addr) \
++({ \
++ __asm__ __volatile__( \
++ "stbio %0, 0(%1)" \
++ : : "r"(b), "r" (addr)); \
++})
++
++#define writew(b,addr) \
++({ \
++ __asm__ __volatile__( \
++ "sthio %0, 0(%1)" \
++ : : "r"(b), "r" (addr)); \
++})
++
++#define writel(b,addr) \
++({ \
++ __asm__ __volatile__( \
++ "stwio %0, 0(%1)" \
++ : : "r"(b), "r" (addr)); \
++})
++
++#define __raw_readb readb
++#define __raw_readw readw
++#define __raw_readl readl
++#define __raw_writeb writeb
++#define __raw_writew writew
++#define __raw_writel writel
++
++#define mmiowb()
++
++/*
++ * make the short names macros so specific devices
++ * can override them as required
++ */
++
++#define memset_io(addr,c,len) memset((void *)(((unsigned int)(addr)) | 0x80000000),(c),(len))
++#define memcpy_fromio(to,from,len) memcpy((to),(void *)(((unsigned int)(from)) | 0x80000000),(len))
++#define memcpy_toio(to,from,len) memcpy((void *)(((unsigned int)(to)) | 0x80000000),(from),(len))
++
++#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)
++
++/* IO macros are needed by userspace programs */
++#ifdef __KERNEL__
++
++extern inline void insb(unsigned long port, void *dst, unsigned long count)
++{
++ unsigned char *p=(unsigned char*)dst;
++ while (count--)
++ *p++ = inb(port);
++}
++
++/* See arch/niosnommu/io.c for optimized version */
++extern inline void _insw(unsigned long port, void *dst, unsigned long count)
++{
++ unsigned short *p=(unsigned short*)dst;
++ while (count--)
++ *p++ = inw(port);
++}
++
++/* See arch/niosnommu/kernel/io.c for unaligned destination pointer */
++extern inline void _insl(unsigned long port, void *dst, unsigned long count)
++{
++ unsigned long *p=(unsigned long*)dst;
++ while (count--)
++ *p++ = inl(port);
++}
++
++extern inline void outsb(unsigned long port, void *src, unsigned long count)
++{
++ unsigned char *p=(unsigned char*)src;
++ while (count--)
++ outb( *p++, port );
++}
++
++/* See arch/niosnommu/io.c for optimized version */
++extern inline void _outsw(unsigned long port, void *src, unsigned long count)
++{
++ unsigned short *p=(unsigned short*)src;
++ while (count--)
++ outw( *p++, port );
++}
++
++/* See arch/niosnommu/kernel/io.c for unaligned source pointer */
++extern inline void _outsl(unsigned long port, void *src, unsigned long count)
++{
++ unsigned long *p=(unsigned long*)src;
++ while (count--)
++ outl( *p++, port );
++}
++
++
++
++extern inline void mapioaddr(unsigned long physaddr, unsigned long virt_addr,
++ int bus, int rdonly)
++{
++ return;
++}
++
++//vic - copied from m68knommu
++
++/* Values for nocacheflag and cmode */
++#define IOMAP_FULL_CACHING 0
++#define IOMAP_NOCACHE_SER 1
++#define IOMAP_NOCACHE_NONSER 2
++#define IOMAP_WRITETHROUGH 3
++
++extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
++extern void __iounmap(void *addr, unsigned long size);
++
++extern inline void *ioremap(unsigned long physaddr, unsigned long size)
++{
++ return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
++}
++extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
++{
++ return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
++}
++extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
++{
++ return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
++}
++extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
++{
++ return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
++}
++
++extern void iounmap(void *addr);
++
++
++#define IO_SPACE_LIMIT 0xffffffff
++
++#define dma_cache_inv(_start,_size) dcache_push(_start,_size)
++#define dma_cache_wback(_start,_size) dcache_push(_start,_size)
++#define dma_cache_wback_inv(_start,_size) dcache_push(_start,_size)
++
++/* Pages to physical address... */
++#define page_to_phys(page) page_to_virt(page)
++#define page_to_bus(page) page_to_virt(page)
++
++#define mm_ptov(vaddr) ((void *) (vaddr))
++#define mm_vtop(vaddr) ((unsigned long) (vaddr))
++#define phys_to_virt(vaddr) ((void *) (vaddr))
++#define virt_to_phys(vaddr) ((unsigned long) (vaddr))
++
++#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
++
++#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)
++#ifndef irq_canonicalize
++#define irq_canonicalize(i) (i)
++#endif
++
++#endif /* __KERNEL__ */
++
++#endif /* !(__NIOS2_IO_H) */
++
+diff --git a/include/asm-nios2nommu/ioctl.h b/include/asm-nios2nommu/ioctl.h
+new file mode 100644
+index 0000000..c02a36a
+--- /dev/null
++++ b/include/asm-nios2nommu/ioctl.h
+@@ -0,0 +1,100 @@
++/* $Id: ioctl.h,v 1.1 2006/07/05 06:20:25 gerg Exp $
++ *
++ * linux/ioctl.h for Linux by H.H. Bergman.
++ *
++ * 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 _NIOS2_IOCTL_H
++#define _NIOS2_IOCTL_H
++
++/* ioctl command encoding: 32 bits total, command in lower 16 bits,
++ * size of the parameter structure in the lower 14 bits of the
++ * upper 16 bits.
++ * Encoding the size of the parameter structure in the ioctl request
++ * is useful for catching programs compiled with old versions
++ * and to avoid overwriting user space outside the user buffer area.
++ * The highest 2 bits are reserved for indicating the ``access mode''.
++ * NOTE: This limits the max parameter size to 16kB -1 !
++ */
++
++/*
++ * I don't really have any idea about what this should look like, so
++ * for the time being, this is heavily based on the PC definitions.
++ */
++
++/*
++ * The following is for compatibility across the various Linux
++ * platforms. The i386 ioctl numbering scheme doesn't really enforce
++ * a type field. De facto, however, the top 8 bits of the lower 16
++ * bits are indeed used as a type field, so we might just as well make
++ * this explicit here. Please be sure to use the decoding macros
++ * below from now on.
++ */
++#define _IOC_NRBITS 8
++#define _IOC_TYPEBITS 8
++#define _IOC_SIZEBITS 14
++#define _IOC_DIRBITS 2
++
++#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
++#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
++#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
++#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
++
++#define _IOC_NRSHIFT 0
++#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
++#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
++#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
++
++/*
++ * Direction bits.
++ */
++#define _IOC_NONE 0U
++#define _IOC_WRITE 1U
++#define _IOC_READ 2U
++
++#define _IOC(dir,type,nr,size) \
++ (((dir) << _IOC_DIRSHIFT) | \
++ ((type) << _IOC_TYPESHIFT) | \
++ ((nr) << _IOC_NRSHIFT) | \
++ ((size) << _IOC_SIZESHIFT))
++
++/* used to create numbers */
++#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
++#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
++#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
++#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
++
++/* used to decode ioctl numbers.. */
++#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
++#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
++#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
++#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
++
++/* ...and for the drivers/sound files... */
++
++#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
++#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
++#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
++#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
++#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
++
++#endif /* _NIOS2_IOCTL_H */
+diff --git a/include/asm-nios2nommu/ioctls.h b/include/asm-nios2nommu/ioctls.h
+new file mode 100644
+index 0000000..288025c
+--- /dev/null
++++ b/include/asm-nios2nommu/ioctls.h
+@@ -0,0 +1,103 @@
++/*
++ * 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 __ARCH_NIOS2_IOCTLS_H__
++#define __ARCH_NIOS2_IOCTLS_H__
++
++#include <asm/ioctl.h>
++
++/* 0x54 is just a magic number to make these relatively unique ('T') */
++
++#define TCGETS 0x5401
++#define TCSETS 0x5402
++#define TCSETSW 0x5403
++#define TCSETSF 0x5404
++#define TCGETA 0x5405
++#define TCSETA 0x5406
++#define TCSETAW 0x5407
++#define TCSETAF 0x5408
++#define TCSBRK 0x5409
++#define TCXONC 0x540A
++#define TCFLSH 0x540B
++#define TIOCEXCL 0x540C
++#define TIOCNXCL 0x540D
++#define TIOCSCTTY 0x540E
++#define TIOCGPGRP 0x540F
++#define TIOCSPGRP 0x5410
++#define TIOCOUTQ 0x5411
++#define TIOCSTI 0x5412
++#define TIOCGWINSZ 0x5413
++#define TIOCSWINSZ 0x5414
++#define TIOCMGET 0x5415
++#define TIOCMBIS 0x5416
++#define TIOCMBIC 0x5417
++#define TIOCMSET 0x5418
++#define TIOCGSOFTCAR 0x5419
++#define TIOCSSOFTCAR 0x541A
++#define FIONREAD 0x541B
++#define TIOCINQ FIONREAD
++#define TIOCLINUX 0x541C
++#define TIOCCONS 0x541D
++#define TIOCGSERIAL 0x541E
++#define TIOCSSERIAL 0x541F
++#define TIOCPKT 0x5420
++#define FIONBIO 0x5421
++#define TIOCNOTTY 0x5422
++#define TIOCSETD 0x5423
++#define TIOCGETD 0x5424
++#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
++#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
++#define TIOCSBRK 0x5427 /* BSD compatibility */
++#define TIOCCBRK 0x5428 /* BSD compatibility */
++#define TIOCGSID 0x5429 /* Return the session ID of FD */
++#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
++#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
++
++#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
++#define FIOCLEX 0x5451
++#define FIOASYNC 0x5452
++#define TIOCSERCONFIG 0x5453
++#define TIOCSERGWILD 0x5454
++#define TIOCSERSWILD 0x5455
++#define TIOCGLCKTRMIOS 0x5456
++#define TIOCSLCKTRMIOS 0x5457
++#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
++#define TIOCSERGETLSR 0x5459 /* Get line status register */
++#define TIOCSERGETMULTI 0x545A /* Get multiport config */
++#define TIOCSERSETMULTI 0x545B /* Set multiport config */
++
++#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
++#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
++#define FIOQSIZE 0x545E
++
++/* Used for packet mode */
++#define TIOCPKT_DATA 0
++#define TIOCPKT_FLUSHREAD 1
++#define TIOCPKT_FLUSHWRITE 2
++#define TIOCPKT_STOP 4
++#define TIOCPKT_START 8
++#define TIOCPKT_NOSTOP 16
++#define TIOCPKT_DOSTOP 32
++
++#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
++
++#endif /* __ARCH_NIOS2_IOCTLS_H__ */
+diff --git a/include/asm-nios2nommu/ipc.h b/include/asm-nios2nommu/ipc.h
+new file mode 100644
+index 0000000..cb86a31
+--- /dev/null
++++ b/include/asm-nios2nommu/ipc.h
+@@ -0,0 +1,51 @@
++#ifndef __NIOS2_IPC_H__
++#define __NIOS2_IPC_H__
++
++/* Copied from sparc version
++ * These are used to wrap system calls on the Nios.
++ *
++ * See arch/niosnommu/kernel/sys_nios.c for ugly details..
++ *
++ * 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.
++ *
++ */
++struct ipc_kludge {
++ struct msgbuf *msgp;
++ long msgtyp;
++};
++
++#define SEMOP 1
++#define SEMGET 2
++#define SEMCTL 3
++#define MSGSND 11
++#define MSGRCV 12
++#define MSGGET 13
++#define MSGCTL 14
++#define SHMAT 21
++#define SHMDT 22
++#define SHMGET 23
++#define SHMCTL 24
++
++/* Used by the DIPC package, try and avoid reusing it */
++#define DIPC 25
++
++#define IPCCALL(version,op) ((version)<<16 | (op))
++
++#endif
+diff --git a/include/asm-nios2nommu/ipcbuf.h b/include/asm-nios2nommu/ipcbuf.h
+new file mode 100644
+index 0000000..ef59533
+--- /dev/null
++++ b/include/asm-nios2nommu/ipcbuf.h
+@@ -0,0 +1,49 @@
++#ifndef __NIOS2_IPCBUF_H__
++#define __NIOS2_IPCBUF_H__
++
++/* Copied from asm-m68k/ipcbuf.h
++ * The user_ipc_perm structure for Nios architecture.
++ * Note extra padding because this structure is passed back and forth
++ * between kernel and user space.
++ *
++ * Pad space is left for:
++ * - 32-bit mode_t and seq
++ * - 2 miscellaneous 32-bit values
++ *
++ * 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.
++ *
++ */
++
++struct ipc64_perm
++{
++ __kernel_key_t key;
++ __kernel_uid32_t uid;
++ __kernel_gid32_t gid;
++ __kernel_uid32_t cuid;
++ __kernel_gid32_t cgid;
++ __kernel_mode_t mode;
++ unsigned short __pad1;
++ unsigned short seq;
++ unsigned short __pad2;
++ unsigned long __unused1;
++ unsigned long __unused2;
++};
++
++#endif /* __NIOS2_IPCBUF_H__ */
+diff --git a/include/asm-nios2nommu/irq.h b/include/asm-nios2nommu/irq.h
+new file mode 100644
+index 0000000..f0e37a2
+--- /dev/null
++++ b/include/asm-nios2nommu/irq.h
+@@ -0,0 +1,181 @@
++/*
++ * 21Mar2001 1.1 dgt/microtronix
++ *
++ * 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 _NIOS2NOMMU_IRQ_H_
++#define _NIOS2NOMMU_IRQ_H_
++
++extern void disable_irq(unsigned int);
++extern void enable_irq(unsigned int);
++
++#include <linux/interrupt.h>
++
++#define SYS_IRQS 32
++#define NR_IRQS SYS_IRQS
++
++/*
++ * Interrupt source definitions
++ * General interrupt sources are the level 1-7.
++ * Adding an interrupt service routine for one of these sources
++ * results in the addition of that routine to a chain of routines.
++ * Each one is called in succession. Each individual interrupt
++ * service routine should determine if the device associated with
++ * that routine requires service.
++ */
++
++#define IRQ01 (1) /* level 1 interrupt */
++#define IRQ02 (2) /* level 2 interrupt */
++#define IRQ03 (3) /* level 3 interrupt */
++#define IRQ04 (4) /* level 4 interrupt */
++#define IRQ05 (5) /* level 5 interrupt */
++#define IRQ06 (6) /* level 6 interrupt */
++#define IRQ07 (7) /* level 7 interrupt */
++#define IRQ08 (8) /* level 8 interrupt */
++#define IRQ09 (9) /* level 9 interrupt */
++#define IRQ0A (10) /* level 10 interrupt */
++#define IRQ0B (11) /* level 11 interrupt */
++#define IRQ0C (12) /* level 12 interrupt */
++#define IRQ0D (13) /* level 13 interrupt */
++#define IRQ0E (14) /* level 14 interrupt */
++#define IRQ0F (15) /* level 15 interrupt */
++#define IRQ10 (16) /* level 16 interrupt */
++#define IRQ12 (17) /* level 17 interrupt */
++#define IRQ13 (18) /* level 18 interrupt */
++#define IRQ14 (19) /* level 19 interrupt */
++#define IRQ15 (20) /* level 20 interrupt */
++#define IRQ16 (21) /* level 21 interrupt */
++#define IRQ17 (22) /* level 22 interrupt */
++#define IRQ18 (23) /* level 23 interrupt */
++#define IRQ19 (24) /* level 24 interrupt */
++#define IRQ1A (25) /* level 25 interrupt */
++#define IRQ1B (26) /* level 26 interrupt */
++#define IRQ1C (27) /* level 27 interrupt */
++#define IRQ1D (28) /* level 28 interrupt */
++#define IRQ1E (29) /* level 29 interrupt */
++#define IRQ1F (30) /* level 30 interrupt */
++#define IRQ20 (31) /* level 31 interrupt */
++#define IRQ21 (32) /* level 32 interrupt */
++
++#define IRQMAX IRQ21
++
++/*
++ * "Generic" interrupt sources
++ */
++
++/*
++ * Machine specific interrupt sources.
++ *
++ * Adding an interrupt service routine for a source with this bit
++ * set indicates a special machine specific interrupt source.
++ * The machine specific files define these sources.
++ *
++ * Removed, they are not used by any one.
++ */
++
++/*
++ * various flags for request_irq()
++ */
++#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */
++#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */
++#define IRQ_FLG_FAST (0x0004)
++#define IRQ_FLG_SLOW (0x0008)
++#define IRQ_FLG_STD (0x8000) /* internally used */
++
++/*
++ * Functions to set and clear the interrupt mask.
++ */
++
++/*
++ * Use a zero to clean the bit.
++ */
++static inline void clrimr(int mask)
++{
++ int flags;
++
++ local_irq_save(flags);
++ __asm__ __volatile__(
++ "rdctl r8, ienable\n"
++ "and r8,r8,%0\n"
++ "wrctl ienable, r8\n"
++ : /* No output */
++ : "r" (mask)
++ : "r8");
++ local_irq_restore(flags);
++}
++
++/*
++ * Use a one to set the bit.
++ */
++static inline void setimr(int mask)
++{
++ int flags;
++
++ local_irq_save(flags);
++ __asm__ __volatile__(
++ "rdctl r8, ienable\n"
++ "or r8,r8,%0\n"
++ "wrctl ienable, r8\n"
++ : /* No output */
++ : "r" (mask)
++ : "r8");
++ local_irq_restore(flags);
++}
++
++/*
++ * This structure is used to chain together the ISRs for a particular
++ * interrupt source (if it supports chaining).
++ */
++typedef struct irq_node {
++ irq_handler_t handler;
++ unsigned long flags;
++ void *dev_id;
++ const char *devname;
++ struct irq_node *next;
++} irq_node_t;
++
++/*
++ * This function returns a new irq_node_t
++ */
++extern irq_node_t *new_irq_node(void);
++
++/*
++ * This structure has only 4 elements for speed reasons
++ */
++typedef struct irq_hand {
++ irq_handler_t handler;
++ unsigned long flags;
++ void *dev_id;
++ const char *devname;
++} irq_hand_t;
++
++/* count of spurious interrupts */
++extern volatile unsigned int num_spurious;
++
++#define disable_irq_nosync(i) disable_irq(i)
++
++#ifndef irq_canonicalize
++#define irq_canonicalize(i) (i)
++#endif
++
++#endif /* _NIOS2NOMMU_IRQ_H_ */
+diff --git a/include/asm-nios2nommu/irq_node.h b/include/asm-nios2nommu/irq_node.h
+new file mode 100644
+index 0000000..24f9763
+--- /dev/null
++++ b/include/asm-nios2nommu/irq_node.h
+@@ -0,0 +1,36 @@
++#ifndef _NIOS2NOMMU_IRQNODE_H_
++#define _NIOS2NOMMU_IRQNODE_H_
++
++#include <linux/interrupt.h>
++
++/*
++ * This structure is used to chain together the ISRs for a particular
++ * interrupt source (if it supports chaining).
++ */
++typedef struct irq_node {
++ irqreturn_t (*handler)(int, void *, struct pt_regs *);
++ unsigned long flags;
++ void *dev_id;
++ const char *devname;
++ struct irq_node *next;
++} irq_node_t;
++
++/*
++ * This structure has only 4 elements for speed reasons
++ */
++typedef struct irq_handler {
++ irqreturn_t (*handler)(int, void *, struct pt_regs *);
++ unsigned long flags;
++ void *dev_id;
++ const char *devname;
++} irq_handler_t;
++
++/* count of spurious interrupts */
++extern volatile unsigned int num_spurious;
++
++/*
++ * This function returns a new irq_node_t
++ */
++extern irq_node_t *new_irq_node(void);
++
++#endif /* _NIOS2NOMMU_IRQNODE_H_ */
+diff --git a/include/asm-nios2nommu/irq_regs.h b/include/asm-nios2nommu/irq_regs.h
+new file mode 100644
+index 0000000..3dd9c0b
+--- /dev/null
++++ b/include/asm-nios2nommu/irq_regs.h
+@@ -0,0 +1 @@
++#include <asm-generic/irq_regs.h>
+diff --git a/include/asm-nios2nommu/kdebug.h b/include/asm-nios2nommu/kdebug.h
+new file mode 100644
+index 0000000..6ece1b0
+--- /dev/null
++++ b/include/asm-nios2nommu/kdebug.h
+@@ -0,0 +1 @@
++#include <asm-generic/kdebug.h>
+diff --git a/include/asm-nios2nommu/kmap_types.h b/include/asm-nios2nommu/kmap_types.h
+new file mode 100644
+index 0000000..a26b91d
+--- /dev/null
++++ b/include/asm-nios2nommu/kmap_types.h
+@@ -0,0 +1,43 @@
++/*
++ * 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_KMAP_TYPES_H
++#define _ASM_KMAP_TYPES_H
++
++enum km_type {
++ KM_BOUNCE_READ,
++ KM_SKB_SUNRPC_DATA,
++ KM_SKB_DATA_SOFTIRQ,
++ KM_USER0,
++ KM_USER1,
++ KM_BIO_SRC_IRQ,
++ KM_BIO_DST_IRQ,
++ KM_PTE0,
++ KM_PTE1,
++ KM_IRQ0,
++ KM_IRQ1,
++ KM_SOFTIRQ0,
++ KM_SOFTIRQ1,
++ KM_TYPE_NR
++};
++
++#endif
+diff --git a/include/asm-nios2nommu/linkage.h b/include/asm-nios2nommu/linkage.h
+new file mode 100644
+index 0000000..db79297
+--- /dev/null
++++ b/include/asm-nios2nommu/linkage.h
+@@ -0,0 +1,29 @@
++/*
++ * 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_LINKAGE_H
++#define __ASM_LINKAGE_H
++
++#define __ALIGN .align 3
++#define __ALIGN_STR ".align 3"
++
++#endif
+diff --git a/include/asm-nios2nommu/linux_logo.h b/include/asm-nios2nommu/linux_logo.h
+new file mode 100644
+index 0000000..f9d38e7
+--- /dev/null
++++ b/include/asm-nios2nommu/linux_logo.h
+@@ -0