| 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__*/ |