diff options
Diffstat (limited to 'toolchain')
-rw-r--r-- | toolchain/kernel-headers/Config.in | 2 | ||||
-rw-r--r-- | toolchain/kernel-headers/kernel-headers.mk | 3 | ||||
-rw-r--r-- | toolchain/kernel-headers/linux-2.6.23-nios2nommu.patch | 26567 |
3 files changed, 26570 insertions, 2 deletions
diff --git a/toolchain/kernel-headers/Config.in b/toolchain/kernel-headers/Config.in index 28618e663..15cb496aa 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 b6fe3e56c..fef5afd89 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 000000000..6e558fd66 --- /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(¤t->sighand->siglock); ++ saveset = current->blocked; ++ siginitset(¤t->blocked, mask); ++ recalc_sigpending(); ++ spin_unlock_irq(¤t->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(¤t->sighand->siglock); ++ saveset = current->blocked; ++ current->blocked = newset; ++ recalc_sigpending(); ++ spin_unlock_irq(¤t->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(¤t->sighand->siglock); ++ current->blocked = set; ++ recalc_sigpending(); ++ spin_unlock_irq(¤t->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(¤t->sighand->siglock); ++ current->blocked = set; ++ recalc_sigpending(); ++ spin_unlock_irq(¤t->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(¤t->sighand->siglock); ++ sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); ++ sigaddset(¤t->blocked,sig); ++ recalc_sigpending(); ++ spin_unlock_irq(¤t->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 = ¤t->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(¤t->mm->mmap_sem); ++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); ++ up_write(¤t->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,0 +1,953 @@ ++/* $Id: linux_logo.h,v 1.1 2006/07/05 06:20:25 gerg Exp $ ++ * include/asm-nios/linux_logo.h: This is a linux logo ++ * to be displayed on boot. ++ * ++ * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu) ++ * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) ++ * Copyright (C) 2004 Micrtronix Datacom Ltd. ++ * ++ * You can put anything here, but: ++ * LINUX_LOGO_COLORS has to be less than 224 ++ * image size has to be 80x80 ++ * values have to start from 0x20 ++ * (i.e. RGB(linux_logo_red[0], ++ * linux_logo_green[0], ++ * linux_logo_blue[0]) is color 0x20) ++ * BW image has to be 80x80 as well, with MS bit ++ * on the left ++ * Serial_console ascii image can be any size, ++ * but should contain %s to display the version ++ * ++ * 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/init.h> ++#include <linux/version.h> ++ ++#define linux_logo_banner "Linux/NIOS2 version " UTS_RELEASE ++ ++#define __HAVE_ARCH_LINUX_LOGO ++#define __HAVE_ARCH_LINUX_LOGO16 ++ ++#define LINUX_LOGO_COLORS 221 ++ ++#ifdef INCLUDE_LINUX_LOGO_DATA ++ ++unsigned char linux_logo_red[] __initdata = { ++ 0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22, ++ 0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56, ++ 0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65, ++ 0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6, ++ 0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6, ++ 0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7, ++ 0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79, ++ 0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7, ++ 0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8, ++ 0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6, ++ 0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee, ++ 0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c, ++ 0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e, ++ 0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c, ++ 0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8, ++ 0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xfe, ++ 0xf6, 0xec, 0xfe, 0xd2, 0xea, 0xf5, 0xf2, 0xf2, ++ 0xe9, 0xee, 0xf6, 0xf2, 0xee, 0xf6, 0xda, 0xd4, ++ 0xfa, 0xca, 0xf2, 0xf6, 0xfe, 0xf2, 0xda, 0xe4, ++ 0xf6, 0xdd, 0xf2, 0xee, 0xfa, 0xf0, 0x12, 0x4a, ++ 0xd6, 0xf2, 0x8e, 0xf2, 0xf6, 0xf6, 0xb5, 0xf1, ++ 0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x16, 0x9a, ++ 0x2e, 0xd2, 0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62, ++ 0xda, 0xee, 0xd6, 0xa3, 0x74, 0xa7, 0xa2, 0xe0, ++ 0xae, 0xbe, 0xce, 0xe2, 0xa3, 0x8e, 0x6d, 0x8e, ++ 0x32, 0xaf, 0x50, 0x9e, 0x5b, 0x8a, 0x98, 0x82, ++ 0x7a, 0x82, 0x56, 0x7c, 0x8a, 0x56, 0x5e, 0x86, ++ 0x6a, 0x52, 0x59, 0x64, 0x5e, ++}; ++ ++unsigned char linux_logo_green[] __initdata = { ++ 0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22, ++ 0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56, ++ 0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65, ++ 0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6, ++ 0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6, ++ 0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7, ++ 0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c, ++ 0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae, ++ 0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8, ++ 0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda, ++ 0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca, ++ 0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76, ++ 0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46, ++ 0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b, ++ 0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c, ++ 0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xfa, ++ 0xea, 0xd7, 0xf6, 0xbc, 0xda, 0xde, 0xda, 0xe6, ++ 0xca, 0xd8, 0xea, 0xe0, 0xcc, 0xf2, 0xce, 0xb2, ++ 0xee, 0xa2, 0xd6, 0xe6, 0xf6, 0xd7, 0xc5, 0xb8, ++ 0xc6, 0xb9, 0xce, 0xde, 0xce, 0xc6, 0x0e, 0x36, ++ 0xae, 0xbe, 0x86, 0xba, 0xbe, 0xe6, 0x8e, 0xc4, ++ 0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x12, 0x7a, ++ 0x20, 0xc6, 0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46, ++ 0xce, 0xd6, 0xa6, 0x6e, 0x51, 0x72, 0x92, 0xa6, ++ 0x87, 0x96, 0xa2, 0xd6, 0x85, 0x7a, 0x6a, 0x6e, ++ 0x22, 0x76, 0x36, 0x76, 0x3c, 0x6e, 0x63, 0x53, ++ 0x66, 0x62, 0x42, 0x50, 0x56, 0x42, 0x56, 0x56, ++ 0x56, 0x3e, 0x51, 0x52, 0x56, ++}; ++ ++unsigned char linux_logo_blue[] __initdata = { ++ 0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22, ++ 0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56, ++ 0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65, ++ 0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6, ++ 0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6, ++ 0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7, ++ 0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08, ++ 0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f, ++ 0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e, ++ 0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c, ++ 0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f, ++ 0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a, ++ 0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e, ++ 0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b, ++ 0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c, ++ 0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xea, ++ 0xb6, 0x7c, 0xda, 0x8e, 0xa6, 0x87, 0x66, 0xb6, ++ 0x81, 0x6a, 0xc6, 0x9a, 0x5b, 0xd2, 0xb6, 0x6a, ++ 0xca, 0x45, 0x92, 0xb2, 0xca, 0x52, 0x8a, 0x3e, ++ 0x2e, 0x66, 0x66, 0xae, 0x3e, 0x47, 0x06, 0x0e, ++ 0x52, 0x36, 0x6a, 0x0e, 0x0e, 0xbe, 0x2c, 0x0e, ++ 0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x06, 0x2e, ++ 0x06, 0x9e, 0x4e, 0x36, 0x06, 0x58, 0x24, 0x06, ++ 0x9e, 0xae, 0x3a, 0x08, 0x08, 0x07, 0x5e, 0x0a, ++ 0x32, 0x2e, 0x2a, 0xb2, 0x43, 0x48, 0x5f, 0x2e, ++ 0x06, 0x06, 0x07, 0x24, 0x06, 0x32, 0x06, 0x06, ++ 0x46, 0x2e, 0x22, 0x06, 0x06, 0x1e, 0x4c, 0x06, ++ 0x3a, 0x22, 0x42, 0x34, 0x42, ++}; ++ ++unsigned char linux_logo[] __initdata = { ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, ++ 0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, ++ 0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d, ++ 0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22, ++ 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, ++ 0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24, ++ 0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25, ++ 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25, ++ 0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c, ++ 0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33, ++ 0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31, ++ 0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34, ++ 0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36, ++ 0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22, ++ 0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25, ++ 0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22, ++ 0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36, ++ 0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36, ++ 0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36, ++ 0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36, ++ 0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36, ++ 0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21, ++ 0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23, ++ 0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21, ++ 0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21, ++ 0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b, ++ 0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26, ++ 0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d, ++ 0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32, ++ 0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a, ++ 0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b, ++ 0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37, ++ 0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58, ++ 0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21, ++ 0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35, ++ 0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, ++ 0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22, ++ 0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67, ++ 0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36, ++ 0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e, ++ 0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73, ++ 0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78, ++ 0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21, ++ 0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79, ++ 0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c, ++ 0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28, ++ 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24, ++ 0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71, ++ 0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36, ++ 0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26, ++ 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21, ++ 0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89, ++ 0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36, ++ 0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32, ++ 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21, ++ 0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e, ++ 0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23, ++ 0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31, ++ 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22, ++ 0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63, ++ 0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c, ++ 0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51, ++ 0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21, ++ 0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97, ++ 0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98, ++ 0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, ++ 0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32, ++ 0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50, ++ 0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48, ++ 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23, ++ 0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98, ++ 0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50, ++ 0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, ++ 0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, ++ 0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b, ++ 0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b, ++ 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, ++ 0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, ++ 0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48, ++ 0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, ++ 0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25, ++ 0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, ++ 0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33, ++ 0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, ++ 0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34, ++ 0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48, ++ 0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52, ++ 0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23, ++ 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c, ++ 0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c, ++ 0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b, ++ 0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93, ++ 0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26, ++ 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28, ++ 0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99, ++ 0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48, ++ 0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93, ++ 0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32, ++ 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36, ++ 0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48, ++ 0x48, 0x48, 0x48, 0x9b, 0x99, 0x9f, 0x52, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47, ++ 0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30, ++ 0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, ++ 0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36, ++ 0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48, ++ 0x47, 0x9f, 0x48, 0x48, 0x48, 0xa0, 0xa1, 0xa2, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, ++ 0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36, ++ 0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f, ++ 0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36, ++ 0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48, ++ 0xa3, 0xa4, 0x48, 0x48, 0x9f, 0xa5, 0xa6, 0x9f, ++ 0x48, 0x48, 0x48, 0xa2, 0xa7, 0x47, 0x48, 0x48, ++ 0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23, ++ 0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d, ++ 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25, ++ 0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x48, ++ 0xa8, 0xa1, 0x48, 0x48, 0x9f, 0xa9, 0xa6, 0x9f, ++ 0x48, 0x48, 0xaa, 0xa1, 0xa5, 0x9f, 0x48, 0x48, ++ 0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30, ++ 0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32, ++ 0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a, ++ 0x36, 0x24, 0x4f, 0x48, 0x52, 0x52, 0x48, 0x48, ++ 0xab, 0xac, 0xa0, 0x48, 0xad, 0xa6, 0xa6, 0x9f, ++ 0x48, 0xa2, 0xa9, 0xa6, 0xa2, 0x48, 0x48, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x47, 0x32, 0x30, ++ 0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21, ++ 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25, ++ 0x36, 0x3a, 0x48, 0x48, 0xae, 0xaf, 0x48, 0x48, ++ 0xad, 0xac, 0xa1, 0x9f, 0xa2, 0xa9, 0xa9, 0xa2, ++ 0x48, 0xab, 0x78, 0xa7, 0x48, 0x48, 0x48, 0x48, ++ 0x9f, 0x48, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21, ++ 0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36, ++ 0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21, ++ 0x23, 0x43, 0x48, 0x48, 0xb0, 0xb1, 0xb2, 0x9f, ++ 0x48, 0xb3, 0xa5, 0xb3, 0xab, 0xa9, 0xa9, 0xb3, ++ 0xb4, 0xa9, 0xb5, 0xb0, 0x48, 0x48, 0xa0, 0xa5, ++ 0xa1, 0xad, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36, ++ 0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36, ++ 0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36, ++ 0x2e, 0x9b, 0x48, 0x48, 0x48, 0xb6, 0xb7, 0xa4, ++ 0xa2, 0xa7, 0xb5, 0x78, 0x6f, 0x6f, 0x6e, 0x6f, ++ 0xa9, 0xb5, 0xab, 0x48, 0x9f, 0xab, 0xa9, 0xa1, ++ 0xaa, 0x48, 0x48, 0x48, 0x48, 0x48, 0x98, 0x36, ++ 0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36, ++ 0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36, ++ 0x54, 0x48, 0x48, 0x48, 0x48, 0xa2, 0xa8, 0xa1, ++ 0xa5, 0xa6, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, ++ 0x6f, 0x78, 0xa5, 0xa0, 0xa0, 0x78, 0xa6, 0xa2, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36, ++ 0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36, ++ 0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, ++ 0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21, ++ 0x43, 0x48, 0x4b, 0xa2, 0x9f, 0x48, 0xa2, 0xa1, ++ 0xb8, 0x6e, 0x6e, 0xb5, 0x78, 0x6f, 0x78, 0x78, ++ 0x6e, 0x6f, 0x78, 0xb5, 0xa6, 0xa1, 0xa0, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4b, 0x21, ++ 0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, ++ 0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25, ++ 0x52, 0x48, 0xa3, 0xb1, 0xb6, 0xb3, 0xaa, 0xac, ++ 0x68, 0x68, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, ++ 0x78, 0x6f, 0x6f, 0xb5, 0xa6, 0xb4, 0x48, 0x9f, ++ 0xb4, 0xb4, 0xa2, 0x9f, 0x48, 0x48, 0x4f, 0x21, ++ 0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, ++ 0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a, ++ 0x47, 0x48, 0xa2, 0xb6, 0xaf, 0xb9, 0xba, 0x68, ++ 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x78, ++ 0x6f, 0x6f, 0xa6, 0x6f, 0xb5, 0xa0, 0xaa, 0xa6, ++ 0xa6, 0xa9, 0xb2, 0xb3, 0x48, 0x48, 0x4c, 0x22, ++ 0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28, ++ 0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39, ++ 0x9b, 0x48, 0x48, 0x48, 0xb0, 0xb0, 0xba, 0xb8, ++ 0x68, 0x68, 0x69, 0x78, 0x6f, 0xb5, 0x6f, 0xb5, ++ 0x78, 0x78, 0x78, 0x78, 0x78, 0xa5, 0xbb, 0xa9, ++ 0xa5, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x23, ++ 0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28, ++ 0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31, ++ 0x9b, 0x48, 0x48, 0x48, 0x48, 0x9f, 0xac, 0x68, ++ 0xbc, 0x6e, 0x6e, 0x6e, 0xb5, 0x6f, 0x6e, 0x6f, ++ 0x6f, 0x78, 0x78, 0xb5, 0xb5, 0xa5, 0x9f, 0x9f, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x46, 0x22, ++ 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, ++ 0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d, ++ 0x9b, 0x48, 0x48, 0xb0, 0xaa, 0xb3, 0xbd, 0xb8, ++ 0xb8, 0x68, 0x6e, 0x6e, 0xb5, 0x6f, 0x78, 0x6e, ++ 0x78, 0x6f, 0x78, 0x78, 0xb5, 0xa9, 0xa2, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36, ++ 0x24, 0x27, 0xbe, 0x24, 0x25, 0x28, 0x21, 0x36, ++ 0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25, ++ 0x39, 0x4d, 0xbf, 0x84, 0x81, 0x57, 0x21, 0x39, ++ 0x52, 0x48, 0x48, 0x62, 0xb1, 0xc0, 0xc1, 0xc1, ++ 0xb8, 0xb8, 0x68, 0xbc, 0x6e, 0x6e, 0x6e, 0x78, ++ 0x78, 0x78, 0x78, 0x6e, 0x78, 0xa9, 0xa0, 0xab, ++ 0xb3, 0xa2, 0x48, 0x48, 0x48, 0x48, 0x53, 0x28, ++ 0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30, ++ 0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30, ++ 0x2d, 0xc2, 0x7a, 0xc3, 0xc4, 0xc4, 0x7f, 0x22, ++ 0x51, 0x52, 0x48, 0x48, 0xb0, 0xaa, 0xa8, 0xbd, ++ 0x68, 0xb8, 0xb8, 0x68, 0x68, 0x6e, 0x6e, 0x6f, ++ 0x6e, 0x6e, 0xb5, 0x6e, 0x78, 0xab, 0xab, 0xb5, ++ 0x78, 0xa6, 0xb3, 0xc5, 0xac, 0xac, 0xc6, 0x61, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32, ++ 0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31, ++ 0x4d, 0x91, 0x5b, 0xc3, 0xc4, 0xc4, 0xc4, 0x5a, ++ 0x21, 0x2e, 0x46, 0x48, 0x48, 0x48, 0xb0, 0x64, ++ 0xc1, 0xb8, 0xb8, 0xb8, 0x68, 0x71, 0x6e, 0x6e, ++ 0x6f, 0x71, 0x6f, 0x6f, 0xa6, 0xa0, 0x9f, 0xb4, ++ 0xb4, 0xa0, 0xa1, 0xb7, 0xc7, 0x69, 0x66, 0xc8, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25, ++ 0x83, 0xc9, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a, ++ 0x60, 0x85, 0xca, 0xcb, 0xc4, 0xc4, 0xc4, 0x82, ++ 0x86, 0x36, 0x32, 0x3f, 0xa2, 0xa4, 0xa8, 0xa9, ++ 0xb8, 0xb8, 0xb8, 0xb8, 0x68, 0x6e, 0x6e, 0x6e, ++ 0x6e, 0x71, 0x6f, 0x71, 0xa6, 0xb4, 0x9f, 0x9f, ++ 0x48, 0x48, 0x48, 0xcc, 0xc3, 0xc7, 0xcd, 0xce, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57, ++ 0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x23, 0x30, 0x31, 0xcf, 0x91, 0x7e, 0x90, 0x90, ++ 0x8b, 0x5b, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0x5d, 0xd0, 0x36, 0x24, 0xd1, 0xb1, 0xaf, 0xaa, ++ 0xba, 0xb8, 0x68, 0x68, 0x68, 0x71, 0x6e, 0x6e, ++ 0x6e, 0x6f, 0x6e, 0x78, 0xa1, 0xa9, 0xa1, 0xb0, ++ 0x9f, 0x9b, 0x99, 0xcc, 0x64, 0x5c, 0x8b, 0xd0, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d, ++ 0x82, 0x5c, 0xd2, 0x2a, 0x23, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, ++ 0x24, 0x2b, 0xcf, 0x8b, 0x5b, 0x76, 0x5b, 0x5b, ++ 0x7b, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc7, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x99, 0x48, ++ 0xa2, 0xa8, 0xb7, 0xc1, 0xb8, 0x68, 0x68, 0xbc, ++ 0x68, 0x6e, 0xb5, 0xb4, 0xb4, 0xab, 0xb5, 0xa1, ++ 0xb0, 0x4f, 0x3f, 0xd3, 0x7b, 0x7b, 0x85, 0x80, ++ 0xbe, 0x36, 0x36, 0x36, 0x21, 0xd4, 0x7e, 0x7b, ++ 0x64, 0x64, 0xd5, 0x35, 0x24, 0x21, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, ++ 0x26, 0x31, 0xd6, 0x5b, 0x64, 0xc3, 0xc3, 0xcb, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0x66, 0xd7, 0x36, 0x36, 0x36, 0x2c, 0x4b, ++ 0xd8, 0xd9, 0xb3, 0xa8, 0xbd, 0xbd, 0xbd, 0xbd, ++ 0xa9, 0xab, 0xb3, 0xa5, 0xa2, 0x9f, 0xa2, 0xa1, ++ 0x6a, 0x9a, 0x3f, 0xda, 0x76, 0x76, 0x7a, 0x63, ++ 0xdb, 0xdc, 0x86, 0xdc, 0xdd, 0x90, 0x5b, 0x64, ++ 0xc3, 0xc3, 0xde, 0x2d, 0x27, 0x23, 0x21, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, ++ 0x26, 0x2d, 0x91, 0x5b, 0x64, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc7, 0x83, 0xce, 0x36, 0x36, 0x36, 0x30, ++ 0xb1, 0xd9, 0x48, 0xa1, 0xb2, 0xb0, 0xb0, 0xb3, ++ 0xa2, 0x48, 0xa7, 0xbd, 0xa9, 0xa2, 0x48, 0x9f, ++ 0xaa, 0x9a, 0x3f, 0xb1, 0x5b, 0x7b, 0xdf, 0x85, ++ 0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xc3, 0xc4, ++ 0xc4, 0xcb, 0x5d, 0xd5, 0x39, 0x26, 0x23, 0x21, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, ++ 0x26, 0x2d, 0xe0, 0xdf, 0x64, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc7, 0x88, 0x36, 0x36, 0x36, 0x36, ++ 0x2d, 0x9b, 0x48, 0xb9, 0xaf, 0xa2, 0xa2, 0xb9, ++ 0xa8, 0x9f, 0x48, 0xa7, 0xb7, 0xd9, 0x48, 0x48, ++ 0x9b, 0x45, 0x3f, 0xe1, 0x6d, 0x7b, 0xca, 0xdf, ++ 0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc3, 0xe2, 0x37, 0x35, 0x26, 0x23, ++ 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, ++ 0x26, 0x2e, 0xe0, 0x7a, 0x7b, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc7, 0x72, 0x73, 0x36, 0x36, 0x36, ++ 0x24, 0x52, 0x48, 0xa3, 0xaf, 0x9f, 0x48, 0xb6, ++ 0xaf, 0xa2, 0x48, 0x9f, 0xe3, 0xd8, 0x48, 0x48, ++ 0x48, 0x46, 0x42, 0xd6, 0x7a, 0x7b, 0x64, 0x7b, ++ 0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xc3, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xcb, 0x64, 0xe2, 0x4d, 0x2c, 0x27, ++ 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, ++ 0x25, 0x31, 0xe4, 0x8b, 0x7b, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc7, 0x89, 0xbe, 0x36, 0x36, ++ 0x32, 0x47, 0x48, 0x4f, 0xa0, 0x48, 0x48, 0xe3, ++ 0x92, 0x9f, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48, ++ 0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xc3, 0xcb, ++ 0xc3, 0x64, 0x64, 0xc3, 0xc3, 0xcb, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x5d, 0xe5, 0x2c, ++ 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, ++ 0x25, 0x31, 0xe4, 0x85, 0x7b, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0x66, 0x57, 0x27, 0x4d, ++ 0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, ++ 0x99, 0x34, 0xbe, 0xdb, 0x7a, 0x7b, 0xc3, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0xe4, ++ 0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, ++ 0x26, 0x2d, 0xe4, 0x85, 0x7b, 0xcb, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc7, 0x5f, 0x92, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44, ++ 0x35, 0x36, 0xce, 0xdd, 0x7a, 0x7b, 0xcb, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0xc3, 0xe1, ++ 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, ++ 0x30, 0x2f, 0xd6, 0x8b, 0x7b, 0xcb, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0x66, 0x89, 0x45, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25, ++ 0x36, 0x36, 0x61, 0xdb, 0x6d, 0x64, 0xcb, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x7b, 0xdf, 0xe5, ++ 0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28, ++ 0x33, 0xe6, 0x63, 0xdf, 0xc3, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x72, 0x81, 0xe7, ++ 0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, ++ 0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36, ++ 0x36, 0x36, 0xe8, 0x8f, 0x6d, 0x64, 0xcb, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc3, 0xca, 0x8b, 0xcf, 0x2c, ++ 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, ++ 0x35, 0x96, 0x75, 0xca, 0xc3, 0xcb, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x7b, 0x81, 0xdb, ++ 0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b, ++ 0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x73, 0xdb, 0x7a, 0x7b, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0x64, 0x76, 0x7a, 0x91, 0xd5, 0x31, 0x30, ++ 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, ++ 0x39, 0x97, 0x75, 0xdf, 0x7b, 0x64, 0xc3, 0xc3, ++ 0xcb, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0x7b, 0x7a, 0xe9, ++ 0xea, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30, ++ 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x21, 0xea, 0xdd, 0x8b, 0x7b, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x64, 0x64, ++ 0x76, 0x85, 0xe0, 0xd5, 0x34, 0x2b, 0x27, 0x28, ++ 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28, ++ 0x33, 0xeb, 0x63, 0x7e, 0x7a, 0x6d, 0xdf, 0x5b, ++ 0x76, 0x7b, 0x64, 0x64, 0xc3, 0xcb, 0xc4, 0xc4, ++ 0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x76, 0x85, 0xdb, ++ 0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x21, 0xec, 0xdd, 0x75, 0x76, 0xc3, 0xc4, ++ 0xc4, 0xc4, 0xcb, 0xc3, 0x64, 0x76, 0xdf, 0x8b, ++ 0xd6, 0xd5, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, ++ 0x27, 0x31, 0xed, 0xeb, 0xdd, 0x74, 0x63, 0x90, ++ 0x7e, 0x75, 0x8b, 0x6d, 0xdf, 0x76, 0x64, 0xc3, ++ 0xcb, 0xcb, 0xcb, 0xcb, 0x64, 0x7a, 0x84, 0xee, ++ 0x79, 0xbe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, ++ 0x36, 0x21, 0xea, 0xee, 0x63, 0x6d, 0x7b, 0x64, ++ 0xcb, 0xc3, 0x64, 0x7b, 0xdf, 0x75, 0x63, 0x96, ++ 0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, ++ 0x28, 0x27, 0x35, 0x2d, 0x41, 0xd5, 0xe7, 0x8f, ++ 0xdb, 0xdd, 0xe9, 0x74, 0x84, 0x90, 0x85, 0x6d, ++ 0x5b, 0x7b, 0x7b, 0xca, 0x6d, 0x90, 0xdb, 0xef, ++ 0xec, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30, ++ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36, ++ 0x36, 0x21, 0xd4, 0x80, 0xe9, 0x7e, 0x6d, 0x76, ++ 0xca, 0x76, 0x6d, 0x85, 0x63, 0xdb, 0xd5, 0x34, ++ 0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f, ++ 0x41, 0xf0, 0xf1, 0x6c, 0x80, 0xee, 0xdb, 0x74, ++ 0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xef, 0x79, ++ 0xe8, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d, ++ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38, ++ 0x4d, 0x37, 0xf2, 0xf3, 0x8f, 0x74, 0x63, 0x7e, ++ 0x75, 0x7e, 0x63, 0xe9, 0x88, 0xe6, 0x31, 0x2a, ++ 0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30, ++ 0x33, 0x39, 0x2e, 0x51, 0x41, 0xd2, 0x6c, 0xf3, ++ 0x80, 0xee, 0xee, 0xee, 0xf4, 0xf3, 0xd7, 0xf5, ++ 0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27, ++ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a, ++ 0x2b, 0x34, 0xf6, 0xec, 0xf7, 0x8f, 0xdd, 0xe9, ++ 0xe9, 0xdd, 0xee, 0x6c, 0x41, 0x39, 0x27, 0x28, ++ 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, ++ 0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41, ++ 0xf8, 0xd7, 0x79, 0x79, 0x79, 0xec, 0xf9, 0x51, ++ 0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22, ++ 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23, ++ 0x24, 0x2a, 0x31, 0xfa, 0xea, 0x79, 0xf3, 0x80, ++ 0xf7, 0xdc, 0xfb, 0x2f, 0x35, 0x26, 0x23, 0x21, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b, ++ 0x31, 0x2f, 0xf6, 0xfa, 0xfa, 0x2f, 0x2e, 0x33, ++ 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x21, 0x28, 0x27, 0x35, 0x34, 0xfa, 0xfa, 0xfa, ++ 0xfc, 0xf6, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28, ++ 0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28, ++ 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35, ++ 0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, ++ 0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24, ++ 0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, ++}; ++ ++unsigned char linux_logo16[1]; ++ ++#endif /* INCLUDE_LINUX_LOGO_DATA */ ++ ++#include <linux/linux_logo.h> ++ +diff --git a/include/asm-nios2nommu/local.h b/include/asm-nios2nommu/local.h +new file mode 100644 +index 0000000..5ed7d1c +--- /dev/null ++++ b/include/asm-nios2nommu/local.h +@@ -0,0 +1,28 @@ ++/* ++ * 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_LOCAL_H ++#define __NIOS2NOMMU_LOCAL_H ++ ++#include <asm-generic/local.h> ++ ++#endif /* __NIOS2NOMMU_LOCAL_H */ +diff --git a/include/asm-nios2nommu/mc146818rtc.h b/include/asm-nios2nommu/mc146818rtc.h +new file mode 100644 +index 0000000..3492fc0 +--- /dev/null ++++ b/include/asm-nios2nommu/mc146818rtc.h +@@ -0,0 +1,29 @@ ++/* ++ * Machine dependent access functions for RTC registers. ++ * ++ * 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_MC146818RTC_H ++#define _NIOS2_MC146818RTC_H ++ ++/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */ ++ ++#endif /* _NIOS2_MC146818RTC_H */ +diff --git a/include/asm-nios2nommu/mman.h b/include/asm-nios2nommu/mman.h +new file mode 100644 +index 0000000..516ab26 +--- /dev/null ++++ b/include/asm-nios2nommu/mman.h +@@ -0,0 +1,68 @@ ++/* ++ * Copied from the m68k port. ++ * ++ * Copyright (C) 2004, Microtronix Datacom Ltd. ++ * ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or ++ * NON INFRINGEMENT. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++#ifndef __NIOS2_MMAN_H__ ++#define __NIOS2_MMAN_H__ ++ ++#define PROT_READ 0x1 /* page can be read */ ++#define PROT_WRITE 0x2 /* page can be written */ ++#define PROT_EXEC 0x4 /* page can be executed */ ++#define PROT_SEM 0x8 /* page may be used for atomic ops */ ++#define PROT_NONE 0x0 /* page can not be accessed */ ++#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ ++#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ ++ ++#define MAP_SHARED 0x01 /* Share changes */ ++#define MAP_PRIVATE 0x02 /* Changes are private */ ++#define MAP_TYPE 0x0f /* Mask for type of mapping */ ++#define MAP_FIXED 0x10 /* Interpret addr exactly */ ++#define MAP_ANONYMOUS 0x20 /* don't use a file */ ++ ++#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ ++#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ ++#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ ++#define MAP_LOCKED 0x2000 /* pages are locked */ ++#define MAP_NORESERVE 0x4000 /* don't check for reservations */ ++#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ ++#define MAP_NONBLOCK 0x10000 /* do not block on IO */ ++ ++#define MS_ASYNC 1 /* sync memory asynchronously */ ++#define MS_INVALIDATE 2 /* invalidate the caches */ ++#define MS_SYNC 4 /* synchronous memory sync */ ++ ++#define MCL_CURRENT 1 /* lock all current mappings */ ++#define MCL_FUTURE 2 /* lock all future mappings */ ++ ++#define MADV_NORMAL 0x0 /* default page-in behavior */ ++#define MADV_RANDOM 0x1 /* page-in minimum required */ ++#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ ++#define MADV_WILLNEED 0x3 /* pre-fault pages */ ++#define MADV_DONTNEED 0x4 /* discard these pages */ ++ ++/* compatibility flags */ ++#define MAP_ANON MAP_ANONYMOUS ++#define MAP_FILE 0 ++ ++#endif /* __NIOS2_MMAN_H__ */ ++ +diff --git a/include/asm-nios2nommu/mmu.h b/include/asm-nios2nommu/mmu.h +new file mode 100644 +index 0000000..b6e579d +--- /dev/null ++++ b/include/asm-nios2nommu/mmu.h +@@ -0,0 +1,36 @@ ++/* ++ * ++ * Taken from the m68knommu. ++ * ++ * Copyright (C) 2004, Microtronix Datacom Ltd. ++ * ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or ++ * NON INFRINGEMENT. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++#ifndef __NIOS2NOMMU_MMU_H ++#define __NIOS2NOMMU_MMU_H ++ ++/* Copyright (C) 2002, David McCullough <davidm@snapgear.com> */ ++ ++typedef struct { ++ struct vm_list_struct *vmlist; ++ unsigned long end_brk; ++} mm_context_t; ++ ++#endif /* __NIOS2NOMMU_MMU_H */ +diff --git a/include/asm-nios2nommu/mmu_context.h b/include/asm-nios2nommu/mmu_context.h +new file mode 100644 +index 0000000..795cd09 +--- /dev/null ++++ b/include/asm-nios2nommu/mmu_context.h +@@ -0,0 +1,57 @@ ++/* ++ * ++ * Taken from the m68knommu. ++ * ++ * Copyright (C) 2004, Microtronix Datacom Ltd. ++ * ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or ++ * NON INFRINGEMENT. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++#ifndef __NIOS2NOMMU_MMU_CONTEXT_H ++#define __NIOS2NOMMU_MMU_CONTEXT_H ++ ++#include <asm/setup.h> ++#include <asm/page.h> ++#include <asm/pgalloc.h> ++ ++static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) ++{ ++} ++ ++extern inline int ++init_new_context(struct task_struct *tsk, struct mm_struct *mm) ++{ ++ // mm->context = virt_to_phys(mm->pgd); ++ return(0); ++} ++ ++#define destroy_context(mm) do { } while(0) ++ ++static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) ++{ ++} ++ ++#define deactivate_mm(tsk,mm) do { } while (0) ++ ++extern inline void activate_mm(struct mm_struct *prev_mm, ++ struct mm_struct *next_mm) ++{ ++} ++ ++#endif +diff --git a/include/asm-nios2nommu/module.h b/include/asm-nios2nommu/module.h +new file mode 100644 +index 0000000..864f335 +--- /dev/null ++++ b/include/asm-nios2nommu/module.h +@@ -0,0 +1,36 @@ ++#ifndef _NIOS2_MODULE_H ++#define _NIOS2_MODULE_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/module.h ++ * ++ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al ++ * ++ * Copyright (C) 2004 Microtronix Datacom Ltd ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * Jan/20/2004 dgt NiosII ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++struct mod_arch_specific ++{ ++}; ++ ++#define Elf_Shdr Elf32_Shdr ++#define Elf_Sym Elf32_Sym ++#define Elf_Ehdr Elf32_Ehdr ++ ++#endif /* _NIOS_MODULE_H */ +diff --git a/include/asm-nios2nommu/msgbuf.h b/include/asm-nios2nommu/msgbuf.h +new file mode 100644 +index 0000000..4d090f7 +--- /dev/null ++++ b/include/asm-nios2nommu/msgbuf.h +@@ -0,0 +1,56 @@ ++/* ++ * Taken from the m68k. ++ * ++ * Copyright (C) 2004, Microtronix Datacom Ltd. ++ * ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or ++ * NON INFRINGEMENT. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++#ifndef _NIOS2_MSGBUF_H ++#define _NIOS2_MSGBUF_H ++ ++/* ++ * The msqid64_ds structure for nios2 architecture. ++ * Note extra padding because this structure is passed back and forth ++ * between kernel and user space. ++ * ++ * Pad space is left for: ++ * - 64-bit time_t to solve y2038 problem ++ * - 2 miscellaneous 32-bit values ++ */ ++ ++struct msqid64_ds { ++ struct ipc64_perm msg_perm; ++ __kernel_time_t msg_stime; /* last msgsnd time */ ++ unsigned long __unused1; ++ __kernel_time_t msg_rtime; /* last msgrcv time */ ++ unsigned long __unused2; ++ __kernel_time_t msg_ctime; /* last change time */ ++ unsigned long __unused3; ++ unsigned long msg_cbytes; /* current number of bytes on queue */ ++ unsigned long msg_qnum; /* number of messages in queue */ ++ unsigned long msg_qbytes; /* max number of bytes on queue */ ++ __kernel_pid_t msg_lspid; /* pid of last msgsnd */ ++ __kernel_pid_t msg_lrpid; /* last receive pid */ ++ unsigned long __unused4; ++ unsigned long __unused5; ++}; ++ ++#endif /* _NIOS2_MSGBUF_H */ ++ +diff --git a/include/asm-nios2nommu/mutex.h b/include/asm-nios2nommu/mutex.h +new file mode 100644 +index 0000000..458c1f7 +--- /dev/null ++++ b/include/asm-nios2nommu/mutex.h +@@ -0,0 +1,9 @@ ++/* ++ * Pull in the generic implementation for the mutex fastpath. ++ * ++ * TODO: implement optimized primitives instead, or leave the generic ++ * implementation in place, or pick the atomic_xchg() based generic ++ * implementation. (see asm-generic/mutex-xchg.h for details) ++ */ ++ ++#include <asm-generic/mutex-dec.h> +diff --git a/include/asm-nios2nommu/namei.h b/include/asm-nios2nommu/namei.h +new file mode 100644 +index 0000000..d925c4e +--- /dev/null ++++ b/include/asm-nios2nommu/namei.h +@@ -0,0 +1,36 @@ ++/* ++ * linux/include/asm-nios/namei.h ++ * Moved from m68k version ++ * Included from linux/fs/namei.c ++ * ++ * 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_NAMEI_H ++#define __NIOS2_NAMEI_H ++ ++/* This dummy routine maybe changed to something useful ++ * for /usr/gnemul/ emulation stuff. ++ * Look at asm-sparc/namei.h for details. ++ */ ++ ++#define __emul_prefix() NULL ++ ++#endif +diff --git a/include/asm-nios2nommu/ndma.h b/include/asm-nios2nommu/ndma.h +new file mode 100644 +index 0000000..6b4604d +--- /dev/null ++++ b/include/asm-nios2nommu/ndma.h +@@ -0,0 +1,64 @@ ++#ifndef __NDMA_H__ ++ #define __NDMA_H__ ++ ++ #ifndef __ASSEMBLY__ ++ ++// DMA Registers ++typedef volatile struct ++{ ++ int np_dmastatus; // status register ++ int np_dmareadaddress; // read address ++ int np_dmawriteaddress; // write address ++ int np_dmalength; // length in bytes ++ int np_dmareserved1; // reserved ++ int np_dmareserved2; // reserved ++ int np_dmacontrol; // control register ++ int np_dmareserved3; // control register alternate ++} np_dma; ++ ++// DMA Register Bits ++enum ++{ ++ np_dmacontrol_byte_bit = 0, // Byte transaction ++ np_dmacontrol_hw_bit = 1, // Half-word transaction ++ np_dmacontrol_word_bit = 2, // Word transaction ++ np_dmacontrol_go_bit = 3, // enable execution ++ np_dmacontrol_i_en_bit = 4, // enable interrupt ++ np_dmacontrol_reen_bit = 5, // Enable read end-of-packet ++ np_dmacontrol_ween_bit = 6, // Enable write end-of-packet ++ np_dmacontrol_leen_bit = 7, // Enable length=0 transaction end ++ np_dmacontrol_rcon_bit = 8, // Read from a fixed address ++ np_dmacontrol_wcon_bit = 9, // Write to a fixed address ++ np_dmacontrol_doubleword_bit = 10, // Double-word transaction ++ np_dmacontrol_quadword_bit = 11, // Quad-word transaction ++ ++ np_dmastatus_done_bit = 0, // 1 when done. Status write clears. ++ np_dmastatus_busy_bit = 1, // 1 when busy. ++ np_dmastatus_reop_bit = 2, // read-eop received ++ np_dmastatus_weop_bit = 3, // write-eop received ++ np_dmastatus_len_bit = 4, // requested length transacted ++ ++ np_dmacontrol_byte_mask = (1 << 0), // Byte transaction ++ np_dmacontrol_hw_mask = (1 << 1), // Half-word transaction ++ np_dmacontrol_word_mask = (1 << 2), // Word transaction ++ np_dmacontrol_go_mask = (1 << 3), // enable execution ++ np_dmacontrol_i_en_mask = (1 << 4), // enable interrupt ++ np_dmacontrol_reen_mask = (1 << 5), // Enable read end-of-packet ++ np_dmacontrol_ween_mask = (1 << 6), // Enable write end-of-packet ++ np_dmacontrol_leen_mask = (1 << 7), // Enable length=0 transaction end ++ np_dmacontrol_rcon_mask = (1 << 8), // Read from a fixed address ++ np_dmacontrol_wcon_mask = (1 << 9), // Write to a fixed address ++ np_dmacontrol_doubleword_mask = (1 << 10), // Double-word transaction ++ np_dmacontrol_quadword_mask = (1 << 11), // Quad-word transaction ++ ++ np_dmastatus_done_mask = (1 << 0), // 1 when done. Status write clears. ++ np_dmastatus_busy_mask = (1 << 1), // 1 when busy. ++ np_dmastatus_reop_mask = (1 << 2), // read-eop received ++ np_dmastatus_weop_mask = (1 << 3), // write-eop received ++ np_dmastatus_len_mask = (1 << 4), // requested length transacted ++}; ++ ++ #endif /* __ASSEMBLY__ */ ++ ++#endif ++/* End of File */ +diff --git a/include/asm-nios2nommu/nios.h b/include/asm-nios2nommu/nios.h +new file mode 100644 +index 0000000..df17672 +--- /dev/null ++++ b/include/asm-nios2nommu/nios.h +@@ -0,0 +1,7 @@ ++#ifndef __NIOS_H__ ++#define __NIOS_H__ ++ ++#include <nios2_system.h> ++ ++#endif ++ +diff --git a/include/asm-nios2nommu/page.h b/include/asm-nios2nommu/page.h +new file mode 100644 +index 0000000..764e73c +--- /dev/null ++++ b/include/asm-nios2nommu/page.h +@@ -0,0 +1,124 @@ ++/* ++ * 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_PAGE_H ++#define _NIOS2_PAGE_H ++ ++/* copied from m68knommu arch */ ++ ++/* PAGE_SHIFT determines the page size */ ++ ++#define PAGE_SHIFT (12) ++#define PAGE_SIZE (1UL << PAGE_SHIFT) ++#define PAGE_MASK (~(PAGE_SIZE-1)) ++ ++#ifdef __KERNEL__ ++ ++#include <asm/setup.h> ++ ++#if PAGE_SHIFT < 13 ++#define THREAD_SIZE (8192) ++#else ++#define THREAD_SIZE PAGE_SIZE ++#endif ++ ++#ifndef __ASSEMBLY__ ++ ++#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) ++#define free_user_page(page, addr) free_page(addr) ++ ++#define clear_page(page) memset((page), 0, PAGE_SIZE) ++#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) ++ ++#define clear_user_page(page, vaddr, pg) clear_page(page) ++#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) ++ ++/* ++ * These are used to make use of C type-checking.. ++ */ ++typedef struct { unsigned long pte; } pte_t; ++typedef struct { unsigned long pmd[16]; } pmd_t; ++typedef struct { unsigned long pgd; } pgd_t; ++typedef struct { unsigned long pgprot; } pgprot_t; ++ ++#define pte_val(x) ((x).pte) ++#define pmd_val(x) ((&x)->pmd[0]) ++#define pgd_val(x) ((x).pgd) ++#define pgprot_val(x) ((x).pgprot) ++ ++#define __pte(x) ((pte_t) { (x) } ) ++#define __pmd(x) ((pmd_t) { (x) } ) ++#define __pgd(x) ((pgd_t) { (x) } ) ++#define __pgprot(x) ((pgprot_t) { (x) } ) ++ ++/* to align the pointer to the (next) page boundary */ ++#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) ++ ++extern unsigned long memory_start; ++extern unsigned long memory_end; ++ ++#endif /* !__ASSEMBLY__ */ ++#include <asm/nios.h> ++#define PAGE_OFFSET ((int)(nasys_program_mem)) ++ ++#ifndef __ASSEMBLY__ ++ ++#define __pa(vaddr) virt_to_phys((void *)(vaddr)) ++#define __va(paddr) phys_to_virt((unsigned long)(paddr)) ++ ++#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) ++ ++#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) ++#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) ++ ++#define virt_to_page(addr) ((void*) addr < (void*) memory_end ? mem_map + \ ++ (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) : 0UL) ++#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET) ++#define VALID_PAGE(page) (((page) - mem_map) < max_mapnr) ++ ++#define pfn_to_page(pfn) virt_to_page(pfn_to_virt(pfn)) ++#define page_to_pfn(page) virt_to_pfn(page_to_virt(page)) ++#define pfn_valid(pfn) ((pfn) < max_mapnr) ++ ++#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \ ++ ((void *)(kaddr) < (void *)memory_end)) ++ ++#ifdef CONFIG_NO_KERNEL_MSG ++#define BUG_PRINT() ++#else ++#define BUG_PRINT() printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__) ++#endif ++ ++#ifdef na_cpu_oci_core ++#define BUG_PANIC() asm volatile ("break") /* drop to debugger */ ++#else ++// #define BUG_PANIC() while(1) ++#define BUG_PANIC() panic("BUG!") ++#endif ++ ++#endif /* __ASSEMBLY__ */ ++ ++#include <asm-generic/page.h> ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* _NIOS2_PAGE_H */ +diff --git a/include/asm-nios2nommu/param.h b/include/asm-nios2nommu/param.h +new file mode 100644 +index 0000000..e75a355 +--- /dev/null ++++ b/include/asm-nios2nommu/param.h +@@ -0,0 +1,49 @@ ++#ifndef _NIOS_PARAM_H ++#define _NIOS_PARAM_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/param.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 ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++#ifndef HZ ++#define HZ 100 ++#endif ++ ++#ifdef __KERNEL__ ++#define USER_HZ HZ ++#define CLOCKS_PER_SEC (USER_HZ) ++#endif ++ ++#define EXEC_PAGESIZE 4096 ++ ++#ifndef NGROUPS ++#define NGROUPS 32 ++#endif ++ ++#ifndef NOGROUP ++#define NOGROUP (-1) ++#endif ++ ++#define MAXHOSTNAMELEN 64 /* max length of hostname */ ++ ++#endif +diff --git a/include/asm-nios2nommu/pci.h b/include/asm-nios2nommu/pci.h +new file mode 100644 +index 0000000..be3b3b2 +--- /dev/null ++++ b/include/asm-nios2nommu/pci.h +@@ -0,0 +1,126 @@ ++#ifndef __ASM_SH_PCI_H ++#define __ASM_SH_PCI_H ++ ++#ifdef __KERNEL__ ++ ++#include <linux/dma-mapping.h> ++ ++/* Can be used to override the logic in pci_scan_bus for skipping ++ already-configured bus numbers - to be used for buggy BIOSes ++ or architectures with incomplete PCI setup by the loader */ ++ ++#define pcibios_assign_all_busses() 1 ++#define pcibios_scan_all_fns(a, b) 0 ++ ++/* ++ * A board can define one or more PCI channels that represent built-in (or ++ * external) PCI controllers. ++ */ ++struct pci_channel { ++ struct pci_ops *pci_ops; ++ struct resource *io_resource; ++ struct resource *mem_resource; ++ int first_devfn; ++ int last_devfn; ++}; ++ ++/* ++ * Each board initializes this array and terminates it with a NULL entry. ++ */ ++extern struct pci_channel board_pci_channels[]; ++ ++#define PCIBIOS_MIN_IO board_pci_channels->io_resource->start ++#define PCIBIOS_MIN_MEM board_pci_channels->mem_resource->start ++ ++struct pci_dev; ++ ++extern void pcibios_set_master(struct pci_dev *dev); ++ ++static inline void pcibios_penalize_isa_irq(int irq, int active) ++{ ++ /* We don't do dynamic PCI IRQ allocation */ ++} ++ ++/* Dynamic DMA mapping stuff. ++ * SuperH has everything mapped statically like x86. ++ */ ++ ++/* The PCI address space does equal the physical memory ++ * address space. The networking and block device layers use ++ * this boolean for bounce buffer decisions. ++ */ ++#define PCI_DMA_BUS_IS_PHYS (1) ++ ++#include <linux/types.h> ++#include <linux/slab.h> ++#include <asm/scatterlist.h> ++#include <linux/string.h> ++#include <asm/io.h> ++ ++/* pci_unmap_{single,page} being a nop depends upon the ++ * configuration. ++ */ ++#ifdef CONFIG_SH_PCIDMA_NONCOHERENT ++#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ ++ dma_addr_t ADDR_NAME; ++#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \ ++ __u32 LEN_NAME; ++#define pci_unmap_addr(PTR, ADDR_NAME) \ ++ ((PTR)->ADDR_NAME) ++#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \ ++ (((PTR)->ADDR_NAME) = (VAL)) ++#define pci_unmap_len(PTR, LEN_NAME) \ ++ ((PTR)->LEN_NAME) ++#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ ++ (((PTR)->LEN_NAME) = (VAL)) ++#else ++#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) ++#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) ++#define pci_unmap_addr(PTR, ADDR_NAME) (0) ++#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0) ++#define pci_unmap_len(PTR, LEN_NAME) (0) ++#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) ++#endif ++ ++/* Not supporting more than 32-bit PCI bus addresses now, but ++ * must satisfy references to this function. Change if needed. ++ */ ++#define pci_dac_dma_supported(pci_dev, mask) (0) ++ ++/* These macros should be used after a pci_map_sg call has been done ++ * to get bus addresses of each of the SG entries and their lengths. ++ * You should only work with the number of sg entries pci_map_sg ++ * returns, or alternatively stop on the first sg_dma_len(sg) which ++ * is 0. ++ */ ++#define sg_dma_address(sg) (virt_to_bus((sg)->dma_address)) ++#define sg_dma_len(sg) ((sg)->length) ++ ++#ifdef CONFIG_PCI ++static inline void pci_dma_burst_advice(struct pci_dev *pdev, ++ enum pci_dma_burst_strategy *strat, ++ unsigned long *strategy_parameter) ++{ ++ *strat = PCI_DMA_BURST_INFINITY; ++ *strategy_parameter = ~0UL; ++} ++#endif ++ ++/* Board-specific fixup routines. */ ++extern void pcibios_fixup(void); ++extern void pcibios_fixup_irqs(void); ++ ++#ifdef CONFIG_PCI_AUTO ++extern int pciauto_assign_resources(int busno, struct pci_channel *hose); ++#endif ++ ++#endif /* __KERNEL__ */ ++ ++/* generic pci stuff */ ++#include <asm-generic/pci.h> ++ ++/* generic DMA-mapping stuff */ ++#include <asm-generic/pci-dma-compat.h> ++ ++#endif /* __ASM_SH_PCI_H */ ++ +diff --git a/include/asm-nios2nommu/percpu.h b/include/asm-nios2nommu/percpu.h +new file mode 100644 +index 0000000..cd6d4a3 +--- /dev/null ++++ b/include/asm-nios2nommu/percpu.h +@@ -0,0 +1,30 @@ ++#ifndef __ARCH_NIOS2NOMMU_PERCPU__ ++#define __ARCH_NIOS2NOMMU_PERCPU__ ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/percpu.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-generic/percpu.h> ++ ++#endif /* __ARCH_NIOS2NOMMU_PERCPU__ */ +diff --git a/include/asm-nios2nommu/pgalloc.h b/include/asm-nios2nommu/pgalloc.h +new file mode 100644 +index 0000000..a997ada +--- /dev/null ++++ b/include/asm-nios2nommu/pgalloc.h +@@ -0,0 +1,32 @@ ++#ifndef _NIOS2NOMMU_PGALLOC_H ++#define _NIOS2NOMMU_PGALLOC_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/pgalloc.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/setup.h> ++ ++#define check_pgt_cache() do { } while (0) ++ ++#endif /* _NIOS2NOMMU_PGALLOC_H */ +diff --git a/include/asm-nios2nommu/pgtable.h b/include/asm-nios2nommu/pgtable.h +new file mode 100644 +index 0000000..4124a33 +--- /dev/null ++++ b/include/asm-nios2nommu/pgtable.h +@@ -0,0 +1,112 @@ ++#ifndef _NIOS_PGTABLE_H ++#define _NIOS_PGTABLE_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/pgtable.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-generic/4level-fixup.h> ++ ++//vic - this bit copied from m68knommu version ++#include <asm/setup.h> ++#include <asm/io.h> ++#include <linux/sched.h> ++ ++typedef pte_t *pte_addr_t; ++ ++#define pgd_present(pgd) (1) /* pages are always present on NO_MM */ ++#define pgd_none(pgd) (0) ++#define pgd_bad(pgd) (0) ++#define pgd_clear(pgdp) ++#define kern_addr_valid(addr) (1) ++#define pmd_offset(a, b) ((void *)0) ++ ++#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */ ++#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */ ++#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */ ++#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */ ++#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */ ++//vic - this bit copied from m68knommu version ++ ++extern void paging_init(void); ++#define swapper_pg_dir ((pgd_t *) 0) ++ ++#define __swp_type(x) (0) ++#define __swp_offset(x) (0) ++#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) }) ++#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) ++#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) ++ ++static inline int pte_file(pte_t pte) { return 0; } ++ ++/* ++ * ZERO_PAGE is a global shared page that is always zero: used ++ * for zero-mapped memory areas etc.. ++ */ ++#define ZERO_PAGE(vaddr) (virt_to_page(0)) ++ ++extern unsigned int kobjsize(const void *objp); ++extern int is_in_rom(unsigned long); ++ ++/* ++ * No page table caches to initialise ++ */ ++#define pgtable_cache_init() do { } while (0) ++ ++#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ ++ remap_pfn_range(vma, vaddr, pfn, size, prot) ++ ++extern inline void flush_cache_mm(struct mm_struct *mm) ++{ ++} ++ ++extern inline void flush_cache_range(struct mm_struct *mm, ++ unsigned long start, ++ unsigned long end) ++{ ++} ++ ++/* Push the page at kernel virtual address and clear the icache */ ++extern inline void flush_page_to_ram (unsigned long address) ++{ ++} ++ ++/* Push n pages at kernel virtual address and clear the icache */ ++extern inline void flush_pages_to_ram (unsigned long address, int n) ++{ ++} ++ ++/* ++ * All 32bit addresses are effectively valid for vmalloc... ++ * Sort of meaningless for non-VM targets. ++ */ ++#define VMALLOC_START 0 ++#define VMALLOC_END 0xffffffff ++ ++#define arch_enter_lazy_mmu_mode() do {} while (0) ++#define arch_leave_lazy_mmu_mode() do {} while (0) ++#define arch_flush_lazy_mmu_mode() do {} while (0) ++#define arch_enter_lazy_cpu_mode() do {} while (0) ++#define arch_leave_lazy_cpu_mode() do {} while (0) ++#define arch_flush_lazy_cpu_mode() do {} while (0) ++ ++#endif /* _NIOS_PGTABLE_H */ +diff --git a/include/asm-nios2nommu/pio_struct.h b/include/asm-nios2nommu/pio_struct.h +new file mode 100644 +index 0000000..8ce5176 +--- /dev/null ++++ b/include/asm-nios2nommu/pio_struct.h +@@ -0,0 +1,14 @@ ++// PIO Peripheral ++ ++// PIO Registers ++typedef volatile struct ++ { ++ int np_piodata; // read/write, up to 32 bits ++ int np_piodirection; // write/readable, up to 32 bits, 1->output bit ++ int np_piointerruptmask; // write/readable, up to 32 bits, 1->enable interrupt ++ int np_pioedgecapture; // read, up to 32 bits, cleared by any write ++ } np_pio; ++ ++// PIO Routines ++void nr_pio_showhex(int value); // shows low byte on pio named na_seven_seg_pio ++ +diff --git a/include/asm-nios2nommu/poll.h b/include/asm-nios2nommu/poll.h +new file mode 100644 +index 0000000..f6b9ab8 +--- /dev/null ++++ b/include/asm-nios2nommu/poll.h +@@ -0,0 +1,48 @@ ++#ifndef __NIOS2_POLL_H ++#define __NIOS2_POLL_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/poll.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 ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++#define POLLIN 1 ++#define POLLPRI 2 ++#define POLLOUT 4 ++#define POLLERR 8 ++#define POLLHUP 16 ++#define POLLNVAL 32 ++#define POLLRDNORM 64 ++#define POLLWRNORM POLLOUT ++#define POLLRDBAND 128 ++#define POLLWRBAND 256 ++#define POLLMSG 0x0400 ++#define POLLREMOVE 0x1000 ++#define POLLRDHUP 0x2000 ++ ++struct pollfd { ++ int fd; ++ short events; ++ short revents; ++}; ++ ++#endif +diff --git a/include/asm-nios2nommu/posix_types.h b/include/asm-nios2nommu/posix_types.h +new file mode 100644 +index 0000000..0b019b5 +--- /dev/null ++++ b/include/asm-nios2nommu/posix_types.h +@@ -0,0 +1,89 @@ ++#ifndef __ARCH_NIOS2_POSIX_TYPES_H ++#define __ARCH_NIOS2_POSIX_TYPES_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/posix_types.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 ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++/* ++ * This file is generally used by user-level software, so you need to ++ * be a little careful about namespace pollution etc. Also, we cannot ++ * assume GCC is being used. ++ */ ++ ++typedef unsigned long __kernel_ino_t; ++typedef unsigned short __kernel_mode_t; ++typedef unsigned short __kernel_nlink_t; ++typedef long __kernel_off_t; ++typedef int __kernel_pid_t; ++typedef unsigned short __kernel_ipc_pid_t; ++typedef unsigned short __kernel_uid_t; ++typedef unsigned short __kernel_gid_t; ++typedef unsigned int __kernel_size_t; ++typedef int __kernel_ssize_t; ++typedef int __kernel_ptrdiff_t; ++typedef long __kernel_time_t; ++typedef long __kernel_suseconds_t; ++typedef long __kernel_clock_t; ++typedef int __kernel_timer_t; ++typedef int __kernel_clockid_t; ++typedef int __kernel_daddr_t; ++typedef char * __kernel_caddr_t; ++typedef unsigned short __kernel_uid16_t; ++typedef unsigned short __kernel_gid16_t; ++typedef unsigned int __kernel_uid32_t; ++typedef unsigned int __kernel_gid32_t; ++ ++typedef unsigned short __kernel_old_uid_t; ++typedef unsigned short __kernel_old_gid_t; ++typedef unsigned short __kernel_old_dev_t; ++ ++#ifdef __GNUC__ ++typedef long long __kernel_loff_t; ++#endif ++ ++typedef struct { ++#if defined(__KERNEL__) || defined(__USE_ALL) ++ int val[2]; ++#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ ++ int __val[2]; ++#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ ++} __kernel_fsid_t; ++ ++#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) ++ ++#undef __FD_SET ++#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) ++ ++#undef __FD_CLR ++#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) ++ ++#undef __FD_ISSET ++#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) ++ ++#undef __FD_ZERO ++#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) ++ ++#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ ++ ++#endif +diff --git a/include/asm-nios2nommu/preem_latency.h b/include/asm-nios2nommu/preem_latency.h +new file mode 100644 +index 0000000..6defb5c +--- /dev/null ++++ b/include/asm-nios2nommu/preem_latency.h +@@ -0,0 +1,39 @@ ++#ifndef _ASM_PREEM_LATENCY_H ++#define _ASM_PREEM_LATENCY_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/preem_latency.h ++ * ++ * timing support for preempt-stats patch ++ * ++ * 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/nios.h> ++ ++#define readclock(low) \ ++do {\ ++ *(volatile unsigned long *)na_Counter_64_bit=1; \ ++ low=*(volatile unsigned long *)na_Counter_64_bit; \ ++} while (0) ++#define readclock_init() ++ ++#endif /* _ASM_PREEM_LATENCY_H */ +diff --git a/include/asm-nios2nommu/processor.h b/include/asm-nios2nommu/processor.h +new file mode 100644 +index 0000000..5332f94 +--- /dev/null ++++ b/include/asm-nios2nommu/processor.h +@@ -0,0 +1,148 @@ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/processor.h ++ * ++ * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) ++ * Copyright (C) 2001 Ken Hill (khill@microtronix.com) ++ * Vic Phillips (vic@microtronix.com) ++ * Copyright (C) 2004 Microtronix Datacom Ltd ++ * ++ * hacked from: ++ * include/asm-sparc/processor.h ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * Jan/20/2004 dgt NiosII ++ * Nov/02/2003 dgt Fix task_size ++ * ++ ---------------------------------------------------------------------*/ ++ ++#ifndef __ASM_NIOS_PROCESSOR_H ++#define __ASM_NIOS_PROCESSOR_H ++ ++#define NIOS2_FLAG_KTHREAD 0x00000001 /* task is a kernel thread */ ++#define NIOS2_FLAG_COPROC 0x00000002 /* Thread used coprocess */ ++#define NIOS2_FLAG_DEBUG 0x00000004 /* task is being debugged */ ++ ++#define NIOS2_OP_NOP 0x1883a ++#define NIOS2_OP_BREAK 0x3da03a ++ ++#ifndef __ASSEMBLY__ ++ ++/* ++ * Default implementation of macro that returns current ++ * instruction pointer ("program counter"). ++ */ ++#define current_text_addr() ({ __label__ _l; _l: &&_l;}) ++ ++#include <linux/a.out.h> ++#include <linux/string.h> ++ ++#include <asm/ptrace.h> ++#include <asm/signal.h> ++#include <asm/segment.h> ++#include <asm/current.h> ++#include <asm/system.h> /* for get_hi_limit */ ++ ++/* ++ * Bus types ++ */ ++#define EISA_bus 0 ++#define EISA_bus__is_a_macro /* for versions in ksyms.c */ ++#define MCA_bus 0 ++#define MCA_bus__is_a_macro /* for versions in ksyms.c */ ++ ++/* ++ * The nios has no problems with write protection ++ */ ++#define wp_works_ok 1 ++#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ ++ ++/* Whee, this is STACK_TOP and the lowest kernel address too... */ ++#if 0 ++#define KERNBASE 0x00000000 /* First address the kernel will eventually be */ ++#define TASK_SIZE (KERNBASE) ++#define MAX_USER_ADDR TASK_SIZE ++#define MMAP_SEARCH_START (TASK_SIZE/3) ++#endif ++ ++#define TASK_SIZE ((unsigned int) nasys_program_mem_end) //...this is better... ++ ++/* ++ * This decides where the kernel will search for a free chunk of vm ++ * space during mmap's. We won't be using it ++ */ ++#define TASK_UNMAPPED_BASE 0 ++ ++/* The Nios processor specific thread struct. */ ++struct thread_struct { ++ struct pt_regs *kregs; ++ ++ /* For signal handling */ ++ unsigned long sig_address; ++ unsigned long sig_desc; ++ ++ /* Context switch saved kernel state. */ ++ unsigned long ksp; ++ unsigned long kpsr; ++ unsigned long kesr; ++ ++ /* Flags are defined below */ ++ ++ unsigned long flags; ++ int current_ds; ++ struct exec core_exec; /* just what it says. */ ++}; ++ ++#define INIT_MMAP { &init_mm, (0), (0), \ ++ __pgprot(0x0) , VM_READ | VM_WRITE | VM_EXEC } ++ ++#define INIT_THREAD { \ ++ .kregs = 0, \ ++ .sig_address = 0, \ ++ .sig_desc = 0, \ ++ .ksp = 0, \ ++ .kpsr = 0, \ ++ .kesr = PS_S, \ ++ .flags = NIOS2_FLAG_KTHREAD, \ ++ .current_ds = __KERNEL_DS, \ ++ .core_exec = INIT_EXEC \ ++} ++ ++/* Free all resources held by a thread. */ ++extern void release_thread(struct task_struct *); ++ ++extern unsigned long thread_saved_pc(struct task_struct *t); ++ ++extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp); ++ ++/* Prepare to copy thread state - unlazy all lazy status */ ++#define prepare_to_copy(tsk) do { } while (0) ++ ++extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); ++ ++unsigned long get_wchan(struct task_struct *p); ++ ++#define KSTK_EIP(tsk) ((tsk)->thread.kregs->ea) ++#define KSTK_ESP(tsk) ((tsk)->thread.kregs->sp) ++ ++#ifdef __KERNEL__ ++/* Allocation and freeing of basic task resources. */ ++ ++//;dgt2;#define alloc_task_struct() ((struct task_struct *) xx..see..linux..fork..xx __get_free_pages(GFP_KERNEL,1)) ++//;dgt2;#define get_task_struct(tsk) xx..see..linux..sched.h...atomic_inc(&mem_map[MAP_NR(tsk)].count) ++ ++#endif ++ ++#define cpu_relax() do { } while (0) ++#endif /* __ASSEMBLY__ */ ++#endif /* __ASM_NIOS_PROCESSOR_H */ +diff --git a/include/asm-nios2nommu/ptrace.h b/include/asm-nios2nommu/ptrace.h +new file mode 100644 +index 0000000..d669e08 +--- /dev/null ++++ b/include/asm-nios2nommu/ptrace.h +@@ -0,0 +1,140 @@ ++/* ++ * Taken from the m68k port. ++ * ++ * Copyright (C) 2004, Microtronix Datacom Ltd. ++ * ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or ++ * NON INFRINGEMENT. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++#ifndef _NIOS2NOMMU_PTRACE_H ++#define _NIOS2NOMMU_PTRACE_H ++ ++#ifndef __ASSEMBLY__ ++ ++#define PTR_R0 0 ++#define PTR_R1 1 ++#define PTR_R2 2 ++#define PTR_R3 3 ++#define PTR_R4 4 ++#define PTR_R5 5 ++#define PTR_R6 6 ++#define PTR_R7 7 ++#define PTR_R8 8 ++#define PTR_R9 9 ++#define PTR_R10 10 ++#define PTR_R11 11 ++#define PTR_R12 12 ++#define PTR_R13 13 ++#define PTR_R14 14 ++#define PTR_R15 15 ++#define PTR_R16 16 ++#define PTR_R17 17 ++#define PTR_R18 18 ++#define PTR_R19 19 ++#define PTR_R20 20 ++#define PTR_R21 21 ++#define PTR_R22 22 ++#define PTR_R23 23 ++#define PTR_R24 24 ++#define PTR_R25 25 ++#define PTR_GP 26 ++#define PTR_SP 27 ++#define PTR_FP 28 ++#define PTR_EA 29 ++#define PTR_BA 30 ++#define PTR_RA 31 ++#define PTR_STATUS 32 ++#define PTR_ESTATUS 33 ++#define PTR_BSTATUS 34 ++#define PTR_IENABLE 35 ++#define PTR_IPENDING 36 ++ ++/* this struct defines the way the registers are stored on the ++ stack during a system call. ++ ++ There is a fake_regs in setup.c that has to match pt_regs.*/ ++ ++struct pt_regs { ++ unsigned long r8; ++ unsigned long r9; ++ unsigned long r10; ++ unsigned long r11; ++ unsigned long r12; ++ unsigned long r13; ++ unsigned long r14; ++ unsigned long r15; ++ unsigned long r1; ++ unsigned long r2; ++ unsigned long r3; ++ unsigned long r4; ++ unsigned long r5; ++ unsigned long r6; ++ unsigned long r7; ++ unsigned long orig_r2; ++ unsigned long ra; ++ unsigned long fp; ++ unsigned long sp; ++ unsigned long gp; ++ unsigned long estatus; ++ unsigned long status_extension; ++ unsigned long ea; ++}; ++ ++ ++/* ++ * This is the extended stack used by signal handlers and the context ++ * switcher: it's pushed after the normal "struct pt_regs". ++ */ ++struct switch_stack { ++ unsigned long r16; ++ unsigned long r17; ++ unsigned long r18; ++ unsigned long r19; ++ unsigned long r20; ++ unsigned long r21; ++ unsigned long r22; ++ unsigned long r23; ++ unsigned long fp; ++ unsigned long gp; ++ unsigned long ra; ++}; ++ ++#ifdef __KERNEL__ ++/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ ++#define PTRACE_GETREGS 12 ++#define PTRACE_SETREGS 13 ++#ifdef CONFIG_FPU ++#define PTRACE_GETFPREGS 14 ++#define PTRACE_SETFPREGS 15 ++#endif ++ ++#ifndef PS_S ++#define PS_S (0x00000001) ++#endif ++#ifndef PS_T ++#define PS_T (0x00000002) ++#endif ++ ++#define user_mode(regs) (!((regs)->status_extension & PS_S)) ++#define instruction_pointer(regs) ((regs)->ra) ++#define profile_pc(regs) instruction_pointer(regs) ++extern void show_regs(struct pt_regs *); ++ ++#endif /* __KERNEL__ */ ++#endif /* __ASSEMBLY__ */ ++#endif /* _NIOS2NOMMU_PTRACE_H */ +diff --git a/include/asm-nios2nommu/resource.h b/include/asm-nios2nommu/resource.h +new file mode 100644 +index 0000000..9c2499a +--- /dev/null ++++ b/include/asm-nios2nommu/resource.h +@@ -0,0 +1,6 @@ ++#ifndef __ASM_SH_RESOURCE_H ++#define __ASM_SH_RESOURCE_H ++ ++#include <asm-generic/resource.h> ++ ++#endif /* __ASM_SH_RESOURCE_H */ +diff --git a/include/asm-nios2nommu/rmap.h b/include/asm-nios2nommu/rmap.h +new file mode 100644 +index 0000000..b3664cc +--- /dev/null ++++ b/include/asm-nios2nommu/rmap.h +@@ -0,0 +1,2 @@ ++/* Do not need anything here */ ++ +diff --git a/include/asm-nios2nommu/scatterlist.h b/include/asm-nios2nommu/scatterlist.h +new file mode 100644 +index 0000000..20898e2 +--- /dev/null ++++ b/include/asm-nios2nommu/scatterlist.h +@@ -0,0 +1,13 @@ ++#ifndef __ASM_SH_SCATTERLIST_H ++#define __ASM_SH_SCATTERLIST_H ++ ++struct scatterlist { ++ struct page * page; /* Location for highmem page, if any */ ++ unsigned int offset;/* for highmem, page offset */ ++ dma_addr_t dma_address; ++ unsigned int length; ++}; ++ ++#define ISA_DMA_THRESHOLD (0xffffffff) ++ ++#endif /* !(__ASM_SH_SCATTERLIST_H) */ +diff --git a/include/asm-nios2nommu/sections.h b/include/asm-nios2nommu/sections.h +new file mode 100644 +index 0000000..61b3f71 +--- /dev/null ++++ b/include/asm-nios2nommu/sections.h +@@ -0,0 +1,30 @@ ++#ifndef _NIOS2NOMMU_SECTIONS_H ++#define _NIOS2NOMMU_SECTIONS_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/sections.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-generic/sections.h> ++ ++#endif /* _NIOS2NOMMU_SECTIONS_H */ +diff --git a/include/asm-nios2nommu/segment.h b/include/asm-nios2nommu/segment.h +new file mode 100644 +index 0000000..25871b3 +--- /dev/null ++++ b/include/asm-nios2nommu/segment.h +@@ -0,0 +1,75 @@ ++#ifndef _NIOS2NOMMU_SEGMENT_H ++#define _NIOS2NOMMU_SEGMENT_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/segment.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 ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++/* define constants */ ++/* Address spaces (FC0-FC2) */ ++#define USER_DATA (1) ++#ifndef __USER_DS ++#define __USER_DS (USER_DATA) ++#endif ++#define USER_PROGRAM (2) ++#define SUPER_DATA (5) ++#ifndef __KERNEL_DS ++#define __KERNEL_DS (SUPER_DATA) ++#endif ++#define SUPER_PROGRAM (6) ++#define CPU_SPACE (7) ++ ++#ifndef __ASSEMBLY__ ++ ++typedef struct { ++ unsigned long seg; ++} mm_segment_t; ++ ++#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) ++#define USER_DS MAKE_MM_SEG(__USER_DS) ++#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS) ++ ++/* ++ * Get/set the SFC/DFC registers for MOVES instructions ++ */ ++ ++static inline mm_segment_t get_fs(void) ++{ ++ return USER_DS; ++} ++ ++static inline mm_segment_t get_ds(void) ++{ ++ /* return the supervisor data space code */ ++ return KERNEL_DS; ++} ++ ++static inline void set_fs(mm_segment_t val) ++{ ++} ++ ++#define segment_eq(a,b) ((a).seg == (b).seg) ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* _NIOS2NOMMU_SEGMENT_H */ +diff --git a/include/asm-nios2nommu/semaphore-helper.h b/include/asm-nios2nommu/semaphore-helper.h +new file mode 100644 +index 0000000..a8905d1 +--- /dev/null ++++ b/include/asm-nios2nommu/semaphore-helper.h +@@ -0,0 +1,99 @@ ++#ifndef _NIOS2NOMMU_SEMAPHORE_HELPER_H ++#define _NIOS2NOMMU_SEMAPHORE_HELPER_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/semaphore.h ++ * ++ * SMP- and interrupt-safe semaphores helper functions. ++ * ++ * Derived from M68knommu ++ * ++ * (C) Copyright 1996 Linus Torvalds ++ * m68k version by Andreas Schwab ++ * 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 ++ * ++ ---------------------------------------------------------------------*/ ++ ++/* ++ * These two _must_ execute atomically wrt each other. ++ */ ++static inline void wake_one_more(struct semaphore * sem) ++{ ++ atomic_inc(&sem->waking); ++} ++ ++static inline int waking_non_zero(struct semaphore *sem) ++{ ++ int ret; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&semaphore_wake_lock, flags); ++ ret = 0; ++ if (atomic_read(&sem->waking) > 0) { ++ atomic_dec(&sem->waking); ++ ret = 1; ++ } ++ spin_unlock_irqrestore(&semaphore_wake_lock, flags); ++ return ret; ++} ++ ++/* ++ * waking_non_zero_interruptible: ++ * 1 got the lock ++ * 0 go to sleep ++ * -EINTR interrupted ++ */ ++static inline int waking_non_zero_interruptible(struct semaphore *sem, ++ struct task_struct *tsk) ++{ ++ int ret; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&semaphore_wake_lock, flags); ++ ret = 0; ++ if (atomic_read(&sem->waking) > 0) { ++ atomic_dec(&sem->waking); ++ ret = 1; ++ } else if (signal_pending(tsk)) { ++ atomic_inc(&sem->count); ++ ret = -EINTR; ++ } ++ spin_unlock_irqrestore(&semaphore_wake_lock, flags); ++ return ret; ++} ++ ++/* ++ * waking_non_zero_trylock: ++ * 1 failed to lock ++ * 0 got the lock ++ */ ++static inline int waking_non_zero_trylock(struct semaphore *sem) ++{ ++ int ret; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&semaphore_wake_lock, flags); ++ ret = 1; ++ if (atomic_read(&sem->waking) > 0) { ++ atomic_dec(&sem->waking); ++ ret = 0; ++ } else ++ atomic_inc(&sem->count); ++ spin_unlock_irqrestore(&semaphore_wake_lock, flags); ++ return ret; ++} ++ ++#endif +diff --git a/include/asm-nios2nommu/semaphore.h b/include/asm-nios2nommu/semaphore.h +new file mode 100644 +index 0000000..8d66c77 +--- /dev/null ++++ b/include/asm-nios2nommu/semaphore.h +@@ -0,0 +1,152 @@ ++#ifndef _NIOS2NOMMU_SEMAPHORE_H ++#define _NIOS2NOMMU_SEMAPHORE_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/semaphore.h ++ * ++ * Interrupt-safe semaphores.. ++ * ++ * Derived from M68knommu ++ * ++ * (C) Copyright 1996 Linus Torvalds ++ * m68k version by Andreas Schwab ++ * 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 ++ * ++ ---------------------------------------------------------------------*/ ++ ++#define RW_LOCK_BIAS 0x01000000 ++ ++#ifndef __ASSEMBLY__ ++ ++#include <linux/linkage.h> ++#include <linux/wait.h> ++#include <linux/spinlock.h> ++#include <linux/rwsem.h> ++ ++#include <asm/system.h> ++#include <asm/atomic.h> ++ ++struct semaphore { ++ atomic_t count; ++ atomic_t waking; ++ wait_queue_head_t wait; ++}; ++ ++#define __SEMAPHORE_INITIALIZER(name, n) \ ++{ \ ++ .count = ATOMIC_INIT(n), \ ++ .waking = ATOMIC_INIT(0), \ ++ .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ ++} ++ ++#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ ++ struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) ++ ++#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) ++#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) ++ ++static inline void sema_init (struct semaphore *sem, int val) ++{ ++ *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); ++} ++ ++static inline void init_MUTEX (struct semaphore *sem) ++{ ++ sema_init(sem, 1); ++} ++ ++static inline void init_MUTEX_LOCKED (struct semaphore *sem) ++{ ++ sema_init(sem, 0); ++} ++ ++asmlinkage void __down_failed(void /* special register calling convention */); ++asmlinkage int __down_failed_interruptible(void /* params in registers */); ++asmlinkage int __down_failed_trylock(void /* params in registers */); ++asmlinkage void __up_wakeup(void /* special register calling convention */); ++ ++asmlinkage void __down(struct semaphore * sem); ++asmlinkage int __down_interruptible(struct semaphore * sem); ++asmlinkage int __down_trylock(struct semaphore * sem); ++asmlinkage void __up(struct semaphore * sem); ++ ++extern spinlock_t semaphore_wake_lock; ++ ++/* ++ * This is ugly, but we want the default case to fall through. ++ * "down_failed" is a special asm handler that calls the C ++ * routine that actually waits. ++ */ ++static inline void down(struct semaphore * sem) ++{ ++ might_sleep(); ++ ++ #if 0 ++ ...Nios2 has no atomic "decrement memory".... ++ #else ++ if (atomic_dec_return(&sem->count) < 0) ++ __down(sem); ++ #endif ++} ++ ++static inline int down_interruptible(struct semaphore * sem) ++{ ++ int ret = 0; ++ ++ ++ might_sleep(); ++ ++ #if 0 ++ ...Nios2 has no atomic "decrement memory".... ++ #else ++ if(atomic_dec_return(&sem->count) < 0) ++ ret = __down_interruptible(sem); ++ return ret; ++ #endif ++} ++ ++static inline int down_trylock(struct semaphore * sem) ++{ ++ #if 0 ++ ...Nios2 has no atomic "decrement memory".... ++ #else ++ int ret = 0; ++ ++ if (atomic_dec_return (&sem->count) < 0) ++ ret = __down_trylock(sem); ++ return ret; ++ #endif ++} ++ ++/* ++ * Note! This is subtle. We jump to wake people up only if ++ * the semaphore was negative (== somebody was waiting on it). ++ * The default case (no contention) will result in NO ++ * jumps for both down() and up(). ++ */ ++static inline void up(struct semaphore * sem) ++{ ++ #if 0 ++ ...Nios2 has no atomic "increment memory".... ++ #else ++ if (atomic_inc_return(&sem->count) <= 0) ++ __up(sem); ++ #endif ++} ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif +diff --git a/include/asm-nios2nommu/sembuf.h b/include/asm-nios2nommu/sembuf.h +new file mode 100644 +index 0000000..e530cab +--- /dev/null ++++ b/include/asm-nios2nommu/sembuf.h +@@ -0,0 +1,48 @@ ++#ifndef _NIOS_SEMBUF_H ++#define _NIOS_SEMBUF_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/sembuf.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 ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++/* ++ * Note extra padding because this structure is passed back and forth ++ * between kernel and user space. ++ * ++ * Pad space is left for: ++ * - 64-bit time_t to solve y2038 problem ++ * - 2 miscellaneous 32-bit values ++ */ ++ ++struct semid64_ds { ++ struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ ++ __kernel_time_t sem_otime; /* last semop time */ ++ unsigned long __unused1; ++ __kernel_time_t sem_ctime; /* last change time */ ++ unsigned long __unused2; ++ unsigned long sem_nsems; /* no. of semaphores in array */ ++ unsigned long __unused3; ++ unsigned long __unused4; ++}; ++ ++#endif /* _NIOS_SEMBUF_H */ +diff --git a/include/asm-nios2nommu/setup.h b/include/asm-nios2nommu/setup.h +new file mode 100644 +index 0000000..c5a655a +--- /dev/null ++++ b/include/asm-nios2nommu/setup.h +@@ -0,0 +1,31 @@ ++/* Copied from i386 port. ++ * Just a place holder. We don't want to have to test x86 before ++ * we include stuff ++ * ++ * 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_SETUP_H ++#define _NIOS2_SETUP_H ++ ++#define COMMAND_LINE_SIZE 512 ++ ++#endif /* _NIOS2_SETUP_H */ +diff --git a/include/asm-nios2nommu/shmbuf.h b/include/asm-nios2nommu/shmbuf.h +new file mode 100644 +index 0000000..f6e6e7d +--- /dev/null ++++ b/include/asm-nios2nommu/shmbuf.h +@@ -0,0 +1,64 @@ ++#ifndef _NIOS_SHMBUF_H ++#define _NIOS_SHMBUF_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/shmbuf.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 ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++/* Note extra padding because this structure is passed back and forth ++ * between kernel and user space. ++ * ++ * Pad space is left for: ++ * - 64-bit time_t to solve y2038 problem ++ * - 2 miscellaneous 32-bit values ++ */ ++ ++struct shmid64_ds { ++ struct ipc64_perm shm_perm; /* operation perms */ ++ size_t shm_segsz; /* size of segment (bytes) */ ++ __kernel_time_t shm_atime; /* last attach time */ ++ unsigned long __unused1; ++ __kernel_time_t shm_dtime; /* last detach time */ ++ unsigned long __unused2; ++ __kernel_time_t shm_ctime; /* last change time */ ++ unsigned long __unused3; ++ __kernel_pid_t shm_cpid; /* pid of creator */ ++ __kernel_pid_t shm_lpid; /* pid of last operator */ ++ unsigned long shm_nattch; /* no. of current attaches */ ++ unsigned long __unused4; ++ unsigned long __unused5; ++}; ++ ++struct shminfo64 { ++ unsigned long shmmax; ++ unsigned long shmmin; ++ unsigned long shmmni; ++ unsigned long shmseg; ++ unsigned long shmall; ++ unsigned long __unused1; ++ unsigned long __unused2; ++ unsigned long __unused3; ++ unsigned long __unused4; ++}; ++ ++#endif /* _NIOS_SHMBUF_H */ +diff --git a/include/asm-nios2nommu/shmparam.h b/include/asm-nios2nommu/shmparam.h +new file mode 100644 +index 0000000..94efe2d +--- /dev/null ++++ b/include/asm-nios2nommu/shmparam.h +@@ -0,0 +1,30 @@ ++#ifndef __NIOS2NOMMU_SHMPARAM_H__ ++#define __NIOS2NOMMU_SHMPARAM_H__ ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/shmparam.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 ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ ++ ++#endif /* __NIOS2NOMMU_SHMPARAM_H__ */ +diff --git a/include/asm-nios2nommu/sigcontext.h b/include/asm-nios2nommu/sigcontext.h +new file mode 100644 +index 0000000..7321e7d +--- /dev/null ++++ b/include/asm-nios2nommu/sigcontext.h +@@ -0,0 +1,35 @@ ++/* ++ * Taken from the m68knommu. ++ * ++ * Copyright (C) 2004, Microtronix Datacom Ltd. ++ * ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or ++ * NON INFRINGEMENT. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++#ifndef _ASM_NIOS2NOMMU_SIGCONTEXT_H ++#define _ASM_NIOS2NOMMU_SIGCONTEXT_H ++ ++#include <asm/ptrace.h> ++ ++struct sigcontext { ++ struct pt_regs regs; ++ unsigned long sc_mask; /* old sigmask */ ++}; ++ ++#endif +diff --git a/include/asm-nios2nommu/siginfo.h b/include/asm-nios2nommu/siginfo.h +new file mode 100644 +index 0000000..c047c0b +--- /dev/null ++++ b/include/asm-nios2nommu/siginfo.h +@@ -0,0 +1,28 @@ ++/* ++ * 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_SIGINFO_H ++#define _NIOS2NOMMU_SIGINFO_H ++ ++#include <asm-generic/siginfo.h> ++ ++#endif +diff --git a/include/asm-nios2nommu/signal.h b/include/asm-nios2nommu/signal.h +new file mode 100644 +index 0000000..c86a20c +--- /dev/null ++++ b/include/asm-nios2nommu/signal.h +@@ -0,0 +1,181 @@ ++/* ++ * Copyright (C) 2004, Microtronix Datacom Ltd. ++ * ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or ++ * NON INFRINGEMENT. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++#ifndef _NIOS2_SIGNAL_H ++#define _NIOS2_SIGNAL_H ++ ++#include <linux/types.h> ++ ++/* Avoid too many header ordering problems. */ ++struct siginfo; ++ ++#ifdef __KERNEL__ ++/* Most things should be clean enough to redefine this at will, if care ++ is taken to make libc match. */ ++ ++#define _NSIG 64 ++#define _NSIG_BPW 32 ++#define _NSIG_WORDS (_NSIG / _NSIG_BPW) ++ ++typedef unsigned long old_sigset_t; /* at least 32 bits */ ++ ++typedef struct { ++ unsigned long sig[_NSIG_WORDS]; ++} sigset_t; ++ ++#else ++/* Here we must cater to libcs that poke about in kernel headers. */ ++ ++#define NSIG 32 ++typedef unsigned long sigset_t; ++ ++#endif /* __KERNEL__ */ ++ ++#define SIGHUP 1 ++#define SIGINT 2 ++#define SIGQUIT 3 ++#define SIGILL 4 ++#define SIGTRAP 5 ++#define SIGABRT 6 ++#define SIGIOT 6 ++#define SIGBUS 7 ++#define SIGFPE 8 ++#define SIGKILL 9 ++#define SIGUSR1 10 ++#define SIGSEGV 11 ++#define SIGUSR2 12 ++#define SIGPIPE 13 ++#define SIGALRM 14 ++#define SIGTERM 15 ++#define SIGSTKFLT 16 ++#define SIGCHLD 17 ++#define SIGCONT 18 ++#define SIGSTOP 19 ++#define SIGTSTP 20 ++#define SIGTTIN 21 ++#define SIGTTOU 22 ++#define SIGURG 23 ++#define SIGXCPU 24 ++#define SIGXFSZ 25 ++#define SIGVTALRM 26 ++#define SIGPROF 27 ++#define SIGWINCH 28 ++#define SIGIO 29 ++#define SIGPOLL SIGIO ++/* ++#define SIGLOST 29 ++*/ ++#define SIGPWR 30 ++#define SIGSYS 31 ++#define SIGUNUSED 31 ++ ++/* These should not be considered constants from userland. */ ++#define SIGRTMIN 32 ++#define SIGRTMAX _NSIG ++ ++/* ++ * SA_FLAGS values: ++ * ++ * SA_ONSTACK indicates that a registered stack_t will be used. ++ * SA_RESTART flag to get restarting signals (which were the default long ago) ++ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. ++ * SA_RESETHAND clears the handler when the signal is delivered. ++ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. ++ * SA_NODEFER prevents the current signal from being masked in the handler. ++ * ++ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single ++ * Unix names RESETHAND and NODEFER respectively. ++ */ ++#define SA_NOCLDSTOP 0x00000001 ++#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ ++#define SA_SIGINFO 0x00000004 ++#define SA_ONSTACK 0x08000000 ++#define SA_RESTART 0x10000000 ++#define SA_NODEFER 0x40000000 ++#define SA_RESETHAND 0x80000000 ++ ++#define SA_NOMASK SA_NODEFER ++#define SA_ONESHOT SA_RESETHAND ++ ++/* ++ * sigaltstack controls ++ */ ++#define SS_ONSTACK 1 ++#define SS_DISABLE 2 ++ ++#define MINSIGSTKSZ 2048 ++#define SIGSTKSZ 8192 ++ ++#include <asm-generic/signal.h> ++ ++#ifdef __KERNEL__ ++struct old_sigaction { ++ __sighandler_t sa_handler; ++ old_sigset_t sa_mask; ++ unsigned long sa_flags; ++ void (*sa_restorer)(void); ++}; ++ ++struct sigaction { ++ __sighandler_t sa_handler; ++ unsigned long sa_flags; ++ void (*sa_restorer)(void); ++ sigset_t sa_mask; /* mask last for extensibility */ ++}; ++ ++struct k_sigaction { ++ struct sigaction sa; ++}; ++#else ++/* Here we must cater to libcs that poke about in kernel headers. */ ++ ++struct sigaction { ++ union { ++ __sighandler_t _sa_handler; ++ void (*_sa_sigaction)(int, struct siginfo *, void *); ++ } _u; ++ sigset_t sa_mask; ++ unsigned long sa_flags; ++ void (*sa_restorer)(void); ++}; ++ ++#define sa_handler _u._sa_handler ++#define sa_sigaction _u._sa_sigaction ++ ++#endif /* __KERNEL__ */ ++ ++typedef struct sigaltstack { ++ void *ss_sp; ++ int ss_flags; ++ size_t ss_size; ++} stack_t; ++ ++#ifdef __KERNEL__ ++ ++#include <asm/sigcontext.h> ++#undef __HAVE_ARCH_SIG_BITOPS ++ ++#define ptrace_signal_deliver(regs, cookie) do { } while (0) ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* _NIOS2_SIGNAL_H */ +diff --git a/include/asm-nios2nommu/smp.h b/include/asm-nios2nommu/smp.h +new file mode 100644 +index 0000000..fb23307 +--- /dev/null ++++ b/include/asm-nios2nommu/smp.h +@@ -0,0 +1,32 @@ ++#ifndef __ASM_SMP_H ++#define __ASM_SMP_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/smp.h ++ * ++ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al ++ * ++ * Copyright (C) 2004 Microtronix Datacom Ltd ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * Jan/20/2004 dgt NiosII ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++#ifdef CONFIG_SMP ++#error SMP not supported ++#endif ++ ++#endif +diff --git a/include/asm-nios2nommu/socket.h b/include/asm-nios2nommu/socket.h +new file mode 100644 +index 0000000..5452e2b +--- /dev/null ++++ b/include/asm-nios2nommu/socket.h +@@ -0,0 +1,79 @@ ++#ifndef _ASM_SOCKET_H ++#define _ASM_SOCKET_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/socket.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/sockios.h> ++ ++/* For setsockopt(2) */ ++#define SOL_SOCKET 1 ++ ++#define SO_DEBUG 1 ++#define SO_REUSEADDR 2 ++#define SO_TYPE 3 ++#define SO_ERROR 4 ++#define SO_DONTROUTE 5 ++#define SO_BROADCAST 6 ++#define SO_SNDBUF 7 ++#define SO_RCVBUF 8 ++#define SO_SNDBUFFORCE 32 ++#define SO_RCVBUFFORCE 33 ++#define SO_KEEPALIVE 9 ++#define SO_OOBINLINE 10 ++#define SO_NO_CHECK 11 ++#define SO_PRIORITY 12 ++#define SO_LINGER 13 ++#define SO_BSDCOMPAT 14 ++/* To add :#define SO_REUSEPORT 15 */ ++#define SO_PASSCRED 16 ++#define SO_PEERCRED 17 ++#define SO_RCVLOWAT 18 ++#define SO_SNDLOWAT 19 ++#define SO_RCVTIMEO 20 ++#define SO_SNDTIMEO 21 ++ ++/* Security levels - as per NRL IPv6 - don't actually do anything */ ++#define SO_SECURITY_AUTHENTICATION 22 ++#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 ++#define SO_SECURITY_ENCRYPTION_NETWORK 24 ++ ++#define SO_BINDTODEVICE 25 ++ ++/* Socket filtering */ ++#define SO_ATTACH_FILTER 26 ++#define SO_DETACH_FILTER 27 ++ ++#define SO_PEERNAME 28 ++#define SO_TIMESTAMP 29 ++#define SCM_TIMESTAMP SO_TIMESTAMP ++ ++#define SO_ACCEPTCONN 30 ++ ++#define SO_PEERSEC 31 /* ;dgt2;tmp; */ ++#define SO_PASSSEC 34 ++#define SO_TIMESTAMPNS 35 ++#define SCM_TIMESTAMPNS SO_TIMESTAMPNS ++ ++#endif /* _ASM_SOCKET_H */ +diff --git a/include/asm-nios2nommu/sockios.h b/include/asm-nios2nommu/sockios.h +new file mode 100644 +index 0000000..c604aa7 +--- /dev/null ++++ b/include/asm-nios2nommu/sockios.h +@@ -0,0 +1,39 @@ ++#ifndef _ASM_NIOS_SOCKIOS_H ++#define _ASM_NIOS_SOCKIOS_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/sockios.h ++ * ++ * Socket-level I/O control calls. ++ * ++ * 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 ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++#define FIOSETOWN 0x8901 ++#define SIOCSPGRP 0x8902 ++#define FIOGETOWN 0x8903 ++#define SIOCGPGRP 0x8904 ++#define SIOCATMARK 0x8905 ++#define SIOCGSTAMP 0x8906 /* Get stamp */ ++#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ ++ ++#endif /* !(_ASM_NIOS_SOCKIOS_H) */ ++ +diff --git a/include/asm-nios2nommu/spi.h b/include/asm-nios2nommu/spi.h +new file mode 100644 +index 0000000..6efb82c +--- /dev/null ++++ b/include/asm-nios2nommu/spi.h +@@ -0,0 +1,92 @@ ++#ifndef _ASM_SPI_H_ ++#define _ASM_SPI_H_ 1 ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/spi.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/nios.h> ++ ++int register_NIOS_SPI( void ); ++void unregister_NIOS_SPI( void ); ++ ++#if defined(MODULE) ++void cleanup_module( void ); ++int init_module( void ); ++#endif ++ ++#if defined(__KERNEL__) ++int spi_reset ( void ); ++#endif ++ ++ ++#define clockCS 0x01 ++#define temperatureCS 0x02 ++ ++#define clock_read_base 0x00 ++#define clock_write_base 0x80 ++#define clock_read_control 0x0F ++#define clock_read_trickle 0x11 ++ ++#define clock_read_sec 0x00 ++#define clock_read_min 0x01 ++#define clock_read_hour 0x02 ++#define clock_read_day 0x03 ++#define clock_read_date 0x04 ++#define clock_read_month 0x05 ++#define clock_read_year 0x06 ++ ++#define clock_write_control 0x8F ++#define clock_write_trickle 0x91 ++#define clock_write_sec 0x80 ++#define clock_write_min 0x81 ++#define clock_write_hour 0x82 ++#define clock_write_day 0x83 ++#define clock_write_date 0x84 ++#define clock_write_month 0x85 ++#define clock_write_year 0x86 ++ ++#define clock_write_ram_start 0xA0 ++#define clock_write_ram_end 0x100 ++#define clock_read_ram_start 0x20 ++#define clock_read_ram_end 0x80 ++ ++ ++#define clock_sec_def 0x11 ++#define clock_min_def 0x59 ++#define clock_hour_def 0x71 ++#define clock_day_def 0x00 ++#define clock_date_def 0x20 ++#define clock_month_def 0x12 ++#define clock_year_def 0x34 ++ ++#define temp_read_base 0x00 ++#define temp_write_base 0x80 ++#define temp_read_control 0x00 ++#define temp_write_control 0x80 ++#define temp_read_msb 0x02 ++#define temp_read_lsb 0x01 ++ ++#define MAX_TEMP_VAR 10 ++ ++#endif /*_ASM_SPI_H_*/ +diff --git a/include/asm-nios2nommu/spi_struct.h b/include/asm-nios2nommu/spi_struct.h +new file mode 100644 +index 0000000..c7b2faf +--- /dev/null ++++ b/include/asm-nios2nommu/spi_struct.h +@@ -0,0 +1,57 @@ ++// SPI Registers ++typedef volatile struct ++ { ++ int np_spirxdata; // Read-only, 1-16 bit ++ int np_spitxdata; // Write-only, same width as rxdata ++ int np_spistatus; // Read-only, 9-bit ++ int np_spicontrol; // Read/Write, 9-bit ++ int np_spireserved; // reserved ++ int np_spislaveselect; // Read/Write, 1-16 bit, master only ++ int np_spiendofpacket; // Read/write, same width as txdata, rxdata. ++ } np_spi; ++ ++// SPI Status Register Bits ++enum ++ { ++ np_spistatus_eop_bit = 9, ++ np_spistatus_e_bit = 8, ++ np_spistatus_rrdy_bit = 7, ++ np_spistatus_trdy_bit = 6, ++ np_spistatus_tmt_bit = 5, ++ np_spistatus_toe_bit = 4, ++ np_spistatus_roe_bit = 3, ++ ++ np_spistatus_eop_mask = (1 << 9), ++ np_spistatus_e_mask = (1 << 8), ++ np_spistatus_rrdy_mask = (1 << 7), ++ np_spistatus_trdy_mask = (1 << 6), ++ np_spistatus_tmt_mask = (1 << 5), ++ np_spistatus_toe_mask = (1 << 4), ++ np_spistatus_roe_mask = (1 << 3), ++ }; ++ ++// SPI Control Register Bits ++enum ++ { ++ np_spicontrol_sso_bit = 10, ++ np_spicontrol_ieop_bit = 9, ++ np_spicontrol_ie_bit = 8, ++ np_spicontrol_irrdy_bit = 7, ++ np_spicontrol_itrdy_bit = 6, ++ np_spicontrol_itoe_bit = 4, ++ np_spicontrol_iroe_bit = 3, ++ ++ np_spicontrol_sso_mask = (1 << 10), ++ np_spicontrol_ieop_mask = (1 << 9), ++ np_spicontrol_ie_mask = (1 << 8), ++ np_spicontrol_irrdy_mask = (1 << 7), ++ np_spicontrol_itrdy_mask = (1 << 6), ++ np_spicontrol_itoe_mask = (1 << 4), ++ np_spicontrol_iroe_mask = (1 << 3), ++ }; ++ ++// SPI Routines. ++int nr_spi_rxchar(np_spi *spiBase); ++int nr_spi_txchar(int i, np_spi *spiBase); ++ ++ +diff --git a/include/asm-nios2nommu/spinlock.h b/include/asm-nios2nommu/spinlock.h +new file mode 100644 +index 0000000..f518755 +--- /dev/null ++++ b/include/asm-nios2nommu/spinlock.h +@@ -0,0 +1,30 @@ ++#ifndef __NIOS_SPINLOCK_H ++#define __NIOS_SPINLOCK_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/spinlock.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 ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++#error "Nios doesn't do SMP yet" ++ ++#endif +diff --git a/include/asm-nios2nommu/stat.h b/include/asm-nios2nommu/stat.h +new file mode 100644 +index 0000000..bd27a97 +--- /dev/null ++++ b/include/asm-nios2nommu/stat.h +@@ -0,0 +1,102 @@ ++#ifndef _ASMNIOS2NOMMU_STAT_H ++#define _ASMNIOS2NOMMU_STAT_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/stat.h ++ * ++ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al ++ * ++ * Copyright (C) 2004 Microtronix Datacom Ltd ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * Jan/20/2004 dgt NiosII ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++struct __old_kernel_stat { ++ unsigned short st_dev; ++ unsigned short st_ino; ++ unsigned short st_mode; ++ unsigned short st_nlink; ++ unsigned short st_uid; ++ unsigned short st_gid; ++ unsigned short st_rdev; ++ unsigned long st_size; ++ unsigned long st_atime; ++ unsigned long st_mtime; ++ unsigned long st_ctime; ++}; ++ ++struct stat { ++ unsigned short st_dev; ++ unsigned short __pad1; ++ unsigned long st_ino; ++ unsigned short st_mode; ++ unsigned short st_nlink; ++ unsigned short st_uid; ++ unsigned short st_gid; ++ unsigned short st_rdev; ++ unsigned short __pad2; ++ unsigned long st_size; ++ unsigned long st_blksize; ++ unsigned long st_blocks; ++ unsigned long st_atime; ++ unsigned long __unused1; ++ unsigned long st_mtime; ++ unsigned long __unused2; ++ unsigned long st_ctime; ++ unsigned long __unused3; ++ unsigned long __unused4; ++ unsigned long __unused5; ++}; ++ ++/* This matches struct stat64 in glibc2.1, hence the absolutely ++ * insane amounts of padding around dev_t's. ++ */ ++struct stat64 { ++ unsigned long long st_dev; ++ unsigned char __pad1[4]; ++ ++#define STAT64_HAS_BROKEN_ST_INO 1 ++ unsigned long __st_ino; ++ ++ unsigned int st_mode; ++ unsigned int st_nlink; ++ ++ unsigned long st_uid; ++ unsigned long st_gid; ++ ++ unsigned long long st_rdev; ++ unsigned char __pad3[4]; ++ ++ long long st_size; ++ unsigned long st_blksize; ++ ++ unsigned long __pad4; /* future possible st_blocks high bits */ ++ unsigned long st_blocks; /* Number 512-byte blocks allocated. */ ++ ++ unsigned long st_atime; ++ unsigned long st_atime_nsec; ++ ++ unsigned long st_mtime; ++ unsigned long st_mtime_nsec; ++ ++ unsigned long st_ctime; ++ unsigned long st_ctime_nsec; ++ ++ unsigned long long st_ino; ++}; ++ ++#endif +diff --git a/include/asm-nios2nommu/statfs.h b/include/asm-nios2nommu/statfs.h +new file mode 100644 +index 0000000..c4637f6 +--- /dev/null ++++ b/include/asm-nios2nommu/statfs.h +@@ -0,0 +1,30 @@ ++#ifndef _NIOS2NOMMU_STATFS_H ++#define _NIOS2NOMMU_STATFS_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/statfs.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/statfs.h> ++ ++#endif /* _NIOS2NOMMU_STATFS_H */ +diff --git a/include/asm-nios2nommu/string.h b/include/asm-nios2nommu/string.h +new file mode 100644 +index 0000000..7e39479 +--- /dev/null ++++ b/include/asm-nios2nommu/string.h +@@ -0,0 +1,45 @@ ++#ifndef __NIOS_STRING_H__ ++#define __NIOS_STRING_H__ ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/string.h ++ * ++ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al ++ * ++ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) ++ * Copyright (C) 2004 Microtronix Datacom Ltd ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * Jan/20/2004 dgt NiosII ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++#ifdef __KERNEL__ /* only set these up for kernel code */ ++ ++#define __HAVE_ARCH_MEMMOVE ++void * memmove(void * d, const void * s, size_t count); ++#define __HAVE_ARCH_MEMCPY ++extern void * memcpy(void *d, const void *s, size_t count); ++#define __HAVE_ARCH_MEMSET ++extern void * memset(void * s,int c,size_t count); ++ ++#if 0 ++#define __HAVE_ARCH_BCOPY ++#define __HAVE_ARCH_STRLEN ++#endif ++ ++#endif /* KERNEL */ ++ ++#endif /* !(__NIOS_STRING_H__) */ +diff --git a/include/asm-nios2nommu/system.h b/include/asm-nios2nommu/system.h +new file mode 100644 +index 0000000..7c35af0 +--- /dev/null ++++ b/include/asm-nios2nommu/system.h +@@ -0,0 +1,172 @@ ++/* ++ * Taken from the m68k. ++ * ++ * Copyright (C) 2004, Microtronix Datacom Ltd. ++ * ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or ++ * NON INFRINGEMENT. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++#ifndef _NIOS2NOMMU_SYSTEM_H ++#define _NIOS2NOMMU_SYSTEM_H ++ ++#include <linux/linkage.h> ++#include <linux/compiler.h> ++#include <asm/segment.h> ++#include <asm/entry.h> ++#include <asm/nios.h> ++ ++/* ++ * switch_to(n) should switch tasks to task ptr, first checking that ++ * ptr isn't the current task, in which case it does nothing. This ++ * also clears the TS-flag if the task we switched to has used the ++ * math co-processor latest. ++ */ ++ ++/* ++ */ ++asmlinkage void resume(void); ++#define switch_to(prev,next,last) \ ++{ \ ++ void *_last; \ ++ __asm__ __volatile__( \ ++ "mov r4, %1\n" \ ++ "mov r5, %2\n" \ ++ "call resume\n" \ ++ "mov %0,r4\n" \ ++ : "=r" (_last) \ ++ : "r" (prev), "r" (next) \ ++ : "r4","r5","r7","r8","ra"); \ ++ (last) = _last; \ ++} ++ ++#define local_irq_enable() __asm__ __volatile__ ( \ ++ "rdctl r8, status\n" \ ++ "ori r8, r8, 1\n" \ ++ "wrctl status, r8\n" \ ++ : : : "r8") ++ ++#define local_irq_disable() __asm__ __volatile__ ( \ ++ "rdctl r8, status\n" \ ++ "andi r8, r8, 0xfffe\n" \ ++ "wrctl status, r8\n" \ ++ : : : "r8") ++ ++#define local_save_flags(x) __asm__ __volatile__ ( \ ++ "rdctl r8, status\n" \ ++ "mov %0, r8\n" \ ++ :"=r" (x) : : "r8", "memory") ++ ++#define local_irq_restore(x) __asm__ __volatile__ ( \ ++ "mov r8, %0\n" \ ++ "wrctl status, r8\n" \ ++ : :"r" (x) : "memory") ++ ++/* For spinlocks etc */ ++#define local_irq_save(x) do { local_save_flags(x); local_irq_disable(); } while (0) ++ ++#define irqs_disabled() \ ++({ \ ++ unsigned long flags; \ ++ local_save_flags(flags); \ ++ ((flags & NIOS2_STATUS_PIE_MSK) == 0x0); \ ++}) ++ ++#define iret() __asm__ __volatile__ ("eret": : :"memory", "ea") ++ ++/* ++ * Force strict CPU ordering. ++ * Not really required on m68k... ++ */ ++#define nop() asm volatile ("nop"::) ++#define mb() asm volatile ("" : : :"memory") ++#define rmb() asm volatile ("" : : :"memory") ++#define wmb() asm volatile ("" : : :"memory") ++#define set_rmb(var, value) do { xchg(&var, value); } while (0) ++#define set_mb(var, value) set_rmb(var, value) ++#define set_wmb(var, value) do { var = value; wmb(); } while (0) ++ ++#ifdef CONFIG_SMP ++#define smp_mb() mb() ++#define smp_rmb() rmb() ++#define smp_wmb() wmb() ++#define smp_read_barrier_depends() read_barrier_depends() ++#else ++#define smp_mb() barrier() ++#define smp_rmb() barrier() ++#define smp_wmb() barrier() ++#define smp_read_barrier_depends() do { } while(0) ++#endif ++ ++#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) ++#define tas(ptr) (xchg((ptr),1)) ++ ++struct __xchg_dummy { unsigned long a[100]; }; ++#define __xg(x) ((volatile struct __xchg_dummy *)(x)) ++ ++static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) ++{ ++ unsigned long tmp, flags; ++ ++ local_irq_save(flags); ++ ++ switch (size) { ++ case 1: ++ __asm__ __volatile__( \ ++ "ldb %0, %2\n" \ ++ "stb %1, %2\n" \ ++ : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory"); ++ break; ++ case 2: ++ __asm__ __volatile__( \ ++ "ldh %0, %2\n" \ ++ "sth %1, %2\n" \ ++ : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory"); ++ break; ++ case 4: ++ __asm__ __volatile__( \ ++ "ldw %0, %2\n" \ ++ "stw %1, %2\n" \ ++ : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory"); ++ break; ++ } ++ local_irq_restore(flags); ++ return tmp; ++} ++ ++/* ++ * Atomic compare and exchange. Compare OLD with MEM, if identical, ++ * store NEW in MEM. Return the initial value in MEM. Success is ++ * indicated by comparing RETURN with OLD. ++ */ ++#define __HAVE_ARCH_CMPXCHG 1 ++ ++static __inline__ unsigned long ++cmpxchg(volatile int *p, int old, int new) ++{ ++ unsigned long flags; ++ int prev; ++ ++ local_irq_save(flags); ++ if ((prev = *p) == old) ++ *p = new; ++ local_irq_restore(flags); ++ return(prev); ++} ++ ++#endif /* _NIOS2NOMMU_SYSTEM_H */ +diff --git a/include/asm-nios2nommu/termbits.h b/include/asm-nios2nommu/termbits.h +new file mode 100644 +index 0000000..74ef61d +--- /dev/null ++++ b/include/asm-nios2nommu/termbits.h +@@ -0,0 +1,210 @@ ++#ifndef __ARCH_NIOS_TERMBITS_H__ ++#define __ARCH_NIOS_TERMBITS_H__ ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/termbits.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 <linux/posix_types.h> ++ ++typedef unsigned char cc_t; ++typedef unsigned int speed_t; ++typedef unsigned int tcflag_t; ++ ++#define NCCS 19 ++struct termios { ++ tcflag_t c_iflag; /* input mode flags */ ++ tcflag_t c_oflag; /* output mode flags */ ++ tcflag_t c_cflag; /* control mode flags */ ++ tcflag_t c_lflag; /* local mode flags */ ++ cc_t c_line; /* line discipline */ ++ cc_t c_cc[NCCS]; /* control characters */ ++}; ++ ++struct ktermios { ++ tcflag_t c_iflag; /* input mode flags */ ++ tcflag_t c_oflag; /* output mode flags */ ++ tcflag_t c_cflag; /* control mode flags */ ++ tcflag_t c_lflag; /* local mode flags */ ++ cc_t c_line; /* line discipline */ ++ cc_t c_cc[NCCS]; /* control characters */ ++ speed_t c_ispeed; /* input speed */ ++ speed_t c_ospeed; /* output speed */ ++}; ++ ++/* c_cc characters */ ++#define VINTR 0 ++#define VQUIT 1 ++#define VERASE 2 ++#define VKILL 3 ++#define VEOF 4 ++#define VTIME 5 ++#define VMIN 6 ++#define VSWTC 7 ++#define VSTART 8 ++#define VSTOP 9 ++#define VSUSP 10 ++#define VEOL 11 ++#define VREPRINT 12 ++#define VDISCARD 13 ++#define VWERASE 14 ++#define VLNEXT 15 ++#define VEOL2 16 ++ ++ ++/* c_iflag bits */ ++#define IGNBRK 0000001 ++#define BRKINT 0000002 ++#define IGNPAR 0000004 ++#define PARMRK 0000010 ++#define INPCK 0000020 ++#define ISTRIP 0000040 ++#define INLCR 0000100 ++#define IGNCR 0000200 ++#define ICRNL 0000400 ++#define IUCLC 0001000 ++#define IXON 0002000 ++#define IXANY 0004000 ++#define IXOFF 0010000 ++#define IMAXBEL 0020000 ++#define IUTF8 0040000 ++ ++/* c_oflag bits */ ++#define OPOST 0000001 ++#define OLCUC 0000002 ++#define ONLCR 0000004 ++#define OCRNL 0000010 ++#define ONOCR 0000020 ++#define ONLRET 0000040 ++#define OFILL 0000100 ++#define OFDEL 0000200 ++#define NLDLY 0000400 ++#define NL0 0000000 ++#define NL1 0000400 ++#define CRDLY 0003000 ++#define CR0 0000000 ++#define CR1 0001000 ++#define CR2 0002000 ++#define CR3 0003000 ++#define TABDLY 0014000 ++#define TAB0 0000000 ++#define TAB1 0004000 ++#define TAB2 0010000 ++#define TAB3 0014000 ++#define XTABS 0014000 ++#define BSDLY 0020000 ++#define BS0 0000000 ++#define BS1 0020000 ++#define VTDLY 0040000 ++#define VT0 0000000 ++#define VT1 0040000 ++#define FFDLY 0100000 ++#define FF0 0000000 ++#define FF1 0100000 ++ ++/* c_cflag bit meaning */ ++#define CBAUD 0010017 ++#define B0 0000000 /* hang up */ ++#define B50 0000001 ++#define B75 0000002 ++#define B110 0000003 ++#define B134 0000004 ++#define B150 0000005 ++#define B200 0000006 ++#define B300 0000007 ++#define B600 0000010 ++#define B1200 0000011 ++#define B1800 0000012 ++#define B2400 0000013 ++#define B4800 0000014 ++#define B9600 0000015 ++#define B19200 0000016 ++#define B38400 0000017 ++#define EXTA B19200 ++#define EXTB B38400 ++#define CSIZE 0000060 ++#define CS5 0000000 ++#define CS6 0000020 ++#define CS7 0000040 ++#define CS8 0000060 ++#define CSTOPB 0000100 ++#define CREAD 0000200 ++#define PARENB 0000400 ++#define PARODD 0001000 ++#define HUPCL 0002000 ++#define CLOCAL 0004000 ++#define CBAUDEX 0010000 ++#define B57600 0010001 ++#define B115200 0010002 ++#define B230400 0010003 ++#define B460800 0010004 ++#define B500000 0010005 ++#define B576000 0010006 ++#define B921600 0010007 ++#define B1000000 0010010 ++#define B1152000 0010011 ++#define B1500000 0010012 ++#define B2000000 0010013 ++#define B2500000 0010014 ++#define B3000000 0010015 ++#define B3500000 0010016 ++#define B4000000 0010017 ++#define CIBAUD 002003600000 /* input baud rate (not used) */ ++#define CMSPAR 010000000000 /* mark or space (stick) parity */ ++#define CRTSCTS 020000000000 /* flow control */ ++ ++/* c_lflag bits */ ++#define ISIG 0000001 ++#define ICANON 0000002 ++#define XCASE 0000004 ++#define ECHO 0000010 ++#define ECHOE 0000020 ++#define ECHOK 0000040 ++#define ECHONL 0000100 ++#define NOFLSH 0000200 ++#define TOSTOP 0000400 ++#define ECHOCTL 0001000 ++#define ECHOPRT 0002000 ++#define ECHOKE 0004000 ++#define FLUSHO 0010000 ++#define PENDIN 0040000 ++#define IEXTEN 0100000 ++ ++ ++/* tcflow() and TCXONC use these */ ++#define TCOOFF 0 ++#define TCOON 1 ++#define TCIOFF 2 ++#define TCION 3 ++ ++/* tcflush() and TCFLSH use these */ ++#define TCIFLUSH 0 ++#define TCOFLUSH 1 ++#define TCIOFLUSH 2 ++ ++/* tcsetattr uses these */ ++#define TCSANOW 0 ++#define TCSADRAIN 1 ++#define TCSAFLUSH 2 ++ ++#endif /* __ARCH_NIOS_TERMBITS_H__ */ +diff --git a/include/asm-nios2nommu/termios.h b/include/asm-nios2nommu/termios.h +new file mode 100644 +index 0000000..db0dddf +--- /dev/null ++++ b/include/asm-nios2nommu/termios.h +@@ -0,0 +1,132 @@ ++#ifndef _NIOS_TERMIOS_H ++#define _NIOS_TERMIOS_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/termios.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/termbits.h> ++#include <asm/ioctls.h> ++ ++struct winsize { ++ unsigned short ws_row; ++ unsigned short ws_col; ++ unsigned short ws_xpixel; ++ unsigned short ws_ypixel; ++}; ++ ++#define NCC 8 ++struct termio { ++ unsigned short c_iflag; /* input mode flags */ ++ unsigned short c_oflag; /* output mode flags */ ++ unsigned short c_cflag; /* control mode flags */ ++ unsigned short c_lflag; /* local mode flags */ ++ unsigned char c_line; /* line discipline */ ++ unsigned char c_cc[NCC]; /* control characters */ ++}; ++ ++#ifdef __KERNEL__ ++/* intr=^C quit=^| erase=del kill=^U ++ eof=^D vtime=\0 vmin=\1 sxtc=\0 ++ start=^Q stop=^S susp=^Z eol=\0 ++ reprint=^R discard=^U werase=^W lnext=^V ++ eol2=\0 ++*/ ++#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" ++#endif ++ ++/* modem lines */ ++#define TIOCM_LE 0x001 ++#define TIOCM_DTR 0x002 ++#define TIOCM_RTS 0x004 ++#define TIOCM_ST 0x008 ++#define TIOCM_SR 0x010 ++#define TIOCM_CTS 0x020 ++#define TIOCM_CAR 0x040 ++#define TIOCM_RNG 0x080 ++#define TIOCM_DSR 0x100 ++#define TIOCM_CD TIOCM_CAR ++#define TIOCM_RI TIOCM_RNG ++#define TIOCM_OUT1 0x2000 ++#define TIOCM_OUT2 0x4000 ++#define TIOCM_LOOP 0x8000 ++ ++/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ ++ ++/* line disciplines */ ++#define N_TTY 0 ++#define N_SLIP 1 ++#define N_MOUSE 2 ++#define N_PPP 3 ++#define N_STRIP 4 ++#define N_AX25 5 ++#define N_X25 6 /* X.25 async */ ++#define N_6PACK 7 ++#define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */ ++#define N_R3964 9 /* Reserved for Simatic R3964 module */ ++#define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */ ++#define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */ ++#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ ++#define N_HDLC 13 /* synchronous HDLC */ ++#define N_SYNC_PPP 14 ++#define N_HCI 15 /* Bluetooth HCI UART */ ++ ++#ifdef __KERNEL__ ++ ++/* ++ * Translate a "termio" structure into a "termios". Ugh. ++ */ ++#define user_termio_to_kernel_termios(termios, termio) \ ++({ \ ++ unsigned short tmp; \ ++ get_user(tmp, &(termio)->c_iflag); \ ++ (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ ++ get_user(tmp, &(termio)->c_oflag); \ ++ (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ ++ get_user(tmp, &(termio)->c_cflag); \ ++ (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ ++ get_user(tmp, &(termio)->c_lflag); \ ++ (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ ++ get_user((termios)->c_line, &(termio)->c_line); \ ++ copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ ++}) ++ ++/* ++ * Translate a "termios" structure into a "termio". Ugh. ++ */ ++#define kernel_termios_to_user_termio(termio, termios) \ ++({ \ ++ put_user((termios)->c_iflag, &(termio)->c_iflag); \ ++ put_user((termios)->c_oflag, &(termio)->c_oflag); \ ++ put_user((termios)->c_cflag, &(termio)->c_cflag); \ ++ put_user((termios)->c_lflag, &(termio)->c_lflag); \ ++ put_user((termios)->c_line, &(termio)->c_line); \ ++ copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ ++}) ++ ++#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) ++#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* _NIOS_TERMIOS_H */ +diff --git a/include/asm-nios2nommu/thread_info.h b/include/asm-nios2nommu/thread_info.h +new file mode 100644 +index 0000000..6d51e0c +--- /dev/null ++++ b/include/asm-nios2nommu/thread_info.h +@@ -0,0 +1,127 @@ ++/* thread_info.h: niosnommu low-level thread information ++ * adapted from the m68knommu ++ * ++ * Copyright (C) 2004 Microtronix Datacom Ltd. ++ * Copyright (C) 2002 Microtronix Datacom ++ * ++ * - Incorporating suggestions made by Linus Torvalds and Dave Miller ++ * ++ * 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_THREAD_INFO_H ++#define _ASM_THREAD_INFO_H ++ ++#include <asm/page.h> ++ ++#ifdef __KERNEL__ ++ ++#ifndef __ASSEMBLY__ ++ ++/* ++ * low level task data. ++ */ ++struct thread_info { ++ struct task_struct *task; /* main task structure */ ++ struct exec_domain *exec_domain; /* execution domain */ ++ unsigned long flags; /* low level flags */ ++ int cpu; /* cpu we're on */ ++ int preempt_count; /* 0 => preemptable, <0 => BUG*/ ++ struct restart_block restart_block; ++}; ++ ++/* ++ * macros/functions for gaining access to the thread information structure ++ */ ++#define INIT_THREAD_INFO(tsk) \ ++{ \ ++ .task = &tsk, \ ++ .exec_domain = &default_exec_domain, \ ++ .flags = 0, \ ++ .cpu = 0, \ ++ .preempt_count = 1, \ ++ .restart_block = { \ ++ .fn = do_no_restart_syscall, \ ++ }, \ ++} ++ ++#define init_thread_info (init_thread_union.thread_info) ++#define init_stack (init_thread_union.stack) ++ ++ ++/* how to get the thread information struct from C ++ usable only in supervisor mode */ ++static inline struct thread_info *current_thread_info(void) ++{ ++ struct thread_info *ti; ++ __asm__ __volatile__( ++ "mov %0, sp\n" ++ "and %0, %0, %1\n" ++ : "=&r"(ti) ++ : "r" (~(THREAD_SIZE-1)) ++ ); ++ return ti; ++} ++ ++/* thread information allocation */ ++#define alloc_thread_info(tsk) ((struct thread_info *) \ ++ __get_free_pages(GFP_KERNEL, 1)) ++#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) ++#define put_thread_info(ti) put_task_struct((ti)->task) ++ ++#define PREEMPT_ACTIVE 0x4000000 ++ ++/* ++ * thread information flag bit numbers ++ */ ++#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ ++#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ ++#define TIF_SIGPENDING 2 /* signal pending */ ++#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ ++#define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling ++ TIF_NEED_RESCHED */ ++#define TIF_MEMDIE 5 ++ ++/* as above, but as bit values */ ++#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) ++#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) ++#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) ++#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) ++#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) ++ ++#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ ++ ++#else /* __ASSEMBLY__ */ ++ ++/* how to get the thread information struct from ASM ++ usable only in supervisor mode */ ++.macro GET_THREAD_INFO reg ++.if THREAD_SIZE & 0xffff0000 ++ andhi \reg, sp, %hi(~(THREAD_SIZE-1)) ++.else ++ addi \reg, r0, %lo(~(THREAD_SIZE-1)) ++ and \reg, \reg, sp ++.endif ++.endm ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* _ASM_THREAD_INFO_H */ +diff --git a/include/asm-nios2nommu/timer_struct.h b/include/asm-nios2nommu/timer_struct.h +new file mode 100644 +index 0000000..d811a37 +--- /dev/null ++++ b/include/asm-nios2nommu/timer_struct.h +@@ -0,0 +1,38 @@ ++ ++// ---------------------------------------------- ++// Timer Peripheral ++ ++// Timer Registers ++typedef volatile struct ++ { ++ int np_timerstatus; // read only, 2 bits (any write to clear TO) ++ int np_timercontrol; // write/readable, 4 bits ++ int np_timerperiodl; // write/readable, 16 bits ++ int np_timerperiodh; // write/readable, 16 bits ++ int np_timersnapl; // read only, 16 bits ++ int np_timersnaph; // read only, 16 bits ++ } np_timer; ++ ++// Timer Register Bits ++enum ++ { ++ np_timerstatus_run_bit = 1, // timer is running ++ np_timerstatus_to_bit = 0, // timer has timed out ++ ++ np_timercontrol_stop_bit = 3, // stop the timer ++ np_timercontrol_start_bit = 2, // start the timer ++ np_timercontrol_cont_bit = 1, // continous mode ++ np_timercontrol_ito_bit = 0, // enable time out interrupt ++ ++ np_timerstatus_run_mask = (1<<1), // timer is running ++ np_timerstatus_to_mask = (1<<0), // timer has timed out ++ ++ np_timercontrol_stop_mask = (1<<3), // stop the timer ++ np_timercontrol_start_mask = (1<<2), // start the timer ++ np_timercontrol_cont_mask = (1<<1), // continous mode ++ np_timercontrol_ito_mask = (1<<0) // enable time out interrupt ++ }; ++ ++// Timer Routines ++int nr_timer_milliseconds(void); // Starts on first call, hogs timer1. ++ +diff --git a/include/asm-nios2nommu/timex.h b/include/asm-nios2nommu/timex.h +new file mode 100644 +index 0000000..abd48cc +--- /dev/null ++++ b/include/asm-nios2nommu/timex.h +@@ -0,0 +1,48 @@ ++#ifndef _ASMNIOS2NOMMU_TIMEX_H ++#define _ASMNIOS2NOMMU_TIMEX_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/timex.h ++ * ++ * timex specifications ++ * ++ * 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/nios.h> ++ ++ ++#define CLOCK_TICK_RATE nasys_clock_freq /* Underlying HZ */ ++ ++#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ ++ ++#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \ ++ (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \ ++ << (SHIFT_SCALE-SHIFT_HZ)) / HZ) ++ ++typedef unsigned long cycles_t; ++ ++static inline cycles_t get_cycles(void) ++{ ++ return 0; ++} ++ ++#endif +diff --git a/include/asm-nios2nommu/tlb.h b/include/asm-nios2nommu/tlb.h +new file mode 100644 +index 0000000..c597b25 +--- /dev/null ++++ b/include/asm-nios2nommu/tlb.h +@@ -0,0 +1,35 @@ ++#ifndef __NIOS_TLB_H__ ++#define __NIOS_TLB_H__ ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/tlb.h ++ * ++ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al ++ * ++ * Copyright (C) 2003 Microtronix Datacom Ltd ++ * Copyright (C) 2002 NEC Corporation ++ * Copyright (C) 2002 Miles Bader <miles@gnu.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. ++ * ++ * 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. ++ * ++ * ++ * Written by Miles Bader <miles@gnu.org> ++ * Jan/20/2004 dgt NiosII ++ * ++ ---------------------------------------------------------------------*/ ++ ++#define tlb_flush(tlb) ((void)0) ++ ++#include <asm-generic/tlb.h> ++ ++#endif /* __NIOS_TLB_H__ */ ++ +diff --git a/include/asm-nios2nommu/tlbflush.h b/include/asm-nios2nommu/tlbflush.h +new file mode 100644 +index 0000000..63cbe52 +--- /dev/null ++++ b/include/asm-nios2nommu/tlbflush.h +@@ -0,0 +1,86 @@ ++#ifndef _NIOS2NOMMU_TLBFLUSH_H ++#define _NIOS2NOMMU_TLBFLUSH_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/tlbflush.h ++ * ++ * Ported from m68knommu. ++ * ++ * 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 <asm/setup.h> ++ ++/* ++ * flush all user-space atc entries. ++ */ ++static inline void __flush_tlb(void) ++{ ++ BUG(); ++} ++ ++static inline void __flush_tlb_one(unsigned long addr) ++{ ++ BUG(); ++} ++ ++#define flush_tlb() __flush_tlb() ++ ++/* ++ * flush all atc entries (both kernel and user-space entries). ++ */ ++static inline void flush_tlb_all(void) ++{ ++ BUG(); ++} ++ ++static inline void flush_tlb_mm(struct mm_struct *mm) ++{ ++ BUG(); ++} ++ ++static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) ++{ ++ BUG(); ++} ++ ++static inline void flush_tlb_range(struct mm_struct *mm, ++ unsigned long start, unsigned long end) ++{ ++ BUG(); ++} ++ ++extern inline void flush_tlb_kernel_page(unsigned long addr) ++{ ++ BUG(); ++} ++ ++extern inline void flush_tlb_pgtables(struct mm_struct *mm, ++ unsigned long start, unsigned long end) ++{ ++ BUG(); ++} ++ ++#endif /* _NIOS2NOMMU_TLBFLUSH_H */ +diff --git a/include/asm-nios2nommu/topology.h b/include/asm-nios2nommu/topology.h +new file mode 100644 +index 0000000..cfe1054 +--- /dev/null ++++ b/include/asm-nios2nommu/topology.h +@@ -0,0 +1,30 @@ ++#ifndef _ASM_NIOS2NOMMU_TOPOLOGY_H ++#define _ASM_NIOS2NOMMU_TOPOLOGY_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/topology.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-generic/topology.h> ++ ++#endif /* _ASM_NIOS2NOMMU_TOPOLOGY_H */ +diff --git a/include/asm-nios2nommu/traps.h b/include/asm-nios2nommu/traps.h +new file mode 100644 +index 0000000..e03ef7f +--- /dev/null ++++ b/include/asm-nios2nommu/traps.h +@@ -0,0 +1,27 @@ ++/* ++ * Copyright (C) 2004, Microtronix Datacom Ltd. ++ * ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or ++ * NON INFRINGEMENT. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++#ifndef _NIOS2_TRAPS_H ++#define _NIOS2_TRAPS_H ++ ++#define TRAP_ID_SYSCALL 0 ++#define TRAP_ID_APPDEBUG 1 ++#endif /* !(_NIOS2_TRAPS_H) */ +diff --git a/include/asm-nios2nommu/types.h b/include/asm-nios2nommu/types.h +new file mode 100644 +index 0000000..dd7a48e +--- /dev/null ++++ b/include/asm-nios2nommu/types.h +@@ -0,0 +1,91 @@ ++#ifndef _NIOS_TYPES_H ++#define _NIOS_TYPES_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/types.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 ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++/* ++ * This file is never included by application software unless ++ * explicitly requested (e.g., via linux/types.h) in which case the ++ * application is Linux specific so (user-) name space pollution is ++ * not a major issue. However, for interoperability, libraries still ++ * need to be careful to avoid a name clashes. ++ */ ++ ++#ifndef __ASSEMBLY__ ++ ++typedef unsigned short umode_t; ++ ++/* ++ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the ++ * header files exported to user space ++ */ ++ ++typedef __signed__ char __s8; ++typedef unsigned char __u8; ++ ++typedef __signed__ short __s16; ++typedef unsigned short __u16; ++ ++typedef __signed__ int __s32; ++typedef unsigned int __u32; ++ ++#if defined(__GNUC__) && !defined(__STRICT_ANSI__) ++typedef __signed__ long long __s64; ++typedef unsigned long long __u64; ++#endif ++ ++#endif /* __ASSEMBLY__ */ ++ ++/* ++ * These aren't exported outside the kernel to avoid name space clashes ++ */ ++#ifdef __KERNEL__ ++ ++#define BITS_PER_LONG 32 ++ ++#ifndef __ASSEMBLY__ ++ ++typedef signed char s8; ++typedef unsigned char u8; ++ ++typedef signed short s16; ++typedef unsigned short u16; ++ ++typedef signed int s32; ++typedef unsigned int u32; ++ ++typedef signed long long s64; ++typedef unsigned long long u64; ++ ++/* DMA addresses are always 32-bits wide */ ++ ++typedef u32 dma_addr_t; ++typedef u32 dma64_addr_t; ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* _NIOS_TYPES_H */ +diff --git a/include/asm-nios2nommu/uaccess.h b/include/asm-nios2nommu/uaccess.h +new file mode 100644 +index 0000000..e7ea20a +--- /dev/null ++++ b/include/asm-nios2nommu/uaccess.h +@@ -0,0 +1,184 @@ ++#ifndef __NIOS2NOMMU_UACCESS_H ++#define __NIOS2NOMMU_UACCESS_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * asm-nios2nommu/uaccess.h ++ * ++ * User space memory access 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. ++ * ++ * ++ * Ported from asm-m68knommu/uaccess.h --wentao ++ * Jan/20/2004 dgt NiosII ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++#include <linux/sched.h> ++#include <linux/mm.h> ++#include <asm/segment.h> ++#include <asm/nios.h> ++ ++#define VERIFY_READ 0 ++#define VERIFY_WRITE 1 ++ ++#define access_ok(type,addr,size) _access_ok((unsigned long)(addr),(size)) ++ ++static inline int _access_ok(unsigned long addr, unsigned long size) ++{ ++ return (((unsigned long)addr < (unsigned long)nasys_program_mem_end) && ++ (((unsigned long)addr >= (unsigned long)nasys_program_mem))); ++} ++ ++extern inline int verify_area(int type, const void * addr, unsigned long size) ++{ ++ return access_ok(type,addr,size)?0:-EFAULT; ++} ++ ++/* ++ * The exception table consists of pairs of addresses: the first is the ++ * address of an instruction that is allowed to fault, and the second is ++ * the address at which the program should continue. No registers are ++ * modified, so it is entirely up to the continuation code to figure out ++ * what to do. ++ * ++ * All the routines below use bits of fixup code that are out of line ++ * with the main instruction path. This means when everything is well, ++ * we don't even have to jump over them. Further, they do not intrude ++ * on our cache or tlb entries. ++ */ ++ ++#define ARCH_HAS_SEARCH_EXTABLE ++//;dgt2;tmp; ++ ++struct exception_table_entry ++{ ++ unsigned long insn, fixup; ++}; ++ ++/* Returns 0 if exception not found and fixup otherwise. */ ++extern unsigned long search_exception_table(unsigned long); ++ ++ ++/* ++ * These are the main single-value transfer routines. They automatically ++ * use the right size if we just have the right pointer type. ++ */ ++ ++#define put_user(x, ptr) \ ++({ \ ++ int __pu_err = 0; \ ++ typeof(*(ptr)) __pu_val = (x); \ ++ switch (sizeof (*(ptr))) { \ ++ case 1: \ ++ case 2: \ ++ case 4: \ ++ case 8: \ ++ memcpy(ptr, &__pu_val, sizeof (*(ptr))); \ ++ break; \ ++ default: \ ++ __pu_err = __put_user_bad(); \ ++ break; \ ++ } \ ++ __pu_err; \ ++}) ++#define __put_user(x, ptr) put_user(x, ptr) ++ ++extern int __put_user_bad(void); ++ ++/* ++ * Tell gcc we read from memory instead of writing: this is because ++ * we do not write to any memory gcc knows about, so there are no ++ * aliasing issues. ++ */ ++ ++#define __ptr(x) ((unsigned long *)(x)) ++ ++#define get_user(x, ptr) \ ++({ \ ++ int __gu_err = 0; \ ++ typeof(*(ptr)) __gu_val = 0; \ ++ switch (sizeof(*(ptr))) { \ ++ case 1: \ ++ case 2: \ ++ case 4: \ ++ case 8: \ ++ memcpy(&__gu_val, ptr, sizeof (*(ptr))); \ ++ break; \ ++ default: \ ++ __gu_val = 0; \ ++ __gu_err = __get_user_bad(); \ ++ break; \ ++ } \ ++ (x) = __gu_val; \ ++ __gu_err; \ ++}) ++#define __get_user(x, ptr) get_user(x, ptr) ++ ++extern int __get_user_bad(void); ++ ++#define copy_from_user(to, from, n) (memcpy(to, from, n), 0) ++#define copy_to_user(to, from, n) (memcpy(to, from, n), 0) ++ ++#define __copy_from_user(to, from, n) copy_from_user(to, from, n) ++#define __copy_to_user(to, from, n) copy_to_user(to, from, n) ++#define __copy_to_user_inatomic __copy_to_user ++#define __copy_from_user_inatomic __copy_from_user ++ ++#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; }) ++ ++#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; }) ++ ++/* ++ * Copy a null terminated string from userspace. ++ */ ++ ++static inline long ++strncpy_from_user(char *dst, const char *src, long count) ++{ ++ char *tmp; ++ strncpy(dst, src, count); ++ for (tmp = dst; *tmp && count > 0; tmp++, count--) ++ ; ++ return(tmp - dst); /* DAVIDM should we count a NUL ? check getname */ ++} ++ ++/* ++ * Return the size of a string (including the ending 0) ++ * ++ * Return 0 on exception, a value greater than N if too long ++ */ ++static inline long strnlen_user(const char *src, long n) ++{ ++ return(strlen(src) + 1); /* DAVIDM make safer */ ++} ++ ++#define strlen_user(str) strnlen_user(str, 32767) ++ ++/* ++ * Zero Userspace ++ */ ++ ++static inline unsigned long __clear_user(void *to, unsigned long n) ++{ ++ memset(to, 0, n); ++ return(0); ++} ++ ++#define clear_user(to, n) __clear_user(to, n) ++ ++#endif /* _NIOS2NOMMU_UACCESS_H */ +diff --git a/include/asm-nios2nommu/uart_struct.h b/include/asm-nios2nommu/uart_struct.h +new file mode 100644 +index 0000000..d955192 +--- /dev/null ++++ b/include/asm-nios2nommu/uart_struct.h +@@ -0,0 +1,83 @@ ++ ++// UART Registers ++typedef volatile struct ++ { ++ int np_uartrxdata; // Read-only, 8-bit ++ int np_uarttxdata; // Write-only, 8-bit ++ int np_uartstatus; // Read-only, 8-bit ++ int np_uartcontrol; // Read/Write, 9-bit ++ int np_uartdivisor; // Read/Write, 16-bit, optional ++ int np_uartendofpacket; // Read/Write, end-of-packet character ++ } np_uart; ++ ++// UART Status Register Bits ++enum ++ { ++ np_uartstatus_eop_bit = 12, ++ np_uartstatus_cts_bit = 11, ++ np_uartstatus_dcts_bit = 10, ++ np_uartstatus_e_bit = 8, ++ np_uartstatus_rrdy_bit = 7, ++ np_uartstatus_trdy_bit = 6, ++ np_uartstatus_tmt_bit = 5, ++ np_uartstatus_toe_bit = 4, ++ np_uartstatus_roe_bit = 3, ++ np_uartstatus_brk_bit = 2, ++ np_uartstatus_fe_bit = 1, ++ np_uartstatus_pe_bit = 0, ++ ++ np_uartstatus_eop_mask = (1<<12), ++ np_uartstatus_cts_mask = (1<<11), ++ np_uartstatus_dcts_mask = (1<<10), ++ np_uartstatus_e_mask = (1<<8), ++ np_uartstatus_rrdy_mask = (1<<7), ++ np_uartstatus_trdy_mask = (1<<6), ++ np_uartstatus_tmt_mask = (1<<5), ++ np_uartstatus_toe_mask = (1<<4), ++ np_uartstatus_roe_mask = (1<<3), ++ np_uartstatus_brk_mask = (1<<2), ++ np_uartstatus_fe_mask = (1<<1), ++ np_uartstatus_pe_mask = (1<<0) ++ }; ++ ++// UART Control Register Bits ++enum ++ { ++ np_uartcontrol_ieop_bit = 12, ++ np_uartcontrol_rts_bit = 11, ++ np_uartcontrol_idcts_bit = 10, ++ np_uartcontrol_tbrk_bit = 9, ++ np_uartcontrol_ie_bit = 8, ++ np_uartcontrol_irrdy_bit = 7, ++ np_uartcontrol_itrdy_bit = 6, ++ np_uartcontrol_itmt_bit = 5, ++ np_uartcontrol_itoe_bit = 4, ++ np_uartcontrol_iroe_bit = 3, ++ np_uartcontrol_ibrk_bit = 2, ++ np_uartcontrol_ife_bit = 1, ++ np_uartcontrol_ipe_bit = 0, ++ ++ np_uartcontrol_ieop_mask = (1<<12), ++ np_uartcontrol_rts_mask = (1<<11), ++ np_uartcontrol_idcts_mask = (1<<10), ++ np_uartcontrol_tbrk_mask = (1<<9), ++ np_uartcontrol_ie_mask = (1<<8), ++ np_uartcontrol_irrdy_mask = (1<<7), ++ np_uartcontrol_itrdy_mask = (1<<6), ++ np_uartcontrol_itmt_mask = (1<<5), ++ np_uartcontrol_itoe_mask = (1<<4), ++ np_uartcontrol_iroe_mask = (1<<3), ++ np_uartcontrol_ibrk_mask = (1<<2), ++ np_uartcontrol_ife_mask = (1<<1), ++ np_uartcontrol_ipe_mask = (1<<0) ++ }; ++ ++// UART Routines ++int nr_uart_rxchar(np_uart *uartBase); // 0 for default UART ++void nr_uart_txcr(void); ++void nr_uart_txchar(int c,np_uart *uartBase); // 0 for default UART ++void nr_uart_txhex(int x); // 16 or 32 bits ++void nr_uart_txhex16(short x); ++void nr_uart_txhex32(long x); ++void nr_uart_txstring(char *s); ++ +diff --git a/include/asm-nios2nommu/ucontext.h b/include/asm-nios2nommu/ucontext.h +new file mode 100644 +index 0000000..f2e7ce2 +--- /dev/null ++++ b/include/asm-nios2nommu/ucontext.h +@@ -0,0 +1,63 @@ ++#ifndef _NIOSKNOMMU_UCONTEXT_H ++#define _NIOSKNOMMU_UCONTEXT_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/ucontext.h ++ * ++ * Derived from M68knommu ++ * ++ * Copyright (C) 2004 Microtronix Datacom Ltd ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * Jan/20/2004 dgt NiosII ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++typedef int greg_t; ++#define NGREG 32 ++typedef greg_t gregset_t[NGREG]; ++ ++#ifdef CONFIG_FPU ++typedef struct fpregset { ++ int f_pcr; ++ int f_psr; ++ int f_fpiaddr; ++ int f_fpregs[8][3]; ++} fpregset_t; ++#endif ++ ++struct mcontext { ++ int version; ++ int status_extension; ++ gregset_t gregs; ++#ifdef CONFIG_FPU ++ fpregset_t fpregs; ++#endif ++}; ++ ++#define MCONTEXT_VERSION 2 ++ ++struct ucontext { ++ unsigned long uc_flags; ++ struct ucontext *uc_link; ++ stack_t uc_stack; ++ struct mcontext uc_mcontext; ++#ifdef CONFIG_FPU ++ unsigned long uc_filler[80]; ++#endif ++ sigset_t uc_sigmask; /* mask last for extensibility */ ++}; ++ ++#endif +diff --git a/include/asm-nios2nommu/unaligned.h b/include/asm-nios2nommu/unaligned.h +new file mode 100644 +index 0000000..4876185 +--- /dev/null ++++ b/include/asm-nios2nommu/unaligned.h +@@ -0,0 +1,6 @@ ++#ifndef __NIOS2_UNALIGNED_H ++#define __NIOS2_UNALIGNED_H ++ ++#include <asm-generic/unaligned.h> ++ ++#endif /* __NIOS2_UNALIGNED_H */ +diff --git a/include/asm-nios2nommu/unistd.h b/include/asm-nios2nommu/unistd.h +new file mode 100644 +index 0000000..43cd165 +--- /dev/null ++++ b/include/asm-nios2nommu/unistd.h +@@ -0,0 +1,395 @@ ++#ifndef _ASM_NIOS_UNISTD_H_ ++#define _ASM_NIOS_UNISTD_H_ ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/unistd.h ++ * ++ * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al ++ * ++ * Copyright (C) 2004 Microtronix Datacom Ltd ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * //vic - kernel_thread moved to process.c ++ * Jan/20/2004 dgt NiosII ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++#include <asm/traps.h> ++ ++/* TRAP isr expects the trap# (syscall=#TRAP_ID_SYSCALL) in r2, ++ * the syscall # in r3, and arguments in r4, r5, ... ++ * Return argument expected in r2. ++ */ ++ ++#define __NR_restart_syscall 0 ++#define __NR_exit 1 ++#define __NR_fork 2 ++#define __NR_read 3 ++#define __NR_write 4 ++#define __NR_open 5 ++#define __NR_close 6 ++#define __NR_waitpid 7 ++#define __NR_creat 8 ++#define __NR_link 9 ++#define __NR_unlink 10 ++#define __NR_execve 11 ++#define __NR_chdir 12 ++#define __NR_time 13 ++#define __NR_mknod 14 ++#define __NR_chmod 15 ++#define __NR_chown 16 ++#define __NR_break 17 ++#define __NR_oldstat 18 ++#define __NR_lseek 19 ++#define __NR_getpid 20 ++#define __NR_mount 21 ++#define __NR_umount 22 ++#define __NR_setuid 23 ++#define __NR_getuid 24 ++#define __NR_stime 25 ++#define __NR_ptrace 26 ++#define __NR_alarm 27 ++#define __NR_oldfstat 28 ++#define __NR_pause 29 ++#define __NR_utime 30 ++#define __NR_stty 31 ++#define __NR_gtty 32 ++#define __NR_access 33 ++#define __NR_nice 34 ++#define __NR_ftime 35 ++#define __NR_sync 36 ++#define __NR_kill 37 ++#define __NR_rename 38 ++#define __NR_mkdir 39 ++#define __NR_rmdir 40 ++#define __NR_dup 41 ++#define __NR_pipe 42 ++#define __NR_times 43 ++#define __NR_prof 44 ++#define __NR_brk 45 ++#define __NR_setgid 46 ++#define __NR_getgid 47 ++#define __NR_signal 48 ++#define __NR_geteuid 49 ++#define __NR_getegid 50 ++#define __NR_acct 51 ++#define __NR_umount2 52 //vic #define __NR_phys 52 ++#define __NR_lock 53 ++#define __NR_ioctl 54 ++#define __NR_fcntl 55 ++#define __NR_mpx 56 ++#define __NR_setpgid 57 ++#define __NR_ulimit 58 ++#define __NR_oldolduname 59 ++#define __NR_umask 60 ++#define __NR_chroot 61 ++#define __NR_ustat 62 ++#define __NR_dup2 63 ++#define __NR_getppid 64 ++#define __NR_getpgrp 65 ++#define __NR_setsid 66 ++#define __NR_sigaction 67 ++#define __NR_sgetmask 68 ++#define __NR_ssetmask 69 ++#define __NR_setreuid 70 ++#define __NR_setregid 71 ++#define __NR_sigsuspend 72 ++#define __NR_sigpending 73 ++#define __NR_sethostname 74 ++#define __NR_setrlimit 75 ++#define __NR_getrlimit 76 ++#define __NR_getrusage 77 ++#define __NR_gettimeofday 78 ++#define __NR_settimeofday 79 ++#define __NR_getgroups 80 ++#define __NR_setgroups 81 ++#define __NR_select 82 ++#define __NR_symlink 83 ++#define __NR_oldlstat 84 ++#define __NR_readlink 85 ++#define __NR_uselib 86 ++#define __NR_swapon 87 ++#define __NR_reboot 88 ++#define __NR_readdir 89 ++#define __NR_mmap 90 ++#define __NR_munmap 91 ++#define __NR_truncate 92 ++#define __NR_ftruncate 93 ++#define __NR_fchmod 94 ++#define __NR_fchown 95 ++#define __NR_getpriority 96 ++#define __NR_setpriority 97 ++#define __NR_profil 98 ++#define __NR_statfs 99 ++#define __NR_fstatfs 100 ++#define __NR_ioperm 101 ++#define __NR_socketcall 102 ++#define __NR_syslog 103 ++#define __NR_setitimer 104 ++#define __NR_getitimer 105 ++#define __NR_stat 106 ++#define __NR_lstat 107 ++#define __NR_fstat 108 ++#define __NR_olduname 109 ++#define __NR_iopl /* 110 */ not supported ++#define __NR_vhangup 111 ++#define __NR_idle /* 112 */ Obsolete ++#define __NR_vm86 /* 113 */ not supported ++#define __NR_wait4 114 ++#define __NR_swapoff 115 ++#define __NR_sysinfo 116 ++#define __NR_ipc 117 ++#define __NR_fsync 118 ++#define __NR_sigreturn 119 ++#define __NR_clone 120 ++#define __NR_setdomainname 121 ++#define __NR_uname 122 ++#define __NR_cacheflush 123 ++#define __NR_adjtimex 124 ++#define __NR_mprotect 125 ++#define __NR_sigprocmask 126 ++#define __NR_create_module 127 ++#define __NR_init_module 128 ++#define __NR_delete_module 129 ++#define __NR_get_kernel_syms 130 ++#define __NR_quotactl 131 ++#define __NR_getpgid 132 ++#define __NR_fchdir 133 ++#define __NR_bdflush 134 ++#define __NR_sysfs 135 ++#define __NR_personality 136 ++#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ ++#define __NR_setfsuid 138 ++#define __NR_setfsgid 139 ++#define __NR__llseek 140 ++#define __NR_getdents 141 ++#define __NR__newselect 142 ++#define __NR_flock 143 ++ /* 144 __NR_msync obsolete */ ++#define __NR_readv 145 ++#define __NR_writev 146 ++#define __NR_getsid 147 ++#define __NR_fdatasync 148 ++#define __NR__sysctl 149 ++#define __NR_mlock 150 ++#define __NR_munlock 151 ++#define __NR_mlockall 152 ++#define __NR_munlockall 153 ++#define __NR_sched_setparam 154 ++#define __NR_sched_getparam 155 ++#define __NR_sched_setscheduler 156 ++#define __NR_sched_getscheduler 157 ++#define __NR_sched_yield 158 ++#define __NR_sched_get_priority_max 159 ++#define __NR_sched_get_priority_min 160 ++#define __NR_sched_rr_get_interval 161 ++#define __NR_nanosleep 162 ++#define __NR_mremap 163 ++#define __NR_setresuid 164 ++#define __NR_getresuid 165 ++#define __NR_getpagesize 166 ++#define __NR_query_module 167 ++#define __NR_poll 168 ++#define __NR_nfsservctl 169 ++#define __NR_setresgid 170 ++#define __NR_getresgid 171 ++#define __NR_prctl 172 ++#define __NR_rt_sigreturn 173 ++#define __NR_rt_sigaction 174 ++#define __NR_rt_sigprocmask 175 ++#define __NR_rt_sigpending 176 ++#define __NR_rt_sigtimedwait 177 ++#define __NR_rt_sigqueueinfo 178 ++#define __NR_rt_sigsuspend 179 ++#define __NR_pread 180 ++#define __NR_pwrite 181 ++#define __NR_lchown 182 ++#define __NR_getcwd 183 ++#define __NR_capget 184 ++#define __NR_capset 185 ++#define __NR_sigaltstack 186 ++#define __NR_sendfile 187 ++#define __NR_getpmsg 188 /* some people actually want streams */ ++#define __NR_putpmsg 189 /* some people actually want streams */ ++#define __NR_vfork 190 ++#define __NR_ugetrlimit 191 ++#define __NR_mmap2 192 ++#define __NR_truncate64 193 ++#define __NR_ftruncate64 194 ++#define __NR_stat64 195 ++#define __NR_lstat64 196 ++#define __NR_fstat64 197 ++#define __NR_chown32 198 ++#define __NR_getuid32 199 ++#define __NR_getgid32 200 ++#define __NR_geteuid32 201 ++#define __NR_getegid32 202 ++#define __NR_setreuid32 203 ++#define __NR_setregid32 204 ++#define __NR_getgroups32 205 ++#define __NR_setgroups32 206 ++#define __NR_fchown32 207 ++#define __NR_setresuid32 208 ++#define __NR_getresuid32 209 ++#define __NR_setresgid32 210 ++#define __NR_getresgid32 211 ++#define __NR_lchown32 212 ++#define __NR_setuid32 213 ++#define __NR_setgid32 214 ++#define __NR_setfsuid32 215 ++#define __NR_setfsgid32 216 ++#define __NR_pivot_root 217 ++/* 218 unused */ ++/* 219 unused */ ++#define __NR_getdents64 220 ++#define __NR_gettid 221 ++#define __NR_tkill 222 ++#define __NR_setxattr 223 ++#define __NR_lsetxattr 224 ++#define __NR_fsetxattr 225 ++#define __NR_getxattr 226 ++#define __NR_lgetxattr 227 ++#define __NR_fgetxattr 228 ++#define __NR_listxattr 229 ++#define __NR_llistxattr 230 ++#define __NR_flistxattr 231 ++#define __NR_removexattr 232 ++#define __NR_lremovexattr 233 ++#define __NR_fremovexattr 234 ++#define __NR_futex 235 ++#define __NR_sendfile64 236 ++#define __NR_mincore 237 ++#define __NR_madvise 238 ++#define __NR_fcntl64 239 ++#define __NR_readahead 240 ++#define __NR_io_setup 241 ++#define __NR_io_destroy 242 ++#define __NR_io_getevents 243 ++#define __NR_io_submit 244 ++#define __NR_io_cancel 245 ++#define __NR_fadvise64 246 ++#define __NR_exit_group 247 ++#define __NR_lookup_dcookie 248 ++#define __NR_epoll_create 249 ++#define __NR_epoll_ctl 250 ++#define __NR_epoll_wait 251 ++#define __NR_remap_file_pages 252 ++#define __NR_set_tid_address 253 ++#define __NR_timer_create 254 ++#define __NR_timer_settime 255 ++#define __NR_timer_gettime 256 ++#define __NR_timer_getoverrun 257 ++#define __NR_timer_delete 258 ++#define __NR_clock_settime 259 ++#define __NR_clock_gettime 260 ++#define __NR_clock_getres 261 ++#define __NR_clock_nanosleep 262 ++#define __NR_statfs64 263 ++#define __NR_fstatfs64 264 ++#define __NR_tgkill 265 ++#define __NR_utimes 266 ++#define __NR_fadvise64_64 267 ++#define __NR_mbind 268 ++#define __NR_get_mempolicy 269 ++#define __NR_set_mempolicy 270 ++#define __NR_mq_open 271 ++#define __NR_mq_unlink 272 ++#define __NR_mq_timedsend 273 ++#define __NR_mq_timedreceive 274 ++#define __NR_mq_notify 275 ++#define __NR_mq_getsetattr 276 ++#define __NR_waitid 277 ++#define __NR_sys_setaltroot 278 ++#define __NR_add_key 279 ++#define __NR_request_key 280 ++#define __NR_keyctl 281 ++#define __NR_ioprio_set 282 ++#define __NR_ioprio_get 283 ++#define __NR_inotify_init 284 ++#define __NR_inotify_add_watch 285 ++#define __NR_inotify_rm_watch 286 ++#define __NR_migrate_pages 287 ++#define __NR_openat 288 ++#define __NR_mkdirat 289 ++#define __NR_mknodat 290 ++#define __NR_fchownat 291 ++#define __NR_futimesat 292 ++#define __NR_fstatat64 293 ++#define __NR_unlinkat 294 ++#define __NR_renameat 295 ++#define __NR_linkat 296 ++#define __NR_symlinkat 297 ++#define __NR_readlinkat 298 ++#define __NR_fchmodat 299 ++#define __NR_faccessat 300 ++#define __NR_pselect6 301 ++#define __NR_ppoll 302 ++#define __NR_unshare 303 ++#define __NR_set_robust_list 304 ++#define __NR_get_robust_list 305 ++#define __NR_splice 306 ++#define __NR_sync_file_range 307 ++#define __NR_tee 308 ++#define __NR_vmsplice 309 ++#define __NR_move_pages 310 ++#define __NR_sched_setaffinity 311 ++#define __NR_sched_getaffinity 312 ++#define __NR_kexec_load 313 ++#define __NR_getcpu 314 ++#define __NR_epoll_pwait 315 ++#define __NR_utimensat 316 ++#define __NR_signalfd 317 ++#define __NR_timerfd 318 ++#define __NR_eventfd 319 ++#define __NR_pread64 320 ++#define __NR_pwrite64 321 ++ ++#ifdef __KERNEL__ ++#define NR_syscalls 322 ++ ++#define __ARCH_WANT_IPC_PARSE_VERSION ++#define __ARCH_WANT_OLD_READDIR ++#define __ARCH_WANT_OLD_STAT ++#define __ARCH_WANT_STAT64 ++#define __ARCH_WANT_SYS_ALARM ++#define __ARCH_WANT_SYS_GETHOSTNAME ++#define __ARCH_WANT_SYS_PAUSE ++#define __ARCH_WANT_SYS_SGETMASK ++#define __ARCH_WANT_SYS_SIGNAL ++#define __ARCH_WANT_SYS_TIME ++#define __ARCH_WANT_SYS_UTIME ++#define __ARCH_WANT_SYS_WAITPID ++#define __ARCH_WANT_SYS_SOCKETCALL ++#define __ARCH_WANT_SYS_FADVISE64 ++#define __ARCH_WANT_SYS_GETPGRP ++#define __ARCH_WANT_SYS_LLSEEK ++#define __ARCH_WANT_SYS_NICE ++#define __ARCH_WANT_SYS_OLD_GETRLIMIT ++#define __ARCH_WANT_SYS_OLDUMOUNT ++#define __ARCH_WANT_SYS_SIGPENDING ++#define __ARCH_WANT_SYS_SIGPROCMASK ++#define __ARCH_WANT_SYS_RT_SIGACTION ++ ++/* ++ * "Conditional" syscalls ++ * ++ * What we want is __attribute__((weak,alias("sys_ni_syscall"))), ++ * but it doesn't work on all toolchains, so we just do it by hand ++ */ ++#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall"); ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* _ASM_NIOS_UNISTD_H_ */ +diff --git a/include/asm-nios2nommu/user.h b/include/asm-nios2nommu/user.h +new file mode 100644 +index 0000000..3cdc2ba +--- /dev/null ++++ b/include/asm-nios2nommu/user.h +@@ -0,0 +1,112 @@ ++#ifndef _NIOS2NOMMU_USER_H ++#define _NIOS2NOMMU_USER_H ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/user.h ++ * ++ * Derived from M68knommu ++ * ++ * Copyright (C) 2004 Microtronix Datacom Ltd ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * Jan/20/2004 dgt NiosII ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++#include <asm/page.h> ++ ++/* Core file format: The core file is written in such a way that gdb ++ can understand it and provide useful information to the user (under ++ linux we use the 'trad-core' bfd). There are quite a number of ++ obstacles to being able to view the contents of the floating point ++ registers, and until these are solved you will not be able to view the ++ contents of them. Actually, you can read in the core file and look at ++ the contents of the user struct to find out what the floating point ++ registers contain. ++ The actual file contents are as follows: ++ UPAGE: 1 page consisting of a user struct that tells gdb what is present ++ in the file. Directly after this is a copy of the task_struct, which ++ is currently not used by gdb, but it may come in useful at some point. ++ All of the registers are stored as part of the upage. The upage should ++ always be only one page. ++ DATA: The data area is stored. We use current->end_text to ++ current->brk to pick up all of the user variables, plus any memory ++ that may have been malloced. No attempt is made to determine if a page ++ is demand-zero or if a page is totally unused, we just cover the entire ++ range. All of the addresses are rounded in such a way that an integral ++ number of pages is written. ++ STACK: We need the stack information in order to get a meaningful ++ backtrace. We need to write the data from (esp) to ++ current->start_stack, so we round each of these off in order to be able ++ to write an integer number of pages. ++ The minimum core file size is 3 pages, or 12288 bytes. ++*/ ++ ++struct user_m68kfp_struct { ++ unsigned long fpregs[8*3]; /* fp0-fp7 registers */ ++ unsigned long fpcntl[3]; /* fp control regs */ ++}; ++ ++/* This is needs more work, probably should look like gdb useage */ ++struct user_regs_struct { ++ long r1,r2,r3,r4,r5,r6,r7,r8; ++ long r9,r10,r11,r12,r13,r14,r15; ++ long r16,r17,r18,r19,r20,r21,r22,r23; ++ long gp; ++ long sp; ++ long ra; ++ long fp; ++ long orig_r2; ++ long estatus; ++ long status_extension; ++ long ea; ++}; ++ ++ ++/* When the kernel dumps core, it starts by dumping the user struct - ++ this will be used by gdb to figure out where the data and stack segments ++ are within the file, and what virtual addresses to use. */ ++struct user{ ++/* We start with the registers, to mimic the way that "memory" is returned ++ from the ptrace(3,...) function. */ ++ struct user_regs_struct regs; /* Where the registers are actually stored */ ++/* ptrace does not yet supply these. Someday.... */ ++ int u_fpvalid; /* True if math co-processor being used. */ ++ /* for this mess. Not yet used. */ ++ struct user_m68kfp_struct m68kfp; /* Math Co-processor registers. */ ++/* The rest of this junk is to help gdb figure out what goes where */ ++ unsigned long int u_tsize; /* Text segment size (pages). */ ++ unsigned long int u_dsize; /* Data segment size (pages). */ ++ unsigned long int u_ssize; /* Stack segment size (pages). */ ++ unsigned long start_code; /* Starting virtual address of text. */ ++ unsigned long start_stack; /* Starting virtual address of stack area. ++ This is actually the bottom of the stack, ++ the top of the stack is always found in the ++ esp register. */ ++ long int signal; /* Signal that caused the core dump. */ ++ int reserved; /* No longer used */ ++ struct user_regs_struct *u_ar0; ++ /* Used by gdb to help find the values for */ ++ /* the registers. */ ++ struct user_m68kfp_struct* u_fpstate; /* Math Co-processor pointer. */ ++ unsigned long magic; /* To uniquely identify a core file */ ++ char u_comm[32]; /* User command that was responsible */ ++}; ++#define NBPG PAGE_SIZE ++#define UPAGES 1 ++#define HOST_TEXT_START_ADDR (u.start_code) ++#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) ++ ++#endif +diff --git a/include/asm-nios2nommu/virtconvert.h b/include/asm-nios2nommu/virtconvert.h +new file mode 100644 +index 0000000..89bf899 +--- /dev/null ++++ b/include/asm-nios2nommu/virtconvert.h +@@ -0,0 +1,46 @@ ++#ifndef __NIOS_VIRT_CONVERT__ ++#define __NIOS_VIRT_CONVERT__ ++ ++/*-------------------------------------------------------------------- ++ * ++ * include/asm-nios2nommu/virtconvert.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 ++ * ++ ---------------------------------------------------------------------*/ ++ ++ ++/* ++ * Macros used for converting between virtual and physical mappings. ++ */ ++ ++#ifdef __KERNEL__ ++ ++#include <asm/setup.h> ++#include <asm/page.h> ++ ++#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 ++ ++#endif /*__KERNEL__ */ ++#endif /*__NIOS_VIRT_CONVERT__*/ |