Merge branch 'for-linus' of git://git.monstr.eu/linux-2.6-microblaze
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 Apr 2009 15:17:52 +0000 (08:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 Apr 2009 15:17:52 +0000 (08:17 -0700)
* 'for-linus' of git://git.monstr.eu/linux-2.6-microblaze: (60 commits)
  microblaze_v8: Add MAINTAINERS fragment
  microblaze_v8: Uartlite for Microblaze
  microblaze_v8: Makefiles for Microblaze cpu
  microblaze_v8: Kconfig patches
  microblaze_v8: Interrupt handling and timer support
  microblaze_v8: syscalls.h
  microblaze_v8: pci headers
  microblaze_v8: Kbuild file
  microblaze_v8: string.h thread_info.h
  microblaze_v8: unistd.h
  microblaze_v8: fcntl.h sockios.h ucontext.h
  microblaze_v8: pool.h socket.h
  microblaze_v8: device.h param.h topology.h
  microblaze_v8: headers files entry.h current.h mman.h registers.h sembuf.h
  microblaze_v8: namei.h
  microblaze_v8: gpio.h, serial.h
  microblaze_v8: headers simple files - empty or redirect to asm-generic
  microblaze_v8: sigcontext.h siginfo.h
  microblaze_v8: termbits.h termios.h
  microblaze_v8: stats headers
  ...

159 files changed:
MAINTAINERS
arch/microblaze/Kconfig [new file with mode: 0644]
arch/microblaze/Kconfig.debug [new file with mode: 0644]
arch/microblaze/Makefile [new file with mode: 0644]
arch/microblaze/boot/Makefile [new file with mode: 0644]
arch/microblaze/configs/nommu_defconfig [new file with mode: 0644]
arch/microblaze/include/asm/Kbuild [new file with mode: 0644]
arch/microblaze/include/asm/atomic.h [new file with mode: 0644]
arch/microblaze/include/asm/auxvec.h [new file with mode: 0644]
arch/microblaze/include/asm/bitops.h [new file with mode: 0644]
arch/microblaze/include/asm/bug.h [new file with mode: 0644]
arch/microblaze/include/asm/bugs.h [new file with mode: 0644]
arch/microblaze/include/asm/byteorder.h [new file with mode: 0644]
arch/microblaze/include/asm/cache.h [new file with mode: 0644]
arch/microblaze/include/asm/cacheflush.h [new file with mode: 0644]
arch/microblaze/include/asm/checksum.h [new file with mode: 0644]
arch/microblaze/include/asm/clinkage.h [new file with mode: 0644]
arch/microblaze/include/asm/cpuinfo.h [new file with mode: 0644]
arch/microblaze/include/asm/cputable.h [new file with mode: 0644]
arch/microblaze/include/asm/cputime.h [new file with mode: 0644]
arch/microblaze/include/asm/current.h [new file with mode: 0644]
arch/microblaze/include/asm/delay.h [new file with mode: 0644]
arch/microblaze/include/asm/device.h [new file with mode: 0644]
arch/microblaze/include/asm/div64.h [new file with mode: 0644]
arch/microblaze/include/asm/dma-mapping.h [new file with mode: 0644]
arch/microblaze/include/asm/dma.h [new file with mode: 0644]
arch/microblaze/include/asm/elf.h [new file with mode: 0644]
arch/microblaze/include/asm/emergency-restart.h [new file with mode: 0644]
arch/microblaze/include/asm/entry.h [new file with mode: 0644]
arch/microblaze/include/asm/errno.h [new file with mode: 0644]
arch/microblaze/include/asm/exceptions.h [new file with mode: 0644]
arch/microblaze/include/asm/fcntl.h [new file with mode: 0644]
arch/microblaze/include/asm/flat.h [new file with mode: 0644]
arch/microblaze/include/asm/futex.h [new file with mode: 0644]
arch/microblaze/include/asm/gpio.h [new file with mode: 0644]
arch/microblaze/include/asm/hardirq.h [new file with mode: 0644]
arch/microblaze/include/asm/hw_irq.h [new file with mode: 0644]
arch/microblaze/include/asm/io.h [new file with mode: 0644]
arch/microblaze/include/asm/ioctl.h [new file with mode: 0644]
arch/microblaze/include/asm/ioctls.h [new file with mode: 0644]
arch/microblaze/include/asm/ipc.h [new file with mode: 0644]
arch/microblaze/include/asm/ipcbuf.h [new file with mode: 0644]
arch/microblaze/include/asm/irq.h [new file with mode: 0644]
arch/microblaze/include/asm/irq_regs.h [new file with mode: 0644]
arch/microblaze/include/asm/irqflags.h [new file with mode: 0644]
arch/microblaze/include/asm/kdebug.h [new file with mode: 0644]
arch/microblaze/include/asm/kmap_types.h [new file with mode: 0644]
arch/microblaze/include/asm/linkage.h [new file with mode: 0644]
arch/microblaze/include/asm/lmb.h [new file with mode: 0644]
arch/microblaze/include/asm/local.h [new file with mode: 0644]
arch/microblaze/include/asm/mman.h [new file with mode: 0644]
arch/microblaze/include/asm/mmu.h [new file with mode: 0644]
arch/microblaze/include/asm/mmu_context.h [new file with mode: 0644]
arch/microblaze/include/asm/module.h [new file with mode: 0644]
arch/microblaze/include/asm/msgbuf.h [new file with mode: 0644]
arch/microblaze/include/asm/mutex.h [new file with mode: 0644]
arch/microblaze/include/asm/namei.h [new file with mode: 0644]
arch/microblaze/include/asm/of_device.h [new file with mode: 0644]
arch/microblaze/include/asm/of_platform.h [new file with mode: 0644]
arch/microblaze/include/asm/page.h [new file with mode: 0644]
arch/microblaze/include/asm/param.h [new file with mode: 0644]
arch/microblaze/include/asm/pci-bridge.h [new file with mode: 0644]
arch/microblaze/include/asm/pci.h [new file with mode: 0644]
arch/microblaze/include/asm/percpu.h [new file with mode: 0644]
arch/microblaze/include/asm/pgalloc.h [new file with mode: 0644]
arch/microblaze/include/asm/pgtable.h [new file with mode: 0644]
arch/microblaze/include/asm/poll.h [new file with mode: 0644]
arch/microblaze/include/asm/posix_types.h [new file with mode: 0644]
arch/microblaze/include/asm/processor.h [new file with mode: 0644]
arch/microblaze/include/asm/prom.h [new file with mode: 0644]
arch/microblaze/include/asm/ptrace.h [new file with mode: 0644]
arch/microblaze/include/asm/pvr.h [new file with mode: 0644]
arch/microblaze/include/asm/registers.h [new file with mode: 0644]
arch/microblaze/include/asm/resource.h [new file with mode: 0644]
arch/microblaze/include/asm/scatterlist.h [new file with mode: 0644]
arch/microblaze/include/asm/sections.h [new file with mode: 0644]
arch/microblaze/include/asm/segment.h [new file with mode: 0644]
arch/microblaze/include/asm/selfmod.h [new file with mode: 0644]
arch/microblaze/include/asm/sembuf.h [new file with mode: 0644]
arch/microblaze/include/asm/serial.h [new file with mode: 0644]
arch/microblaze/include/asm/setup.h [new file with mode: 0644]
arch/microblaze/include/asm/shmbuf.h [new file with mode: 0644]
arch/microblaze/include/asm/shmparam.h [new file with mode: 0644]
arch/microblaze/include/asm/sigcontext.h [new file with mode: 0644]
arch/microblaze/include/asm/siginfo.h [new file with mode: 0644]
arch/microblaze/include/asm/signal.h [new file with mode: 0644]
arch/microblaze/include/asm/socket.h [new file with mode: 0644]
arch/microblaze/include/asm/sockios.h [new file with mode: 0644]
arch/microblaze/include/asm/stat.h [new file with mode: 0644]
arch/microblaze/include/asm/statfs.h [new file with mode: 0644]
arch/microblaze/include/asm/string.h [new file with mode: 0644]
arch/microblaze/include/asm/swab.h [new file with mode: 0644]
arch/microblaze/include/asm/syscalls.h [new file with mode: 0644]
arch/microblaze/include/asm/system.h [new file with mode: 0644]
arch/microblaze/include/asm/termbits.h [new file with mode: 0644]
arch/microblaze/include/asm/termios.h [new file with mode: 0644]
arch/microblaze/include/asm/thread_info.h [new file with mode: 0644]
arch/microblaze/include/asm/timex.h [new file with mode: 0644]
arch/microblaze/include/asm/tlb.h [new file with mode: 0644]
arch/microblaze/include/asm/tlbflush.h [new file with mode: 0644]
arch/microblaze/include/asm/topology.h [new file with mode: 0644]
arch/microblaze/include/asm/types.h [new file with mode: 0644]
arch/microblaze/include/asm/uaccess.h [new file with mode: 0644]
arch/microblaze/include/asm/ucontext.h [new file with mode: 0644]
arch/microblaze/include/asm/unaligned.h [new file with mode: 0644]
arch/microblaze/include/asm/unistd.h [new file with mode: 0644]
arch/microblaze/include/asm/user.h [new file with mode: 0644]
arch/microblaze/include/asm/vga.h [new file with mode: 0644]
arch/microblaze/include/asm/xor.h [new file with mode: 0644]
arch/microblaze/kernel/Makefile [new file with mode: 0644]
arch/microblaze/kernel/asm-offsets.c [new file with mode: 0644]
arch/microblaze/kernel/cpu/Makefile [new file with mode: 0644]
arch/microblaze/kernel/cpu/cache.c [new file with mode: 0644]
arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c [new file with mode: 0644]
arch/microblaze/kernel/cpu/cpuinfo-static.c [new file with mode: 0644]
arch/microblaze/kernel/cpu/cpuinfo.c [new file with mode: 0644]
arch/microblaze/kernel/cpu/mb.c [new file with mode: 0644]
arch/microblaze/kernel/cpu/pvr.c [new file with mode: 0644]
arch/microblaze/kernel/early_printk.c [new file with mode: 0644]
arch/microblaze/kernel/entry-nommu.S [new file with mode: 0644]
arch/microblaze/kernel/exceptions.c [new file with mode: 0644]
arch/microblaze/kernel/head.S [new file with mode: 0644]
arch/microblaze/kernel/heartbeat.c [new file with mode: 0644]
arch/microblaze/kernel/hw_exception_handler.S [new file with mode: 0644]
arch/microblaze/kernel/init_task.c [new file with mode: 0644]
arch/microblaze/kernel/intc.c [new file with mode: 0644]
arch/microblaze/kernel/irq.c [new file with mode: 0644]
arch/microblaze/kernel/microblaze_ksyms.c [new file with mode: 0644]
arch/microblaze/kernel/module.c [new file with mode: 0644]
arch/microblaze/kernel/of_device.c [new file with mode: 0644]
arch/microblaze/kernel/of_platform.c [new file with mode: 0644]
arch/microblaze/kernel/process.c [new file with mode: 0644]
arch/microblaze/kernel/prom.c [new file with mode: 0644]
arch/microblaze/kernel/prom_parse.c [new file with mode: 0644]
arch/microblaze/kernel/ptrace.c [new file with mode: 0644]
arch/microblaze/kernel/selfmod.c [new file with mode: 0644]
arch/microblaze/kernel/setup.c [new file with mode: 0644]
arch/microblaze/kernel/signal.c [new file with mode: 0644]
arch/microblaze/kernel/sys_microblaze.c [new file with mode: 0644]
arch/microblaze/kernel/syscall_table.S [new file with mode: 0644]
arch/microblaze/kernel/timer.c [new file with mode: 0644]
arch/microblaze/kernel/traps.c [new file with mode: 0644]
arch/microblaze/kernel/vmlinux.lds.S [new file with mode: 0644]
arch/microblaze/lib/Makefile [new file with mode: 0644]
arch/microblaze/lib/checksum.c [new file with mode: 0644]
arch/microblaze/lib/fastcopy.S [new file with mode: 0644]
arch/microblaze/lib/memcpy.c [new file with mode: 0644]
arch/microblaze/lib/memmove.c [new file with mode: 0644]
arch/microblaze/lib/memset.c [new file with mode: 0644]
arch/microblaze/lib/uaccess.c [new file with mode: 0644]
arch/microblaze/mm/Makefile [new file with mode: 0644]
arch/microblaze/mm/init.c [new file with mode: 0644]
arch/microblaze/platform/Kconfig.platform [new file with mode: 0644]
arch/microblaze/platform/Makefile [new file with mode: 0644]
arch/microblaze/platform/generic/Kconfig.auto [new file with mode: 0644]
arch/microblaze/platform/generic/Makefile [new file with mode: 0644]
arch/microblaze/platform/generic/system.dts [new file with mode: 0644]
arch/microblaze/platform/platform.c [new file with mode: 0644]
drivers/serial/Kconfig

index 5d84358..bff9f9f 100644 (file)
@@ -2992,6 +2992,14 @@ L:       linux-mtd@lists.infradead.org
 T:     git git://git.infradead.org/mtd-2.6.git
 S:     Maintained
 
+MICROBLAZE ARCHITECTURE
+P:     Michal Simek
+M:     monstr@monstr.eu
+L:     microblaze-uclinux@itee.uq.edu.au
+W:     http://www.monstr.eu/fdt/
+T:     git git://git.monstr.eu/linux-2.6-microblaze.git
+S:     Supported
+
 MICROTEK X6 SCANNER
 P:     Oliver Neukum
 M:     oliver@neukum.name
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
new file mode 100644 (file)
index 0000000..8cc312b
--- /dev/null
@@ -0,0 +1,141 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+
+mainmenu "Linux/Microblaze Kernel Configuration"
+
+config MICROBLAZE
+       def_bool y
+       select HAVE_LMB
+
+config SWAP
+       def_bool n
+
+config RWSEM_GENERIC_SPINLOCK
+       def_bool y
+
+config RWSEM_XCHGADD_ALGORITHM
+       bool
+
+config ARCH_HAS_ILOG2_U32
+       def_bool n
+
+config ARCH_HAS_ILOG2_U64
+       def_bool n
+
+config GENERIC_FIND_NEXT_BIT
+       def_bool y
+
+config GENERIC_HWEIGHT
+       def_bool y
+
+config GENERIC_HARDIRQS
+       def_bool y
+
+config GENERIC_IRQ_PROBE
+       def_bool y
+
+config GENERIC_CALIBRATE_DELAY
+       def_bool y
+
+config GENERIC_TIME
+       def_bool y
+
+config GENERIC_TIME_VSYSCALL
+       def_bool n
+
+config GENERIC_CLOCKEVENTS
+       def_bool y
+
+config GENERIC_HARDIRQS_NO__DO_IRQ
+       def_bool y
+
+config PCI
+       depends on !MMU
+       def_bool n
+
+config NO_DMA
+       depends on !MMU
+       def_bool n
+
+source "init/Kconfig"
+
+source "kernel/Kconfig.freezer"
+
+source "arch/microblaze/platform/Kconfig.platform"
+
+menu "Processor type and features"
+
+source kernel/time/Kconfig
+
+source "kernel/Kconfig.preempt"
+
+source "kernel/Kconfig.hz"
+
+config MMU
+       def_bool n
+
+config NO_MMU
+       bool
+       depends on !MMU
+       default y
+
+comment "Boot options"
+
+config CMDLINE_BOOL
+       bool "Default bootloader kernel arguments"
+
+config CMDLINE
+       string "Default kernel command string"
+       depends on CMDLINE_BOOL
+       default "console=ttyUL0,115200"
+       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.
+
+config CMDLINE_FORCE
+       bool "Force default kernel command string"
+       depends on CMDLINE_BOOL
+       default n
+       help
+         Set this to have arguments from the default kernel command string
+         override those passed by the boot loader.
+
+config OF
+       def_bool y
+
+config OF_DEVICE
+       def_bool y
+
+config PROC_DEVICETREE
+       bool "Support for device tree in /proc"
+       depends on PROC_FS
+       help
+         This option adds a device-tree directory under /proc which contains
+         an image of the device tree that the kernel copies from Open
+         Firmware or other boot firmware. If unsure, say Y here.
+
+endmenu
+
+source "mm/Kconfig"
+
+menu "Exectuable file formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/microblaze/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
diff --git a/arch/microblaze/Kconfig.debug b/arch/microblaze/Kconfig.debug
new file mode 100644 (file)
index 0000000..242cd35
--- /dev/null
@@ -0,0 +1,26 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config EARLY_PRINTK
+       bool "Early printk function for kernel"
+       default n
+       help
+         This option turns on/off early printk messages to console.
+         First Uartlite node is taken.
+
+config HEART_BEAT
+       bool "Heart beat function for kernel"
+       default n
+       help
+         This option turns on/off heart beat kernel functionality.
+         First GPIO node is taken.
+
+config DEBUG_BOOTMEM
+       depends on DEBUG_KERNEL
+       bool "Debug BOOTMEM initialization"
+
+endmenu
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile
new file mode 100644 (file)
index 0000000..0dcbb98
--- /dev/null
@@ -0,0 +1,69 @@
+UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
+
+# What CPU vesion are we building for, and crack it open
+# as major.minor.rev
+CPU_VER=$(subst ",,$(CONFIG_XILINX_MICROBLAZE0_HW_VER) )
+CPU_MAJOR=$(shell echo $(CPU_VER) | cut -d '.' -f 1)
+CPU_MINOR=$(shell echo $(CPU_VER) | cut -d '.' -f 2)
+CPU_REV=$(shell echo $(CPU_VER) | cut -d '.' -f 3)
+
+export CPU_VER CPU_MAJOR CPU_MINOR CPU_REV
+
+# Use cpu-related CONFIG_ vars to set compile options.
+
+# Work out HW multipler support.  This is icky.
+# 1. Spartan2 has no HW multiplers.
+# 2. MicroBlaze v3.x always uses them, except in Spartan 2
+# 3. All other FPGa/CPU ver combos, we can trust the CONFIG_ settings
+ifeq (,$(findstring spartan2,$(CONFIG_XILINX_MICROBLAZE0_FAMILY)))
+  ifeq ($(CPU_MAJOR),3)
+    CPUFLAGS-1 += -mno-xl-soft-mul
+  else
+    # USE_HW_MUL can be 0, 1, or 2, defining a heirarchy of HW Mul support.
+    CPUFLAGS-$(subst 1,,$(CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL)) += -mxl-multiply-high
+    CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL) += -mno-xl-soft-mul
+  endif
+endif
+CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_DIV) += -mno-xl-soft-div
+CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_BARREL) += -mxl-barrel-shift
+CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_PCMP) += -mxl-pattern-compare
+
+CPUFLAGS-1 += $(call cc-option,-mcpu=v$(CPU_VER))
+
+# The various CONFIG_XILINX cpu features options are integers 0/1/2...
+# rather than bools y/n
+CFLAGS += $(CPUFLAGS-1)
+CFLAGS += $(CPUFLAGS-2)
+
+# r31 holds current when in kernel mode
+CFLAGS += -ffixed-r31
+
+LDFLAGS_BLOB := --format binary --oformat elf32-microblaze
+
+LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+
+head-y         := arch/microblaze/kernel/head.o
+libs-y         += arch/microblaze/lib/ $(LIBGCC)
+core-y         += arch/microblaze/kernel/ arch/microblaze/mm/ \
+                  arch/microblaze/platform/
+
+boot := arch/$(ARCH)/boot
+
+# defines filename extension depending memory management type
+ifeq ($(CONFIG_MMU),)
+MMUEXT         := -nommu
+endif
+export MMUEXT
+
+all: linux.bin
+
+archclean:
+       $(Q)$(MAKE) $(clean)=$(boot)
+
+linux.bin linux.bin.gz: vmlinux
+       $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+define archhelp
+  echo  '* linux.bin    - Create raw binary'
+  echo  '  linux.bin.gz - Create compressed raw binary'
+endef
diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile
new file mode 100644 (file)
index 0000000..844edf4
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# arch/microblaze/boot/Makefile
+#
+
+targets := linux.bin linux.bin.gz
+
+OBJCOPYFLAGS_linux.bin  := -O binary
+
+$(obj)/linux.bin: vmlinux FORCE
+       $(call if_changed,objcopy)
+       @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+
+$(obj)/linux.bin.gz: $(obj)/linux.bin FORCE
+       $(call if_changed,gzip)
+       @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+
+clean-kernel += linux.bin linux.bin.gz
diff --git a/arch/microblaze/configs/nommu_defconfig b/arch/microblaze/configs/nommu_defconfig
new file mode 100644 (file)
index 0000000..beb7ecd
--- /dev/null
@@ -0,0 +1,804 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29
+# Tue Mar 24 10:23:20 2009
+#
+CONFIG_MICROBLAZE=y
+# CONFIG_SWAP is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_GENERIC_TIME_VSYSCALL is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+# CONFIG_PCI is not set
+# CONFIG_NO_DMA is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=1
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# Platform options
+#
+CONFIG_PLATFORM_GENERIC=y
+# CONFIG_SELFMOD is not set
+# CONFIG_OPT_LIB_FUNCTION is not set
+# CONFIG_ALLOW_EDIT_AUTO is not set
+CONFIG_KERNEL_BASE_ADDR=0x90000000
+CONFIG_XILINX_MICROBLAZE0_FAMILY="virtex5"
+CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1
+CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1
+CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1
+CONFIG_XILINX_MICROBLAZE0_USE_DIV=1
+CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=2
+CONFIG_XILINX_MICROBLAZE0_USE_FPU=2
+CONFIG_XILINX_MICROBLAZE0_HW_VER="7.10.d"
+
+#
+# Processor type and features
+#
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_MMU is not set
+CONFIG_NO_MMU=y
+
+#
+# Boot options
+#
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyUL0,115200"
+# CONFIG_CMDLINE_FORCE is not set
+CONFIG_OF=y
+CONFIG_OF_DEVICE=y
+CONFIG_PROC_DEVICETREE=y
+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_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+
+#
+# Exectuable file formats
+#
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_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_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA 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
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_UCLINUX=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# 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_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_UARTLITE=y
+CONFIG_SERIAL_UARTLITE_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# 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_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# 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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_OBJECTS_SELFTEST=y
+CONFIG_DEBUG_OBJECTS_FREE=y
+CONFIG_DEBUG_OBJECTS_TIMERS=y
+CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_SG=y
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_HEART_BEAT=y
+# CONFIG_DEBUG_BOOTMEM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
new file mode 100644 (file)
index 0000000..31820df
--- /dev/null
@@ -0,0 +1,26 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += linkage.h
+header-y += msgbuf.h
+header-y += poll.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += socket.h
+header-y += sockios.h
+header-y += statfs.h
+header-y += stat.h
+header-y += termbits.h
+header-y += ucontext.h
+
+unifdef-y += cputable.h
+unifdef-y += elf.h
+unifdef-y += termios.h
diff --git a/arch/microblaze/include/asm/atomic.h b/arch/microblaze/include/asm/atomic.h
new file mode 100644 (file)
index 0000000..a448d94
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_ATOMIC_H
+#define _ASM_MICROBLAZE_ATOMIC_H
+
+#include <linux/types.h>
+#include <linux/compiler.h> /* likely */
+#include <asm/system.h> /* local_irq_XXX and friends */
+
+#define ATOMIC_INIT(i)         { (i) }
+#define atomic_read(v)         ((v)->counter)
+#define atomic_set(v, i)       (((v)->counter) = (i))
+
+#define atomic_inc(v)          (atomic_add_return(1, (v)))
+#define atomic_dec(v)          (atomic_sub_return(1, (v)))
+
+#define atomic_add(i, v)       (atomic_add_return(i, (v)))
+#define atomic_sub(i, v)       (atomic_sub_return(i, (v)))
+
+#define atomic_inc_return(v)   (atomic_add_return(1, (v)))
+#define atomic_dec_return(v)   (atomic_sub_return(1, (v)))
+
+#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+#define atomic_inc_not_zero(v) (atomic_add_unless((v), 1, 0))
+
+#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
+
+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;
+}
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+       int c, old;
+
+       c = atomic_read(v);
+       while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
+               c = old;
+       return c != u;
+}
+
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       *addr &= ~mask;
+       local_irq_restore(flags);
+}
+
+/**
+ * atomic_add_return - add and return
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v and returns @i + @v
+ */
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+       unsigned long flags;
+       int val;
+
+       local_irq_save(flags);
+       val = v->counter;
+       v->counter = val += i;
+       local_irq_restore(flags);
+
+       return val;
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+       return atomic_add_return(-i, v);
+}
+
+/*
+ * Atomically test *v and decrement if it is greater than 0.
+ * The function returns the old value of *v minus 1.
+ */
+static inline int atomic_dec_if_positive(atomic_t *v)
+{
+       unsigned long flags;
+       int res;
+
+       local_irq_save(flags);
+       res = v->counter - 1;
+       if (res >= 0)
+               v->counter = res;
+       local_irq_restore(flags);
+
+       return res;
+}
+
+#define atomic_add_negative(a, v)      (atomic_add_return((a), (v)) < 0)
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+/* Atomic operations are already serializing */
+#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_MICROBLAZE_ATOMIC_H */
diff --git a/arch/microblaze/include/asm/auxvec.h b/arch/microblaze/include/asm/auxvec.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/arch/microblaze/include/asm/bitops.h b/arch/microblaze/include/asm/bitops.h
new file mode 100644 (file)
index 0000000..d6df1fd
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_BITOPS_H
+#define _ASM_MICROBLAZE_BITOPS_H
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ */
+
+#include <asm/byteorder.h> /* swab32 */
+#include <asm/system.h> /* save_flags */
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()     barrier()
+#define smp_mb__after_clear_bit()      barrier()
+#include <asm-generic/bitops.h>
+#include <asm-generic/bitops/__fls.h>
+
+#endif /* _ASM_MICROBLAZE_BITOPS_H */
diff --git a/arch/microblaze/include/asm/bug.h b/arch/microblaze/include/asm/bug.h
new file mode 100644 (file)
index 0000000..8eb2cdd
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_BUG_H
+#define _ASM_MICROBLAZE_BUG_H
+
+#include <linux/kernel.h>
+#include <asm-generic/bug.h>
+
+#endif /* _ASM_MICROBLAZE_BUG_H */
diff --git a/arch/microblaze/include/asm/bugs.h b/arch/microblaze/include/asm/bugs.h
new file mode 100644 (file)
index 0000000..f2c6593
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_BUGS_H
+#define _ASM_MICROBLAZE_BUGS_H
+
+static inline void check_bugs(void)
+{
+       /* nothing to do */
+}
+
+#endif /* _ASM_MICROBLAZE_BUGS_H */
diff --git a/arch/microblaze/include/asm/byteorder.h b/arch/microblaze/include/asm/byteorder.h
new file mode 100644 (file)
index 0000000..ce9c587
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _ASM_MICROBLAZE_BYTEORDER_H
+#define _ASM_MICROBLAZE_BYTEORDER_H
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _ASM_MICROBLAZE_BYTEORDER_H */
diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h
new file mode 100644 (file)
index 0000000..c4c64b4
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Cache operations
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_CACHE_H
+#define _ASM_MICROBLAZE_CACHE_H
+
+#include <asm/registers.h>
+
+#define L1_CACHE_SHIFT 2
+/* word-granular cache in microblaze */
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
+#define SMP_CACHE_BYTES        L1_CACHE_BYTES
+
+void _enable_icache(void);
+void _disable_icache(void);
+void _invalidate_icache(unsigned int addr);
+
+#define __enable_icache()              _enable_icache()
+#define __disable_icache()             _disable_icache()
+#define __invalidate_icache(addr)      _invalidate_icache(addr)
+
+void _enable_dcache(void);
+void _disable_dcache(void);
+void _invalidate_dcache(unsigned int addr);
+
+#define __enable_dcache()              _enable_dcache()
+#define __disable_dcache()             _disable_dcache()
+#define __invalidate_dcache(addr)      _invalidate_dcache(addr)
+
+/* FIXME - I don't think this is right */
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
+#define UNCACHED_SHADOW_MASK (CONFIG_XILINX_ERAM_SIZE)
+#endif
+
+#endif /* _ASM_MICROBLAZE_CACHE_H */
diff --git a/arch/microblaze/include/asm/cacheflush.h b/arch/microblaze/include/asm/cacheflush.h
new file mode 100644 (file)
index 0000000..3300b78
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ * based on v850 version which was
+ * Copyright (C) 2001,02,03 NEC Electronics Corporation
+ * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ */
+
+#ifndef _ASM_MICROBLAZE_CACHEFLUSH_H
+#define _ASM_MICROBLAZE_CACHEFLUSH_H
+
+/* Somebody depends on this; sigh... */
+#include <linux/mm.h>
+
+/*
+ * Cache handling functions.
+ * Microblaze has a write-through data cache, meaning that the data cache
+ * never needs to be flushed.  The only flushing operations that are
+ * implemented are to invalidate the instruction cache.  These are called
+ * after loading a user application into memory, we must invalidate the
+ * instruction cache to make sure we don't fetch old, bad code.
+ */
+
+/* FIXME for LL-temac driver */
+#define invalidate_dcache_range(start, end) \
+                       __invalidate_dcache_range(start, end)
+
+#define flush_cache_all()                      __invalidate_cache_all()
+#define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_range(vma, start, end)     __invalidate_cache_all()
+#define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
+
+#define flush_dcache_range(start, end) __invalidate_dcache_range(start, end)
+#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, len) __invalidate_icache_range(start, len)
+#define flush_icache_page(vma, pg)             do { } while (0)
+
+#define flush_cache_vmap(start, end)           do { } while (0)
+#define flush_cache_vunmap(start, end)         do { } while (0)
+
+struct page;
+struct mm_struct;
+struct vm_area_struct;
+
+/* see arch/microblaze/kernel/cache.c */
+extern void __invalidate_icache_all(void);
+extern void __invalidate_icache_range(unsigned long start, unsigned long end);
+extern void __invalidate_icache_page(struct vm_area_struct *vma,
+                               struct page *page);
+extern void __invalidate_icache_user_range(struct vm_area_struct *vma,
+                               struct page *page,
+                               unsigned long adr, int len);
+extern void __invalidate_cache_sigtramp(unsigned long addr);
+
+extern void __invalidate_dcache_all(void);
+extern void __invalidate_dcache_range(unsigned long start, unsigned long end);
+extern void __invalidate_dcache_page(struct vm_area_struct *vma,
+                               struct page *page);
+extern void __invalidate_dcache_user_range(struct vm_area_struct *vma,
+                               struct page *page,
+                               unsigned long adr, int len);
+
+extern inline void __invalidate_cache_all(void)
+{
+       __invalidate_icache_all();
+       __invalidate_dcache_all();
+}
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+do { memcpy((dst), (src), (len)); \
+       flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \
+} while (0)
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+       memcpy((dst), (src), (len))
+
+#endif /* _ASM_MICROBLAZE_CACHEFLUSH_H */
diff --git a/arch/microblaze/include/asm/checksum.h b/arch/microblaze/include/asm/checksum.h
new file mode 100644 (file)
index 0000000..92b3076
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_CHECKSUM_H
+#define _ASM_MICROBLAZE_CHECKSUM_H
+
+#include <linux/in6.h>
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __wsum
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
+                  unsigned short proto, __wsum sum)
+{
+       __asm__("add %0, %0, %1\n\t"
+               "addc %0, %0, %2\n\t"
+               "addc %0, %0, %3\n\t"
+               "addc %0, %0, r0\n\t"
+               : "+&d" (sum)
+               : "d" (saddr), "d" (daddr), "d" (len + proto));
+
+       return sum;
+}
+
+/*
+ * 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
+ */
+extern __wsum csum_partial(const void *buff, int len, __wsum sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern __wsum 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 __wsum csum_partial_copy_from_user(const char *src, char *dst,
+                                       int len, int sum, int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)  \
+       csum_partial_copy((src), (dst), (len), (sum))
+
+/*
+ *     This is a version of ip_compute_csum() optimized for IP headers,
+ *     which always checksum on 4 octet boundaries.
+ *
+ */
+extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
+
+/*
+ *     Fold a partial checksum
+ */
+static inline __sum16 csum_fold(unsigned int sum)
+{
+       sum = (sum & 0xffff) + (sum >> 16);
+       sum = (sum & 0xffff) + (sum >> 16);
+       return ~sum;
+}
+
+static inline __sum16
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
+                 unsigned short proto, __wsum sum)
+{
+       return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+extern __sum16 ip_compute_csum(const unsigned char *buff, int len);
+
+#endif /* _ASM_MICROBLAZE_CHECKSUM_H */
diff --git a/arch/microblaze/include/asm/clinkage.h b/arch/microblaze/include/asm/clinkage.h
new file mode 100644 (file)
index 0000000..9e21843
--- /dev/null
@@ -0,0 +1 @@
+#include <linux/linkage.h>
diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h
new file mode 100644 (file)
index 0000000..52f28f6
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Generic support for queying CPU info
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_CPUINFO_H
+#define _ASM_MICROBLAZE_CPUINFO_H
+
+#include <asm/prom.h>
+
+/* CPU Version and FPGA Family code conversion table type */
+struct cpu_ver_key {
+       const char *s;
+       const unsigned k;
+};
+
+extern const struct cpu_ver_key cpu_ver_lookup[];
+
+struct family_string_key {
+       const char *s;
+       const unsigned k;
+};
+
+extern const struct family_string_key family_string_lookup[];
+
+struct cpuinfo {
+       /* Core CPU configuration */
+       u32 use_instr;
+       u32 use_mult;
+       u32 use_fpu;
+       u32 use_exc;
+       u32 ver_code;
+       u32 mmu;
+
+       /* CPU caches */
+       u32 use_icache;
+       u32 icache_tagbits;
+       u32 icache_write;
+       u32 icache_line;
+       u32 icache_size;
+       unsigned long icache_base;
+       unsigned long icache_high;
+
+       u32 use_dcache;
+       u32 dcache_tagbits;
+       u32 dcache_write;
+       u32 dcache_line;
+       u32 dcache_size;
+       unsigned long dcache_base;
+       unsigned long dcache_high;
+
+       /* Bus connections */
+       u32 use_dopb;
+       u32 use_iopb;
+       u32 use_dlmb;
+       u32 use_ilmb;
+       u32 num_fsl;
+
+       /* CPU interrupt line info */
+       u32 irq_edge;
+       u32 irq_positive;
+
+       u32 area_optimised;
+
+       /* HW debug support */
+       u32 hw_debug;
+       u32 num_pc_brk;
+       u32 num_rd_brk;
+       u32 num_wr_brk;
+       u32 cpu_clock_freq; /* store real freq of cpu */
+       u32 freq_div_hz; /* store freq/HZ */
+
+       /* FPGA family */
+       u32 fpga_family_code;
+
+       /* User define */
+       u32 pvr_user1;
+       u32 pvr_user2;
+};
+
+extern struct cpuinfo cpuinfo;
+
+/* fwd declarations of the various CPUinfo populators */
+void setup_cpuinfo(void);
+
+void set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu);
+void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu);
+
+static inline unsigned int fcpu(struct device_node *cpu, char *n)
+{
+       int *val;
+       return (val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0;
+}
+
+#endif /* _ASM_MICROBLAZE_CPUINFO_H */
diff --git a/arch/microblaze/include/asm/cputable.h b/arch/microblaze/include/asm/cputable.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/arch/microblaze/include/asm/cputime.h b/arch/microblaze/include/asm/cputime.h
new file mode 100644 (file)
index 0000000..6d68ad7
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/cputime.h>
diff --git a/arch/microblaze/include/asm/current.h b/arch/microblaze/include/asm/current.h
new file mode 100644 (file)
index 0000000..8375ea9
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_CURRENT_H
+#define _ASM_MICROBLAZE_CURRENT_H
+
+# ifndef __ASSEMBLY__
+/*
+ * Dedicate r31 to keeping the current task pointer
+ */
+register struct task_struct *current asm("r31");
+
+# define get_current() current
+# endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_CURRENT_H */
diff --git a/arch/microblaze/include/asm/delay.h b/arch/microblaze/include/asm/delay.h
new file mode 100644 (file)
index 0000000..05b7d39
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * include/asm-microblaze/delay.h
+ *
+ * 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) 2008 Michal Simek
+ * Copyright (C) 2007 John Williams
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_MICROBLAZE_DELAY_H
+#define _ASM_MICROBLAZE_DELAY_H
+
+extern inline void __delay(unsigned long loops)
+{
+       asm volatile ("# __delay                \n\t"           \
+                       "1: addi        %0, %0, -1\t\n"         \
+                       "bneid  %0, 1b          \t\n"           \
+                       "nop                    \t\n"
+                       : "=r" (loops)
+                       : "0" (loops));
+}
+
+/*
+ * 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 long long tmp =
+               (unsigned long long)x * (unsigned long long)loops_per_jiffy \
+                       * 226LL;
+       unsigned loops = tmp >> 32;
+
+/*
+       __asm__("mulxuu %0,%1,%2" : "=r" (loops) :
+               "r" (x), "r" (loops_per_jiffy * 226));
+*/
+       __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() : __udelay((n) * HZ)) : \
+       __udelay((n) * HZ))
+
+#define muldiv(a, b, c)                (((a)*(b))/(c))
+
+#endif /* _ASM_MICROBLAZE_DELAY_H */
diff --git a/arch/microblaze/include/asm/device.h b/arch/microblaze/include/asm/device.h
new file mode 100644 (file)
index 0000000..c042830
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License v2. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_DEVICE_H
+#define _ASM_MICROBLAZE_DEVICE_H
+
+struct device_node;
+
+struct dev_archdata {
+       /* Optional pointer to an OF device node */
+       struct device_node      *of_node;
+};
+
+#endif /* _ASM_MICROBLAZE_DEVICE_H */
+
+
diff --git a/arch/microblaze/include/asm/div64.h b/arch/microblaze/include/asm/div64.h
new file mode 100644 (file)
index 0000000..6cd978c
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h
new file mode 100644 (file)
index 0000000..1733625
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_DMA_MAPPING_H
+#define _ASM_MICROBLAZE_DMA_MAPPING_H
+
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+#include <linux/bug.h>
+
+struct scatterlist;
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+
+/* FIXME */
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+       return 1;
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page,
+       unsigned long offset, size_t size,
+       enum dma_data_direction direction)
+{
+       BUG();
+       return 0;
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+       enum dma_data_direction direction)
+{
+       BUG();
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+       enum dma_data_direction direction)
+{
+       BUG();
+       return 0;
+}
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+       enum dma_data_direction direction)
+{
+       BUG();
+}
+
+static inline void
+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+                       enum dma_data_direction direction)
+{
+       BUG();
+}
+
+static inline void
+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+               size_t size, enum dma_data_direction direction)
+{
+       BUG();
+}
+
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+               enum dma_data_direction direction)
+{
+       BUG();
+}
+
+static inline void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+               enum dma_data_direction direction)
+{
+       BUG();
+}
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+       return 0;
+}
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+                               dma_addr_t *dma_handle, int flag)
+{
+       return NULL; /* consistent_alloc(flag, size, dma_handle); */
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+                       void *vaddr, dma_addr_t dma_handle)
+{
+       BUG();
+}
+
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+       enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+
+       return virt_to_bus(ptr);
+}
+
+static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
+                                   size_t size,
+                                   enum dma_data_direction direction)
+{
+       switch (direction) {
+       case DMA_FROM_DEVICE:
+               flush_dcache_range((unsigned)dma_addr,
+                       (unsigned)dma_addr + size);
+                       /* Fall through */
+       case DMA_TO_DEVICE:
+               break;
+       default:
+               BUG();
+       }
+}
+
+#endif /* _ASM_MICROBLAZE_DMA_MAPPING_H */
diff --git a/arch/microblaze/include/asm/dma.h b/arch/microblaze/include/asm/dma.h
new file mode 100644 (file)
index 0000000..0967fa0
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_DMA_H
+#define _ASM_MICROBLAZE_DMA_H
+
+/* we don't have dma address limit. define it as zero to be
+ * unlimited. */
+#define MAX_DMA_ADDRESS                (0)
+
+#endif /* _ASM_MICROBLAZE_DMA_H */
diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h
new file mode 100644 (file)
index 0000000..81337f2
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_ELF_H
+#define _ASM_MICROBLAZE_ELF_H
+
+/*
+ * Note there is no "official" ELF designation for Microblaze.
+ * I've snaffled the value from the microblaze binutils source code
+ * /binutils/microblaze/include/elf/microblaze.h
+ */
+#define EM_XILINX_MICROBLAZE   0xbaab
+#define ELF_ARCH               EM_XILINX_MICROBLAZE
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x)      ((x)->e_machine == EM_XILINX_MICROBLAZE)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS      ELFCLASS32
+
+#endif /* _ASM_MICROBLAZE_ELF_H */
diff --git a/arch/microblaze/include/asm/emergency-restart.h b/arch/microblaze/include/asm/emergency-restart.h
new file mode 100644 (file)
index 0000000..3711bd9
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/emergency-restart.h>
diff --git a/arch/microblaze/include/asm/entry.h b/arch/microblaze/include/asm/entry.h
new file mode 100644 (file)
index 0000000..7f57e42
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Definitions used by low-level trap handlers
+ *
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2007 - 2008 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.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.
+ */
+
+#ifndef _ASM_MICROBLAZE_ENTRY_H
+#define _ASM_MICROBLAZE_ENTRY_H
+
+#include <asm/percpu.h>
+#include <asm/ptrace.h>
+
+/*
+ * These are per-cpu variables required in entry.S, among other
+ * places
+ */
+
+#define PER_CPU(var) per_cpu__##var
+
+# ifndef __ASSEMBLY__
+DECLARE_PER_CPU(unsigned int, KSP); /* Saved kernel stack pointer */
+DECLARE_PER_CPU(unsigned int, KM); /* Kernel/user mode */
+DECLARE_PER_CPU(unsigned int, ENTRY_SP); /* Saved SP on kernel entry */
+DECLARE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */
+DECLARE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */
+DECLARE_PER_CPU(unsigned int, SYSCALL_SAVE); /* Saved syscall number */
+# endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_ENTRY_H */
diff --git a/arch/microblaze/include/asm/errno.h b/arch/microblaze/include/asm/errno.h
new file mode 100644 (file)
index 0000000..4c82b50
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/errno.h>
diff --git a/arch/microblaze/include/asm/exceptions.h b/arch/microblaze/include/asm/exceptions.h
new file mode 100644 (file)
index 0000000..4cdd215
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Preliminary support for HW exception handing for Microblaze
+ *
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_EXCEPTIONS_H
+#define _ASM_MICROBLAZE_EXCEPTIONS_H
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+/* Macros to enable and disable HW exceptions in the MSR */
+/* Define MSR enable bit for HW exceptions */
+#define HWEX_MSR_BIT (1 << 8)
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+#define __enable_hw_exceptions()                                       \
+       __asm__ __volatile__ (" msrset  r0, %0;                         \
+                               nop;"                                   \
+                               :                                       \
+                               : "i" (HWEX_MSR_BIT)                    \
+                               : "memory")
+
+#define __disable_hw_exceptions()                                      \
+       __asm__ __volatile__ (" msrclr r0, %0;                          \
+                               nop;"                                   \
+                               :                                       \
+                               : "i" (HWEX_MSR_BIT)                    \
+                               : "memory")
+#else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+#define __enable_hw_exceptions()                                       \
+       __asm__ __volatile__ ("                                         \
+                               mfs     r12, rmsr;                      \
+                               nop;                                    \
+                               ori     r12, r12, %0;                   \
+                               mts     rmsr, r12;                      \
+                               nop;"                                   \
+                               :                                       \
+                               : "i" (HWEX_MSR_BIT)                    \
+                               : "memory", "r12")
+
+#define __disable_hw_exceptions()                                      \
+       __asm__ __volatile__ ("                                         \
+                               mfs     r12, rmsr;                      \
+                               nop;                                    \
+                               andi    r12, r12, ~%0;                  \
+                               mts     rmsr, r12;                      \
+                               nop;"                                   \
+                               :                                       \
+                               : "i" (HWEX_MSR_BIT)                    \
+                               : "memory", "r12")
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+
+asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
+                                                       int fsr, int addr);
+
+#if defined(CONFIG_XMON)
+extern void xmon(struct pt_regs *regs);
+extern int xmon_bpt(struct pt_regs *regs);
+extern int xmon_sstep(struct pt_regs *regs);
+extern int xmon_iabr_match(struct pt_regs *regs);
+extern int xmon_dabr_match(struct pt_regs *regs);
+extern void (*xmon_fault_handler)(struct pt_regs *regs);
+
+void (*debugger)(struct pt_regs *regs) = xmon;
+int (*debugger_bpt)(struct pt_regs *regs) = xmon_bpt;
+int (*debugger_sstep)(struct pt_regs *regs) = xmon_sstep;
+int (*debugger_iabr_match)(struct pt_regs *regs) = xmon_iabr_match;
+int (*debugger_dabr_match)(struct pt_regs *regs) = xmon_dabr_match;
+void (*debugger_fault_handler)(struct pt_regs *regs);
+#elif defined(CONFIG_KGDB)
+void (*debugger)(struct pt_regs *regs);
+int (*debugger_bpt)(struct pt_regs *regs);
+int (*debugger_sstep)(struct pt_regs *regs);
+int (*debugger_iabr_match)(struct pt_regs *regs);
+int (*debugger_dabr_match)(struct pt_regs *regs);
+void (*debugger_fault_handler)(struct pt_regs *regs);
+#else
+#define debugger(regs)                 do { } while (0)
+#define debugger_bpt(regs)             0
+#define debugger_sstep(regs)           0
+#define debugger_iabr_match(regs)      0
+#define debugger_dabr_match(regs)      0
+#define debugger_fault_handler         ((void (*)(struct pt_regs *))0)
+#endif
+
+#endif /*__ASSEMBLY__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_EXCEPTIONS_H */
diff --git a/arch/microblaze/include/asm/fcntl.h b/arch/microblaze/include/asm/fcntl.h
new file mode 100644 (file)
index 0000000..46ab12d
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/fcntl.h>
diff --git a/arch/microblaze/include/asm/flat.h b/arch/microblaze/include/asm/flat.h
new file mode 100644 (file)
index 0000000..acf0da5
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * uClinux flat-format executables
+ *
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_FLAT_H
+#define _ASM_MICROBLAZE_FLAT_H
+
+#include <asm/unaligned.h>
+
+#define        flat_stack_align(sp) /* nothing needed */
+#define        flat_argvp_envp_on_stack()      0
+#define        flat_old_ram_flag(flags)        (flags)
+#define        flat_reloc_valid(reloc, size)   ((reloc) <= (size))
+#define        flat_set_persistent(relval, p)          0
+
+/*
+ * Microblaze works a little differently from other arches, because
+ * of the MICROBLAZE_64 reloc type. Here, a 32 bit address is split
+ * over two instructions, an 'imm' instruction which provides the top
+ * 16 bits, then the instruction "proper" which provides the low 16
+ * bits.
+ */
+
+/*
+ * Crack open a symbol reference and extract the address to be
+ * relocated. rp is a potentially unaligned pointer to the
+ * reference
+ */
+
+static inline unsigned long
+flat_get_addr_from_rp(unsigned long *rp, unsigned long relval,
+                       unsigned long flags, unsigned long *persistent)
+{
+       unsigned long addr;
+       (void)flags;
+
+       /* Is it a split 64/32 reference? */
+       if (relval & 0x80000000) {
+               /* Grab the two halves of the reference */
+               unsigned long val_hi, val_lo;
+
+               val_hi = get_unaligned(rp);
+               val_lo = get_unaligned(rp+1);
+
+               /* Crack the address out */
+               addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff);
+       } else {
+               /* Get the address straight out */
+               addr = get_unaligned(rp);
+       }
+
+       return addr;
+}
+
+/*
+ * Insert an address into the symbol reference at rp. rp is potentially
+ * unaligned.
+ */
+
+static inline void
+flat_put_addr_at_rp(unsigned long *rp, unsigned long addr, unsigned long relval)
+{
+       /* Is this a split 64/32 reloc? */
+       if (relval & 0x80000000) {
+               /* Get the two "halves" */
+               unsigned long val_hi = get_unaligned(rp);
+               unsigned long val_lo = get_unaligned(rp + 1);
+
+               /* insert the address */
+               val_hi = (val_hi & 0xffff0000) | addr >> 16;
+               val_lo = (val_lo & 0xffff0000) | (addr & 0xffff);
+
+               /* store the two halves back into memory */
+               put_unaligned(val_hi, rp);
+               put_unaligned(val_lo, rp+1);
+       } else {
+               /* Put it straight in, no messing around */
+               put_unaligned(addr, rp);
+       }
+}
+
+#define        flat_get_relocate_addr(rel)     (rel & 0x7fffffff)
+
+#endif /* _ASM_MICROBLAZE_FLAT_H */
diff --git a/arch/microblaze/include/asm/futex.h b/arch/microblaze/include/asm/futex.h
new file mode 100644 (file)
index 0000000..0b74582
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/futex.h>
diff --git a/arch/microblaze/include/asm/gpio.h b/arch/microblaze/include/asm/gpio.h
new file mode 100644 (file)
index 0000000..ea04632
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Generic GPIO API implementation for PowerPC.
+ *
+ * Copyright (c) 2007-2008  MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __ASM_POWERPC_GPIO_H
+#define __ASM_POWERPC_GPIO_H
+
+#include <linux/errno.h>
+#include <asm-generic/gpio.h>
+
+#ifdef CONFIG_GPIOLIB
+
+/*
+ * We don't (yet) implement inlined/rapid versions for on-chip gpios.
+ * Just call gpiolib.
+ */
+static inline int gpio_get_value(unsigned int gpio)
+{
+       return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned int gpio, int value)
+{
+       __gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned int gpio)
+{
+       return __gpio_cansleep(gpio);
+}
+
+/*
+ * Not implemented, yet.
+ */
+static inline int gpio_to_irq(unsigned int gpio)
+{
+       return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+       return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+#endif /* __ASM_POWERPC_GPIO_H */
diff --git a/arch/microblaze/include/asm/hardirq.h b/arch/microblaze/include/asm/hardirq.h
new file mode 100644 (file)
index 0000000..0f2d6b0
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_HARDIRQ_H
+#define _ASM_MICROBLAZE_HARDIRQ_H
+
+#include <linux/cache.h>
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <asm/current.h>
+#include <linux/ptrace.h>
+
+/* should be defined in each interrupt controller driver */
+extern unsigned int get_irq(struct pt_regs *regs);
+
+typedef struct {
+       unsigned int __softirq_pending;
+} ____cacheline_aligned irq_cpustat_t;
+
+void ack_bad_irq(unsigned int irq);
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+#endif /* _ASM_MICROBLAZE_HARDIRQ_H */
diff --git a/arch/microblaze/include/asm/hw_irq.h b/arch/microblaze/include/asm/hw_irq.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h
new file mode 100644 (file)
index 0000000..cfab034
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_IO_H
+#define _ASM_MICROBLAZE_IO_H
+
+#include <asm/byteorder.h>
+#include <asm/page.h>
+#include <linux/types.h>
+#include <asm/page.h>
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+static inline unsigned char __raw_readb(const volatile void __iomem *addr)
+{
+       return *(volatile unsigned char __force *)addr;
+}
+static inline unsigned short __raw_readw(const volatile void __iomem *addr)
+{
+       return *(volatile unsigned short __force *)addr;
+}
+static inline unsigned int __raw_readl(const volatile void __iomem *addr)
+{
+       return *(volatile unsigned int __force *)addr;
+}
+static inline unsigned long __raw_readq(const volatile void __iomem *addr)
+{
+       return *(volatile unsigned long __force *)addr;
+}
+static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr)
+{
+       *(volatile unsigned char __force *)addr = v;
+}
+static inline void __raw_writew(unsigned short v, volatile void __iomem *addr)
+{
+       *(volatile unsigned short __force *)addr = v;
+}
+static inline void __raw_writel(unsigned int v, volatile void __iomem *addr)
+{
+       *(volatile unsigned int __force *)addr = v;
+}
+static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
+{
+       *(volatile unsigned long __force *)addr = v;
+}
+
+/*
+ * read (readb, readw, readl, readq) and write (writeb, writew,
+ * writel, writeq) accessors are for PCI and thus littel endian.
+ * Linux 2.4 for Microblaze had this wrong.
+ */
+static inline unsigned char readb(const volatile void __iomem *addr)
+{
+       return *(volatile unsigned char __force *)addr;
+}
+static inline unsigned short readw(const volatile void __iomem *addr)
+{
+       return le16_to_cpu(*(volatile unsigned short __force *)addr);
+}
+static inline unsigned int readl(const volatile void __iomem *addr)
+{
+       return le32_to_cpu(*(volatile unsigned int __force *)addr);
+}
+static inline void writeb(unsigned char v, volatile void __iomem *addr)
+{
+       *(volatile unsigned char __force *)addr = v;
+}
+static inline void writew(unsigned short v, volatile void __iomem *addr)
+{
+       *(volatile unsigned short __force *)addr = cpu_to_le16(v);
+}
+static inline void writel(unsigned int v, volatile void __iomem *addr)
+{
+       *(volatile unsigned int __force *)addr = cpu_to_le32(v);
+}
+
+/* ioread and iowrite variants. thease are for now same as __raw_
+ * variants of accessors. we might check for endianess in the feature
+ */
+#define ioread8(addr)          __raw_readb((u8 *)(addr))
+#define ioread16(addr)         __raw_readw((u16 *)(addr))
+#define ioread32(addr)         __raw_readl((u32 *)(addr))
+#define iowrite8(v, addr)      __raw_writeb((u8)(v), (u8 *)(addr))
+#define iowrite16(v, addr)     __raw_writew((u16)(v), (u16 *)(addr))
+#define iowrite32(v, addr)     __raw_writel((u32)(v), (u32 *)(addr))
+
+/* These are the definitions for the x86 IO instructions
+ * inb/inw/inl/outb/outw/outl, the "string" versions
+ * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions
+ * inb_p/inw_p/...
+ * The macros don't do byte-swapping.
+ */
+#define inb(port)              readb((u8 *)((port)))
+#define outb(val, port)                writeb((val), (u8 *)((unsigned long)(port)))
+#define inw(port)              readw((u16 *)((port)))
+#define outw(val, port)                writew((val), (u16 *)((unsigned long)(port)))
+#define inl(port)              readl((u32 *)((port)))
+#define outl(val, port)                writel((val), (u32 *)((unsigned long)(port)))
+
+#define inb_p(port)            inb((port))
+#define outb_p(val, port)      outb((val), (port))
+#define inw_p(port)            inw((port))
+#define outw_p(val, port)      outw((val), (port))
+#define inl_p(port)            inl((port))
+#define outl_p(val, port)      outl((val), (port))
+
+#define memset_io(a, b, c)     memset((void *)(a), (b), (c))
+#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c))
+#define memcpy_toio(a, b, c)   memcpy((void *)(a), (b), (c))
+
+/**
+ *     virt_to_phys - map virtual addresses to physical
+ *     @address: address to remap
+ *
+ *     The returned physical address is the physical (CPU) mapping for
+ *     the memory address given. It is only valid to use this function on
+ *     addresses directly mapped or allocated via kmalloc.
+ *
+ *     This function does not give bus mappings for DMA transfers. In
+ *     almost all conceivable cases a device driver should not be using
+ *     this function
+ */
+static inline unsigned long __iomem virt_to_phys(volatile void *address)
+{
+       return __pa((unsigned long)address);
+}
+
+#define virt_to_bus virt_to_phys
+
+/**
+ *     phys_to_virt - map physical address to virtual
+ *     @address: address to remap
+ *
+ *     The returned virtual address is a current CPU mapping for
+ *     the memory address given. It is only valid to use this function on
+ *     addresses that have a kernel mapping
+ *
+ *     This function does not handle bus mappings for DMA transfers. In
+ *     almost all conceivable cases a device driver should not be using
+ *     this function
+ */
+static inline void *phys_to_virt(unsigned long address)
+{
+       return (void *)__va(address);
+}
+
+#define bus_to_virt(a) phys_to_virt(a)
+
+static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size,
+                       unsigned long flags)
+{
+       return (void *)address;
+}
+
+#define ioremap(physaddr, size)        ((void __iomem *)(unsigned long)(physaddr))
+#define iounmap(addr)          ((void)0)
+#define ioremap_nocache(physaddr, size)        ioremap(physaddr, size)
+
+/*
+ * 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
+
+/*
+ * Big Endian
+ */
+#define out_be32(a, v) __raw_writel((v), (void __iomem __force *)(a))
+#define out_be16(a, v) __raw_writew((v), (a))
+
+#define in_be32(a) __raw_readl((const void __iomem __force *)(a))
+#define in_be16(a) __raw_readw(a)
+
+/*
+ * Little endian
+ */
+
+#define out_le32(a, v) __raw_writel(__cpu_to_le32(v), (a));
+#define out_le16(a, v) __raw_writew(__cpu_to_le16(v), (a))
+
+#define in_le32(a) __le32_to_cpu(__raw_readl(a))
+#define in_le16(a) __le16_to_cpu(__raw_readw(a))
+
+/* Byte ops */
+#define out_8(a, v) __raw_writeb((v), (a))
+#define in_8(a) __raw_readb(a)
+
+/* FIXME */
+static inline void __iomem *ioport_map(unsigned long port, unsigned int len)
+{
+       return (void __iomem *) (port);
+}
+
+static inline void ioport_unmap(void __iomem *addr)
+{
+       /* Nothing to do */
+}
+
+#endif /* _ASM_MICROBLAZE_IO_H */
diff --git a/arch/microblaze/include/asm/ioctl.h b/arch/microblaze/include/asm/ioctl.h
new file mode 100644 (file)
index 0000000..b279fe0
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/ioctl.h>
diff --git a/arch/microblaze/include/asm/ioctls.h b/arch/microblaze/include/asm/ioctls.h
new file mode 100644 (file)
index 0000000..03582b2
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_IOCTLS_H
+#define _ASM_MICROBLAZE_IOCTLS_H
+
+#include <linux/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 */
+/* Get Pty Number (of pty-mux device) */
+#define TIOCGPTN       _IOR('T', 0x30, unsigned int)
+#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 /* _ASM_MICROBLAZE_IOCTLS_H */
diff --git a/arch/microblaze/include/asm/ipc.h b/arch/microblaze/include/asm/ipc.h
new file mode 100644 (file)
index 0000000..a46e3d9
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/ipc.h>
diff --git a/arch/microblaze/include/asm/ipcbuf.h b/arch/microblaze/include/asm/ipcbuf.h
new file mode 100644 (file)
index 0000000..b056fa4
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_IPCBUF_H
+#define _ASM_MICROBLAZE_IPCBUF_H
+
+/*
+ * The user_ipc_perm structure for microblaze 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
+ */
+
+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 /* _ASM_MICROBLAZE_IPCBUF_H */
diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h
new file mode 100644 (file)
index 0000000..db515de
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_IRQ_H
+#define _ASM_MICROBLAZE_IRQ_H
+
+#define NR_IRQS 32
+
+#include <linux/interrupt.h>
+
+extern unsigned int nr_irq;
+
+#define NO_IRQ (-1)
+
+static inline int irq_canonicalize(int irq)
+{
+       return irq;
+}
+
+struct pt_regs;
+extern void do_IRQ(struct pt_regs *regs);
+
+/* irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
+ * @device: Device node of the device whose interrupt is to be mapped
+ * @index: Index of the interrupt to map
+ *
+ * This function is a wrapper that chains of_irq_map_one() and
+ * irq_create_of_mapping() to make things easier to callers
+ */
+struct device_node;
+extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index);
+
+/** FIXME - not implement
+ * irq_dispose_mapping - Unmap an interrupt
+ * @virq: linux virq number of the interrupt to unmap
+ */
+static inline void irq_dispose_mapping(unsigned int virq)
+{
+       return;
+}
+
+#endif /* _ASM_MICROBLAZE_IRQ_H */
diff --git a/arch/microblaze/include/asm/irq_regs.h b/arch/microblaze/include/asm/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/arch/microblaze/include/asm/irqflags.h b/arch/microblaze/include/asm/irqflags.h
new file mode 100644 (file)
index 0000000..dea6564
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_IRQFLAGS_H
+#define _ASM_MICROBLAZE_IRQFLAGS_H
+
+#include <linux/irqflags.h>
+
+# if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+
+# define local_irq_save(flags)                         \
+       do {                                            \
+               asm volatile ("# local_irq_save \n\t"   \
+                               "msrclr %0, %1  \n\t"   \
+                               "nop    \n\t"           \
+                               : "=r"(flags)           \
+                               : "i"(MSR_IE)           \
+                               : "memory");            \
+       } while (0)
+
+# define local_irq_disable()                                   \
+       do {                                                    \
+               asm volatile ("# local_irq_disable \n\t"        \
+                               "msrclr r0, %0 \n\t"            \
+                               "nop    \n\t"                   \
+                               :                               \
+                               : "i"(MSR_IE)                   \
+                               : "memory");                    \
+       } while (0)
+
+# define local_irq_enable()                                    \
+       do {                                                    \
+               asm volatile ("# local_irq_enable \n\t"         \
+                               "msrset r0, %0 \n\t"            \
+                               "nop    \n\t"                   \
+                               :                               \
+                               : "i"(MSR_IE)                   \
+                               : "memory");                    \
+       } while (0)
+
+# else /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR == 0 */
+
+# define local_irq_save(flags)                                 \
+       do {                                                    \
+               register unsigned tmp;                          \
+               asm volatile ("# local_irq_save \n\t"           \
+                               "mfs    %0, rmsr \n\t"          \
+                               "nop \n\t"                      \
+                               "andi   %1, %0, %2 \n\t"        \
+                               "mts    rmsr, %1 \n\t"          \
+                               "nop \n\t"                      \
+                               : "=r"(flags), "=r" (tmp)       \
+                               : "i"(~MSR_IE)                  \
+                               : "memory");                    \
+       } while (0)
+
+# define local_irq_disable()                                   \
+       do {                                                    \
+               register unsigned tmp;                          \
+               asm volatile ("# local_irq_disable \n\t"        \
+                               "mfs    %0, rmsr \n\t"          \
+                               "nop \n\t"                      \
+                               "andi   %0, %0, %1 \n\t"        \
+                               "mts    rmsr, %0 \n\t"          \
+                               "nop \n\t"                      \
+                               : "=r"(tmp)                     \
+                               : "i"(~MSR_IE)                  \
+                               : "memory");                    \
+       } while (0)
+
+# define local_irq_enable()                                    \
+       do {                                                    \
+               register unsigned tmp;                          \
+               asm volatile ("# local_irq_enable \n\t"         \
+                               "mfs    %0, rmsr \n\t"          \
+                               "nop \n\t"                      \
+                               "ori    %0, %0, %1 \n\t"        \
+                               "mts    rmsr, %0 \n\t"          \
+                               "nop \n\t"                      \
+                               : "=r"(tmp)                     \
+                               : "i"(MSR_IE)                   \
+                               : "memory");                    \
+       } while (0)
+
+# endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+
+#define local_save_flags(flags)                                        \
+       do {                                                    \
+               asm volatile ("# local_save_flags \n\t"         \
+                               "mfs    %0, rmsr \n\t"          \
+                               "nop    \n\t"                   \
+                               : "=r"(flags)                   \
+                               :                               \
+                               : "memory");                    \
+       } while (0)
+
+#define local_irq_restore(flags)                       \
+       do {                                            \
+               asm volatile ("# local_irq_restore \n\t"\
+                               "mts    rmsr, %0 \n\t"  \
+                               "nop    \n\t"           \
+                               :                       \
+                               : "r"(flags)            \
+                               : "memory");            \
+       } while (0)
+
+static inline int irqs_disabled(void)
+{
+       unsigned long flags;
+
+       local_save_flags(flags);
+       return ((flags & MSR_IE) == 0);
+}
+
+#define raw_irqs_disabled irqs_disabled
+#define raw_irqs_disabled_flags(flags) ((flags) == 0)
+
+#endif /* _ASM_MICROBLAZE_IRQFLAGS_H */
diff --git a/arch/microblaze/include/asm/kdebug.h b/arch/microblaze/include/asm/kdebug.h
new file mode 100644 (file)
index 0000000..6ece1b0
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/arch/microblaze/include/asm/kmap_types.h b/arch/microblaze/include/asm/kmap_types.h
new file mode 100644 (file)
index 0000000..4d7e222
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_KMAP_TYPES_H
+#define _ASM_MICROBLAZE_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 /* _ASM_MICROBLAZE_KMAP_TYPES_H */
diff --git a/arch/microblaze/include/asm/linkage.h b/arch/microblaze/include/asm/linkage.h
new file mode 100644 (file)
index 0000000..3a8e36d
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_LINKAGE_H
+#define _ASM_MICROBLAZE_LINKAGE_H
+
+#define __ALIGN                .align 4
+#define __ALIGN_STR    ".align 4"
+
+#endif /* _ASM_MICROBLAZE_LINKAGE_H */
diff --git a/arch/microblaze/include/asm/lmb.h b/arch/microblaze/include/asm/lmb.h
new file mode 100644 (file)
index 0000000..a0a0a92
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2008 Michal Simek <monstr@monstr.eu>
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_LMB_H
+#define _ASM_MICROBLAZE_LMB_H
+
+/* LMB limit is OFF */
+#define LMB_REAL_LIMIT 0xFFFFFFFF
+
+#endif /* _ASM_MICROBLAZE_LMB_H */
+
+
diff --git a/arch/microblaze/include/asm/local.h b/arch/microblaze/include/asm/local.h
new file mode 100644 (file)
index 0000000..c11c530
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/local.h>
diff --git a/arch/microblaze/include/asm/mman.h b/arch/microblaze/include/asm/mman.h
new file mode 100644 (file)
index 0000000..4914b13
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_MMAN_H
+#define _ASM_MICROBLAZE_MMAN_H
+
+#include <asm-generic/mman.h>
+
+#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 MCL_CURRENT    1 /* lock all current mappings */
+#define MCL_FUTURE     2 /* lock all future mappings */
+
+#endif /* _ASM_MICROBLAZE_MMAN_H */
diff --git a/arch/microblaze/include/asm/mmu.h b/arch/microblaze/include/asm/mmu.h
new file mode 100644 (file)
index 0000000..0e0431d
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_MMU_H
+#define _ASM_MICROBLAZE_MMU_H
+
+#ifndef __ASSEMBLY__
+typedef struct {
+       struct vm_list_struct   *vmlist;
+       unsigned long           end_brk;
+} mm_context_t;
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_MMU_H */
diff --git a/arch/microblaze/include/asm/mmu_context.h b/arch/microblaze/include/asm/mmu_context.h
new file mode 100644 (file)
index 0000000..150ca01
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_MMU_CONTEXT_H
+#define _ASM_MICROBLAZE_MMU_CONTEXT_H
+
+# define init_new_context(tsk, mm)             ({ 0; })
+
+# define enter_lazy_tlb(mm, tsk)               do {} while (0)
+# define change_mm_context(old, ctx, _pml4)    do {} while (0)
+# define destroy_context(mm)                   do {} while (0)
+# define deactivate_mm(tsk, mm)                        do {} while (0)
+# define switch_mm(prev, next, tsk)            do {} while (0)
+# define activate_mm(prev, next)               do {} while (0)
+
+#endif /* _ASM_MICROBLAZE_MMU_CONTEXT_H */
diff --git a/arch/microblaze/include/asm/module.h b/arch/microblaze/include/asm/module.h
new file mode 100644 (file)
index 0000000..914565a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_MODULE_H
+#define _ASM_MICROBLAZE_MODULE_H
+
+/* Microblaze Relocations */
+#define R_MICROBLAZE_NONE 0
+#define R_MICROBLAZE_32 1
+#define R_MICROBLAZE_32_PCREL 2
+#define R_MICROBLAZE_64_PCREL 3
+#define R_MICROBLAZE_32_PCREL_LO 4
+#define R_MICROBLAZE_64 5
+#define R_MICROBLAZE_32_LO 6
+#define R_MICROBLAZE_SRO32 7
+#define R_MICROBLAZE_SRW32 8
+#define R_MICROBLAZE_64_NONE 9
+#define R_MICROBLAZE_32_SYM_OP_SYM 10
+/* Keep this the last entry. */
+#define R_MICROBLAZE_NUM 11
+
+struct mod_arch_specific {
+       int foo;
+};
+
+#define Elf_Shdr       Elf32_Shdr
+#define Elf_Sym                Elf32_Sym
+#define Elf_Ehdr       Elf32_Ehdr
+
+typedef struct { volatile int counter; } module_t;
+
+#endif /* _ASM_MICROBLAZE_MODULE_H */
diff --git a/arch/microblaze/include/asm/msgbuf.h b/arch/microblaze/include/asm/msgbuf.h
new file mode 100644 (file)
index 0000000..09dd970
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef _ASM_MICROBLAZE_MSGBUF_H
+#define _ASM_MICROBLAZE_MSGBUF_H
+
+/*
+ * The msqid64_ds structure for microblaze 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 /* _ASM_MICROBLAZE_MSGBUF_H */
diff --git a/arch/microblaze/include/asm/mutex.h b/arch/microblaze/include/asm/mutex.h
new file mode 100644 (file)
index 0000000..ff6101a
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/mutex-dec.h>
diff --git a/arch/microblaze/include/asm/namei.h b/arch/microblaze/include/asm/namei.h
new file mode 100644 (file)
index 0000000..61d60b8
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_NAMEI_H
+#define _ASM_MICROBLAZE_NAMEI_H
+
+#ifdef __KERNEL__
+
+/* 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 /* __KERNEL__ */
+
+#endif /* _ASM_MICROBLAZE_NAMEI_H */
diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h
new file mode 100644 (file)
index 0000000..ba917cf
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ *
+ * based on PowerPC of_device.h
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_OF_DEVICE_H
+#define _ASM_MICROBLAZE_OF_DEVICE_H
+#ifdef __KERNEL__
+
+#include <linux/device.h>
+#include <linux/of.h>
+
+/*
+ * The of_device is a kind of "base class" that is a superset of
+ * struct device for use by devices attached to an OF node and
+ * probed using OF properties.
+ */
+struct of_device {
+       struct device_node      *node; /* to be obsoleted */
+       u64                     dma_mask; /* DMA mask */
+       struct device           dev; /* Generic device interface */
+};
+
+extern ssize_t of_device_get_modalias(struct of_device *ofdev,
+                                       char *str, ssize_t len);
+
+extern struct of_device *of_device_alloc(struct device_node *np,
+                                        const char *bus_id,
+                                        struct device *parent);
+
+extern int of_device_uevent(struct device *dev,
+                           struct kobj_uevent_env *env);
+
+extern void of_device_make_bus_id(struct of_device *dev);
+
+/* This is just here during the transition */
+#include <linux/of_device.h>
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_OF_DEVICE_H */
diff --git a/arch/microblaze/include/asm/of_platform.h b/arch/microblaze/include/asm/of_platform.h
new file mode 100644 (file)
index 0000000..187c0ee
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
+ *                     <benh@kernel.crashing.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.
+ */
+
+#ifndef _ASM_MICROBLAZE_OF_PLATFORM_H
+#define _ASM_MICROBLAZE_OF_PLATFORM_H
+
+/* This is just here during the transition */
+#include <linux/of_platform.h>
+
+/*
+ * The list of OF IDs below is used for matching bus types in the
+ * system whose devices are to be exposed as of_platform_devices.
+ *
+ * This is the default list valid for most platforms. This file provides
+ * functions who can take an explicit list if necessary though
+ *
+ * The search is always performed recursively looking for children of
+ * the provided device_node and recursively if such a children matches
+ * a bus type in the list
+ */
+
+static const struct of_device_id of_default_bus_ids[] = {
+       { .type = "soc", },
+       { .compatible = "soc", },
+       { .type = "plb5", },
+       { .type = "plb4", },
+       { .type = "opb", },
+       { .type = "simple", },
+       {},
+};
+
+/* Platform drivers register/unregister */
+static inline int of_register_platform_driver(struct of_platform_driver *drv)
+{
+       return of_register_driver(drv, &of_platform_bus_type);
+}
+static inline void of_unregister_platform_driver(struct of_platform_driver *drv)
+{
+       of_unregister_driver(drv);
+}
+
+/* Platform devices and busses creation */
+extern struct of_device *of_platform_device_create(struct device_node *np,
+                                               const char *bus_id,
+                                               struct device *parent);
+/* pseudo "matches" value to not do deep probe */
+#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
+
+extern int of_platform_bus_probe(struct device_node *root,
+                               const struct of_device_id *matches,
+                               struct device *parent);
+
+extern struct of_device *of_find_device_by_phandle(phandle ph);
+
+extern void of_instantiate_rtc(void);
+
+#endif /* _ASM_MICROBLAZE_OF_PLATFORM_H */
diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h
new file mode 100644 (file)
index 0000000..7238dcf
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ * Changes for MMU support:
+ *    Copyright (C) 2007 Xilinx, Inc.  All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_PAGE_H
+#define _ASM_MICROBLAZE_PAGE_H
+
+#include <linux/pfn.h>
+#include <asm/setup.h>
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT     (12)
+#define PAGE_SIZE      (1UL << PAGE_SHIFT)
+#define PAGE_MASK      (~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#define PAGE_UP(addr)  (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
+#define PAGE_DOWN(addr)        ((addr)&(~((PAGE_SIZE)-1)))
+
+/* align addr on a size boundary - adjust address up/down if needed */
+#define _ALIGN_UP(addr, size)  (((addr)+((size)-1))&(~((size)-1)))
+#define _ALIGN_DOWN(addr, size)        ((addr)&(~((size)-1)))
+
+/* align addr on a size boundary - adjust address up if needed */
+#define _ALIGN(addr, size)     _ALIGN_UP(addr, size)
+
+/*
+ * PAGE_OFFSET -- the first address of the first page of memory. When not
+ * using MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ */
+extern unsigned int __page_offset;
+#define PAGE_OFFSET __page_offset
+
+#define copy_page(to, from)                    memcpy((to), (from), PAGE_SIZE)
+#define get_user_page(vaddr)                   __get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr)             free_page(addr)
+
+#define clear_page(pgaddr)                     memset((pgaddr), 0, PAGE_SIZE)
+
+
+#define clear_user_page(pgaddr, vaddr, page)   memset((pgaddr), 0, PAGE_SIZE)
+#define copy_user_page(vto, vfrom, vaddr, topg) \
+                       memcpy((vto), (vfrom), PAGE_SIZE)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct page *pgtable_t;
+typedef struct { unsigned long pte; }          pte_t;
+typedef struct { unsigned long pgprot; }       pgprot_t;
+typedef struct { unsigned long ste[64]; }      pmd_t;
+typedef struct { pmd_t         pue[1]; }       pud_t;
+typedef struct { pud_t         pge[1]; }       pgd_t;
+
+
+#define pte_val(x)     ((x).pte)
+#define pgprot_val(x)  ((x).pgprot)
+#define pmd_val(x)     ((x).ste[0])
+#define pud_val(x)     ((x).pue[0])
+#define pgd_val(x)     ((x).pge[0])
+
+#define __pte(x)       ((pte_t) { (x) })
+#define __pmd(x)       ((pmd_t) { (x) })
+#define __pgd(x)       ((pgd_t) { (x) })
+#define __pgprot(x)    ((pgprot_t) { (x) })
+
+/**
+ * Conversions for virtual address, physical address, pfn, and struct
+ * page are defined in the following files.
+ *
+ * virt -+
+ *      | asm-microblaze/page.h
+ * phys -+
+ *      | linux/pfn.h
+ *  pfn -+
+ *      | asm-generic/memory_model.h
+ * page -+
+ *
+ */
+
+extern unsigned long max_low_pfn;
+extern unsigned long min_low_pfn;
+extern unsigned long max_pfn;
+
+#define __pa(vaddr)            ((unsigned long) (vaddr))
+#define __va(paddr)            ((void *) (paddr))
+
+#define phys_to_pfn(phys)      (PFN_DOWN(phys))
+#define pfn_to_phys(pfn)       (PFN_PHYS(pfn))
+
+#define virt_to_pfn(vaddr)     (phys_to_pfn((__pa(vaddr))))
+#define pfn_to_virt(pfn)       __va(pfn_to_phys((pfn)))
+
+#define virt_to_page(vaddr)    (pfn_to_page(virt_to_pfn(vaddr)))
+#define page_to_virt(page)     (pfn_to_virt(page_to_pfn(page)))
+
+#define page_to_phys(page)     (pfn_to_phys(page_to_pfn(page)))
+#define page_to_bus(page)      (page_to_phys(page))
+#define phys_to_page(paddr)    (pfn_to_page(phys_to_pfn(paddr)))
+
+extern unsigned int memory_start;
+extern unsigned int memory_end;
+extern unsigned int memory_size;
+
+#define pfn_valid(pfn)         ((pfn) >= min_low_pfn && (pfn) < max_mapnr)
+
+#define ARCH_PFN_OFFSET                (PAGE_OFFSET >> PAGE_SHIFT)
+
+#else
+#define tophys(rd, rs) (addik rd, rs, 0)
+#define tovirt(rd, rs) (addik rd, rs, 0)
+#endif /* __ASSEMBLY__ */
+
+#define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr)))
+
+/* Convert between virtual and physical address for MMU.  */
+/* Handle MicroBlaze processor with virtual memory.  */
+#define __virt_to_phys(addr)   addr
+#define __phys_to_virt(addr)   addr
+
+#define TOPHYS(addr)  __virt_to_phys(addr)
+
+#endif /* __KERNEL__ */
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/page.h>
+
+#endif /* _ASM_MICROBLAZE_PAGE_H */
diff --git a/arch/microblaze/include/asm/param.h b/arch/microblaze/include/asm/param.h
new file mode 100644 (file)
index 0000000..8c538a4
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_PARAM_H
+#define _ASM_MICROBLAZE_PARAM_H
+
+#ifdef __KERNEL__
+#define HZ             CONFIG_HZ       /* internal kernel timer frequency */
+#define USER_HZ                100             /* for user interfaces in "ticks" */
+#define CLOCKS_PER_SEC (USER_HZ)       /* frequency at which times() counts */
+#endif /* __KERNEL__ */
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define EXEC_PAGESIZE  4096
+
+#ifndef NOGROUP
+#define NOGROUP                (-1)
+#endif
+
+#define MAXHOSTNAMELEN 64      /* max length of hostname */
+
+#endif /* _ASM_MICROBLAZE_PARAM_H */
diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
new file mode 100644 (file)
index 0000000..7ad28f6
--- /dev/null
@@ -0,0 +1 @@
+#include <linux/pci.h>
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h
new file mode 100644 (file)
index 0000000..ca03794
--- /dev/null
@@ -0,0 +1 @@
+#include <linux/io.h>
diff --git a/arch/microblaze/include/asm/percpu.h b/arch/microblaze/include/asm/percpu.h
new file mode 100644 (file)
index 0000000..06a959d
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/percpu.h>
diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h
new file mode 100644 (file)
index 0000000..2a4b354
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_PGALLOC_H
+#define _ASM_MICROBLAZE_PGALLOC_H
+
+#define check_pgt_cache()      do {} while (0)
+
+#endif /* _ASM_MICROBLAZE_PGALLOC_H */
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h
new file mode 100644 (file)
index 0000000..4df31e4
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_PGTABLE_H
+#define _ASM_MICROBLAZE_PGTABLE_H
+
+#include <asm/setup.h>
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)                \
+               remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define pgd_present(pgd)       (1) /* pages are always present on non MMU */
+#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 non MMU */
+#define PAGE_SHARED            __pgprot(0) /* these mean nothing to non MMU */
+#define PAGE_COPY              __pgprot(0) /* these mean nothing to non MMU */
+#define PAGE_READONLY          __pgprot(0) /* these mean nothing to non MMU */
+#define PAGE_KERNEL            __pgprot(0) /* these mean nothing to non MMU */
+
+#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 })
+
+#ifndef __ASSEMBLY__
+static inline int pte_file(pte_t pte) { return 0; }
+#endif /* __ASSEMBLY__ */
+
+#define ZERO_PAGE(vaddr)       ({ BUG(); NULL; })
+
+#define swapper_pg_dir ((pgd_t *) NULL)
+
+#define pgtable_cache_init()   do {} while (0)
+
+#define arch_enter_lazy_cpu_mode()     do {} while (0)
+
+#ifndef __ASSEMBLY__
+#include <asm-generic/pgtable.h>
+
+void setup_memory(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_PGTABLE_H */
diff --git a/arch/microblaze/include/asm/poll.h b/arch/microblaze/include/asm/poll.h
new file mode 100644 (file)
index 0000000..c98509d
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/poll.h>
diff --git a/arch/microblaze/include/asm/posix_types.h b/arch/microblaze/include/asm/posix_types.h
new file mode 100644 (file)
index 0000000..b4df41c
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_POSIX_TYPES_H
+#define _ASM_MICROBLAZE_POSIX_TYPES_H
+
+/*
+ * 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 int   __kernel_mode_t;
+typedef unsigned int   __kernel_nlink_t;
+typedef long           __kernel_off_t;
+typedef int            __kernel_pid_t;
+typedef unsigned int   __kernel_ipc_pid_t;
+typedef unsigned int   __kernel_uid_t;
+typedef unsigned int   __kernel_gid_t;
+typedef unsigned long  __kernel_size_t;
+typedef long           __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 int   __kernel_old_uid_t;
+typedef unsigned int   __kernel_old_gid_t;
+typedef unsigned int   __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 /* _ASM_MICROBLAZE_POSIX_TYPES_H */
diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h
new file mode 100644 (file)
index 0000000..d8e1543
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_PROCESSOR_H
+#define _ASM_MICROBLAZE_PROCESSOR_H
+
+#include <asm/ptrace.h>
+#include <asm/setup.h>
+#include <asm/registers.h>
+#include <asm/segment.h>
+
+# ifndef __ASSEMBLY__
+/* from kernel/cpu/mb.c */
+extern const struct seq_operations cpuinfo_op;
+
+# define cpu_relax()           barrier()
+# define cpu_sleep()           do {} while (0)
+# define prepare_to_copy(tsk)  do {} while (0)
+
+# endif /* __ASSEMBLY__ */
+
+/*
+ * User space process size: memory size
+ *
+ * TASK_SIZE on MMU cpu is usually 1GB. However, on no-MMU arch, both
+ * user processes and the kernel is on the same memory region. They
+ * both share the memory space and that is limited by the amount of
+ * physical memory. thus, we set TASK_SIZE == amount of total memory.
+ */
+# define TASK_SIZE     (0x81000000 - 0x80000000)
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+# define current_text_addr() ({ __label__ _l; _l: &&_l; })
+
+/*
+ * 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
+
+/* definition in include/linux/sched.h */
+struct task_struct;
+
+/* thread_struct is gone. use thread_info instead. */
+struct thread_struct { };
+# define INIT_THREAD   { }
+
+/* Do necessary setup to start up a newly executed thread. */
+static inline void start_thread(struct pt_regs *regs,
+                               unsigned long pc,
+                               unsigned long usp)
+{
+       regs->pc = pc;
+       regs->r1 = usp;
+       regs->kernel_mode = 0;
+}
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+/* Free all resources held by a thread. */
+static inline void exit_thread(void)
+{
+}
+
+extern unsigned long thread_saved_pc(struct task_struct *t);
+
+extern unsigned long get_wchan(struct task_struct *p);
+
+/*
+ * create a kernel thread without removing it from tasklists
+ */
+extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+
+# define task_pt_regs(tsk) \
+               (((struct pt_regs *)(THREAD_SIZE + task_stack_page(tsk))) - 1)
+
+# define KSTK_EIP(tsk) (0)
+# define KSTK_ESP(tsk) (0)
+
+#endif /* _ASM_MICROBLAZE_PROCESSOR_H */
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
new file mode 100644 (file)
index 0000000..20f7b3a
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * Definitions for talking to the Open Firmware PROM on
+ * Power Macintosh computers.
+ *
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MICROBLAZE_PROM_H
+#define _ASM_MICROBLAZE_PROM_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/platform_device.h>
+#include <asm/irq.h>
+#include <asm/atomic.h>
+
+#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT        1
+#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT        1
+
+#define of_compat_cmp(s1, s2, l)       strncasecmp((s1), (s2), (l))
+#define of_prop_cmp(s1, s2)            strcmp((s1), (s2))
+#define of_node_cmp(s1, s2)            strcasecmp((s1), (s2))
+
+/* Definitions used by the flattened device tree */
+#define OF_DT_HEADER           0xd00dfeed /* marker */
+#define OF_DT_BEGIN_NODE       0x1 /* Start of node, full name */
+#define OF_DT_END_NODE         0x2 /* End node */
+#define OF_DT_PROP             0x3 /* Property: name off, size, content */
+#define OF_DT_NOP              0x4 /* nop */
+#define OF_DT_END              0x9
+
+#define OF_DT_VERSION          0x10
+
+/*
+ * This is what gets passed to the kernel by prom_init or kexec
+ *
+ * The dt struct contains the device tree structure, full pathes and
+ * property contents. The dt strings contain a separate block with just
+ * the strings for the property names, and is fully page aligned and
+ * self contained in a page, so that it can be kept around by the kernel,
+ * each property name appears only once in this page (cheap compression)
+ *
+ * the mem_rsvmap contains a map of reserved ranges of physical memory,
+ * passing it here instead of in the device-tree itself greatly simplifies
+ * the job of everybody. It's just a list of u64 pairs (base/size) that
+ * ends when size is 0
+ */
+struct boot_param_header {
+       u32     magic; /* magic word OF_DT_HEADER */
+       u32     totalsize; /* total size of DT block */
+       u32     off_dt_struct; /* offset to structure */
+       u32     off_dt_strings; /* offset to strings */
+       u32     off_mem_rsvmap; /* offset to memory reserve map */
+       u32     version; /* format version */
+       u32     last_comp_version; /* last compatible version */
+       /* version 2 fields below */
+       u32     boot_cpuid_phys; /* Physical CPU id we're booting on */
+       /* version 3 fields below */
+       u32     dt_strings_size; /* size of the DT strings block */
+       /* version 17 fields below */
+       u32     dt_struct_size; /* size of the DT structure block */
+};
+
+typedef u32 phandle;
+typedef u32 ihandle;
+
+struct property {
+       char    *name;
+       int     length;
+       void    *value;
+       struct property *next;
+};
+
+struct device_node {
+       const char *name;
+       const char *type;
+       phandle node;
+       phandle linux_phandle;
+       char    *full_name;
+
+       struct  property *properties;
+       struct  property *deadprops; /* removed properties */
+       struct  device_node *parent;
+       struct  device_node *child;
+       struct  device_node *sibling;
+       struct  device_node *next; /* next device of same type */
+       struct  device_node *allnext; /* next in list of all nodes */
+       struct  proc_dir_entry *pde; /* this node's proc directory */
+       struct  kref kref;
+       unsigned long _flags;
+       void    *data;
+};
+
+extern struct device_node *of_chosen;
+
+static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
+{
+       return test_bit(flag, &n->_flags);
+}
+
+static inline void of_node_set_flag(struct device_node *n, unsigned long flag)
+{
+       set_bit(flag, &n->_flags);
+}
+
+#define HAVE_ARCH_DEVTREE_FIXUPS
+
+static inline void set_node_proc_entry(struct device_node *dn,
+                                       struct proc_dir_entry *de)
+{
+       dn->pde = de;
+}
+
+extern struct device_node *allnodes;   /* temporary while merging */
+extern rwlock_t devtree_lock;  /* temporary while merging */
+
+extern struct device_node *of_find_all_nodes(struct device_node *prev);
+extern struct device_node *of_node_get(struct device_node *node);
+extern void of_node_put(struct device_node *node);
+
+/* For scanning the flat device-tree at boot time */
+extern int __init of_scan_flat_dt(int (*it)(unsigned long node,
+                                       const char *uname, int depth,
+                                       void *data),
+                               void *data);
+extern void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
+                                       unsigned long *size);
+extern int __init
+               of_flat_dt_is_compatible(unsigned long node, const char *name);
+extern unsigned long __init of_get_flat_dt_root(void);
+
+/* For updating the device tree at runtime */
+extern void of_attach_node(struct device_node *);
+extern void of_detach_node(struct device_node *);
+
+/* Other Prototypes */
+extern void finish_device_tree(void);
+extern void unflatten_device_tree(void);
+extern int early_uartlite_console(void);
+extern void early_init_devtree(void *);
+extern int machine_is_compatible(const char *compat);
+extern void print_properties(struct device_node *node);
+extern int prom_n_intr_cells(struct device_node *np);
+extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
+extern int prom_add_property(struct device_node *np, struct property *prop);
+extern int prom_remove_property(struct device_node *np, struct property *prop);
+extern int prom_update_property(struct device_node *np,
+                               struct property *newprop,
+                               struct property *oldprop);
+
+extern struct resource *request_OF_resource(struct device_node *node,
+                               int index, const char *name_postfix);
+extern int release_OF_resource(struct device_node *node, int index);
+
+/*
+ * OF address retreival & translation
+ */
+
+/* Helper to read a big number; size is in cells (not bytes) */
+static inline u64 of_read_number(const u32 *cell, int size)
+{
+       u64 r = 0;
+       while (size--)
+               r = (r << 32) | *(cell++);
+       return r;
+}
+
+/* Like of_read_number, but we want an unsigned long result */
+#define of_read_ulong(cell, size)      of_read_number(cell, size)
+
+/* Translate an OF address block into a CPU physical address
+ */
+extern u64 of_translate_address(struct device_node *np, const u32 *addr);
+
+/* Extract an address from a device, returns the region size and
+ * the address space flags too. The PCI version uses a BAR number
+ * instead of an absolute index
+ */
+extern const u32 *of_get_address(struct device_node *dev, int index,
+                       u64 *size, unsigned int *flags);
+extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
+                       u64 *size, unsigned int *flags);
+
+/* Get an address as a resource. Note that if your address is
+ * a PIO address, the conversion will fail if the physical address
+ * can't be internally converted to an IO token with
+ * pci_address_to_pio(), that is because it's either called to early
+ * or it can't be matched to any host bridge IO space
+ */
+extern int of_address_to_resource(struct device_node *dev, int index,
+                               struct resource *r);
+extern int of_pci_address_to_resource(struct device_node *dev, int bar,
+                               struct resource *r);
+
+/* Parse the ibm,dma-window property of an OF node into the busno, phys and
+ * size parameters.
+ */
+void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
+               unsigned long *busno, unsigned long *phys, unsigned long *size);
+
+extern void kdump_move_device_tree(void);
+
+/* CPU OF node matching */
+struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
+
+/* Get the MAC address */
+extern const void *of_get_mac_address(struct device_node *np);
+
+/*
+ * OF interrupt mapping
+ */
+
+/* This structure is returned when an interrupt is mapped. The controller
+ * field needs to be put() after use
+ */
+
+#define OF_MAX_IRQ_SPEC                4 /* We handle specifiers of at most 4 cells */
+
+struct of_irq {
+       struct device_node *controller; /* Interrupt controller node */
+       u32 size; /* Specifier size */
+       u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
+};
+
+/**
+ * of_irq_map_init - Initialize the irq remapper
+ * @flags:     flags defining workarounds to enable
+ *
+ * Some machines have bugs in the device-tree which require certain workarounds
+ * to be applied. Call this before any interrupt mapping attempts to enable
+ * those workarounds.
+ */
+#define OF_IMAP_OLDWORLD_MAC   0x00000001
+#define OF_IMAP_NO_PHANDLE     0x00000002
+
+extern void of_irq_map_init(unsigned int flags);
+
+/**
+ * of_irq_map_raw - Low level interrupt tree parsing
+ * @parent:    the device interrupt parent
+ * @intspec:   interrupt specifier ("interrupts" property of the device)
+ * @ointsize:  size of the passed in interrupt specifier
+ * @addr:      address specifier (start of "reg" property of the device)
+ * @out_irq:   structure of_irq filled by this function
+ *
+ * Returns 0 on success and a negative number on error
+ *
+ * This function is a low-level interrupt tree walking function. It
+ * can be used to do a partial walk with synthetized reg and interrupts
+ * properties, for example when resolving PCI interrupts when no device
+ * node exist for the parent.
+ *
+ */
+
+extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
+                       u32 ointsize, const u32 *addr,
+                       struct of_irq *out_irq);
+
+/**
+ * of_irq_map_one - Resolve an interrupt for a device
+ * @device:    the device whose interrupt is to be resolved
+ * @index:     index of the interrupt to resolve
+ * @out_irq:   structure of_irq filled by this function
+ *
+ * This function resolves an interrupt, walking the tree, for a given
+ * device-tree node. It's the high level pendant to of_irq_map_raw().
+ * It also implements the workarounds for OldWolrd Macs.
+ */
+extern int of_irq_map_one(struct device_node *device, int index,
+                       struct of_irq *out_irq);
+
+/**
+ * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * @pdev:      the device whose interrupt is to be resolved
+ * @out_irq:   structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+struct pci_dev;
+extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+
+extern int of_irq_to_resource(struct device_node *dev, int index,
+                       struct resource *r);
+
+/**
+ * of_iomap - Maps the memory mapped IO for a given device_node
+ * @device:    the device whose io range will be mapped
+ * @index:     index of the io range
+ *
+ * Returns a pointer to the mapped memory
+ */
+extern void __iomem *of_iomap(struct device_node *device, int index);
+
+/*
+ * NB: This is here while we transition from using asm/prom.h
+ * to linux/of.h
+ */
+#include <linux/of.h>
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_PROM_H */
diff --git a/arch/microblaze/include/asm/ptrace.h b/arch/microblaze/include/asm/ptrace.h
new file mode 100644 (file)
index 0000000..f1f0348
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_PTRACE_H
+#define _ASM_MICROBLAZE_PTRACE_H
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+typedef unsigned long microblaze_reg_t;
+
+struct pt_regs {
+       microblaze_reg_t r0;
+       microblaze_reg_t r1;
+       microblaze_reg_t r2;
+       microblaze_reg_t r3;
+       microblaze_reg_t r4;
+       microblaze_reg_t r5;
+       microblaze_reg_t r6;
+       microblaze_reg_t r7;
+       microblaze_reg_t r8;
+       microblaze_reg_t r9;
+       microblaze_reg_t r10;
+       microblaze_reg_t r11;
+       microblaze_reg_t r12;
+       microblaze_reg_t r13;
+       microblaze_reg_t r14;
+       microblaze_reg_t r15;
+       microblaze_reg_t r16;
+       microblaze_reg_t r17;
+       microblaze_reg_t r18;
+       microblaze_reg_t r19;
+       microblaze_reg_t r20;
+       microblaze_reg_t r21;
+       microblaze_reg_t r22;
+       microblaze_reg_t r23;
+       microblaze_reg_t r24;
+       microblaze_reg_t r25;
+       microblaze_reg_t r26;
+       microblaze_reg_t r27;
+       microblaze_reg_t r28;
+       microblaze_reg_t r29;
+       microblaze_reg_t r30;
+       microblaze_reg_t r31;
+       microblaze_reg_t pc;
+       microblaze_reg_t msr;
+       microblaze_reg_t ear;
+       microblaze_reg_t esr;
+       microblaze_reg_t fsr;
+       int kernel_mode;
+};
+
+#define kernel_mode(regs)              ((regs)->kernel_mode)
+#define user_mode(regs)                        (!kernel_mode(regs))
+
+#define instruction_pointer(regs)      ((regs)->pc)
+#define profile_pc(regs)               instruction_pointer(regs)
+
+void show_regs(struct pt_regs *);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_PTRACE_H */
diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h
new file mode 100644 (file)
index 0000000..66f1b30
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Support for the MicroBlaze PVR (Processor Version Register)
+ *
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ * Copyright (C) 2007 - 2009 PetaLogix
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_PVR_H
+#define _ASM_MICROBLAZE_PVR_H
+
+#define PVR_MSR_BIT 0x400
+
+struct pvr_s {
+       unsigned pvr[16];
+};
+
+/* The following taken from Xilinx's standalone BSP pvr.h */
+
+/* Basic PVR mask */
+#define PVR0_PVR_FULL_MASK             0x80000000
+#define PVR0_USE_BARREL_MASK           0x40000000
+#define PVR0_USE_DIV_MASK              0x20000000
+#define PVR0_USE_HW_MUL_MASK           0x10000000
+#define PVR0_USE_FPU_MASK              0x08000000
+#define PVR0_USE_EXC_MASK              0x04000000
+#define PVR0_USE_ICACHE_MASK           0x02000000
+#define PVR0_USE_DCACHE_MASK           0x01000000
+#define PVR0_USE_MMU                   0x00800000      /* new */
+#define PVR0_VERSION_MASK              0x0000FF00
+#define PVR0_USER1_MASK                        0x000000FF
+
+/* User 2 PVR mask */
+#define PVR1_USER2_MASK                        0xFFFFFFFF
+
+/* Configuration PVR masks */
+#define PVR2_D_OPB_MASK                        0x80000000
+#define PVR2_D_LMB_MASK                        0x40000000
+#define PVR2_I_OPB_MASK                        0x20000000
+#define PVR2_I_LMB_MASK                        0x10000000
+#define PVR2_INTERRUPT_IS_EDGE_MASK    0x08000000
+#define PVR2_EDGE_IS_POSITIVE_MASK     0x04000000
+#define PVR2_D_PLB_MASK                        0x02000000      /* new */
+#define PVR2_I_PLB_MASK                        0x01000000      /* new */
+#define PVR2_INTERCONNECT              0x00800000      /* new */
+#define PVR2_USE_EXTEND_FSL            0x00080000      /* new */
+#define PVR2_USE_FSL_EXC               0x00040000      /* new */
+#define PVR2_USE_MSR_INSTR             0x00020000
+#define PVR2_USE_PCMP_INSTR            0x00010000
+#define PVR2_AREA_OPTIMISED            0x00008000
+#define PVR2_USE_BARREL_MASK           0x00004000
+#define PVR2_USE_DIV_MASK              0x00002000
+#define PVR2_USE_HW_MUL_MASK           0x00001000
+#define PVR2_USE_FPU_MASK              0x00000800
+#define PVR2_USE_MUL64_MASK            0x00000400
+#define PVR2_USE_FPU2_MASK             0x00000200      /* new */
+#define PVR2_USE_IPLBEXC               0x00000100
+#define PVR2_USE_DPLBEXC               0x00000080
+#define PVR2_OPCODE_0x0_ILL_MASK       0x00000040
+#define PVR2_UNALIGNED_EXC_MASK                0x00000020
+#define PVR2_ILL_OPCODE_EXC_MASK       0x00000010
+#define PVR2_IOPB_BUS_EXC_MASK         0x00000008
+#define PVR2_DOPB_BUS_EXC_MASK         0x00000004
+#define PVR2_DIV_ZERO_EXC_MASK         0x00000002
+#define PVR2_FPU_EXC_MASK              0x00000001
+
+/* Debug and exception PVR masks */
+#define PVR3_DEBUG_ENABLED_MASK                0x80000000
+#define PVR3_NUMBER_OF_PC_BRK_MASK     0x1E000000
+#define PVR3_NUMBER_OF_RD_ADDR_BRK_MASK        0x00380000
+#define PVR3_NUMBER_OF_WR_ADDR_BRK_MASK        0x0000E000
+#define PVR3_FSL_LINKS_MASK            0x00000380
+
+/* ICache config PVR masks */
+#define PVR4_USE_ICACHE_MASK           0x80000000
+#define PVR4_ICACHE_ADDR_TAG_BITS_MASK 0x7C000000
+#define PVR4_ICACHE_USE_FSL_MASK       0x02000000
+#define PVR4_ICACHE_ALLOW_WR_MASK      0x01000000
+#define PVR4_ICACHE_LINE_LEN_MASK      0x00E00000
+#define PVR4_ICACHE_BYTE_SIZE_MASK     0x001F0000
+
+/* DCache config PVR masks */
+#define PVR5_USE_DCACHE_MASK           0x80000000
+#define PVR5_DCACHE_ADDR_TAG_BITS_MASK 0x7C000000
+#define PVR5_DCACHE_USE_FSL_MASK       0x02000000
+#define PVR5_DCACHE_ALLOW_WR_MASK      0x01000000
+#define PVR5_DCACHE_LINE_LEN_MASK      0x00E00000
+#define PVR5_DCACHE_BYTE_SIZE_MASK     0x001F0000
+
+/* ICache base address PVR mask */
+#define PVR6_ICACHE_BASEADDR_MASK      0xFFFFFFFF
+
+/* ICache high address PVR mask */
+#define PVR7_ICACHE_HIGHADDR_MASK      0xFFFFFFFF
+
+/* DCache base address PVR mask */
+#define PVR8_DCACHE_BASEADDR_MASK      0xFFFFFFFF
+
+/* DCache high address PVR mask */
+#define PVR9_DCACHE_HIGHADDR_MASK      0xFFFFFFFF
+
+/* Target family PVR mask */
+#define PVR10_TARGET_FAMILY_MASK       0xFF000000
+
+/* MMU descrtiption */
+#define PVR11_USE_MMU                  0xC0000000
+#define PVR11_MMU_ITLB_SIZE            0x38000000
+#define PVR11_MMU_DTLB_SIZE            0x07000000
+#define PVR11_MMU_TLB_ACCESS           0x00C00000
+#define PVR11_MMU_ZONES                        0x003C0000
+/* MSR Reset value PVR mask */
+#define PVR11_MSR_RESET_VALUE_MASK     0x000007FF
+
+
+/* PVR access macros */
+#define PVR_IS_FULL(pvr)               (pvr.pvr[0] & PVR0_PVR_FULL_MASK)
+#define PVR_USE_BARREL(pvr)            (pvr.pvr[0] & PVR0_USE_BARREL_MASK)
+#define PVR_USE_DIV(pvr)               (pvr.pvr[0] & PVR0_USE_DIV_MASK)
+#define PVR_USE_HW_MUL(pvr)            (pvr.pvr[0] & PVR0_USE_HW_MUL_MASK)
+#define PVR_USE_FPU(pvr)               (pvr.pvr[0] & PVR0_USE_FPU_MASK)
+#define PVR_USE_FPU2(pvr)              (pvr.pvr[2] & PVR2_USE_FPU2_MASK)
+#define PVR_USE_ICACHE(pvr)            (pvr.pvr[0] & PVR0_USE_ICACHE_MASK)
+#define PVR_USE_DCACHE(pvr)            (pvr.pvr[0] & PVR0_USE_DCACHE_MASK)
+#define PVR_VERSION(pvr)       ((pvr.pvr[0] & PVR0_VERSION_MASK) >> 8)
+#define PVR_USER1(pvr)                 (pvr.pvr[0] & PVR0_USER1_MASK)
+#define PVR_USER2(pvr)                 (pvr.pvr[1] & PVR1_USER2_MASK)
+
+#define PVR_D_OPB(pvr)                 (pvr.pvr[2] & PVR2_D_OPB_MASK)
+#define PVR_D_LMB(pvr)                 (pvr.pvr[2] & PVR2_D_LMB_MASK)
+#define PVR_I_OPB(pvr)                 (pvr.pvr[2] & PVR2_I_OPB_MASK)
+#define PVR_I_LMB(pvr)                 (pvr.pvr[2] & PVR2_I_LMB_MASK)
+#define PVR_INTERRUPT_IS_EDGE(pvr) \
+                       (pvr.pvr[2] & PVR2_INTERRUPT_IS_EDGE_MASK)
+#define PVR_EDGE_IS_POSITIVE(pvr) \
+                       (pvr.pvr[2] & PVR2_EDGE_IS_POSITIVE_MASK)
+#define PVR_USE_MSR_INSTR(pvr)         (pvr.pvr[2] & PVR2_USE_MSR_INSTR)
+#define PVR_USE_PCMP_INSTR(pvr)                (pvr.pvr[2] & PVR2_USE_PCMP_INSTR)
+#define PVR_AREA_OPTIMISED(pvr)                (pvr.pvr[2] & PVR2_AREA_OPTIMISED)
+#define PVR_USE_MUL64(pvr)             (pvr.pvr[2] & PVR2_USE_MUL64_MASK)
+#define PVR_OPCODE_0x0_ILLEGAL(pvr) \
+                       (pvr.pvr[2] & PVR2_OPCODE_0x0_ILL_MASK)
+#define PVR_UNALIGNED_EXCEPTION(pvr) \
+                       (pvr.pvr[2] & PVR2_UNALIGNED_EXC_MASK)
+#define PVR_ILL_OPCODE_EXCEPTION(pvr) \
+                       (pvr.pvr[2] & PVR2_ILL_OPCODE_EXC_MASK)
+#define PVR_IOPB_BUS_EXCEPTION(pvr) \
+                       (pvr.pvr[2] & PVR2_IOPB_BUS_EXC_MASK)
+#define PVR_DOPB_BUS_EXCEPTION(pvr) \
+                       (pvr.pvr[2] & PVR2_DOPB_BUS_EXC_MASK)
+#define PVR_DIV_ZERO_EXCEPTION(pvr) \
+                       (pvr.pvr[2] & PVR2_DIV_ZERO_EXC_MASK)
+#define PVR_FPU_EXCEPTION(pvr)         (pvr.pvr[2] & PVR2_FPU_EXC_MASK)
+#define PVR_FSL_EXCEPTION(pvr)         (pvr.pvr[2] & PVR2_USE_EXTEND_FSL)
+
+#define PVR_DEBUG_ENABLED(pvr)         (pvr.pvr[3] & PVR3_DEBUG_ENABLED_MASK)
+#define PVR_NUMBER_OF_PC_BRK(pvr) \
+                       ((pvr.pvr[3] & PVR3_NUMBER_OF_PC_BRK_MASK) >> 25)
+#define PVR_NUMBER_OF_RD_ADDR_BRK(pvr) \
+                       ((pvr.pvr[3] & PVR3_NUMBER_OF_RD_ADDR_BRK_MASK) >> 19)
+#define PVR_NUMBER_OF_WR_ADDR_BRK(pvr) \
+                       ((pvr.pvr[3] & PVR3_NUMBER_OF_WR_ADDR_BRK_MASK) >> 13)
+#define PVR_FSL_LINKS(pvr)     ((pvr.pvr[3] & PVR3_FSL_LINKS_MASK) >> 7)
+
+#define PVR_ICACHE_ADDR_TAG_BITS(pvr) \
+                       ((pvr.pvr[4] & PVR4_ICACHE_ADDR_TAG_BITS_MASK) >> 26)
+#define PVR_ICACHE_USE_FSL(pvr)                (pvr.pvr[4] & PVR4_ICACHE_USE_FSL_MASK)
+#define PVR_ICACHE_ALLOW_WR(pvr)       (pvr.pvr[4] & PVR4_ICACHE_ALLOW_WR_MASK)
+#define PVR_ICACHE_LINE_LEN(pvr) \
+                       (1 << ((pvr.pvr[4] & PVR4_ICACHE_LINE_LEN_MASK) >> 21))
+#define PVR_ICACHE_BYTE_SIZE(pvr) \
+                       (1 << ((pvr.pvr[4] & PVR4_ICACHE_BYTE_SIZE_MASK) >> 16))
+
+#define PVR_DCACHE_ADDR_TAG_BITS(pvr) \
+                       ((pvr.pvr[5] & PVR5_DCACHE_ADDR_TAG_BITS_MASK) >> 26)
+#define PVR_DCACHE_USE_FSL(pvr)                (pvr.pvr[5] & PVR5_DCACHE_USE_FSL_MASK)
+#define PVR_DCACHE_ALLOW_WR(pvr)       (pvr.pvr[5] & PVR5_DCACHE_ALLOW_WR_MASK)
+#define PVR_DCACHE_LINE_LEN(pvr) \
+                       (1 << ((pvr.pvr[5] & PVR5_DCACHE_LINE_LEN_MASK) >> 21))
+#define PVR_DCACHE_BYTE_SIZE(pvr) \
+                       (1 << ((pvr.pvr[5] & PVR5_DCACHE_BYTE_SIZE_MASK) >> 16))
+
+
+#define PVR_ICACHE_BASEADDR(pvr)       (pvr.pvr[6] & PVR6_ICACHE_BASEADDR_MASK)
+#define PVR_ICACHE_HIGHADDR(pvr)       (pvr.pvr[7] & PVR7_ICACHE_HIGHADDR_MASK)
+
+#define PVR_DCACHE_BASEADDR(pvr)       (pvr.pvr[8] & PVR8_DCACHE_BASEADDR_MASK)
+#define PVR_DCACHE_HIGHADDR(pvr)       (pvr.pvr[9] & PVR9_DCACHE_HIGHADDR_MASK)
+
+#define PVR_TARGET_FAMILY(pvr) ((pvr.pvr[10] & PVR10_TARGET_FAMILY_MASK) >> 24)
+
+#define PVR_MSR_RESET_VALUE(pvr) \
+                               (pvr.pvr[11] & PVR11_MSR_RESET_VALUE_MASK)
+
+/* mmu */
+#define PVR_USE_MMU(pvr)       ((pvr.pvr[11] & PVR11_USE_MMU) >> 30)
+#define PVR_MMU_ITLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_ITLB_SIZE)
+#define PVR_MMU_DTLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_DTLB_SIZE)
+#define PVR_MMU_TLB_ACCESS(pvr)        (pvr.pvr[11] & PVR11_MMU_TLB_ACCESS)
+#define PVR_MMU_ZONES(pvr)     (pvr.pvr[11] & PVR11_MMU_ZONES)
+
+
+int cpu_has_pvr(void);
+void get_pvr(struct pvr_s *pvr);
+
+#endif /* _ASM_MICROBLAZE_PVR_H */
diff --git a/arch/microblaze/include/asm/registers.h b/arch/microblaze/include/asm/registers.h
new file mode 100644 (file)
index 0000000..834142d
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_REGISTERS_H
+#define _ASM_MICROBLAZE_REGISTERS_H
+
+#define MSR_BE (1<<0) /* 0x001 */
+#define MSR_IE (1<<1) /* 0x002 */
+#define MSR_C  (1<<2) /* 0x004 */
+#define MSR_BIP        (1<<3) /* 0x008 */
+#define MSR_FSL        (1<<4) /* 0x010 */
+#define MSR_ICE        (1<<5) /* 0x020 */
+#define MSR_DZ (1<<6) /* 0x040 */
+#define MSR_DCE        (1<<7) /* 0x080 */
+#define MSR_EE (1<<8) /* 0x100 */
+#define MSR_EIP        (1<<9) /* 0x200 */
+#define MSR_CC (1<<31)
+
+/* Floating Point Status Register (FSR) Bits */
+#define FSR_IO         (1<<4) /* Invalid operation */
+#define FSR_DZ         (1<<3) /* Divide-by-zero */
+#define FSR_OF         (1<<2) /* Overflow */
+#define FSR_UF         (1<<1) /* Underflow */
+#define FSR_DO         (1<<0) /* Denormalized operand error */
+
+#endif /* _ASM_MICROBLAZE_REGISTERS_H */
diff --git a/arch/microblaze/include/asm/resource.h b/arch/microblaze/include/asm/resource.h
new file mode 100644 (file)
index 0000000..04bc4db
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/resource.h>
diff --git a/arch/microblaze/include/asm/scatterlist.h b/arch/microblaze/include/asm/scatterlist.h
new file mode 100644 (file)
index 0000000..08ff1d0
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SCATTERLIST_H
+#define _ASM_MICROBLAZE_SCATTERLIST_H
+
+struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+       unsigned long   sg_magic;
+#endif
+       unsigned long   page_link;
+       dma_addr_t      dma_address;
+       unsigned int    offset;
+       unsigned int    length;
+};
+
+#define sg_dma_address(sg)      ((sg)->dma_address)
+#define sg_dma_len(sg)          ((sg)->length)
+
+#define ISA_DMA_THRESHOLD (~0UL)
+
+#endif /* _ASM_MICROBLAZE_SCATTERLIST_H */
diff --git a/arch/microblaze/include/asm/sections.h b/arch/microblaze/include/asm/sections.h
new file mode 100644 (file)
index 0000000..8434a43
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SECTIONS_H
+#define _ASM_MICROBLAZE_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+# ifndef __ASSEMBLY__
+extern char _ssbss[], _esbss[];
+extern unsigned long __ivt_start[], __ivt_end[];
+
+#  ifdef CONFIG_MTD_UCLINUX
+extern char *_ebss;
+#  endif
+
+extern u32 _fdt_start[], _fdt_end[];
+
+# endif /* !__ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_SECTIONS_H */
diff --git a/arch/microblaze/include/asm/segment.h b/arch/microblaze/include/asm/segment.h
new file mode 100644 (file)
index 0000000..7f5dcc5
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SEGMENT_H
+#define _ASM_MICROBLAZE_SEGMENT_H
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+       unsigned long seg;
+} mm_segment_t;
+
+/*
+ * On Microblaze the fs value is actually the top of the corresponding
+ * address space.
+ *
+ * The fs value determines whether argument validity checking should be
+ * performed or not. If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ *
+ * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal.
+ */
+#  define KERNEL_DS    ((mm_segment_t){0})
+#  define USER_DS      KERNEL_DS
+
+# define get_ds()      (KERNEL_DS)
+# define get_fs()      (current_thread_info()->addr_limit)
+# define set_fs(x) \
+               do { current_thread_info()->addr_limit = (x); } while (0)
+
+# define segment_eq(a, b)              ((a).seg == (b).seg)
+
+# endif /* __ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_SEGMENT_H */
diff --git a/arch/microblaze/include/asm/selfmod.h b/arch/microblaze/include/asm/selfmod.h
new file mode 100644 (file)
index 0000000..c42aff2
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SELFMOD_H
+#define _ASM_MICROBLAZE_SELFMOD_H
+
+/*
+ * BARRIER_BASE_ADDR is constant address for selfmod function.
+ * do not change this value - selfmod function is in
+ * arch/microblaze/kernel/selfmod.c: selfmod_function()
+ *
+ * last 16 bits is used for storing register offset
+ */
+
+#define BARRIER_BASE_ADDR      0x1234ff00
+
+void selfmod_function(const int *arr_fce, const unsigned int base);
+
+#endif /* _ASM_MICROBLAZE_SELFMOD_H */
diff --git a/arch/microblaze/include/asm/sembuf.h b/arch/microblaze/include/asm/sembuf.h
new file mode 100644 (file)
index 0000000..b804ed7
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SEMBUF_H
+#define _ASM_MICROBLAZE_SEMBUF_H
+
+/*
+ * The semid64_ds structure for microblaze 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 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 /* _ASM_MICROBLAZE_SEMBUF_H */
diff --git a/arch/microblaze/include/asm/serial.h b/arch/microblaze/include/asm/serial.h
new file mode 100644 (file)
index 0000000..39bfc8c
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SERIAL_H
+#define _ASM_MICROBLAZE_SERIAL_H
+
+# define BASE_BAUD (1843200 / 16)
+
+#endif /* _ASM_MICROBLAZE_SERIAL_H */
diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h
new file mode 100644 (file)
index 0000000..9b98e8e
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SETUP_H
+#define _ASM_MICROBLAZE_SETUP_H
+
+#define COMMAND_LINE_SIZE      256
+
+# ifndef __ASSEMBLY__
+
+#  ifdef __KERNEL__
+extern unsigned int boot_cpuid; /* move to smp.h */
+
+extern char cmd_line[COMMAND_LINE_SIZE];
+#  endif/* __KERNEL__ */
+
+void early_printk(const char *fmt, ...);
+
+int setup_early_printk(char *opt);
+void disable_early_printk(void);
+
+void heartbeat(void);
+void setup_heartbeat(void);
+
+unsigned long long sched_clock(void);
+
+void time_init(void);
+void init_IRQ(void);
+void machine_early_init(const char *cmdline, unsigned int ram,
+                                               unsigned int fdt);
+
+void machine_restart(char *cmd);
+void machine_shutdown(void);
+void machine_halt(void);
+void machine_power_off(void);
+
+# endif /* __ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_SETUP_H */
diff --git a/arch/microblaze/include/asm/shmbuf.h b/arch/microblaze/include/asm/shmbuf.h
new file mode 100644 (file)
index 0000000..f829c58
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef _ASM_MICROBLAZE_SHMBUF_H
+#define _ASM_MICROBLAZE_SHMBUF_H
+
+/*
+ * The shmid64_ds structure for microblaze 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 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 /* _ASM_MICROBLAZE_SHMBUF_H */
diff --git a/arch/microblaze/include/asm/shmparam.h b/arch/microblaze/include/asm/shmparam.h
new file mode 100644 (file)
index 0000000..9f5fc2b
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _ASM_MICROBLAZE_SHMPARAM_H
+#define _ASM_MICROBLAZE_SHMPARAM_H
+
+#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
+
+#endif /* _ASM_MICROBLAZE_SHMPARAM_H */
diff --git a/arch/microblaze/include/asm/sigcontext.h b/arch/microblaze/include/asm/sigcontext.h
new file mode 100644 (file)
index 0000000..55873c8
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SIGCONTEXT_H
+#define _ASM_MICROBLAZE_SIGCONTEXT_H
+
+/* FIXME should be linux/ptrace.h */
+#include <asm/ptrace.h>
+
+struct sigcontext {
+       struct pt_regs regs;
+       unsigned long oldmask;
+};
+
+#endif /* _ASM_MICROBLAZE_SIGCONTEXT_H */
diff --git a/arch/microblaze/include/asm/siginfo.h b/arch/microblaze/include/asm/siginfo.h
new file mode 100644 (file)
index 0000000..f162911
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SIGINFO_H
+#define _ASM_MICROBLAZE_SIGINFO_H
+
+#include <linux/types.h>
+#include <asm-generic/siginfo.h>
+
+#endif /* _ASM_MICROBLAZE_SIGINFO_H */
diff --git a/arch/microblaze/include/asm/signal.h b/arch/microblaze/include/asm/signal.h
new file mode 100644 (file)
index 0000000..9676fad
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *     Yasushi SHOJI <yashi@atmark-techno.com>
+ *     Tetsuya OHKAWA <tetsuya@atmark-techno.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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SIGNAL_H
+#define _ASM_MICROBLAZE_SIGNAL_H
+
+#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
+#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
+
+#define SA_RESTORER    0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK     1
+#define SS_DISABLE     2
+
+#define MINSIGSTKSZ    2048
+#define SIGSTKSZ       8192
+
+# ifndef __ASSEMBLY__
+# include <linux/types.h>
+# include <asm-generic/signal.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;
+
+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;
+};
+
+#  include <asm/sigcontext.h>
+#  undef __HAVE_ARCH_SIG_BITOPS
+
+#  define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#  else /* !__KERNEL__ */
+
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+#  define NSIG         32
+typedef unsigned long sigset_t;
+
+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;
+
+# endif /* __ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_SIGNAL_H */
diff --git a/arch/microblaze/include/asm/socket.h b/arch/microblaze/include/asm/socket.h
new file mode 100644 (file)
index 0000000..f919b6b
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SOCKET_H
+#define _ASM_MICROBLAZE_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(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
+#define SO_PASSSEC             34
+
+#define SO_TIMESTAMPNS         35
+#define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
+
+#define SO_MARK                        36
+
+#endif /* _ASM_MICROBLAZE_SOCKET_H */
diff --git a/arch/microblaze/include/asm/sockios.h b/arch/microblaze/include/asm/sockios.h
new file mode 100644 (file)
index 0000000..9fff57a
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SOCKIOS_H
+#define _ASM_MICROBLAZE_SOCKIOS_H
+
+#include <linux/ioctl.h>
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN      0x8901
+#define SIOCSPGRP      0x8902
+#define FIOGETOWN      0x8903
+#define SIOCGPGRP      0x8904
+#define SIOCATMARK     0x8905
+#define SIOCGSTAMP     0x8906          /* Get stamp (timeval) */
+#define SIOCGSTAMPNS   0x8907          /* Get stamp (timespec) */
+
+#endif /* _ASM_MICROBLAZE_SOCKIOS_H */
diff --git a/arch/microblaze/include/asm/stat.h b/arch/microblaze/include/asm/stat.h
new file mode 100644 (file)
index 0000000..5f18b8a
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Microblaze stat structure
+ *
+ * Copyright (C) 2001,02,03 NEC Electronics Corporation
+ * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
+ *
+ * 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 Miles Bader <miles@gnu.org>
+ */
+
+#ifndef _ASM_MICROBLAZE_STAT_H
+#define _ASM_MICROBLAZE_STAT_H
+
+#include <linux/posix_types.h>
+
+struct stat {
+       unsigned int    st_dev;
+       unsigned long   st_ino;
+       unsigned int    st_mode;
+       unsigned int    st_nlink;
+       unsigned int    st_uid;
+       unsigned int    st_gid;
+       unsigned int    st_rdev;
+       unsigned long   st_size;
+       unsigned long   st_blksize;
+       unsigned long   st_blocks;
+       unsigned long   st_atime;
+       unsigned long   __unused1; /* unsigned long  st_atime_nsec */
+       unsigned long   st_mtime;
+       unsigned long   __unused2; /* unsigned long  st_mtime_nsec */
+       unsigned long   st_ctime;
+       unsigned long   __unused3; /* unsigned long  st_ctime_nsec */
+       unsigned long   __unused4;
+       unsigned long   __unused5;
+};
+
+struct stat64 {
+       unsigned long long      st_dev;
+       unsigned long   __unused1;
+
+       unsigned long long      st_ino;
+
+       unsigned int    st_mode;
+       unsigned int    st_nlink;
+
+       unsigned int    st_uid;
+       unsigned int    st_gid;
+
+       unsigned long long      st_rdev;
+       unsigned long   __unused3;
+
+       long long       st_size;
+       unsigned long   st_blksize;
+
+       unsigned long   st_blocks; /* No. of 512-byte blocks allocated */
+       unsigned long   __unused4; /* future possible st_blocks high bits */
+
+       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   __unused8;
+};
+
+#endif /* _ASM_MICROBLAZE_STAT_H */
diff --git a/arch/microblaze/include/asm/statfs.h b/arch/microblaze/include/asm/statfs.h
new file mode 100644 (file)
index 0000000..0b91fe1
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/statfs.h>
diff --git a/arch/microblaze/include/asm/string.h b/arch/microblaze/include/asm/string.h
new file mode 100644 (file)
index 0000000..f7728c9
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_STRING_H
+#define _ASM_MICROBLAZE_STRING_H
+
+#ifndef __KERNEL__
+
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+
+extern void *memset(void *, int, __kernel_size_t);
+extern void *memcpy(void *, const void *, __kernel_size_t);
+extern void *memmove(void *, const void *, __kernel_size_t);
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_MICROBLAZE_STRING_H */
diff --git a/arch/microblaze/include/asm/swab.h b/arch/microblaze/include/asm/swab.h
new file mode 100644 (file)
index 0000000..b375d7b
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _ASM_MICROBLAZE_SWAB_H
+#define _ASM_MICROBLAZE_SWAB_H
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#define __SWAB_64_THRU_32__
+#endif
+
+#endif /* _ASM_MICROBLAZE_SWAB_H */
diff --git a/arch/microblaze/include/asm/syscalls.h b/arch/microblaze/include/asm/syscalls.h
new file mode 100644 (file)
index 0000000..9cb4ff0
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef __ASM_MICROBLAZE_SYSCALLS_H
+#define __ASM_MICROBLAZE_SYSCALLS_H
+#ifdef __KERNEL__
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <linux/signal.h>
+
+/* FIXME will be removed */
+asmlinkage int sys_ipc(uint call, int first, int second,
+                               int third, void *ptr, long fifth);
+
+struct pt_regs;
+asmlinkage int sys_vfork(struct pt_regs *regs);
+asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs);
+asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv,
+                       char __user *__user *envp, struct pt_regs *regs);
+
+asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len,
+                       unsigned long prot, unsigned long flags,
+                       unsigned long fd, unsigned long pgoff);
+
+asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
+                       unsigned long prot, unsigned long flags,
+                       unsigned long fd, off_t offset);
+
+/* from signal.c */
+asmlinkage int sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs);
+
+asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
+               struct pt_regs *regs);
+
+asmlinkage int sys_sigaction(int sig, const struct old_sigaction *act,
+               struct old_sigaction *oact);
+
+asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
+               struct pt_regs *regs);
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs);
+
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs);
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_MICROBLAZE_SYSCALLS_H */
diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h
new file mode 100644 (file)
index 0000000..c4e3088
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SYSTEM_H
+#define _ASM_MICROBLAZE_SYSTEM_H
+
+#include <asm/registers.h>
+#include <asm/setup.h>
+#include <asm/irqflags.h>
+
+struct task_struct;
+struct thread_info;
+
+extern struct task_struct *_switch_to(struct thread_info *prev,
+                                       struct thread_info *next);
+
+#define switch_to(prev, next, last)                                    \
+       do {                                                            \
+               (last) = _switch_to(task_thread_info(prev),             \
+                                       task_thread_info(next));        \
+       } while (0)
+
+#define smp_read_barrier_depends()     do {} while (0)
+#define read_barrier_depends()         do {} while (0)
+
+#define nop()                  asm volatile ("nop")
+#define mb()                   barrier()
+#define rmb()                  mb()
+#define wmb()                  mb()
+#define set_mb(var, value)     do { var = value; mb(); } while (0)
+#define set_wmb(var, value)    do { var = value; wmb(); } while (0)
+
+#define smp_mb()               mb()
+#define smp_rmb()              rmb()
+#define smp_wmb()              wmb()
+
+void show_trace(struct task_struct *task, unsigned long *stack);
+void __bad_xchg(volatile void *ptr, int size);
+
+static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
+                                                               int size)
+{
+       unsigned long ret;
+       unsigned long flags;
+
+       switch (size) {
+       case 1:
+               local_irq_save(flags);
+               ret = *(volatile unsigned char *)ptr;
+               *(volatile unsigned char *)ptr = x;
+               local_irq_restore(flags);
+               break;
+
+       case 4:
+               local_irq_save(flags);
+               ret = *(volatile unsigned long *)ptr;
+               *(volatile unsigned long *)ptr = x;
+               local_irq_restore(flags);
+               break;
+       default:
+               __bad_xchg(ptr, size), ret = 0;
+               break;
+       }
+
+       return ret;
+}
+
+void disable_hlt(void);
+void enable_hlt(void);
+void default_idle(void);
+
+#define xchg(ptr, x) \
+       ((__typeof__(*(ptr))) __xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+
+void free_init_pages(char *what, unsigned long begin, unsigned long end);
+void free_initmem(void);
+extern char *klimit;
+extern void ret_from_fork(void);
+
+#ifdef CONFIG_DEBUG_FS
+extern struct dentry *of_debugfs_root;
+#endif
+
+#define arch_align_stack(x) (x)
+
+#endif /* _ASM_MICROBLAZE_SYSTEM_H */
diff --git a/arch/microblaze/include/asm/termbits.h b/arch/microblaze/include/asm/termbits.h
new file mode 100644 (file)
index 0000000..a1b64bc
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_TERMBITS_H
+#define _ASM_MICROBLAZE_TERMBITS_H
+
+#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 BOTHER         0010000
+#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 */
+
+#define IBSHIFT        16              /* Shift from CBAUD to CIBAUD */
+
+/* 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 /* _ASM_MICROBLAZE_TERMBITS_H */
diff --git a/arch/microblaze/include/asm/termios.h b/arch/microblaze/include/asm/termios.h
new file mode 100644 (file)
index 0000000..102d772
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_TERMIOS_H
+#define _ASM_MICROBLAZE_TERMIOS_H
+
+#include <linux/string.h>
+#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 IR - 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__
+
+#include <asm-generic/termios.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_MICROBLAZE_TERMIOS_H */
diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h
new file mode 100644 (file)
index 0000000..4c3943e
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_THREAD_INFO_H
+#define _ASM_MICROBLAZE_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+/* we have 8k stack */
+#define THREAD_SHIFT           13
+#define THREAD_SIZE            (1 << THREAD_SHIFT)
+#define THREAD_SIZE_ORDER      1
+
+#ifndef __ASSEMBLY__
+# include <linux/types.h>
+# include <asm/processor.h>
+# include <asm/segment.h>
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants
+ *      must also be changed
+ */
+
+struct cpu_context {
+       __u32   r1; /* stack pointer */
+       __u32   r2;
+       /* dedicated registers */
+       __u32   r13;
+       __u32   r14;
+       __u32   r15;
+       __u32   r16;
+       __u32   r17;
+       __u32   r18;
+       /* non-volatile registers */
+       __u32   r19;
+       __u32   r20;
+       __u32   r21;
+       __u32   r22;
+       __u32   r23;
+       __u32   r24;
+       __u32   r25;
+       __u32   r26;
+       __u32   r27;
+       __u32   r28;
+       __u32   r29;
+       __u32   r30;
+       /* r31 is used as current task pointer */
+       /* special purpose registers */
+       __u32   msr;
+       __u32   ear;
+       __u32   esr;
+       __u32   fsr;
+};
+
+struct thread_info {
+       struct task_struct      *task; /* main task structure */
+       struct exec_domain      *exec_domain; /* execution domain */
+       unsigned long           flags; /* low level flags */
+       unsigned long           status; /* thread-synchronous flags */
+       __u32                   cpu; /* current CPU */
+       __s32                   preempt_count; /* 0 => preemptable,< 0 => BUG*/
+       mm_segment_t            addr_limit; /* thread address space */
+       struct restart_block    restart_block;
+
+       struct cpu_context      cpu_context;
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+#define INIT_THREAD_INFO(tsk)                  \
+{                                              \
+       .task           = &tsk,                 \
+       .exec_domain    = &default_exec_domain, \
+       .flags          = 0,                    \
+       .cpu            = 0,                    \
+       .preempt_count  = 1,                    \
+       .addr_limit     = KERNEL_DS,            \
+       .restart_block = {                      \
+               .fn = do_no_restart_syscall,    \
+       },                                      \
+}
+
+#define init_thread_info       (init_thread_union.thread_info)
+#define init_stack             (init_thread_union.stack)
+
+/* how to get the thread information struct from C */
+static inline struct thread_info *current_thread_info(void)
+{
+       register unsigned long sp asm("r1");
+
+       return (struct thread_info *)(sp & ~(THREAD_SIZE-1));
+}
+
+/* thread information allocation */
+#endif /* __ASSEMBLY__ */
+
+#define PREEMPT_ACTIVE         0x10000000
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files may
+ *   need to access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_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 */
+/* restore singlestep on return to user mode */
+#define TIF_SINGLESTEP         4
+#define TIF_IRET               5 /* return with iret */
+#define TIF_MEMDIE             6
+#define TIF_FREEZE             14      /* Freezing for suspend */
+
+/* FIXME change in entry.S */
+#define TIF_KERNEL_TRACE       8       /* kernel trace active */
+
+/* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_POLLING_NRFLAG     16
+
+#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_SINGLESTEP                (1<<TIF_SINGLESTEP)
+#define _TIF_IRET              (1<<TIF_IRET)
+#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE            (1<<TIF_FREEZE)
+#define _TIF_KERNEL_TRACE      (1 << TIF_KERNEL_TRACE)
+
+/* work to do on interrupt/exception return */
+#define _TIF_WORK_MASK         0x0000FFFE
+/* work to do on any return to u-space */
+#define _TIF_ALLWORK_MASK      0x0000FFFF
+
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ */
+/* FPU was used by this task this quantum (SMP) */
+#define TS_USEDFPU             0x0001
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_THREAD_INFO_H */
diff --git a/arch/microblaze/include/asm/timex.h b/arch/microblaze/include/asm/timex.h
new file mode 100644 (file)
index 0000000..678525d
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_TIMEX_H
+#define _ASM_MICROBLAZE_TIMEX_H
+
+#define CLOCK_TICK_RATE 1000 /* Timer input freq. */
+
+typedef unsigned long cycles_t;
+
+#define get_cycles()   (0)
+
+#endif /* _ASM_TIMEX_H */
diff --git a/arch/microblaze/include/asm/tlb.h b/arch/microblaze/include/asm/tlb.h
new file mode 100644 (file)
index 0000000..d1dfe37
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_TLB_H
+#define _ASM_MICROBLAZE_TLB_H
+
+#define tlb_flush(tlb) do {} while (0)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_MICROBLAZE_TLB_H */
diff --git a/arch/microblaze/include/asm/tlbflush.h b/arch/microblaze/include/asm/tlbflush.h
new file mode 100644 (file)
index 0000000..d7fe762
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_TLBFLUSH_H
+#define _ASM_MICROBLAZE_TLBFLUSH_H
+
+#define flush_tlb()                            BUG()
+#define flush_tlb_all()                                BUG()
+#define flush_tlb_mm(mm)                       BUG()
+#define flush_tlb_page(vma, addr)              BUG()
+#define flush_tlb_range(mm, start, end)                BUG()
+#define flush_tlb_pgtables(mm, start, end)     BUG()
+#define flush_tlb_kernel_range(start, end)     BUG()
+
+#endif /* _ASM_MICROBLAZE_TLBFLUSH_H */
diff --git a/arch/microblaze/include/asm/topology.h b/arch/microblaze/include/asm/topology.h
new file mode 100644 (file)
index 0000000..96bcea5
--- /dev/null
@@ -0,0 +1,11 @@
+#include <asm-generic/topology.h>
+
+#ifndef _ASM_MICROBLAZE_TOPOLOGY_H
+#define _ASM_MICROBLAZE_TOPOLOGY_H
+
+struct device_node;
+static inline int of_node_to_nid(struct device_node *device)
+{
+       return 0;
+}
+#endif /* _ASM_MICROBLAZE_TOPOLOGY_H */
diff --git a/arch/microblaze/include/asm/types.h b/arch/microblaze/include/asm/types.h
new file mode 100644 (file)
index 0000000..bebc018
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_TYPES_H
+#define _ASM_MICROBLAZE_TYPES_H
+
+/*
+ * 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.
+ */
+
+#include <asm-generic/int-ll64.h>
+
+# ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#  ifdef __KERNEL__
+#  define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide. */
+
+typedef u32 dma_addr_t;
+
+#  endif/* __KERNEL__ */
+# endif /* __ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_TYPES_H */
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h
new file mode 100644 (file)
index 0000000..5a3ffc3
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_UACCESS_H
+#define _ASM_MICROBLAZE_UACCESS_H
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h> /* RLIMIT_FSIZE */
+#include <linux/mm.h>
+
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/segment.h>
+#include <linux/string.h>
+
+#define VERIFY_READ    0
+#define VERIFY_WRITE   1
+
+extern int ___range_ok(unsigned long addr, unsigned long size);
+
+#define __range_ok(addr, size) \
+               ___range_ok((unsigned long)(addr), (unsigned long)(size))
+
+#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0)
+#define __access_ok(add, size) (__range_ok((addr), (size)) == 0)
+
+extern inline int bad_user_access_length(void)
+{
+       return 0;
+}
+/* FIXME this is function for optimalization -> memcpy */
+#define __get_user(var, ptr)                                   \
+       ({                                                      \
+               int __gu_err = 0;                               \
+               switch (sizeof(*(ptr))) {                       \
+               case 1:                                         \
+               case 2:                                         \
+               case 4:                                         \
+                       (var) = *(ptr);                         \
+                       break;                                  \
+               case 8:                                         \
+                       memcpy((void *) &(var), (ptr), 8);      \
+                       break;                                  \
+               default:                                        \
+                       (var) = 0;                              \
+                       __gu_err = __get_user_bad();            \
+                       break;                                  \
+               }                                               \
+               __gu_err;                                       \
+       })
+
+#define __get_user_bad()       (bad_user_access_length(), (-EFAULT))
+
+#define __put_user(var, ptr)                                   \
+       ({                                                      \
+               int __pu_err = 0;                               \
+               switch (sizeof(*(ptr))) {                       \
+               case 1:                                         \
+               case 2:                                         \
+               case 4:                                         \
+                       *(ptr) = (var);                         \
+                       break;                                  \
+               case 8: {                                       \
+                       typeof(*(ptr)) __pu_val = var;          \
+                       memcpy(ptr, &__pu_val, sizeof(__pu_val));\
+                       }                                       \
+                       break;                                  \
+               default:                                        \
+                       __pu_err = __put_user_bad();            \
+                       break;                                  \
+               }                                                       \
+               __pu_err;                                               \
+       })
+
+#define __put_user_bad()       (bad_user_access_length(), (-EFAULT))
+
+#define put_user(x, ptr)       __put_user(x, ptr)
+#define get_user(x, ptr)       __get_user(x, ptr)
+
+#define copy_to_user(to, from, n)              (memcpy(to, from, n), 0)
+#define copy_from_user(to, from, n)            (memcpy(to, from, n), 0)
+
+#define __copy_to_user(to, from, n)            (copy_to_user(to, from, n))
+#define __copy_from_user(to, from, n)          (copy_from_user(to, from, n))
+#define __copy_to_user_inatomic(to, from, n)   (__copy_to_user(to, from, n))
+#define __copy_from_user_inatomic(to, from, n) (__copy_from_user(to, from, n))
+
+#define __clear_user(addr, n)  (memset((void *)addr, 0, n), 0)
+
+static inline unsigned long clear_user(void *addr, unsigned long size)
+{
+       if (access_ok(VERIFY_WRITE, addr, size))
+               size = __clear_user(addr, size);
+       return size;
+}
+
+/* Returns 0 if exception not found and fixup otherwise. */
+extern unsigned long search_exception_table(unsigned long);
+
+
+extern long strncpy_from_user(char *dst, const char __user *src, long count);
+extern long strnlen_user(const char __user *src, long count);
+extern long __strncpy_from_user(char *dst, const char __user *src, long count);
+
+/*
+ * 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.
+ */
+struct exception_table_entry {
+       unsigned long insn, fixup;
+};
+
+#endif  /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_MICROBLAZE_UACCESS_H */
diff --git a/arch/microblaze/include/asm/ucontext.h b/arch/microblaze/include/asm/ucontext.h
new file mode 100644 (file)
index 0000000..11f6bb3
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_UCONTEXT_H
+#define _ASM_MICROBLAZE_UCONTEXT_H
+
+#include <asm/sigcontext.h>
+
+struct ucontext {
+       unsigned long           uc_flags;
+       struct ucontext         *uc_link;
+       stack_t                 uc_stack;
+       struct sigcontext       uc_mcontext;
+       sigset_t                uc_sigmask; /* mask last for extensibility */
+};
+
+#endif /* _ASM_MICROBLAZE_UCONTEXT_H */
diff --git a/arch/microblaze/include/asm/unaligned.h b/arch/microblaze/include/asm/unaligned.h
new file mode 100644 (file)
index 0000000..9d66b64
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_UNALIGNED_H
+#define _ASM_MICROBLAZE_UNALIGNED_H
+
+# ifdef __KERNEL__
+
+# include <linux/unaligned/access_ok.h>
+# include <linux/unaligned/generic.h>
+
+# define get_unaligned __get_unaligned_be
+# define put_unaligned __put_unaligned_be
+
+# endif        /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_UNALIGNED_H */
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h
new file mode 100644 (file)
index 0000000..d9d3903
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_UNISTD_H
+#define _ASM_MICROBLAZE_UNISTD_H
+
+#define __NR_restart_syscall   0 /* ok */
+#define __NR_exit              1 /* ok */
+#define __NR_fork              2 /* not for no MMU - weird */
+#define __NR_read              3 /* ok */
+#define __NR_write             4 /* ok */
+#define __NR_open              5 /* openat */
+#define __NR_close             6 /* ok */
+#define __NR_waitpid           7 /* waitid */
+#define __NR_creat             8 /* openat */
+#define __NR_link              9 /* linkat */
+#define __NR_unlink            10 /* unlinkat */
+#define __NR_execve            11 /* ok */
+#define __NR_chdir             12 /* ok */
+#define __NR_time              13 /* obsolete -> sys_gettimeofday */
+#define __NR_mknod             14 /* mknodat */
+#define __NR_chmod             15 /* fchmodat */
+#define __NR_lchown            16 /* ok */
+#define __NR_break             17 /* don't know */
+#define __NR_oldstat           18 /* remove */
+#define __NR_lseek             19 /* ok */
+#define __NR_getpid            20 /* ok */
+#define __NR_mount             21 /* ok */
+#define __NR_umount            22 /* ok */  /* use only umount2 */
+#define __NR_setuid            23 /* ok */
+#define __NR_getuid            24 /* ok */
+#define __NR_stime             25 /* obsolete -> sys_settimeofday */
+#define __NR_ptrace            26 /* ok */
+#define __NR_alarm             27 /* obsolete -> sys_setitimer */
+#define __NR_oldfstat          28 /* remove */
+#define __NR_pause             29 /* obsolete -> sys_rt_sigtimedwait */
+#define __NR_utime             30 /* obsolete -> sys_utimesat */
+#define __NR_stty              31 /* remove */
+#define __NR_gtty              32 /* remove */
+#define __NR_access            33 /* faccessat */
+/* can be implemented by sys_setpriority */
+#define __NR_nice              34
+#define __NR_ftime             35 /* remove */
+#define __NR_sync              36 /* ok */
+#define __NR_kill              37 /* ok */
+#define __NR_rename            38 /* renameat */
+#define __NR_mkdir             39 /* mkdirat */
+#define __NR_rmdir             40 /* unlinkat */
+#define __NR_dup               41 /* ok */
+#define __NR_pipe              42 /* ok */
+#define __NR_times             43 /* ok */
+#define __NR_prof              44 /* remove */
+#define __NR_brk               45 /* ok -mmu, nommu specific */
+#define __NR_setgid            46 /* ok */
+#define __NR_getgid            47 /* ok */
+#define __NR_signal            48 /* obsolete -> sys_rt_sigaction */
+#define __NR_geteuid           49 /* ok */
+#define __NR_getegid           50 /* ok */
+#define __NR_acct              51 /* add it and then I can disable it */
+#define __NR_umount2           52 /* remove */
+#define __NR_lock              53 /* remove */
+#define __NR_ioctl             54 /* ok */
+#define __NR_fcntl             55 /* ok -> 64bit version*/
+#define __NR_mpx               56 /* remove */
+#define __NR_setpgid           57 /* ok */
+#define __NR_ulimit            58 /* remove */
+#define __NR_oldolduname       59 /* remove */
+#define __NR_umask             60 /* ok */
+#define __NR_chroot            61 /* ok */
+#define __NR_ustat             62 /* obsolete -> statfs64 */
+#define __NR_dup2              63 /* ok */
+#define __NR_getppid           64 /* ok */
+#define __NR_getpgrp           65 /* obsolete -> sys_getpgid */
+#define __NR_setsid            66 /* ok */
+#define __NR_sigaction         67 /* obsolete -> rt_sigaction */
+#define __NR_sgetmask          68 /* obsolete -> sys_rt_sigprocmask */
+#define __NR_ssetmask          69 /* obsolete ->sys_rt_sigprocmask */
+#define __NR_setreuid          70 /* ok */
+#define __NR_setregid          71 /* ok */
+#define __NR_sigsuspend                72 /* obsolete -> rt_sigsuspend */
+#define __NR_sigpending                73 /* obsolete -> sys_rt_sigpending */
+#define __NR_sethostname       74 /* ok */
+#define __NR_setrlimit         75 /* ok */
+#define __NR_getrlimit         76 /* ok Back compatible 2G limited rlimit */
+#define __NR_getrusage         77 /* ok */
+#define __NR_gettimeofday      78 /* ok */
+#define __NR_settimeofday      79 /* ok */
+#define __NR_getgroups         80 /* ok */
+#define __NR_setgroups         81 /* ok */
+#define __NR_select            82 /* obsolete -> sys_pselect7 */
+#define __NR_symlink           83 /* symlinkat */
+#define __NR_oldlstat          84 /* remove */
+#define __NR_readlink          85 /* obsolete -> sys_readlinkat */
+#define __NR_uselib            86 /* remove */
+#define __NR_swapon            87 /* ok */
+#define __NR_reboot            88 /* ok */
+#define __NR_readdir           89 /* remove ? */
+#define __NR_mmap              90 /* obsolete -> sys_mmap2 */
+#define __NR_munmap            91 /* ok - mmu and nommu */
+#define __NR_truncate          92 /* ok or truncate64 */
+#define __NR_ftruncate         93 /* ok or ftruncate64 */
+#define __NR_fchmod            94 /* ok */
+#define __NR_fchown            95 /* ok */
+#define __NR_getpriority       96 /* ok */
+#define __NR_setpriority       97 /* ok */
+#define __NR_profil            98 /* remove */
+#define __NR_statfs            99 /* ok or statfs64 */
+#define __NR_fstatfs           100  /* ok or fstatfs64 */
+#define __NR_ioperm            101 /* remove */
+#define __NR_socketcall                102 /* remove */
+#define __NR_syslog            103 /* ok */
+#define __NR_setitimer         104 /* ok */
+#define __NR_getitimer         105 /* ok */
+#define __NR_stat              106 /* remove */
+#define __NR_lstat             107 /* remove */
+#define __NR_fstat             108 /* remove */
+#define __NR_olduname          109 /* remove */
+#define __NR_iopl              110 /* remove */
+#define __NR_vhangup           111 /* ok */
+#define __NR_idle              112 /* remove */
+#define __NR_vm86old           113 /* remove */
+#define __NR_wait4             114 /* obsolete -> waitid */
+#define __NR_swapoff           115 /* ok */
+#define __NR_sysinfo           116 /* ok */
+#define __NR_ipc               117 /* remove - direct call */
+#define __NR_fsync             118 /* ok */
+#define __NR_sigreturn         119 /* obsolete -> sys_rt_sigreturn */
+#define __NR_clone             120 /* ok */
+#define __NR_setdomainname     121 /* ok */
+#define __NR_uname             122 /* remove */
+#define __NR_modify_ldt                123 /* remove */
+#define __NR_adjtimex          124 /* ok */
+#define __NR_mprotect          125 /* remove */
+#define __NR_sigprocmask       126 /* obsolete -> sys_rt_sigprocmask */
+#define __NR_create_module     127 /* remove */
+#define __NR_init_module       128 /* ok */
+#define __NR_delete_module     129 /* ok */
+#define __NR_get_kernel_syms   130 /* remove */
+#define __NR_quotactl          131 /* ok */
+#define __NR_getpgid           132 /* ok */
+#define __NR_fchdir            133 /* ok */
+#define __NR_bdflush           134 /* remove */
+#define __NR_sysfs             135 /* needed for busybox */
+#define __NR_personality       136 /* ok */
+#define __NR_afs_syscall       137 /* Syscall for Andrew File System */
+#define __NR_setfsuid          138 /* ok */
+#define __NR_setfsgid          139 /* ok */
+#define __NR__llseek           140 /* remove only lseek */
+#define __NR_getdents          141 /* ok or getdents64 */
+#define __NR__newselect                142 /* remove */
+#define __NR_flock             143 /* ok */
+#define __NR_msync             144 /* remove */
+#define __NR_readv             145 /* ok */
+#define __NR_writev            146 /* ok */
+#define __NR_getsid            147 /* ok */
+#define __NR_fdatasync         148 /* ok */
+#define __NR__sysctl           149 /* remove */
+#define __NR_mlock             150 /* ok - nommu or mmu */
+#define __NR_munlock           151 /* ok - nommu or mmu */
+#define __NR_mlockall          152 /* ok - nommu or mmu */
+#define __NR_munlockall                153 /* ok - nommu or mmu */
+#define __NR_sched_setparam            154 /* ok */
+#define __NR_sched_getparam            155 /* ok */
+#define __NR_sched_setscheduler                156 /* ok */
+#define __NR_sched_getscheduler                157 /* ok */
+#define __NR_sched_yield               158 /* ok */
+#define __NR_sched_get_priority_max    159 /* ok */
+#define __NR_sched_get_priority_min    160 /* ok */
+#define __NR_sched_rr_get_interval     161 /* ok */
+#define __NR_nanosleep         162 /* ok */
+#define __NR_mremap            163 /* ok - nommu or mmu */
+#define __NR_setresuid         164 /* ok */
+#define __NR_getresuid         165 /* ok */
+#define __NR_vm86              166 /* remove */
+#define __NR_query_module      167 /* ok */
+#define __NR_poll              168 /* obsolete -> sys_ppoll */
+#define __NR_nfsservctl                169 /* ok */
+#define __NR_setresgid         170 /* ok */
+#define __NR_getresgid         171 /* ok */
+#define __NR_prctl             172 /* ok */
+#define __NR_rt_sigreturn      173 /* ok */
+#define __NR_rt_sigaction      174 /* ok */
+#define __NR_rt_sigprocmask    175 /* ok */
+#define __NR_rt_sigpending     176 /* ok */
+#define __NR_rt_sigtimedwait   177 /* ok */
+#define __NR_rt_sigqueueinfo   178 /* ok */
+#define __NR_rt_sigsuspend     179 /* ok */
+#define __NR_pread64           180 /* ok */
+#define __NR_pwrite64          181 /* ok */
+#define __NR_chown             182 /* obsolete -> fchownat */
+#define __NR_getcwd            183 /* ok */
+#define __NR_capget            184 /* ok */
+#define __NR_capset            185 /* ok */
+#define __NR_sigaltstack       186 /* remove */
+#define __NR_sendfile          187 /* ok -> exist 64bit version*/
+#define __NR_getpmsg           188 /* remove */
+/* remove - some people actually want streams */
+#define __NR_putpmsg           189
+/* for noMMU - group with clone -> maybe remove */
+#define __NR_vfork             190
+#define __NR_ugetrlimit                191 /* remove - SuS compliant getrlimit */
+#define __NR_mmap2             192 /* ok */
+#define __NR_truncate64                193 /* ok */
+#define __NR_ftruncate64       194 /* ok */
+#define __NR_stat64            195 /* remove _ARCH_WANT_STAT64 */
+#define __NR_lstat64           196 /* remove _ARCH_WANT_STAT64 */
+#define __NR_fstat64           197 /* remove _ARCH_WANT_STAT64 */
+#define __NR_lchown32          198 /* ok - without 32 */
+#define __NR_getuid32          199 /* ok - without 32 */
+#define __NR_getgid32          200 /* ok - without 32 */
+#define __NR_geteuid32         201 /* ok - without 32 */
+#define __NR_getegid32         202 /* ok - without 32 */
+#define __NR_setreuid32                203 /* ok - without 32 */
+#define __NR_setregid32                204 /* ok - without 32 */
+#define __NR_getgroups32       205 /* ok - without 32 */
+#define __NR_setgroups32       206 /* ok - without 32 */
+#define __NR_fchown32          207 /* ok - without 32 */
+#define __NR_setresuid32       208 /* ok - without 32 */
+#define __NR_getresuid32       209 /* ok - without 32 */
+#define __NR_setresgid32       210 /* ok - without 32 */
+#define __NR_getresgid32       211 /* ok - without 32 */
+#define __NR_chown32           212 /* ok - without 32 -obsolete -> fchownat */
+#define __NR_setuid32          213 /* ok - without 32 */
+#define __NR_setgid32          214 /* ok - without 32 */
+#define __NR_setfsuid32                215 /* ok - without 32 */
+#define __NR_setfsgid32                216 /* ok - without 32 */
+#define __NR_pivot_root                217 /* ok */
+#define __NR_mincore           218 /* ok */
+#define __NR_madvise           219 /* ok */
+#define __NR_getdents64                220 /* ok */
+#define __NR_fcntl64           221 /* ok */
+/* 223 is unused */
+#define __NR_gettid            224 /* ok */
+#define __NR_readahead         225 /* ok */
+#define __NR_setxattr          226 /* ok */
+#define __NR_lsetxattr         227 /* ok */
+#define __NR_fsetxattr         228 /* ok */
+#define __NR_getxattr          229 /* ok */
+#define __NR_lgetxattr         230 /* ok */
+#define __NR_fgetxattr         231 /* ok */
+#define __NR_listxattr         232 /* ok */
+#define __NR_llistxattr                233 /* ok */
+#define __NR_flistxattr                234 /* ok */
+#define __NR_removexattr       235 /* ok */
+#define __NR_lremovexattr      236 /* ok */
+#define __NR_fremovexattr      237 /* ok */
+#define __NR_tkill             238 /* ok */
+#define __NR_sendfile64                239 /* ok */
+#define __NR_futex             240 /* ok */
+#define __NR_sched_setaffinity 241 /* ok */
+#define __NR_sched_getaffinity 242 /* ok */
+#define __NR_set_thread_area   243 /* remove */
+#define __NR_get_thread_area   244 /* remove */
+#define __NR_io_setup          245 /* ok */
+#define __NR_io_destroy                246 /* ok */
+#define __NR_io_getevents      247 /* ok */
+#define __NR_io_submit         248 /* ok */
+#define __NR_io_cancel         249 /* ok */
+#define __NR_fadvise64         250 /* remove -> sys_fadvise64_64 */
+/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */
+#define __NR_exit_group                252 /* ok */
+#define __NR_lookup_dcookie    253 /* ok */
+#define __NR_epoll_create      254 /* ok */
+#define __NR_epoll_ctl         255 /* ok */
+#define __NR_epoll_wait                256 /* obsolete -> sys_epoll_pwait */
+#define __NR_remap_file_pages  257 /* only for mmu */
+#define __NR_set_tid_address   258 /* ok */
+#define __NR_timer_create      259 /* ok */
+#define __NR_timer_settime     (__NR_timer_create+1) /* 260 */ /* ok */
+#define __NR_timer_gettime     (__NR_timer_create+2) /* 261 */ /* ok */
+#define __NR_timer_getoverrun  (__NR_timer_create+3) /* 262 */ /* ok */
+#define __NR_timer_delete      (__NR_timer_create+4) /* 263 */ /* ok */
+#define __NR_clock_settime     (__NR_timer_create+5) /* 264 */ /* ok */
+#define __NR_clock_gettime     (__NR_timer_create+6) /* 265 */ /* ok */
+#define __NR_clock_getres      (__NR_timer_create+7) /* 266 */ /* ok */
+#define __NR_clock_nanosleep   (__NR_timer_create+8) /* 267 */ /* ok */
+#define __NR_statfs64          268 /* ok */
+#define __NR_fstatfs64         269 /* ok */
+#define __NR_tgkill            270 /* ok */
+#define __NR_utimes            271 /* obsolete -> sys_futimesat */
+#define __NR_fadvise64_64      272 /* ok */
+#define __NR_vserver           273 /* ok */
+#define __NR_mbind             274 /* only for mmu */
+#define __NR_get_mempolicy     275 /* only for mmu */
+#define __NR_set_mempolicy     276 /* only for mmu */
+#define __NR_mq_open           277 /* ok */
+#define __NR_mq_unlink         (__NR_mq_open+1) /* 278 */ /* ok */
+#define __NR_mq_timedsend      (__NR_mq_open+2) /* 279 */ /* ok */
+#define __NR_mq_timedreceive   (__NR_mq_open+3) /* 280 */ /* ok */
+#define __NR_mq_notify         (__NR_mq_open+4) /* 281 */ /* ok */
+#define __NR_mq_getsetattr     (__NR_mq_open+5) /* 282 */ /* ok */
+#define __NR_kexec_load                283 /* ok */
+#define __NR_waitid            284 /* ok */
+/* #define __NR_sys_setaltroot 285 */
+#define __NR_add_key           286 /* ok */
+#define __NR_request_key       287 /* ok */
+#define __NR_keyctl            288 /* ok */
+#define __NR_ioprio_set                289 /* ok */
+#define __NR_ioprio_get                290 /* ok */
+#define __NR_inotify_init      291 /* ok */
+#define __NR_inotify_add_watch 292 /* ok */
+#define __NR_inotify_rm_watch  293 /* ok */
+#define __NR_migrate_pages     294 /* mmu */
+#define __NR_openat            295 /* ok */
+#define __NR_mkdirat           296 /* ok */
+#define __NR_mknodat           297 /* ok */
+#define __NR_fchownat          298 /* ok */
+#define __NR_futimesat         299 /* obsolete -> sys_utimesat */
+#define __NR_fstatat64         300 /* stat64 */
+#define __NR_unlinkat          301 /* ok */
+#define __NR_renameat          302 /* ok */
+#define __NR_linkat            303 /* ok */
+#define __NR_symlinkat         304 /* ok */
+#define __NR_readlinkat                305 /* ok */
+#define __NR_fchmodat          306 /* ok */
+#define __NR_faccessat         307 /* ok */
+#define __NR_pselect6          308 /* obsolete -> sys_pselect7 */
+#define __NR_ppoll             309 /* ok */
+#define __NR_unshare           310 /* ok */
+#define __NR_set_robust_list   311 /* ok */
+#define __NR_get_robust_list   312 /* ok */
+#define __NR_splice            313 /* ok */
+#define __NR_sync_file_range   314 /* ok */
+#define __NR_tee               315 /* ok */
+#define __NR_vmsplice          316 /* ok */
+#define __NR_move_pages                317 /* mmu */
+#define __NR_getcpu            318 /* ok */
+#define __NR_epoll_pwait       319 /* ok */
+#define __NR_utimensat         320 /* ok */
+#define __NR_signalfd          321 /* ok */
+#define __NR_timerfd_create    322 /* ok */
+#define __NR_eventfd           323 /* ok */
+#define __NR_fallocate         324 /* ok */
+#define __NR_semtimedop                325 /* ok - semaphore group */
+#define __NR_timerfd_settime   326 /* ok */
+#define __NR_timerfd_gettime   327 /* ok */
+/* sysv ipc syscalls */
+#define __NR_semctl            328 /* ok */
+#define __NR_semget            329 /* ok */
+#define __NR_semop             330 /* ok */
+#define __NR_msgctl            331 /* ok */
+#define __NR_msgget            332 /* ok */
+#define __NR_msgrcv            333 /* ok */
+#define __NR_msgsnd            334 /* ok */
+#define __NR_shmat             335 /* ok */
+#define __NR_shmctl            336 /* ok */
+#define __NR_shmdt             337 /* ok */
+#define __NR_shmget            338 /* ok */
+
+
+#define __NR_signalfd4         339 /* new */
+#define __NR_eventfd2          340 /* new */
+#define __NR_epoll_create1     341 /* new */
+#define __NR_dup3              342 /* new */
+#define __NR_pipe2             343 /* new */
+#define __NR_inotify_init1     344 /* new */
+#define __NR_socket            345 /* new */
+#define __NR_socketpair                346 /* new */
+#define __NR_bind              347 /* new */
+#define __NR_listen            348 /* new */
+#define __NR_accept            349 /* new */
+#define __NR_connect           350 /* new */
+#define __NR_getsockname       351 /* new */
+#define __NR_getpeername       352 /* new */
+#define __NR_sendto            353 /* new */
+#define __NR_send              354 /* new */
+#define __NR_recvfrom          355 /* new */
+#define __NR_recv              356 /* new */
+#define __NR_setsockopt                357 /* new */
+#define __NR_getsockopt                358 /* new */
+#define __NR_shutdown          359 /* new */
+#define __NR_sendmsg           360 /* new */
+#define __NR_recvmsg           361 /* new */
+#define __NR_accept04          362 /* new */
+
+#define __NR_syscalls          363
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#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
+/* #define __ARCH_WANT_SYS_RT_SIGSUSPEND */
+
+/*
+ * "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 /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_UNISTD_H */
diff --git a/arch/microblaze/include/asm/user.h b/arch/microblaze/include/asm/user.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/arch/microblaze/include/asm/vga.h b/arch/microblaze/include/asm/vga.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/arch/microblaze/include/asm/xor.h b/arch/microblaze/include/asm/xor.h
new file mode 100644 (file)
index 0000000..c82eb12
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/xor.h>
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
new file mode 100644 (file)
index 0000000..da94bec
--- /dev/null
@@ -0,0 +1,19 @@
+#
+# Makefile
+#
+
+extra-y := head.o vmlinux.lds
+
+obj-y += exceptions.o \
+       hw_exception_handler.o init_task.o intc.o irq.o of_device.o \
+       of_platform.o process.o prom.o prom_parse.o ptrace.o \
+       setup.o signal.o sys_microblaze.o timer.o traps.o
+
+obj-y += cpu/
+
+obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
+obj-$(CONFIG_SELFMOD)          += selfmod.o
+obj-$(CONFIG_HEART_BEAT)       += heartbeat.o
+obj-$(CONFIG_MODULES)          += microblaze_ksyms.o module.o
+
+obj-y  += entry$(MMUEXT).o
diff --git a/arch/microblaze/kernel/asm-offsets.c b/arch/microblaze/kernel/asm-offsets.c
new file mode 100644 (file)
index 0000000..38e1a2e
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/init.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/ptrace.h>
+#include <linux/hardirq.h>
+#include <linux/thread_info.h>
+#include <linux/kbuild.h>
+
+int main(int argc, char *argv[])
+{
+       /* struct pt_regs */
+       DEFINE(PT_SIZE, sizeof(struct pt_regs));
+       DEFINE(PT_MSR, offsetof(struct pt_regs, msr));
+       DEFINE(PT_EAR, offsetof(struct pt_regs, ear));
+       DEFINE(PT_ESR, offsetof(struct pt_regs, esr));
+       DEFINE(PT_FSR, offsetof(struct pt_regs, fsr));
+       DEFINE(PT_PC, offsetof(struct pt_regs, pc));
+       DEFINE(PT_R0, offsetof(struct pt_regs, r0));
+       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_R16, offsetof(struct pt_regs, r16));
+       DEFINE(PT_R17, offsetof(struct pt_regs, r17));
+       DEFINE(PT_R18, offsetof(struct pt_regs, r18));
+       DEFINE(PT_R19, offsetof(struct pt_regs, r19));
+       DEFINE(PT_R20, offsetof(struct pt_regs, r20));
+       DEFINE(PT_R21, offsetof(struct pt_regs, r21));
+       DEFINE(PT_R22, offsetof(struct pt_regs, r22));
+       DEFINE(PT_R23, offsetof(struct pt_regs, r23));
+       DEFINE(PT_R24, offsetof(struct pt_regs, r24));
+       DEFINE(PT_R25, offsetof(struct pt_regs, r25));
+       DEFINE(PT_R26, offsetof(struct pt_regs, r26));
+       DEFINE(PT_R27, offsetof(struct pt_regs, r27));
+       DEFINE(PT_R28, offsetof(struct pt_regs, r28));
+       DEFINE(PT_R29, offsetof(struct pt_regs, r29));
+       DEFINE(PT_R30, offsetof(struct pt_regs, r30));
+       DEFINE(PT_R31, offsetof(struct pt_regs, r31));
+       DEFINE(PT_MODE, offsetof(struct pt_regs, kernel_mode));
+       BLANK();
+
+       /* Magic offsets for PTRACE PEEK/POKE etc */
+       DEFINE(PT_TEXT_ADDR, sizeof(struct pt_regs) + 1);
+       DEFINE(PT_TEXT_LEN, sizeof(struct pt_regs) + 2);
+       DEFINE(PT_DATA_ADDR, sizeof(struct pt_regs) + 3);
+       BLANK();
+
+       /* struct task_struct */
+       DEFINE(TS_THREAD_INFO, offsetof(struct task_struct, stack));
+
+       /* struct thread_info */
+       DEFINE(TI_TASK, offsetof(struct thread_info, task));
+       DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
+       DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+       DEFINE(TI_STATUS, offsetof(struct thread_info, status));
+       DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+       DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
+       DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
+       DEFINE(TI_RESTART_BLOCK, offsetof(struct thread_info, restart_block));
+       DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context));
+       BLANK();
+
+       /* struct cpu_context */
+       DEFINE(CC_R1, offsetof(struct cpu_context, r1)); /* r1 */
+       DEFINE(CC_R2, offsetof(struct cpu_context, r2));
+       /* dedicated registers */
+       DEFINE(CC_R13, offsetof(struct cpu_context, r13));
+       DEFINE(CC_R14, offsetof(struct cpu_context, r14));
+       DEFINE(CC_R15, offsetof(struct cpu_context, r15));
+       DEFINE(CC_R16, offsetof(struct cpu_context, r16));
+       DEFINE(CC_R17, offsetof(struct cpu_context, r17));
+       DEFINE(CC_R18, offsetof(struct cpu_context, r18));
+       /* non-volatile registers */
+       DEFINE(CC_R19, offsetof(struct cpu_context, r19));
+       DEFINE(CC_R20, offsetof(struct cpu_context, r20));
+       DEFINE(CC_R21, offsetof(struct cpu_context, r21));
+       DEFINE(CC_R22, offsetof(struct cpu_context, r22));
+       DEFINE(CC_R23, offsetof(struct cpu_context, r23));
+       DEFINE(CC_R24, offsetof(struct cpu_context, r24));
+       DEFINE(CC_R25, offsetof(struct cpu_context, r25));
+       DEFINE(CC_R26, offsetof(struct cpu_context, r26));
+       DEFINE(CC_R27, offsetof(struct cpu_context, r27));
+       DEFINE(CC_R28, offsetof(struct cpu_context, r28));
+       DEFINE(CC_R29, offsetof(struct cpu_context, r29));
+       DEFINE(CC_R30, offsetof(struct cpu_context, r30));
+       /* special purpose registers */
+       DEFINE(CC_MSR, offsetof(struct cpu_context, msr));
+       DEFINE(CC_EAR, offsetof(struct cpu_context, ear));
+       DEFINE(CC_ESR, offsetof(struct cpu_context, esr));
+       DEFINE(CC_FSR, offsetof(struct cpu_context, fsr));
+       BLANK();
+
+       return 0;
+}
diff --git a/arch/microblaze/kernel/cpu/Makefile b/arch/microblaze/kernel/cpu/Makefile
new file mode 100644 (file)
index 0000000..20646e5
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Build the appropriate CPU version support
+#
+
+EXTRA_CFLAGS += -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \
+               -DCPU_REV=$(CPU_REV)
+
+obj-y += cache.o cpuinfo.o cpuinfo-pvr-full.o cpuinfo-static.o mb.o pvr.o
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c
new file mode 100644 (file)
index 0000000..be9fecc
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Cache control for MicroBlaze cache memories
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.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 <asm/cacheflush.h>
+#include <linux/cache.h>
+#include <asm/cpuinfo.h>
+
+/* Exported functions */
+
+void _enable_icache(void)
+{
+       if (cpuinfo.use_icache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+               __asm__ __volatile__ ("                                 \
+                               msrset  r0, %0;                         \
+                               nop; "                                  \
+                               :                                       \
+                               : "i" (MSR_ICE)                         \
+                               : "memory");
+#else
+               __asm__ __volatile__ ("                                 \
+                               mfs     r12, rmsr;                      \
+                               nop;                                    \
+                               ori     r12, r12, %0;                   \
+                               mts     rmsr, r12;                      \
+                               nop; "                                  \
+                               :                                       \
+                               : "i" (MSR_ICE)                         \
+                               : "memory", "r12");
+#endif
+       }
+}
+
+void _disable_icache(void)
+{
+       if (cpuinfo.use_icache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+               __asm__ __volatile__ ("                                 \
+                               msrclr r0, %0;                          \
+                               nop; "                                  \
+                               :                                       \
+                               : "i" (MSR_ICE)                         \
+                               : "memory");
+#else
+               __asm__ __volatile__ ("                                 \
+                               mfs     r12, rmsr;                      \
+                               nop;                                    \
+                               andi    r12, r12, ~%0;                  \
+                               mts     rmsr, r12;                      \
+                               nop; "                                  \
+                               :                                       \
+                               : "i" (MSR_ICE)                         \
+                               : "memory", "r12");
+#endif
+       }
+}
+
+void _invalidate_icache(unsigned int addr)
+{
+       if (cpuinfo.use_icache) {
+               __asm__ __volatile__ ("                                 \
+                               wic     %0, r0"                         \
+                               :                                       \
+                               : "r" (addr));
+       }
+}
+
+void _enable_dcache(void)
+{
+       if (cpuinfo.use_dcache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+               __asm__ __volatile__ ("                                 \
+                               msrset  r0, %0;                         \
+                               nop; "                                  \
+                               :                                       \
+                               : "i" (MSR_DCE)                         \
+                               : "memory");
+#else
+               __asm__ __volatile__ ("                                 \
+                               mfs     r12, rmsr;                      \
+                               nop;                                    \
+                               ori     r12, r12, %0;                   \
+                               mts     rmsr, r12;                      \
+                               nop; "                                  \
+                               :                                       \
+                               : "i" (MSR_DCE)                 \
+                               : "memory", "r12");
+#endif
+       }
+}
+
+void _disable_dcache(void)
+{
+       if (cpuinfo.use_dcache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+               __asm__ __volatile__ ("                                 \
+                               msrclr  r0, %0;                         \
+                               nop; "                                  \
+                               :                                       \
+                               : "i" (MSR_DCE)                 \
+                               : "memory");
+#else
+               __asm__ __volatile__ ("                                 \
+                               mfs     r12, rmsr;                      \
+                               nop;                                    \
+                               andi    r12, r12, ~%0;                  \
+                               mts     rmsr, r12;                      \
+                               nop; "                                  \
+                               :                                       \
+                               : "i" (MSR_DCE)                 \
+                               : "memory", "r12");
+#endif
+       }
+}
+
+void _invalidate_dcache(unsigned int addr)
+{
+       if (cpuinfo.use_dcache)
+               __asm__ __volatile__ ("                                 \
+                               wdc     %0, r0"                         \
+                               :                                       \
+                               : "r" (addr));
+}
+
+void __invalidate_icache_all(void)
+{
+       unsigned int i;
+       unsigned flags;
+
+       if (cpuinfo.use_icache) {
+               local_irq_save(flags);
+               __disable_icache();
+
+               /* Just loop through cache size and invalidate, no need to add
+                       CACHE_BASE address */
+               for (i = 0; i < cpuinfo.icache_size;
+                       i += cpuinfo.icache_line)
+                               __invalidate_icache(i);
+
+               __enable_icache();
+               local_irq_restore(flags);
+       }
+}
+
+void __invalidate_icache_range(unsigned long start, unsigned long end)
+{
+       unsigned int i;
+       unsigned flags;
+       unsigned int align;
+
+       if (cpuinfo.use_icache) {
+               /*
+                * No need to cover entire cache range,
+                * just cover cache footprint
+                */
+               end = min(start + cpuinfo.icache_size, end);
+               align = ~(cpuinfo.icache_line - 1);
+               start &= align; /* Make sure we are aligned */
+               /* Push end up to the next cache line */
+               end = ((end & align) + cpuinfo.icache_line);
+
+               local_irq_save(flags);
+               __disable_icache();
+
+               for (i = start; i < end; i += cpuinfo.icache_line)
+                       __invalidate_icache(i);
+
+               __enable_icache();
+               local_irq_restore(flags);
+       }
+}
+
+void __invalidate_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+       __invalidate_icache_all();
+}
+
+void __invalidate_icache_user_range(struct vm_area_struct *vma,
+                               struct page *page, unsigned long adr,
+                               int len)
+{
+       __invalidate_icache_all();
+}
+
+void __invalidate_cache_sigtramp(unsigned long addr)
+{
+       __invalidate_icache_range(addr, addr + 8);
+}
+
+void __invalidate_dcache_all(void)
+{
+       unsigned int i;
+       unsigned flags;
+
+       if (cpuinfo.use_dcache) {
+               local_irq_save(flags);
+               __disable_dcache();
+
+               /*
+                * Just loop through cache size and invalidate,
+                * no need to add CACHE_BASE address
+                */
+               for (i = 0; i < cpuinfo.dcache_size;
+                       i += cpuinfo.dcache_line)
+                               __invalidate_dcache(i);
+
+               __enable_dcache();
+               local_irq_restore(flags);
+       }
+}
+
+void __invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+       unsigned int i;
+       unsigned flags;
+       unsigned int align;
+
+       if (cpuinfo.use_dcache) {
+               /*
+                * No need to cover entire cache range,
+                * just cover cache footprint
+                */
+               end = min(start + cpuinfo.dcache_size, end);
+               align = ~(cpuinfo.dcache_line - 1);
+               start &= align; /* Make sure we are aligned */
+               /* Push end up to the next cache line */
+               end = ((end & align) + cpuinfo.dcache_line);
+               local_irq_save(flags);
+               __disable_dcache();
+
+               for (i = start; i < end; i += cpuinfo.dcache_line)
+                       __invalidate_dcache(i);
+
+               __enable_dcache();
+               local_irq_restore(flags);
+       }
+}
+
+void __invalidate_dcache_page(struct vm_area_struct *vma, struct page *page)
+{
+       __invalidate_dcache_all();
+}
+
+void __invalidate_dcache_user_range(struct vm_area_struct *vma,
+                               struct page *page, unsigned long adr,
+                               int len)
+{
+       __invalidate_dcache_all();
+}
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
new file mode 100644 (file)
index 0000000..cf7424a
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Support for MicroBlaze PVR (processor version register)
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.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/init.h>
+#include <linux/string.h>
+#include <asm/pvr.h>
+#include <asm/cpuinfo.h>
+
+/*
+ * Helper macro to map between fields in our struct cpuinfo, and
+ * the PVR macros in pvr.h.
+ */
+
+#define CI(c, p) { ci->c = PVR_##p(pvr); }
+#define err_printk(x) \
+       early_printk("ERROR: Microblaze " x " - different for PVR and DTS\n");
+
+void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
+{
+       struct pvr_s pvr;
+       int temp; /* for saving temp value */
+       get_pvr(&pvr);
+
+       temp = PVR_USE_BARREL(pvr) | PVR_USE_MSR_INSTR(pvr) |\
+               PVR_USE_PCMP_INSTR(pvr) | PVR_USE_DIV(pvr);
+       if (ci->use_instr != temp)
+               err_printk("BARREL, MSR, PCMP or DIV");
+       ci->use_instr = temp;
+
+       temp = PVR_USE_HW_MUL(pvr) | PVR_USE_MUL64(pvr);
+       if (ci->use_mult != temp)
+               err_printk("HW_MUL");
+       ci->use_mult = temp;
+
+       temp = PVR_USE_FPU(pvr) | PVR_USE_FPU2(pvr);
+       if (ci->use_fpu != temp)
+               err_printk("HW_FPU");
+       ci->use_fpu = temp;
+
+       ci->use_exc = PVR_OPCODE_0x0_ILLEGAL(pvr) |\
+                       PVR_UNALIGNED_EXCEPTION(pvr) |\
+                       PVR_ILL_OPCODE_EXCEPTION(pvr) |\
+                       PVR_IOPB_BUS_EXCEPTION(pvr) |\
+                       PVR_DOPB_BUS_EXCEPTION(pvr) |\
+                       PVR_DIV_ZERO_EXCEPTION(pvr) |\
+                       PVR_FPU_EXCEPTION(pvr) |\
+                       PVR_FSL_EXCEPTION(pvr);
+
+       CI(pvr_user1, USER1);
+       CI(pvr_user2, USER2);
+
+       CI(mmu, USE_MMU);
+
+       CI(ver_code, VERSION);
+
+       CI(use_icache, USE_ICACHE);
+       CI(icache_tagbits, ICACHE_ADDR_TAG_BITS);
+       CI(icache_write, ICACHE_ALLOW_WR);
+       CI(icache_line, ICACHE_LINE_LEN);
+       CI(icache_size, ICACHE_BYTE_SIZE);
+       CI(icache_base, ICACHE_BASEADDR);
+       CI(icache_high, ICACHE_HIGHADDR);
+
+       CI(use_dcache, USE_DCACHE);
+       CI(dcache_tagbits, DCACHE_ADDR_TAG_BITS);
+       CI(dcache_write, DCACHE_ALLOW_WR);
+       CI(dcache_line, DCACHE_LINE_LEN);
+       CI(dcache_size, DCACHE_BYTE_SIZE);
+       CI(dcache_base, DCACHE_BASEADDR);
+       CI(dcache_high, DCACHE_HIGHADDR);
+
+       CI(use_dopb, D_OPB);
+       CI(use_iopb, I_OPB);
+       CI(use_dlmb, D_LMB);
+       CI(use_ilmb, I_LMB);
+       CI(num_fsl, FSL_LINKS);
+
+       CI(irq_edge, INTERRUPT_IS_EDGE);
+       CI(irq_positive, EDGE_IS_POSITIVE);
+
+       CI(area_optimised, AREA_OPTIMISED);
+
+       CI(hw_debug, DEBUG_ENABLED);
+       CI(num_pc_brk, NUMBER_OF_PC_BRK);
+       CI(num_rd_brk, NUMBER_OF_RD_ADDR_BRK);
+       CI(num_wr_brk, NUMBER_OF_WR_ADDR_BRK);
+
+       CI(fpga_family_code, TARGET_FAMILY);
+
+       /* take timebase-frequency from DTS */
+       ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency");
+}
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c
new file mode 100644 (file)
index 0000000..cfe44ef
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.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/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/cpuinfo.h>
+#include <asm/pvr.h>
+
+const static char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY;
+const static char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER;
+
+#define err_printk(x) \
+       early_printk("ERROR: Microblaze " x "- different for kernel and DTS\n");
+
+void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
+{
+       int i = 0;
+
+       ci->use_instr =
+               (fcpu(cpu, "xlnx,use-barrel") ? PVR0_USE_BARREL_MASK : 0) |
+               (fcpu(cpu, "xlnx,use-msr-instr") ? PVR2_USE_MSR_INSTR : 0) |
+               (fcpu(cpu, "xlnx,use-pcmp-instr") ? PVR2_USE_PCMP_INSTR : 0) |
+               (fcpu(cpu, "xlnx,use-div") ? PVR0_USE_DIV_MASK : 0);
+       if (CONFIG_XILINX_MICROBLAZE0_USE_BARREL)
+               i |= PVR0_USE_BARREL_MASK;
+       if (CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR)
+               i |= PVR2_USE_MSR_INSTR;
+       if (CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR)
+               i |= PVR2_USE_PCMP_INSTR;
+       if (CONFIG_XILINX_MICROBLAZE0_USE_DIV)
+               i |= PVR0_USE_DIV_MASK;
+       if (ci->use_instr != i)
+               err_printk("BARREL, MSR, PCMP or DIV");
+
+       ci->use_mult = fcpu(cpu, "xlnx,use-hw-mul");
+       if (ci->use_mult != CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL)
+               err_printk("HW_MUL");
+       ci->use_mult =
+               (ci->use_mult > 1 ?
+                               (PVR2_USE_MUL64_MASK | PVR0_USE_HW_MUL_MASK) :
+                               (ci->use_mult == 1 ? PVR0_USE_HW_MUL_MASK : 0));
+
+       ci->use_fpu = fcpu(cpu, "xlnx,use-fpu");
+       if (ci->use_fpu != CONFIG_XILINX_MICROBLAZE0_USE_FPU)
+               err_printk("HW_FPU");
+       ci->use_fpu = (ci->use_fpu > 1 ?
+                               (PVR2_USE_FPU2_MASK | PVR0_USE_FPU_MASK) :
+                               (ci->use_fpu == 1 ? PVR0_USE_FPU_MASK : 0));
+
+       ci->use_exc =
+               (fcpu(cpu, "xlnx,unaligned-exceptions") ?
+                               PVR2_UNALIGNED_EXC_MASK : 0) |
+               (fcpu(cpu, "xlnx,ill-opcode-exception") ?
+                               PVR2_ILL_OPCODE_EXC_MASK : 0) |
+               (fcpu(cpu, "xlnx,iopb-bus-exception") ?
+                               PVR2_IOPB_BUS_EXC_MASK : 0) |
+               (fcpu(cpu, "xlnx,dopb-bus-exception") ?
+                               PVR2_DOPB_BUS_EXC_MASK : 0) |
+               (fcpu(cpu, "xlnx,div-zero-exception") ?
+                               PVR2_DIV_ZERO_EXC_MASK : 0) |
+               (fcpu(cpu, "xlnx,fpu-exception") ? PVR2_FPU_EXC_MASK : 0) |
+               (fcpu(cpu, "xlnx,fsl-exception") ? PVR2_USE_EXTEND_FSL : 0);
+
+       ci->use_icache = fcpu(cpu, "xlnx,use-icache");
+       ci->icache_tagbits = fcpu(cpu, "xlnx,addr-tag-bits");
+       ci->icache_write = fcpu(cpu, "xlnx,allow-icache-wr");
+       ci->icache_line = fcpu(cpu, "xlnx,icache-line-len") << 2;
+       if (!ci->icache_line) {
+               if (fcpu(cpu, "xlnx,icache-use-fsl"))
+                       ci->icache_line = 4 << 2;
+               else
+                       ci->icache_line = 1 << 2;
+       }
+       ci->icache_size = fcpu(cpu, "i-cache-size");
+       ci->icache_base = fcpu(cpu, "i-cache-baseaddr");
+       ci->icache_high = fcpu(cpu, "i-cache-highaddr");
+
+       ci->use_dcache = fcpu(cpu, "xlnx,use-dcache");
+       ci->dcache_tagbits = fcpu(cpu, "xlnx,dcache-addr-tag");
+       ci->dcache_write = fcpu(cpu, "xlnx,allow-dcache-wr");
+       ci->dcache_line = fcpu(cpu, "xlnx,dcache-line-len") << 2;
+       if (!ci->dcache_line) {
+               if (fcpu(cpu, "xlnx,dcache-use-fsl"))
+                       ci->dcache_line = 4 << 2;
+               else
+                       ci->dcache_line = 1 << 2;
+       }
+       ci->dcache_size = fcpu(cpu, "d-cache-size");
+       ci->dcache_base = fcpu(cpu, "d-cache-baseaddr");
+       ci->dcache_high = fcpu(cpu, "d-cache-highaddr");
+
+       ci->use_dopb = fcpu(cpu, "xlnx,d-opb");
+       ci->use_iopb = fcpu(cpu, "xlnx,i-opb");
+       ci->use_dlmb = fcpu(cpu, "xlnx,d-lmb");
+       ci->use_ilmb = fcpu(cpu, "xlnx,i-lmb");
+
+       ci->num_fsl = fcpu(cpu, "xlnx,fsl-links");
+       ci->irq_edge = fcpu(cpu, "xlnx,interrupt-is-edge");
+       ci->irq_positive = fcpu(cpu, "xlnx,edge-is-positive");
+       ci->area_optimised = 0;
+
+       ci->hw_debug = fcpu(cpu, "xlnx,debug-enabled");
+       ci->num_pc_brk = fcpu(cpu, "xlnx,number-of-pc-brk");
+       ci->num_rd_brk = fcpu(cpu, "xlnx,number-of-rd-addr-brk");
+       ci->num_wr_brk = fcpu(cpu, "xlnx,number-of-wr-addr-brk");
+
+       ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency");
+
+       ci->pvr_user1 = fcpu(cpu, "xlnx,pvr-user1");
+       ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2");
+
+       ci->mmu = fcpu(cpu, "xlnx,use-mmu");
+
+       ci->ver_code = 0;
+       ci->fpga_family_code = 0;
+
+       /* Do various fixups based on CPU version and FPGA family strings */
+
+       /* Resolved the CPU version code */
+       for (i = 0; cpu_ver_lookup[i].s != NULL; i++) {
+               if (strcmp(cpu_ver_lookup[i].s, cpu_ver_string) == 0)
+                       ci->ver_code = cpu_ver_lookup[i].k;
+       }
+
+       /* Resolved the fpga family code */
+       for (i = 0; family_string_lookup[i].s != NULL; i++) {
+               if (strcmp(family_string_lookup[i].s, family_string) == 0)
+                       ci->fpga_family_code = family_string_lookup[i].k;
+       }
+
+       /* FIXME - mb3 and spartan2 do not exist in PVR */
+       /* This is mb3 and on a non Spartan2 */
+       if (ci->ver_code == 0x20 && ci->fpga_family_code != 0xf0)
+               /* Hardware Multiplier in use */
+               ci->use_mult = 1;
+}
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
new file mode 100644 (file)
index 0000000..4a740df
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.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/init.h>
+#include <linux/slab.h>
+#include <asm/cpuinfo.h>
+#include <asm/pvr.h>
+
+const struct cpu_ver_key cpu_ver_lookup[] = {
+       /* These key value are as per MBV field in PVR0 */
+       {"5.00.a", 0x01},
+       {"5.00.b", 0x02},
+       {"5.00.c", 0x03},
+       {"6.00.a", 0x04},
+       {"6.00.b", 0x06},
+       {"7.00.a", 0x05},
+       {"7.00.b", 0x07},
+       {"7.10.a", 0x08},
+       {"7.10.b", 0x09},
+       {"7.10.c", 0x0a},
+       {"7.10.d", 0x0b},
+       /* FIXME There is no keycode defined in MBV for these versions */
+       {"2.10.a", 0x10},
+       {"3.00.a", 0x20},
+       {"4.00.a", 0x30},
+       {"4.00.b", 0x40},
+       {NULL, 0},
+};
+
+/*
+ * FIXME Not sure if the actual key is defined by Xilinx in the PVR
+ */
+const struct family_string_key family_string_lookup[] = {
+       {"virtex2", 0x4},
+       {"virtex2pro", 0x5},
+       {"spartan3", 0x6},
+       {"virtex4", 0x7},
+       {"virtex5", 0x8},
+       {"spartan3e", 0x9},
+       {"spartan3a", 0xa},
+       {"spartan3an", 0xb},
+       {"spartan3adsp", 0xc},
+       /* FIXME There is no key code defined for spartan2 */
+       {"spartan2", 0xf0},
+       {NULL, 0},
+};
+
+struct cpuinfo cpuinfo;
+
+void __init setup_cpuinfo(void)
+{
+       struct device_node *cpu = NULL;
+
+       cpu = (struct device_node *) of_find_node_by_type(NULL, "cpu");
+       if (!cpu)
+               printk(KERN_ERR "You don't have cpu!!!\n");
+
+       printk(KERN_INFO "%s: initialising\n", __func__);
+
+       switch (cpu_has_pvr()) {
+       case 0:
+               printk(KERN_WARNING
+                       "%s: No PVR support. Using static CPU info from FDT\n",
+                       __func__);
+               set_cpuinfo_static(&cpuinfo, cpu);
+               break;
+/* FIXME I found weird behavior with MB 7.00.a/b
+ * please do not use FULL PVR with MMU */
+       case 1:
+               printk(KERN_INFO "%s: Using full CPU PVR support\n",
+                       __func__);
+               set_cpuinfo_static(&cpuinfo, cpu);
+               set_cpuinfo_pvr_full(&cpuinfo, cpu);
+               break;
+       default:
+               printk(KERN_WARNING "%s: Unsupported PVR setting\n", __func__);
+               set_cpuinfo_static(&cpuinfo, cpu);
+       }
+}
diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c
new file mode 100644 (file)
index 0000000..3b6212b
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * CPU-version specific code
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006-2009 PetaLogix
+ *
+ * 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/init.h>
+#include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/cpu.h>
+#include <linux/initrd.h>
+
+#include <linux/bug.h>
+#include <asm/cpuinfo.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <asm/page.h>
+#include <linux/param.h>
+#include <asm/pvr.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+       int count = 0;
+       char *fpga_family = "Unknown";
+       char *cpu_ver = "Unknown";
+       int i;
+
+       /* Denormalised to get the fpga family string */
+       for (i = 0; family_string_lookup[i].s != NULL; i++) {
+               if (cpuinfo.fpga_family_code == family_string_lookup[i].k) {
+                       fpga_family = (char *)family_string_lookup[i].s;
+                       break;
+               }
+       }
+
+       /* Denormalised to get the hw version string */
+       for (i = 0; cpu_ver_lookup[i].s != NULL; i++) {
+               if (cpuinfo.ver_code == cpu_ver_lookup[i].k) {
+                       cpu_ver = (char *)cpu_ver_lookup[i].s;
+                       break;
+               }
+       }
+
+       count = seq_printf(m,
+                       "CPU-Family:    MicroBlaze\n"
+                       "FPGA-Arch:     %s\n"
+                       "CPU-Ver:       %s\n"
+                       "CPU-MHz:       %d.%02d\n"
+                       "BogoMips:      %lu.%02lu\n",
+                       fpga_family,
+                       cpu_ver,
+                       cpuinfo.cpu_clock_freq /
+                       1000000,
+                       cpuinfo.cpu_clock_freq %
+                       1000000,
+                       loops_per_jiffy / (500000 / HZ),
+                       (loops_per_jiffy / (5000 / HZ)) % 100);
+
+       count += seq_printf(m,
+               "HW:\n Shift:\t\t%s\n"
+               " MSR:\t\t%s\n"
+               " PCMP:\t\t%s\n"
+               " DIV:\t\t%s\n",
+               (cpuinfo.use_instr & PVR0_USE_BARREL_MASK) ? "yes" : "no",
+               (cpuinfo.use_instr & PVR2_USE_MSR_INSTR) ? "yes" : "no",
+               (cpuinfo.use_instr & PVR2_USE_PCMP_INSTR) ? "yes" : "no",
+               (cpuinfo.use_instr & PVR0_USE_DIV_MASK) ? "yes" : "no");
+
+       count += seq_printf(m,
+                       " MMU:\t\t%x\n",
+                       cpuinfo.mmu);
+
+       count += seq_printf(m,
+               " MUL:\t\t%s\n"
+               " FPU:\t\t%s\n",
+               (cpuinfo.use_mult & PVR2_USE_MUL64_MASK) ? "v2" :
+                       (cpuinfo.use_mult & PVR0_USE_HW_MUL_MASK) ? "v1" : "no",
+               (cpuinfo.use_fpu & PVR2_USE_FPU2_MASK) ? "v2" :
+                       (cpuinfo.use_fpu & PVR0_USE_FPU_MASK) ? "v1" : "no");
+
+       count += seq_printf(m,
+               " Exc:\t\t%s%s%s%s%s%s%s%s\n",
+               (cpuinfo.use_exc & PVR2_OPCODE_0x0_ILL_MASK) ? "op0x0 " : "",
+               (cpuinfo.use_exc & PVR2_UNALIGNED_EXC_MASK) ? "unal " : "",
+               (cpuinfo.use_exc & PVR2_ILL_OPCODE_EXC_MASK) ? "ill " : "",
+               (cpuinfo.use_exc & PVR2_IOPB_BUS_EXC_MASK) ? "iopb " : "",
+               (cpuinfo.use_exc & PVR2_DOPB_BUS_EXC_MASK) ? "dopb " : "",
+               (cpuinfo.use_exc & PVR2_DIV_ZERO_EXC_MASK) ? "zero " : "",
+               (cpuinfo.use_exc & PVR2_FPU_EXC_MASK) ? "fpu " : "",
+               (cpuinfo.use_exc & PVR2_USE_FSL_EXC) ? "fsl " : "");
+
+       if (cpuinfo.use_icache)
+               count += seq_printf(m,
+                               "Icache:\t\t%ukB\n",
+                               cpuinfo.icache_size >> 10);
+       else
+               count += seq_printf(m, "Icache:\t\tno\n");
+
+       if (cpuinfo.use_dcache)
+               count += seq_printf(m,
+                               "Dcache:\t\t%ukB\n",
+                               cpuinfo.dcache_size >> 10);
+       else
+               count += seq_printf(m, "Dcache:\t\tno\n");
+
+       count += seq_printf(m,
+                       "HW-Debug:\t%s\n",
+                       cpuinfo.hw_debug ? "yes" : "no");
+
+       count += seq_printf(m,
+                       "PVR-USR1:\t%x\n"
+                       "PVR-USR2:\t%x\n",
+                       cpuinfo.pvr_user1,
+                       cpuinfo.pvr_user2);
+
+       return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+       int i = *pos;
+
+       return i < NR_CPUS ? (void *) (i + 1) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+       ++*pos;
+       return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+const struct seq_operations cpuinfo_op = {
+       .start = c_start,
+       .next = c_next,
+       .stop = c_stop,
+       .show = show_cpuinfo,
+};
diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c
new file mode 100644 (file)
index 0000000..c9a4340
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Support for MicroBlaze PVR (processor version register)
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.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/kernel.h>
+#include <linux/compiler.h>
+#include <asm/system.h>
+#include <asm/exceptions.h>
+#include <asm/pvr.h>
+
+/*
+ * Until we get an assembler that knows about the pvr registers,
+ * this horrible cruft will have to do.
+ * That hardcoded opcode is mfs r3, rpvrNN
+ */
+
+#define get_single_pvr(pvrid, val)                             \
+{                                                              \
+       register unsigned tmp __asm__("r3");                    \
+       tmp = 0x0;      /* Prevent warning about unused */      \
+       __asm__ __volatile__ (                                  \
+                       ".byte 0x94,0x60,0xa0, " #pvrid "\n\t"  \
+                       : "=r" (tmp) : : "memory");             \
+       val = tmp;                                              \
+}
+
+/*
+ * Does the CPU support the PVR register?
+ * return value:
+ * 0: no PVR
+ * 1: simple PVR
+ * 2: full PVR
+ *
+ * This must work on all CPU versions, including those before the
+ * PVR was even an option.
+ */
+
+int cpu_has_pvr(void)
+{
+       unsigned flags;
+       unsigned pvr0;
+
+       local_save_flags(flags);
+
+       /* PVR bit in MSR tells us if there is any support */
+       if (!(flags & PVR_MSR_BIT))
+               return 0;
+
+       get_single_pvr(0x00, pvr0);
+       pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0);
+
+       if (pvr0 & PVR0_PVR_FULL_MASK)
+               return 1;
+
+       /* for partial PVR use static cpuinfo */
+       return 2;
+}
+
+void get_pvr(struct pvr_s *p)
+{
+       get_single_pvr(0, p->pvr[0]);
+       get_single_pvr(1, p->pvr[1]);
+       get_single_pvr(2, p->pvr[2]);
+       get_single_pvr(3, p->pvr[3]);
+       get_single_pvr(4, p->pvr[4]);
+       get_single_pvr(5, p->pvr[5]);
+       get_single_pvr(6, p->pvr[6]);
+       get_single_pvr(7, p->pvr[7]);
+       get_single_pvr(8, p->pvr[8]);
+       get_single_pvr(9, p->pvr[9]);
+       get_single_pvr(10, p->pvr[10]);
+       get_single_pvr(11, p->pvr[11]);
+}
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c
new file mode 100644 (file)
index 0000000..62cc789
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Early printk support for Microblaze.
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2003-2006 Yasushi SHOJI <yashi@atmark-techno.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/console.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/io.h>
+#include <asm/processor.h>
+#include <linux/fcntl.h>
+#include <asm/setup.h>
+#include <asm/prom.h>
+
+static u32 early_console_initialized;
+static u32 base_addr;
+
+static void early_printk_putc(char c)
+{
+       /*
+        * Limit how many times we'll spin waiting for TX FIFO status.
+        * This will prevent lockups if the base address is incorrectly
+        * set, or any other issue on the UARTLITE.
+        * This limit is pretty arbitrary, unless we are at about 10 baud
+        * we'll never timeout on a working UART.
+        */
+
+       unsigned retries = 10000;
+       /* read status bit - 0x8 offset */
+       while (retries-- && (in_be32(base_addr + 8) & (1 << 3)))
+               ;
+
+       /* Only attempt the iowrite if we didn't timeout */
+       /* write to TX_FIFO - 0x4 offset */
+       if (retries)
+               out_be32(base_addr + 4, c & 0xff);
+}
+
+static void early_printk_write(struct console *unused,
+                                       const char *s, unsigned n)
+{
+       while (*s && n-- > 0) {
+               early_printk_putc(*s);
+               if (*s == '\n')
+                       early_printk_putc('\r');
+               s++;
+       }
+}
+
+static struct console early_serial_console = {
+       .name = "earlyser",
+       .write = early_printk_write,
+       .flags = CON_PRINTBUFFER,
+       .index = -1,
+};
+
+static struct console *early_console = &early_serial_console;
+
+void early_printk(const char *fmt, ...)
+{
+       char buf[512];
+       int n;
+       va_list ap;
+
+       if (early_console_initialized) {
+               va_start(ap, fmt);
+               n = vscnprintf(buf, 512, fmt, ap);
+               early_console->write(early_console, buf, n);
+               va_end(ap);
+       }
+}
+
+int __init setup_early_printk(char *opt)
+{
+       if (early_console_initialized)
+               return 1;
+
+       base_addr = early_uartlite_console();
+       if (base_addr) {
+               early_console_initialized = 1;
+               early_printk("early_printk_console is enabled at 0x%08x\n",
+                                                       base_addr);
+
+               /* register_console(early_console); */
+
+               return 0;
+       } else
+               return 1;
+}
+
+void __init disable_early_printk(void)
+{
+       if (!early_console_initialized || !early_console)
+               return;
+       printk(KERN_WARNING "disabling early console\n");
+       unregister_console(early_console);
+       early_console_initialized = 0;
+}
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
new file mode 100644 (file)
index 0000000..f24b126
--- /dev/null
@@ -0,0 +1,596 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+#include <asm/entry.h>
+#include <asm/asm-offsets.h>
+#include <asm/registers.h>
+#include <asm/unistd.h>
+#include <asm/percpu.h>
+#include <asm/signal.h>
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+       .macro  disable_irq
+       msrclr r0, MSR_IE
+       .endm
+
+       .macro  enable_irq
+       msrset r0, MSR_IE
+       .endm
+
+       .macro  clear_bip
+       msrclr r0, MSR_BIP
+       .endm
+#else
+       .macro  disable_irq
+       mfs r11, rmsr
+       andi r11, r11, ~MSR_IE
+       mts rmsr, r11
+       .endm
+
+       .macro  enable_irq
+       mfs r11, rmsr
+       ori r11, r11, MSR_IE
+       mts rmsr, r11
+       .endm
+
+       .macro  clear_bip
+       mfs r11, rmsr
+       andi r11, r11, ~MSR_BIP
+       mts rmsr, r11
+       .endm
+#endif
+
+ENTRY(_interrupt)
+       swi     r1, r0, PER_CPU(ENTRY_SP)       /* save the current sp */
+       swi     r11, r0, PER_CPU(R11_SAVE)      /* temporarily save r11 */
+       lwi     r11, r0, PER_CPU(KM)            /* load mode indicator */
+       beqid   r11, 1f
+       nop
+       brid    2f                              /* jump over */
+       addik   r1, r1, (-PT_SIZE)      /* room for pt_regs (delay slot) */
+1:                                             /* switch to kernel stack */
+       lwi     r1, r0, PER_CPU(CURRENT_SAVE)   /* get the saved current */
+       lwi     r1, r1, TS_THREAD_INFO          /* get the thread info */
+       /* calculate kernel stack pointer */
+       addik   r1, r1, THREAD_SIZE - PT_SIZE
+2:
+       swi     r11, r1, PT_MODE                /* store the mode */
+       lwi     r11, r0, PER_CPU(R11_SAVE)      /* reload r11 */
+       swi     r2, r1, PT_R2
+       swi     r3, r1, PT_R3
+       swi     r4, r1, PT_R4
+       swi     r5, r1, PT_R5
+       swi     r6, r1, PT_R6
+       swi     r7, r1, PT_R7
+       swi     r8, r1, PT_R8
+       swi     r9, r1, PT_R9
+       swi     r10, r1, PT_R10
+       swi     r11, r1, PT_R11
+       swi     r12, r1, PT_R12
+       swi     r13, r1, PT_R13
+       swi     r14, r1, PT_R14
+       swi     r14, r1, PT_PC
+       swi     r15, r1, PT_R15
+       swi     r16, r1, PT_R16
+       swi     r17, r1, PT_R17
+       swi     r18, r1, PT_R18
+       swi     r19, r1, PT_R19
+       swi     r20, r1, PT_R20
+       swi     r21, r1, PT_R21
+       swi     r22, r1, PT_R22
+       swi     r23, r1, PT_R23
+       swi     r24, r1, PT_R24
+       swi     r25, r1, PT_R25
+       swi     r26, r1, PT_R26
+       swi     r27, r1, PT_R27
+       swi     r28, r1, PT_R28
+       swi     r29, r1, PT_R29
+       swi     r30, r1, PT_R30
+       swi     r31, r1, PT_R31
+       /* special purpose registers */
+       mfs     r11, rmsr
+       swi     r11, r1, PT_MSR
+       mfs     r11, rear
+       swi     r11, r1, PT_EAR
+       mfs     r11, resr
+       swi     r11, r1, PT_ESR
+       mfs     r11, rfsr
+       swi     r11, r1, PT_FSR
+       /* reload original stack pointer and save it */
+       lwi     r11, r0, PER_CPU(ENTRY_SP)
+       swi     r11, r1, PT_R1
+       /* update mode indicator we are in kernel mode */
+       addik   r11, r0, 1
+       swi     r11, r0, PER_CPU(KM)
+       /* restore r31 */
+       lwi     r31, r0, PER_CPU(CURRENT_SAVE)
+       /* prepare the link register, the argument and jump */
+       la      r15, r0, ret_from_intr - 8
+       addk    r6, r0, r15
+       braid   do_IRQ
+       add     r5, r0, r1
+
+ret_from_intr:
+       lwi     r11, r1, PT_MODE
+       bneid   r11, 3f
+
+       lwi     r6, r31, TS_THREAD_INFO /* get thread info */
+       lwi     r19, r6, TI_FLAGS       /* get flags in thread info */
+                               /* do an extra work if any bits are set */
+
+       andi    r11, r19, _TIF_NEED_RESCHED
+       beqi    r11, 1f
+       bralid  r15, schedule
+       nop
+1:     andi    r11, r19, _TIF_SIGPENDING
+       beqid   r11, no_intr_reshed
+       addk    r5, r1, r0
+       addk    r7, r0, r0
+       bralid  r15, do_signal
+       addk    r6, r0, r0
+
+no_intr_reshed:
+       /* save mode indicator */
+       lwi     r11, r1, PT_MODE
+3:
+       swi     r11, r0, PER_CPU(KM)
+
+       /* save r31 */
+       swi     r31, r0, PER_CPU(CURRENT_SAVE)
+restore_context:
+       /* special purpose registers */
+       lwi     r11, r1, PT_FSR
+       mts     rfsr, r11
+       lwi     r11, r1, PT_ESR
+       mts     resr, r11
+       lwi     r11, r1, PT_EAR
+       mts     rear, r11
+       lwi     r11, r1, PT_MSR
+       mts     rmsr, r11
+
+       lwi     r31, r1, PT_R31
+       lwi     r30, r1, PT_R30
+       lwi     r29, r1, PT_R29
+       lwi     r28, r1, PT_R28
+       lwi     r27, r1, PT_R27
+       lwi     r26, r1, PT_R26
+       lwi     r25, r1, PT_R25
+       lwi     r24, r1, PT_R24
+       lwi     r23, r1, PT_R23
+       lwi     r22, r1, PT_R22
+       lwi     r21, r1, PT_R21
+       lwi     r20, r1, PT_R20
+       lwi     r19, r1, PT_R19
+       lwi     r18, r1, PT_R18
+       lwi     r17, r1, PT_R17
+       lwi     r16, r1, PT_R16
+       lwi     r15, r1, PT_R15
+       lwi     r14, r1, PT_PC
+       lwi     r13, r1, PT_R13
+       lwi     r12, r1, PT_R12
+       lwi     r11, r1, PT_R11
+       lwi     r10, r1, PT_R10
+       lwi     r9, r1, PT_R9
+       lwi     r8, r1, PT_R8
+       lwi     r7, r1, PT_R7
+       lwi     r6, r1, PT_R6
+       lwi     r5, r1, PT_R5
+       lwi     r4, r1, PT_R4
+       lwi     r3, r1, PT_R3
+       lwi     r2, r1, PT_R2
+       lwi     r1, r1, PT_R1
+       rtid    r14, 0
+       nop
+
+ENTRY(_reset)
+       brai    0;
+
+ENTRY(_user_exception)
+       swi     r1, r0, PER_CPU(ENTRY_SP)       /* save the current sp */
+       swi     r11, r0, PER_CPU(R11_SAVE)      /* temporarily save r11 */
+       lwi     r11, r0, PER_CPU(KM)            /* load mode indicator */
+       beqid   r11, 1f                         /* Already in kernel mode? */
+       nop
+       brid    2f                              /* jump over */
+       addik   r1, r1, (-PT_SIZE)      /* Room for pt_regs (delay slot) */
+1:                                             /* Switch to kernel stack */
+       lwi     r1, r0, PER_CPU(CURRENT_SAVE)   /* get the saved current */
+       lwi     r1, r1, TS_THREAD_INFO          /* get the thread info */
+       /* calculate kernel stack pointer */
+       addik   r1, r1, THREAD_SIZE - PT_SIZE
+       swi     r11, r0, PER_CPU(R11_SAVE)      /* temporarily save r11 */
+       lwi     r11, r0, PER_CPU(KM)            /* load mode indicator */
+2:
+       swi     r11, r1, PT_MODE                /* store the mode */
+       lwi     r11, r0, PER_CPU(R11_SAVE)      /* reload r11 */
+       /* save them on stack */
+       swi     r2, r1, PT_R2
+       swi     r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */
+       swi     r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */
+       swi     r5, r1, PT_R5
+       swi     r6, r1, PT_R6
+       swi     r7, r1, PT_R7
+       swi     r8, r1, PT_R8
+       swi     r9, r1, PT_R9
+       swi     r10, r1, PT_R10
+       swi     r11, r1, PT_R11
+       /* r12: _always_ in clobber list; see unistd.h */
+       swi     r12, r1, PT_R12
+       swi     r13, r1, PT_R13
+       /* r14: _always_ in clobber list; see unistd.h */
+       swi     r14, r1, PT_R14
+       /* but we want to return to the next inst. */
+       addik   r14, r14, 0x4
+       swi     r14, r1, PT_PC          /* increment by 4 and store in pc */
+       swi     r15, r1, PT_R15
+       swi     r16, r1, PT_R16
+       swi     r17, r1, PT_R17
+       swi     r18, r1, PT_R18
+       swi     r19, r1, PT_R19
+       swi     r20, r1, PT_R20
+       swi     r21, r1, PT_R21
+       swi     r22, r1, PT_R22
+       swi     r23, r1, PT_R23
+       swi     r24, r1, PT_R24
+       swi     r25, r1, PT_R25
+       swi     r26, r1, PT_R26
+       swi     r27, r1, PT_R27
+       swi     r28, r1, PT_R28
+       swi     r29, r1, PT_R29
+       swi     r30, r1, PT_R30
+       swi     r31, r1, PT_R31
+
+       disable_irq
+       nop             /* make sure IE bit is in effect */
+       clear_bip       /* once IE is in effect it is safe to clear BIP */
+       nop
+
+       /* special purpose registers */
+       mfs     r11, rmsr
+       swi     r11, r1, PT_MSR
+       mfs     r11, rear
+       swi     r11, r1, PT_EAR
+       mfs     r11, resr
+       swi     r11, r1, PT_ESR
+       mfs     r11, rfsr
+       swi     r11, r1, PT_FSR
+       /* reload original stack pointer and save it */
+       lwi     r11, r0, PER_CPU(ENTRY_SP)
+       swi     r11, r1, PT_R1
+       /* update mode indicator we are in kernel mode */
+       addik   r11, r0, 1
+       swi     r11, r0, PER_CPU(KM)
+       /* restore r31 */
+       lwi     r31, r0, PER_CPU(CURRENT_SAVE)
+       /* re-enable interrupts now we are in kernel mode */
+       enable_irq
+
+       /* See if the system call number is valid. */
+       addi    r11, r12, -__NR_syscalls
+       bgei    r11, 1f                 /* return to user if not valid */
+       /* Figure out which function to use for this system call. */
+       /* Note Microblaze barrel shift is optional, so don't rely on it */
+       add     r12, r12, r12                   /* convert num -> ptr */
+       add     r12, r12, r12
+       lwi     r12, r12, sys_call_table        /* Get function pointer */
+       la      r15, r0, ret_to_user-8          /* set return address */
+       bra     r12                             /* Make the system call. */
+       bri     0                               /* won't reach here */
+1:
+       brid    ret_to_user                     /* jump to syscall epilogue */
+       addi    r3, r0, -ENOSYS                 /* set errno in delay slot */
+
+/*
+ * Debug traps are like a system call, but entered via brki r14, 0x60
+ * All we need to do is send the SIGTRAP signal to current, ptrace and do_signal
+ * will handle the rest
+ */
+ENTRY(_debug_exception)
+       swi     r1, r0, PER_CPU(ENTRY_SP)       /* save the current sp */
+       lwi     r1, r0, PER_CPU(CURRENT_SAVE)   /* get the saved current */
+       lwi     r1, r1, TS_THREAD_INFO          /* get the thread info */
+       addik   r1, r1, THREAD_SIZE - PT_SIZE   /* get the kernel stack */
+       swi     r11, r0, PER_CPU(R11_SAVE)      /* temporarily save r11 */
+       lwi     r11, r0, PER_CPU(KM)            /* load mode indicator */
+//save_context:
+       swi     r11, r1, PT_MODE        /* store the mode */
+       lwi     r11, r0, PER_CPU(R11_SAVE)      /* reload r11 */
+       /* save them on stack */
+       swi     r2, r1, PT_R2
+       swi     r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */
+       swi     r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */
+       swi     r5, r1, PT_R5
+       swi     r6, r1, PT_R6
+       swi     r7, r1, PT_R7
+       swi     r8, r1, PT_R8
+       swi     r9, r1, PT_R9
+       swi     r10, r1, PT_R10
+       swi     r11, r1, PT_R11
+       /* r12: _always_ in clobber list; see unistd.h */
+       swi     r12, r1, PT_R12
+       swi     r13, r1, PT_R13
+       /* r14: _always_ in clobber list; see unistd.h */
+       swi     r14, r1, PT_R14
+       swi     r14, r1, PT_PC /* Will return to interrupted instruction */
+       swi     r15, r1, PT_R15
+       swi     r16, r1, PT_R16
+       swi     r17, r1, PT_R17
+       swi     r18, r1, PT_R18
+       swi     r19, r1, PT_R19
+       swi     r20, r1, PT_R20
+       swi     r21, r1, PT_R21
+       swi     r22, r1, PT_R22
+       swi     r23, r1, PT_R23
+       swi     r24, r1, PT_R24
+       swi     r25, r1, PT_R25
+       swi     r26, r1, PT_R26
+       swi     r27, r1, PT_R27
+       swi     r28, r1, PT_R28
+       swi     r29, r1, PT_R29
+       swi     r30, r1, PT_R30
+       swi     r31, r1, PT_R31
+
+       disable_irq
+       nop             /* make sure IE bit is in effect */
+       clear_bip       /* once IE is in effect it is safe to clear BIP */
+       nop
+
+       /* special purpose registers */
+       mfs     r11, rmsr
+       swi     r11, r1, PT_MSR
+       mfs     r11, rear
+       swi     r11, r1, PT_EAR
+       mfs     r11, resr
+       swi     r11, r1, PT_ESR
+       mfs     r11, rfsr
+       swi     r11, r1, PT_FSR
+       /* reload original stack pointer and save it */
+       lwi     r11, r0, PER_CPU(ENTRY_SP)
+       swi     r11, r1, PT_R1
+       /* update mode indicator we are in kernel mode */
+       addik   r11, r0, 1
+       swi     r11, r0, PER_CPU(KM)
+       /* restore r31 */
+       lwi     r31, r0, PER_CPU(CURRENT_SAVE)
+       /* re-enable interrupts now we are in kernel mode */
+       enable_irq
+
+       addi    r5, r0, SIGTRAP                 /* sending the trap signal */
+       add     r6, r0, r31                     /* to current */
+       bralid  r15, send_sig
+       add     r7, r0, r0                      /* 3rd param zero */
+
+       /* Restore r3/r4 to work around how ret_to_user works */
+       lwi     r3, r1, PT_R3
+       lwi     r4, r1, PT_R4
+       bri     ret_to_user
+
+ENTRY(_break)
+       bri     0
+
+/* struct task_struct *_switch_to(struct thread_info *prev,
+                                       struct thread_info *next); */
+ENTRY(_switch_to)
+       /* prepare return value */
+       addk    r3, r0, r31
+
+       /* save registers in cpu_context */
+       /* use r11 and r12, volatile registers, as temp register */
+       addik   r11, r5, TI_CPU_CONTEXT
+       swi     r1, r11, CC_R1
+       swi     r2, r11, CC_R2
+       /* skip volatile registers.
+        * they are saved on stack when we jumped to _switch_to() */
+       /* dedicated registers */
+       swi     r13, r11, CC_R13
+       swi     r14, r11, CC_R14
+       swi     r15, r11, CC_R15
+       swi     r16, r11, CC_R16
+       swi     r17, r11, CC_R17
+       swi     r18, r11, CC_R18
+       /* save non-volatile registers */
+       swi     r19, r11, CC_R19
+       swi     r20, r11, CC_R20
+       swi     r21, r11, CC_R21
+       swi     r22, r11, CC_R22
+       swi     r23, r11, CC_R23
+       swi     r24, r11, CC_R24
+       swi     r25, r11, CC_R25
+       swi     r26, r11, CC_R26
+       swi     r27, r11, CC_R27
+       swi     r28, r11, CC_R28
+       swi     r29, r11, CC_R29
+       swi     r30, r11, CC_R30
+       /* special purpose registers */
+       mfs     r12, rmsr
+       swi     r12, r11, CC_MSR
+       mfs     r12, rear
+       swi     r12, r11, CC_EAR
+       mfs     r12, resr
+       swi     r12, r11, CC_ESR
+       mfs     r12, rfsr
+       swi     r12, r11, CC_FSR
+
+       /* update r31, the current */
+       lwi     r31, r6, TI_TASK
+       swi     r31, r0, PER_CPU(CURRENT_SAVE)
+
+       /* get new process' cpu context and restore */
+       addik   r11, r6, TI_CPU_CONTEXT
+
+       /* special purpose registers */
+       lwi     r12, r11, CC_FSR
+       mts     rfsr, r12
+       lwi     r12, r11, CC_ESR
+       mts     resr, r12
+       lwi     r12, r11, CC_EAR
+       mts     rear, r12
+       lwi     r12, r11, CC_MSR
+       mts     rmsr, r12
+       /* non-volatile registers */
+       lwi     r30, r11, CC_R30
+       lwi     r29, r11, CC_R29
+       lwi     r28, r11, CC_R28
+       lwi     r27, r11, CC_R27
+       lwi     r26, r11, CC_R26
+       lwi     r25, r11, CC_R25
+       lwi     r24, r11, CC_R24
+       lwi     r23, r11, CC_R23
+       lwi     r22, r11, CC_R22
+       lwi     r21, r11, CC_R21
+       lwi     r20, r11, CC_R20
+       lwi     r19, r11, CC_R19
+       /* dedicated registers */
+       lwi     r18, r11, CC_R18
+       lwi     r17, r11, CC_R17
+       lwi     r16, r11, CC_R16
+       lwi     r15, r11, CC_R15
+       lwi     r14, r11, CC_R14
+       lwi     r13, r11, CC_R13
+       /* skip volatile registers */
+       lwi     r2, r11, CC_R2
+       lwi     r1, r11, CC_R1
+
+       rtsd    r15, 8
+       nop
+
+ENTRY(ret_from_fork)
+       addk    r5, r0, r3
+       addk    r6, r0, r1
+       brlid   r15, schedule_tail
+       nop
+       swi     r31, r1, PT_R31         /* save r31 in user context. */
+                       /* will soon be restored to r31 in ret_to_user */
+       addk    r3, r0, r0
+       brid    ret_to_user
+       nop
+
+work_pending:
+       andi    r11, r19, _TIF_NEED_RESCHED
+       beqi    r11, 1f
+       bralid  r15, schedule
+       nop
+1:     andi    r11, r19, _TIF_SIGPENDING
+       beqi    r11, no_work_pending
+       addk    r5, r1, r0
+       addik   r7, r0, 1
+       bralid  r15, do_signal
+       addk    r6, r0, r0
+       bri     no_work_pending
+
+ENTRY(ret_to_user)
+       disable_irq
+
+       swi     r4, r1, PT_R4           /* return val */
+       swi     r3, r1, PT_R3           /* return val */
+
+       lwi     r6, r31, TS_THREAD_INFO /* get thread info */
+       lwi     r19, r6, TI_FLAGS /* get flags in thread info */
+       bnei    r19, work_pending /* do an extra work if any bits are set */
+no_work_pending:
+       disable_irq
+
+       /* save r31 */
+       swi     r31, r0, PER_CPU(CURRENT_SAVE)
+       /* save mode indicator */
+       lwi     r18, r1, PT_MODE
+       swi     r18, r0, PER_CPU(KM)
+//restore_context:
+       /* special purpose registers */
+       lwi     r18, r1, PT_FSR
+       mts     rfsr, r18
+       lwi     r18, r1, PT_ESR
+       mts     resr, r18
+       lwi     r18, r1, PT_EAR
+       mts     rear, r18
+       lwi     r18, r1, PT_MSR
+       mts     rmsr, r18
+
+       lwi     r31, r1, PT_R31
+       lwi     r30, r1, PT_R30
+       lwi     r29, r1, PT_R29
+       lwi     r28, r1, PT_R28
+       lwi     r27, r1, PT_R27
+       lwi     r26, r1, PT_R26
+       lwi     r25, r1, PT_R25
+       lwi     r24, r1, PT_R24
+       lwi     r23, r1, PT_R23
+       lwi     r22, r1, PT_R22
+       lwi     r21, r1, PT_R21
+       lwi     r20, r1, PT_R20
+       lwi     r19, r1, PT_R19
+       lwi     r18, r1, PT_R18
+       lwi     r17, r1, PT_R17
+       lwi     r16, r1, PT_R16
+       lwi     r15, r1, PT_R15
+       lwi     r14, r1, PT_PC
+       lwi     r13, r1, PT_R13
+       lwi     r12, r1, PT_R12
+       lwi     r11, r1, PT_R11
+       lwi     r10, r1, PT_R10
+       lwi     r9, r1, PT_R9
+       lwi     r8, r1, PT_R8
+       lwi     r7, r1, PT_R7
+       lwi     r6, r1, PT_R6
+       lwi     r5, r1, PT_R5
+       lwi     r4, r1, PT_R4           /* return val */
+       lwi     r3, r1, PT_R3           /* return val */
+       lwi     r2, r1, PT_R2
+       lwi     r1, r1, PT_R1
+
+       rtid    r14, 0
+       nop
+
+sys_vfork_wrapper:
+       brid    sys_vfork
+       addk    r5, r1, r0
+
+sys_clone_wrapper:
+       brid    sys_clone
+       addk    r7, r1, r0
+
+sys_execve_wrapper:
+       brid    sys_execve
+       addk    r8, r1, r0
+
+sys_sigreturn_wrapper:
+       brid    sys_sigreturn
+       addk    r5, r1, r0
+
+sys_rt_sigreturn_wrapper:
+       brid    sys_rt_sigreturn
+       addk    r5, r1, r0
+
+sys_sigsuspend_wrapper:
+       brid    sys_rt_sigsuspend
+       addk    r6, r1, r0
+
+sys_rt_sigsuspend_wrapper:
+       brid    sys_rt_sigsuspend
+       addk    r7, r1, r0
+
+       /* Interrupt vector table */
+       .section        .init.ivt, "ax"
+       .org 0x0
+       brai    _reset
+       brai    _user_exception
+       brai    _interrupt
+       brai    _break
+       brai    _hw_exception_handler
+       .org 0x60
+       brai    _debug_exception
+
+.section .rodata,"a"
+#include "syscall_table.S"
+
+syscall_table_size=(.-sys_call_table)
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
new file mode 100644 (file)
index 0000000..4a8a406
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * HW exception handling
+ *
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008 PetaLogix
+ *
+ * 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.
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kallsyms.h>
+#include <linux/module.h>
+
+#include <asm/exceptions.h>
+#include <asm/entry.h>         /* For KM CPU var */
+#include <asm/uaccess.h>
+#include <asm/errno.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+
+#define MICROBLAZE_ILL_OPCODE_EXCEPTION        0x02
+#define MICROBLAZE_IBUS_EXCEPTION      0x03
+#define MICROBLAZE_DBUS_EXCEPTION      0x04
+#define MICROBLAZE_DIV_ZERO_EXCEPTION  0x05
+#define MICROBLAZE_FPU_EXCEPTION       0x06
+#define MICROBLAZE_PRIVILEG_EXCEPTION  0x07
+
+static DEFINE_SPINLOCK(die_lock);
+
+void die(const char *str, struct pt_regs *fp, long err)
+{
+       console_verbose();
+       spin_lock_irq(&die_lock);
+       printk(KERN_WARNING "Oops: %s, sig: %ld\n", str, err);
+       show_regs(fp);
+       spin_unlock_irq(&die_lock);
+       /* do_exit() should take care of panic'ing from an interrupt
+        * context so we don't handle it here
+        */
+       do_exit(err);
+}
+
+void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
+{
+       siginfo_t info;
+
+       if (kernel_mode(regs)) {
+               debugger(regs);
+               die("Exception in kernel mode", regs, signr);
+       }
+       info.si_signo = signr;
+       info.si_errno = 0;
+       info.si_code = code;
+       info.si_addr = (void __user *) addr;
+       force_sig_info(signr, &info, current);
+}
+
+asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
+                                                       int fsr, int addr)
+{
+#if 0
+       printk(KERN_WARNING "Exception %02x in %s mode, FSR=%08x PC=%08x ESR=%08x\n",
+                       type, user_mode(regs) ? "user" : "kernel", fsr,
+                       (unsigned int) regs->pc, (unsigned int) regs->esr);
+#endif
+
+       switch (type & 0x1F) {
+       case MICROBLAZE_ILL_OPCODE_EXCEPTION:
+               _exception(SIGILL, regs, ILL_ILLOPC, addr);
+               break;
+       case MICROBLAZE_IBUS_EXCEPTION:
+               if (user_mode(regs)) {
+                       printk(KERN_WARNING "Instruction bus error exception in user mode.\n");
+                       _exception(SIGBUS, regs, BUS_ADRERR, addr);
+                       return;
+               }
+               printk(KERN_WARNING "Instruction bus error exception in kernel mode.\n");
+               die("bus exception", regs, SIGBUS);
+               break;
+       case MICROBLAZE_DBUS_EXCEPTION:
+               if (user_mode(regs)) {
+                       printk(KERN_WARNING "Data bus error exception in user mode.\n");
+                       _exception(SIGBUS, regs, BUS_ADRERR, addr);
+                       return;
+               }
+               printk(KERN_WARNING "Data bus error exception in kernel mode.\n");
+               die("bus exception", regs, SIGBUS);
+               break;
+       case MICROBLAZE_DIV_ZERO_EXCEPTION:
+               printk(KERN_WARNING "Divide by zero exception\n");
+               _exception(SIGILL, regs, ILL_ILLOPC, addr);
+               break;
+
+       case MICROBLAZE_FPU_EXCEPTION:
+               /* IEEE FP exception */
+               /* I removed fsr variable and use code var for storing fsr */
+               if (fsr & FSR_IO)
+                       fsr = FPE_FLTINV;
+               else if (fsr & FSR_OF)
+                       fsr = FPE_FLTOVF;
+               else if (fsr & FSR_UF)
+                       fsr = FPE_FLTUND;
+               else if (fsr & FSR_DZ)
+                       fsr = FPE_FLTDIV;
+               else if (fsr & FSR_DO)
+                       fsr = FPE_FLTRES;
+               _exception(SIGFPE, regs, fsr, addr);
+               break;
+
+       default:
+               printk(KERN_WARNING "Unexpected exception %02x "
+                       "PC=%08x in %s mode\n", type, (unsigned int) addr,
+                       kernel_mode(regs) ? "kernel" : "user");
+       }
+       return;
+}
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S
new file mode 100644 (file)
index 0000000..319dc35
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/page.h>
+
+       .text
+ENTRY(_start)
+       mfs     r1, rmsr
+       andi    r1, r1, ~2
+       mts     rmsr, r1
+
+/* save fdt to kernel location */
+/* r7 stores pointer to fdt blob */
+       beqi    r7, no_fdt_arg
+       or      r11, r0, r0 /* incremment */
+       ori     r4, r0, TOPHYS(_fdt_start) /* save bram context */
+       ori     r3, r0, (0x4000 - 4)
+_copy_fdt:
+       lw      r12, r7, r11 /* r12 = r7 + r11 */
+       sw      r12, r4, r11 /* addr[r4 + r11] = r12 */
+       addik   r11, r11, 4 /* increment counting */
+       bgtid   r3, _copy_fdt /* loop for all entries */
+       addik   r3, r3, -4 /* descrement loop */
+no_fdt_arg:
+
+       /* Initialize small data anchors */
+       la      r13, r0, _KERNEL_SDA_BASE_
+       la      r2, r0, _KERNEL_SDA2_BASE_
+
+       /* Initialize stack pointer */
+       la      r1, r0, init_thread_union + THREAD_SIZE - 4
+
+       /* Initialize r31 with current task address */
+       la      r31, r0, init_task
+
+       /*
+        * Call platform dependent initialize function.
+        * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for
+        * the function.
+        */
+       la      r8, r0, machine_early_init
+       brald   r15, r8
+       nop
+
+       la      r15, r0, machine_halt
+       braid   start_kernel
+       nop
diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c
new file mode 100644 (file)
index 0000000..1bdf202
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/sched.h>
+#include <linux/io.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/prom.h>
+
+static unsigned int base_addr;
+
+void heartbeat(void)
+{
+       static unsigned int cnt, period, dist;
+
+       if (base_addr) {
+               if (cnt == 0 || cnt == dist)
+                       out_be32(base_addr, 1);
+               else if (cnt == 7 || cnt == dist + 7)
+                       out_be32(base_addr, 0);
+
+               if (++cnt > period) {
+                       cnt = 0;
+                       /*
+                        * The hyperbolic function below modifies the heartbeat
+                        * period length in dependency of the current (5min)
+                        * load. It goes through the points f(0)=126, f(1)=86,
+                        * f(5)=51, f(inf)->30.
+                        */
+                       period = ((672 << FSHIFT) / (5 * avenrun[0] +
+                                               (7 << FSHIFT))) + 30;
+                       dist = period / 4;
+               }
+       }
+}
+
+void setup_heartbeat(void)
+{
+       struct device_node *gpio = NULL;
+       int j;
+       char *gpio_list[] = {
+                               "xlnx,xps-gpio-1.00.a",
+                               "xlnx,opb-gpio-1.00.a",
+                               NULL
+                       };
+
+       for (j = 0; gpio_list[j] != NULL; j++) {
+               gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]);
+               if (gpio)
+                       break;
+       }
+
+       base_addr = *(int *) of_get_property(gpio, "reg", NULL);
+       base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
+       printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
+
+       if (*(int *) of_get_property(gpio, "xlnx,is-bidir", NULL))
+               out_be32(base_addr + 4, 0); /* GPIO is configured as output */
+}
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
new file mode 100644 (file)
index 0000000..cf9486d
--- /dev/null
@@ -0,0 +1,458 @@
+/*
+ * Exception handling for Microblaze
+ *
+ * Rewriten interrupt handling
+ *
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ *
+ * uClinux customisation (C) 2005 John Williams
+ *
+ * MMU code derived from arch/ppc/kernel/head_4xx.S:
+ *     Copyright (C) 1995-1996 Gary Thomas <gdt@linuxppc.org>
+ *             Initial PowerPC version.
+ *     Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ *             Rewritten for PReP
+ *     Copyright (C) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ *             Low-level exception handers, MMU support, and rewrite.
+ *     Copyright (C) 1997 Dan Malek <dmalek@jlc.net>
+ *             PowerPC 8xx modifications.
+ *     Copyright (C) 1998-1999 TiVo, Inc.
+ *             PowerPC 403GCX modifications.
+ *     Copyright (C) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *             PowerPC 403GCX/405GP modifications.
+ *     Copyright 2000 MontaVista Software Inc.
+ *             PPC405 modifications
+ *     PowerPC 403GCX/405GP modifications.
+ *             Author: MontaVista Software, Inc.
+ *             frank_rowand@mvista.com or source@mvista.com
+ *             debbie_chu@mvista.com
+ *
+ * Original code
+ * Copyright (C) 2004 Xilinx, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+/*
+ * Here are the handlers which don't require enabling translation
+ * and calling other kernel code thus we can keep their design very simple
+ * and do all processing in real mode. All what they need is a valid current
+ * (that is an issue for the CONFIG_REGISTER_TASK_PTR case)
+ * This handlers use r3,r4,r5,r6 and optionally r[current] to work therefore
+ * these registers are saved/restored
+ * The handlers which require translation are in entry.S --KAA
+ *
+ * Microblaze HW Exception Handler
+ * - Non self-modifying exception handler for the following exception conditions
+ *   - Unalignment
+ *   - Instruction bus error
+ *   - Data bus error
+ *   - Illegal instruction opcode
+ *   - Divide-by-zero
+ *
+ * Note we disable interrupts during exception handling, otherwise we will
+ * possibly get multiple re-entrancy if interrupt handles themselves cause
+ * exceptions. JW
+ */
+
+#include <asm/exceptions.h>
+#include <asm/unistd.h>
+#include <asm/page.h>
+
+#include <asm/entry.h>
+#include <asm/current.h>
+#include <linux/linkage.h>
+
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/asm-offsets.h>
+
+/* Helpful Macros */
+#define EX_HANDLER_STACK_SIZ   (4*19)
+#define NUM_TO_REG(num)                r ## num
+
+#define LWREG_NOP                      \
+       bri     ex_handler_unhandled;   \
+       nop;
+
+#define SWREG_NOP                      \
+       bri     ex_handler_unhandled;   \
+       nop;
+
+/* FIXME this is weird - for noMMU kernel is not possible to use brid
+ * instruction which can shorten executed time
+ */
+
+/* r3 is the source */
+#define R3_TO_LWREG_V(regnum)                          \
+       swi     r3, r1, 4 * regnum;                             \
+       bri     ex_handler_done;
+
+/* r3 is the source */
+#define R3_TO_LWREG(regnum)                            \
+       or      NUM_TO_REG (regnum), r0, r3;            \
+       bri     ex_handler_done;
+
+/* r3 is the target */
+#define SWREG_TO_R3_V(regnum)                          \
+       lwi     r3, r1, 4 * regnum;                             \
+       bri     ex_sw_tail;
+
+/* r3 is the target */
+#define SWREG_TO_R3(regnum)                            \
+       or      r3, r0, NUM_TO_REG (regnum);            \
+       bri     ex_sw_tail;
+
+.extern other_exception_handler /* Defined in exception.c */
+
+/*
+ * hw_exception_handler - Handler for exceptions
+ *
+ * Exception handler notes:
+ * - Handles all exceptions
+ * - Does not handle unaligned exceptions during load into r17, r1, r0.
+ * - Does not handle unaligned exceptions during store from r17 (cannot be
+ *   done) and r1 (slows down common case)
+ *
+ *  Relevant register structures
+ *
+ *  EAR - |----|----|----|----|----|----|----|----|
+ *      - <  ##   32 bit faulting address     ##  >
+ *
+ *  ESR - |----|----|----|----|----| - | - |-----|-----|
+ *      -                            W   S   REG   EXC
+ *
+ *
+ * STACK FRAME STRUCTURE (for NO_MMU)
+ * ---------------------------------
+ *
+ *      +-------------+         + 0
+ *      |     MSR     |
+ *      +-------------+         + 4
+ *      |     r1      |
+ *      |      .      |
+ *      |      .      |
+ *      |      .      |
+ *      |      .      |
+ *      |     r18     |
+ *      +-------------+         + 76
+ *      |      .      |
+ *      |      .      |
+ *
+ * NO_MMU kernel use the same r0_ram pointed space - look to vmlinux.lds.S
+ * which is used for storing register values - old style was, that value were
+ * stored in stack but in case of failure you lost information about register.
+ * Currently you can see register value in memory in specific place.
+ * In compare to with previous solution the speed should be the same.
+ *
+ * MMU exception handler has different handling compare to no MMU kernel.
+ * Exception handler use jump table for directing of what happen. For MMU kernel
+ * is this approach better because MMU relate exception are handled by asm code
+ * in this file. In compare to with MMU expect of unaligned exception
+ * is everything handled by C code.
+ */
+
+/*
+ * every of these handlers is entered having R3/4/5/6/11/current saved on stack
+ * and clobbered so care should be taken to restore them if someone is going to
+ * return from exception
+ */
+
+/* wrappers to restore state before coming to entry.S */
+
+.global _hw_exception_handler
+.section .text
+.align 4
+.ent _hw_exception_handler
+_hw_exception_handler:
+       addik   r1, r1, -(EX_HANDLER_STACK_SIZ); /* Create stack frame */
+       swi     r3, r1, PT_R3
+       swi     r4, r1, PT_R4
+       swi     r5, r1, PT_R5
+       swi     r6, r1, PT_R6
+
+       mfs     r5, rmsr;
+       nop
+       swi     r5, r1, 0;
+       mfs     r4, rbtr        /* Save BTR before jumping to handler */
+       nop
+       mfs     r3, resr
+       nop
+
+       andi    r5, r3, 0x1000;         /* Check ESR[DS] */
+       beqi    r5, not_in_delay_slot;  /* Branch if ESR[DS] not set */
+       mfs     r17, rbtr;      /* ESR[DS] set - return address in BTR */
+       nop
+not_in_delay_slot:
+       swi     r17, r1, PT_R17
+
+       andi    r5, r3, 0x1F;           /* Extract ESR[EXC] */
+
+       /* Exceptions enabled here. This will allow nested exceptions */
+       mfs     r6, rmsr;
+       nop
+       swi     r6, r1, 0; /* RMSR_OFFSET */
+       ori     r6, r6, 0x100; /* Turn ON the EE bit */
+       andi    r6, r6, ~2; /* Disable interrupts */
+       mts     rmsr, r6;
+       nop
+
+       xori    r6, r5, 1; /* 00001 = Unaligned Exception */
+       /* Jump to unalignment exception handler */
+       beqi    r6, handle_unaligned_ex;
+
+handle_other_ex: /* Handle Other exceptions here */
+       /* Save other volatiles before we make procedure calls below */
+       swi     r7, r1, PT_R7
+       swi     r8, r1, PT_R8
+       swi     r9, r1, PT_R9
+       swi     r10, r1, PT_R10
+       swi     r11, r1, PT_R11
+       swi     r12, r1, PT_R12
+       swi     r14, r1, PT_R14
+       swi     r15, r1, PT_R15
+       swi     r18, r1, PT_R18
+
+       or      r5, r1, r0
+       andi    r6, r3, 0x1F; /* Load ESR[EC] */
+       lwi     r7, r0, PER_CPU(KM) /* MS: saving current kernel mode to regs */
+       swi     r7, r1, PT_MODE
+       mfs     r7, rfsr
+       nop
+       addk    r8, r17, r0; /* Load exception address */
+       bralid  r15, full_exception; /* Branch to the handler */
+       nop;
+
+       /*
+        * Trigger execution of the signal handler by enabling
+        * interrupts and calling an invalid syscall.
+        */
+       mfs     r5, rmsr;
+       nop
+       ori     r5, r5, 2;
+       mts     rmsr, r5; /* enable interrupt */
+       nop
+       addi    r12, r0, __NR_syscalls;
+       brki    r14, 0x08;
+       mfs     r5, rmsr; /* disable interrupt */
+       nop
+       andi    r5, r5, ~2;
+       mts     rmsr, r5;
+       nop
+
+       lwi     r7, r1, PT_R7
+       lwi     r8, r1, PT_R8
+       lwi     r9, r1, PT_R9
+       lwi     r10, r1, PT_R10
+       lwi     r11, r1, PT_R11
+       lwi     r12, r1, PT_R12
+       lwi     r14, r1, PT_R14
+       lwi     r15, r1, PT_R15
+       lwi     r18, r1, PT_R18
+
+       bri     ex_handler_done; /* Complete exception handling */
+
+/* 0x01 - Unaligned data access exception
+ * This occurs when a word access is not aligned on a word boundary,
+ * or when a 16-bit access is not aligned on a 16-bit boundary.
+ * This handler perform the access, and returns, except for MMU when
+ * the unaligned address is last on a 4k page or the physical address is
+ * not found in the page table, in which case unaligned_data_trap is called.
+ */
+handle_unaligned_ex:
+       /* Working registers already saved: R3, R4, R5, R6
+        *  R3 = ESR
+        *  R4 = BTR
+        */
+       mfs     r4, rear;
+       nop
+
+       andi    r6, r3, 0x3E0; /* Mask and extract the register operand */
+       srl     r6, r6; /* r6 >> 5 */
+       srl     r6, r6;
+       srl     r6, r6;
+       srl     r6, r6;
+       srl     r6, r6;
+       /* Store the register operand in a temporary location */
+       sbi     r6, r0, TOPHYS(ex_reg_op);
+
+       andi    r6, r3, 0x400; /* Extract ESR[S] */
+       bnei    r6, ex_sw;
+ex_lw:
+       andi    r6, r3, 0x800; /* Extract ESR[W] */
+       beqi    r6, ex_lhw;
+       lbui    r5, r4, 0; /* Exception address in r4 */
+       /* Load a word, byte-by-byte from destination address
+               and save it in tmp space */
+       sbi     r5, r0, TOPHYS(ex_tmp_data_loc_0);
+       lbui    r5, r4, 1;
+       sbi     r5, r0, TOPHYS(ex_tmp_data_loc_1);
+       lbui    r5, r4, 2;
+       sbi     r5, r0, TOPHYS(ex_tmp_data_loc_2);
+       lbui    r5, r4, 3;
+       sbi     r5, r0, TOPHYS(ex_tmp_data_loc_3);
+       /* Get the destination register value into r3 */
+       lwi     r3, r0, TOPHYS(ex_tmp_data_loc_0);
+       bri     ex_lw_tail;
+ex_lhw:
+       lbui    r5, r4, 0; /* Exception address in r4 */
+       /* Load a half-word, byte-by-byte from destination
+               address and save it in tmp space */
+       sbi     r5, r0, TOPHYS(ex_tmp_data_loc_0);
+       lbui    r5, r4, 1;
+       sbi     r5, r0, TOPHYS(ex_tmp_data_loc_1);
+       /* Get the destination register value into r3 */
+       lhui    r3, r0, TOPHYS(ex_tmp_data_loc_0);
+ex_lw_tail:
+       /* Get the destination register number into r5 */
+       lbui    r5, r0, TOPHYS(ex_reg_op);
+       /* Form load_word jump table offset (lw_table + (8 * regnum)) */
+       la      r6, r0, TOPHYS(lw_table);
+       addk    r5, r5, r5;
+       addk    r5, r5, r5;
+       addk    r5, r5, r5;
+       addk    r5, r5, r6;
+       bra     r5;
+ex_lw_end: /* Exception handling of load word, ends */
+ex_sw:
+       /* Get the destination register number into r5 */
+       lbui    r5, r0, TOPHYS(ex_reg_op);
+       /* Form store_word jump table offset (sw_table + (8 * regnum)) */
+       la      r6, r0, TOPHYS(sw_table);
+       add     r5, r5, r5;
+       add     r5, r5, r5;
+       add     r5, r5, r5;
+       add     r5, r5, r6;
+       bra     r5;
+ex_sw_tail:
+       mfs     r6, resr;
+       nop
+       andi    r6, r6, 0x800; /* Extract ESR[W] */
+       beqi    r6, ex_shw;
+       /* Get the word - delay slot */
+       swi     r3, r0, TOPHYS(ex_tmp_data_loc_0);
+       /* Store the word, byte-by-byte into destination address */
+       lbui    r3, r0, TOPHYS(ex_tmp_data_loc_0);
+       sbi     r3, r4, 0;
+       lbui    r3, r0, TOPHYS(ex_tmp_data_loc_1);
+       sbi     r3, r4, 1;
+       lbui    r3, r0, TOPHYS(ex_tmp_data_loc_2);
+       sbi     r3, r4, 2;
+       lbui    r3, r0, TOPHYS(ex_tmp_data_loc_3);
+       sbi     r3, r4, 3;
+       bri     ex_handler_done;
+
+ex_shw:
+       /* Store the lower half-word, byte-by-byte into destination address */
+       swi     r3, r0, TOPHYS(ex_tmp_data_loc_0);
+       lbui    r3, r0, TOPHYS(ex_tmp_data_loc_2);
+       sbi     r3, r4, 0;
+       lbui    r3, r0, TOPHYS(ex_tmp_data_loc_3);
+       sbi     r3, r4, 1;
+ex_sw_end: /* Exception handling of store word, ends. */
+
+ex_handler_done:
+       lwi     r5, r1, 0 /* RMSR */
+       mts     rmsr, r5
+       nop
+       lwi     r3, r1, PT_R3
+       lwi     r4, r1, PT_R4
+       lwi     r5, r1, PT_R5
+       lwi     r6, r1, PT_R6
+       lwi     r17, r1, PT_R17
+
+       rted    r17, 0
+       addik   r1, r1, (EX_HANDLER_STACK_SIZ); /* Restore stack frame */
+
+.end _hw_exception_handler
+
+ex_handler_unhandled:
+/* FIXME add handle function for unhandled exception - dump register */
+       bri 0
+
+.section .text
+.align 4
+lw_table:
+lw_r0:         R3_TO_LWREG     (0);
+lw_r1:         LWREG_NOP;
+lw_r2:         R3_TO_LWREG     (2);
+lw_r3:         R3_TO_LWREG_V   (3);
+lw_r4:         R3_TO_LWREG_V   (4);
+lw_r5:         R3_TO_LWREG_V   (5);
+lw_r6:         R3_TO_LWREG_V   (6);
+lw_r7:         R3_TO_LWREG     (7);
+lw_r8:         R3_TO_LWREG     (8);
+lw_r9:         R3_TO_LWREG     (9);
+lw_r10:                R3_TO_LWREG     (10);
+lw_r11:                R3_TO_LWREG     (11);
+lw_r12:                R3_TO_LWREG     (12);
+lw_r13:                R3_TO_LWREG     (13);
+lw_r14:                R3_TO_LWREG     (14);
+lw_r15:                R3_TO_LWREG     (15);
+lw_r16:                R3_TO_LWREG     (16);
+lw_r17:                LWREG_NOP;
+lw_r18:                R3_TO_LWREG     (18);
+lw_r19:                R3_TO_LWREG     (19);
+lw_r20:                R3_TO_LWREG     (20);
+lw_r21:                R3_TO_LWREG     (21);
+lw_r22:                R3_TO_LWREG     (22);
+lw_r23:                R3_TO_LWREG     (23);
+lw_r24:                R3_TO_LWREG     (24);
+lw_r25:                R3_TO_LWREG     (25);
+lw_r26:                R3_TO_LWREG     (26);
+lw_r27:                R3_TO_LWREG     (27);
+lw_r28:                R3_TO_LWREG     (28);
+lw_r29:                R3_TO_LWREG     (29);
+lw_r30:                R3_TO_LWREG     (30);
+lw_r31:                R3_TO_LWREG     (31);
+
+sw_table:
+sw_r0:         SWREG_TO_R3     (0);
+sw_r1:         SWREG_NOP;
+sw_r2:         SWREG_TO_R3     (2);
+sw_r3:         SWREG_TO_R3_V   (3);
+sw_r4:         SWREG_TO_R3_V   (4);
+sw_r5:         SWREG_TO_R3_V   (5);
+sw_r6:         SWREG_TO_R3_V   (6);
+sw_r7:         SWREG_TO_R3     (7);
+sw_r8:         SWREG_TO_R3     (8);
+sw_r9:         SWREG_TO_R3     (9);
+sw_r10:                SWREG_TO_R3     (10);
+sw_r11:                SWREG_TO_R3     (11);
+sw_r12:                SWREG_TO_R3     (12);
+sw_r13:                SWREG_TO_R3     (13);
+sw_r14:                SWREG_TO_R3     (14);
+sw_r15:                SWREG_TO_R3     (15);
+sw_r16:                SWREG_TO_R3     (16);
+sw_r17:                SWREG_NOP;
+sw_r18:                SWREG_TO_R3     (18);
+sw_r19:                SWREG_TO_R3     (19);
+sw_r20:                SWREG_TO_R3     (20);
+sw_r21:                SWREG_TO_R3     (21);
+sw_r22:                SWREG_TO_R3     (22);
+sw_r23:                SWREG_TO_R3     (23);
+sw_r24:                SWREG_TO_R3     (24);
+sw_r25:                SWREG_TO_R3     (25);
+sw_r26:                SWREG_TO_R3     (26);
+sw_r27:                SWREG_TO_R3     (27);
+sw_r28:                SWREG_TO_R3     (28);
+sw_r29:                SWREG_TO_R3     (29);
+sw_r30:                SWREG_TO_R3     (30);
+sw_r31:                SWREG_TO_R3     (31);
+
+/* Temporary data structures used in the handler */
+.section .data
+.align 4
+ex_tmp_data_loc_0:
+       .byte 0
+ex_tmp_data_loc_1:
+       .byte 0
+ex_tmp_data_loc_2:
+       .byte 0
+ex_tmp_data_loc_3:
+       .byte 0
+ex_reg_op:
+       .byte 0
diff --git a/arch/microblaze/kernel/init_task.c b/arch/microblaze/kernel/init_task.c
new file mode 100644 (file)
index 0000000..48eb9fb
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/sched.h>
+#include <linux/init_task.h>
+#include <linux/fs.h>
+#include <linux/mqueue.h>
+
+#include <asm/pgtable.h>
+
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+struct mm_struct init_mm = INIT_MM(init_mm);
+EXPORT_SYMBOL(init_mm);
+
+union thread_union init_thread_union
+       __attribute__((__section__(".data.init_task"))) =
+{ INIT_THREAD_INFO(init_task) };
+
+struct task_struct init_task = INIT_TASK(init_task);
+EXPORT_SYMBOL(init_task);
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
new file mode 100644 (file)
index 0000000..a69d3e3
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/init.h>
+#include <linux/irq.h>
+#include <asm/page.h>
+#include <linux/io.h>
+
+#include <asm/prom.h>
+#include <asm/irq.h>
+
+#ifdef CONFIG_SELFMOD_INTC
+#include <asm/selfmod.h>
+#define INTC_BASE      BARRIER_BASE_ADDR
+#else
+static unsigned int intc_baseaddr;
+#define INTC_BASE      intc_baseaddr
+#endif
+
+unsigned int nr_irq;
+
+/* No one else should require these constants, so define them locally here. */
+#define ISR 0x00                       /* Interrupt Status Register */
+#define IPR 0x04                       /* Interrupt Pending Register */
+#define IER 0x08                       /* Interrupt Enable Register */
+#define IAR 0x0c                       /* Interrupt Acknowledge Register */
+#define SIE 0x10                       /* Set Interrupt Enable bits */
+#define CIE 0x14                       /* Clear Interrupt Enable bits */
+#define IVR 0x18                       /* Interrupt Vector Register */
+#define MER 0x1c                       /* Master Enable Register */
+
+#define MER_ME (1<<0)
+#define MER_HIE (1<<1)
+
+static void intc_enable_or_unmask(unsigned int irq)
+{
+       pr_debug("enable_or_unmask: %d\n", irq);
+       out_be32(INTC_BASE + SIE, 1 << irq);
+}
+
+static void intc_disable_or_mask(unsigned int irq)
+{
+       pr_debug("disable: %d\n", irq);
+       out_be32(INTC_BASE + CIE, 1 << irq);
+}
+
+static void intc_ack(unsigned int irq)
+{
+       pr_debug("ack: %d\n", irq);
+       out_be32(INTC_BASE + IAR, 1 << irq);
+}
+
+static void intc_mask_ack(unsigned int irq)
+{
+       unsigned long mask = 1 << irq;
+       pr_debug("disable_and_ack: %d\n", irq);
+       out_be32(INTC_BASE + CIE, mask);
+       out_be32(INTC_BASE + IAR, mask);
+}
+
+static void intc_end(unsigned int irq)
+{
+       unsigned long mask = 1 << irq;
+       pr_debug("end: %d\n", irq);
+       if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+               out_be32(INTC_BASE + SIE, mask);
+               /* ack level sensitive intr */
+               if (irq_desc[irq].status & IRQ_LEVEL)
+                       out_be32(INTC_BASE + IAR, mask);
+       }
+}
+
+static struct irq_chip intc_dev = {
+       .name = "Xilinx INTC",
+       .unmask = intc_enable_or_unmask,
+       .mask = intc_disable_or_mask,
+       .ack = intc_ack,
+       .mask_ack = intc_mask_ack,
+       .end = intc_end,
+};
+
+unsigned int get_irq(struct pt_regs *regs)
+{
+       int irq;
+
+       /*
+        * NOTE: This function is the one that needs to be improved in
+        * order to handle multiple interrupt controllers. It currently
+        * is hardcoded to check for interrupts only on the first INTC.
+        */
+       irq = in_be32(INTC_BASE + IVR);
+       pr_debug("get_irq: %d\n", irq);
+
+       return irq;
+}
+
+void __init init_IRQ(void)
+{
+       u32 i, j, intr_type;
+       struct device_node *intc = NULL;
+#ifdef CONFIG_SELFMOD_INTC
+       unsigned int intc_baseaddr = 0;
+       static int arr_func[] = {
+                               (int)&get_irq,
+                               (int)&intc_enable_or_unmask,
+                               (int)&intc_disable_or_mask,
+                               (int)&intc_mask_ack,
+                               (int)&intc_ack,
+                               (int)&intc_end,
+                               0
+                       };
+#endif
+       static char *intc_list[] = {
+                               "xlnx,xps-intc-1.00.a",
+                               "xlnx,opb-intc-1.00.c",
+                               "xlnx,opb-intc-1.00.b",
+                               "xlnx,opb-intc-1.00.a",
+                               NULL
+                       };
+
+       for (j = 0; intc_list[j] != NULL; j++) {
+               intc = of_find_compatible_node(NULL, NULL, intc_list[j]);
+               if (intc)
+                       break;
+       }
+
+       intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL);
+       intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
+       nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL);
+
+       intr_type =
+               *(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL);
+       if (intr_type >= (1 << nr_irq))
+               printk(KERN_INFO " ERROR: Mishmash in king-of-intr param\n");
+
+#ifdef CONFIG_SELFMOD_INTC
+       selfmod_function((int *) arr_func, intc_baseaddr);
+#endif
+       printk(KERN_INFO "%s #0 at 0x%08x, num_irq=%d, edge=0x%x\n",
+               intc_list[j], intc_baseaddr, nr_irq, intr_type);
+
+       /*
+        * Disable all external interrupts until they are
+        * explicity requested.
+        */
+       out_be32(intc_baseaddr + IER, 0);
+
+       /* Acknowledge any pending interrupts just in case. */
+       out_be32(intc_baseaddr + IAR, 0xffffffff);
+
+       /* Turn on the Master Enable. */
+       out_be32(intc_baseaddr + MER, MER_HIE | MER_ME);
+
+       for (i = 0; i < nr_irq; ++i) {
+               if (intr_type & (0x00000001 << i)) {
+                       set_irq_chip_and_handler_name(i, &intc_dev,
+                               handle_edge_irq, intc_dev.name);
+                       irq_desc[i].status &= ~IRQ_LEVEL;
+               } else {
+                       set_irq_chip_and_handler_name(i, &intc_dev,
+                               handle_level_irq, intc_dev.name);
+                       irq_desc[i].status |= IRQ_LEVEL;
+               }
+       }
+}
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
new file mode 100644 (file)
index 0000000..f688ee9
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/hardirq.h>
+#include <linux/interrupt.h>
+#include <linux/irqflags.h>
+#include <linux/seq_file.h>
+#include <linux/kernel_stat.h>
+#include <linux/irq.h>
+
+#include <asm/prom.h>
+
+unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
+{
+       struct of_irq oirq;
+
+       if (of_irq_map_one(dev, index, &oirq))
+               return NO_IRQ;
+
+       return oirq.specifier[0];
+}
+EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
+
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves.
+ */
+void ack_bad_irq(unsigned int irq)
+{
+       printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", irq);
+}
+
+static u32 concurrent_irq;
+
+void do_IRQ(struct pt_regs *regs)
+{
+       unsigned int irq;
+       struct pt_regs *old_regs = set_irq_regs(regs);
+
+       irq_enter();
+       irq = get_irq(regs);
+next_irq:
+       BUG_ON(irq == -1U);
+       generic_handle_irq(irq);
+
+       irq = get_irq(regs);
+       if (irq != -1U) {
+               pr_debug("next irq: %d\n", irq);
+               ++concurrent_irq;
+               goto next_irq;
+       }
+
+       irq_exit();
+       set_irq_regs(old_regs);
+}
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+       int i = *(loff_t *) v, j;
+       struct irqaction *action;
+       unsigned long flags;
+
+       if (i == 0) {
+               seq_printf(p, "         ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "CPU%-8d", j);
+               seq_putc(p, '\n');
+       }
+
+       if (i < nr_irq) {
+               spin_lock_irqsave(&irq_desc[i].lock, flags);
+               action = irq_desc[i].action;
+               if (!action)
+                       goto skip;
+               seq_printf(p, "%3d: ", i);
+#ifndef CONFIG_SMP
+               seq_printf(p, "%10u ", kstat_irqs(i));
+#else
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+#endif
+               seq_printf(p, " %8s", irq_desc[i].status &
+                                       IRQ_LEVEL ? "level" : "edge");
+               seq_printf(p, " %8s", irq_desc[i].chip->name);
+               seq_printf(p, "  %s", action->name);
+
+               for (action = action->next; action; action = action->next)
+                       seq_printf(p, ", %s", action->name);
+
+               seq_putc(p, '\n');
+skip:
+               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+       }
+       return 0;
+}
diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c
new file mode 100644 (file)
index 0000000..5f71790
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/cryptohash.h>
+#include <linux/delay.h>
+#include <linux/in6.h>
+#include <linux/syscalls.h>
+
+#include <asm/checksum.h>
+#include <linux/io.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <linux/uaccess.h>
+
+/*
+ * 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 __ashldi3(void);
+EXPORT_SYMBOL(__ashldi3);
+extern void __ashrdi3(void);
+EXPORT_SYMBOL(__ashrdi3);
+extern void __divsi3(void);
+EXPORT_SYMBOL(__divsi3);
+extern void __lshrdi3(void);
+EXPORT_SYMBOL(__lshrdi3);
+extern void __modsi3(void);
+EXPORT_SYMBOL(__modsi3);
+extern void __mulsi3(void);
+EXPORT_SYMBOL(__mulsi3);
+extern void __muldi3(void);
+EXPORT_SYMBOL(__muldi3);
+extern void __ucmpdi2(void);
+EXPORT_SYMBOL(__ucmpdi2);
+extern void __udivsi3(void);
+EXPORT_SYMBOL(__udivsi3);
+extern void __umodsi3(void);
+EXPORT_SYMBOL(__umodsi3);
diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c
new file mode 100644 (file)
index 0000000..5141417
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleloader.h>
+#include <linux/kernel.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+
+#include <asm/pgtable.h>
+
+void *module_alloc(unsigned long size)
+{
+       void *ret;
+       ret = (size == 0) ? NULL : vmalloc(size);
+       pr_debug("module_alloc (%08lx@%08lx)\n", size, (unsigned long int)ret);
+       return ret;
+}
+
+void module_free(struct module *module, void *region)
+{
+       pr_debug("module_free(%s,%08lx)\n", module->name,
+                                       (unsigned long)region);
+       vfree(region);
+}
+
+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 *module)
+{
+       printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
+               module->name);
+       return -ENOEXEC;
+}
+
+int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
+       unsigned int symindex, unsigned int relsec, struct module *module)
+{
+
+       unsigned int i;
+       Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
+       Elf32_Sym *sym;
+       unsigned long int *location;
+       unsigned long int locoffs;
+       unsigned long int value;
+#if __GNUC__ < 4
+       unsigned long int old_value;
+#endif
+
+       pr_debug("Applying add relocation section %u to %u\n",
+               relsec, sechdrs[relsec].sh_info);
+
+       for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
+
+               location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr +
+                               rela[i].r_offset;
+               sym = (Elf32_Sym *)sechdrs[symindex].sh_addr +
+                       ELF32_R_SYM(rela[i].r_info);
+               value = sym->st_value + rela[i].r_addend;
+
+               switch (ELF32_R_TYPE(rela[i].r_info)) {
+
+               /*
+                * Be careful! mb-gcc / mb-ld splits the relocs between the
+                * text and the reloc table. In general this means we must
+                * read the current contents of (*location), add any offset
+                * then store the result back in
+                */
+
+               case R_MICROBLAZE_32:
+#if __GNUC__ < 4
+                       old_value = *location;
+                       *location = value + old_value;
+
+                       pr_debug("R_MICROBLAZE_32 (%08lx->%08lx)\n",
+                               old_value, value);
+#else
+                       *location = value;
+#endif
+                       break;
+
+               case R_MICROBLAZE_64:
+#if __GNUC__ < 4
+                       /* Split relocs only required/used pre gcc4.1.1 */
+                       old_value = ((location[0] & 0x0000FFFF) << 16) |
+                                       (location[1] & 0x0000FFFF);
+                       value += old_value;
+#endif
+                       location[0] = (location[0] & 0xFFFF0000) |
+                                       (value >> 16);
+                       location[1] = (location[1] & 0xFFFF0000) |
+                                       (value & 0xFFFF);
+#if __GNUC__ < 4
+                       pr_debug("R_MICROBLAZE_64 (%08lx->%08lx)\n",
+                               old_value, value);
+#endif
+                       break;
+
+               case R_MICROBLAZE_64_PCREL:
+                       locoffs = (location[0] & 0xFFFF) << 16 |
+                               (location[1] & 0xFFFF);
+                       value -= (unsigned long int)(location) + 4 +
+                               locoffs;
+                       location[0] = (location[0] & 0xFFFF0000) |
+                                       (value >> 16);
+                       location[1] = (location[1] & 0xFFFF0000) |
+                                       (value & 0xFFFF);
+                       pr_debug("R_MICROBLAZE_64_PCREL (%08lx)\n",
+                               value);
+                       break;
+
+               case R_MICROBLAZE_NONE:
+                       pr_debug("R_MICROBLAZE_NONE\n");
+                       break;
+
+               default:
+                       printk(KERN_ERR "module %s: "
+                               "Unknown relocation: %u\n",
+                               module->name,
+                               ELF32_R_TYPE(rela->r_info));
+                       return -ENOEXEC;
+               }
+       }
+       return 0;
+}
+
+int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
+               struct module *module)
+{
+       return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+}
diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c
new file mode 100644 (file)
index 0000000..717edf4
--- /dev/null
@@ -0,0 +1,115 @@
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+
+#include <linux/errno.h>
+
+void of_device_make_bus_id(struct of_device *dev)
+{
+       static atomic_t bus_no_reg_magic;
+       struct device_node *node = dev->node;
+       char *name = dev->dev.bus_id;
+       const u32 *reg;
+       u64 addr;
+       int magic;
+
+       /*
+        * For MMIO, get the physical address
+        */
+       reg = of_get_property(node, "reg", NULL);
+       if (reg) {
+               addr = of_translate_address(node, reg);
+               if (addr != OF_BAD_ADDR) {
+                       snprintf(name, BUS_ID_SIZE,
+                                "%llx.%s", (unsigned long long)addr,
+                                node->name);
+                       return;
+               }
+       }
+
+       /*
+        * No BusID, use the node name and add a globally incremented
+        * counter (and pray...)
+        */
+       magic = atomic_add_return(1, &bus_no_reg_magic);
+       snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1);
+}
+EXPORT_SYMBOL(of_device_make_bus_id);
+
+struct of_device *of_device_alloc(struct device_node *np,
+                                 const char *bus_id,
+                                 struct device *parent)
+{
+       struct of_device *dev;
+
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return NULL;
+
+       dev->node = of_node_get(np);
+       dev->dev.dma_mask = &dev->dma_mask;
+       dev->dev.parent = parent;
+       dev->dev.release = of_release_dev;
+       dev->dev.archdata.of_node = np;
+
+       if (bus_id)
+               strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
+       else
+               of_device_make_bus_id(dev);
+
+       return dev;
+}
+EXPORT_SYMBOL(of_device_alloc);
+
+int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+       struct of_device *ofdev;
+       const char *compat;
+       int seen = 0, cplen, sl;
+
+       if (!dev)
+               return -ENODEV;
+
+       ofdev = to_of_device(dev);
+
+       if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name))
+               return -ENOMEM;
+
+       if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type))
+               return -ENOMEM;
+
+       /* Since the compatible field can contain pretty much anything
+        * it's not really legal to split it out with commas. We split it
+        * up using a number of environment variables instead. */
+
+       compat = of_get_property(ofdev->node, "compatible", &cplen);
+       while (compat && *compat && cplen > 0) {
+               if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
+                       return -ENOMEM;
+
+               sl = strlen(compat) + 1;
+               compat += sl;
+               cplen -= sl;
+               seen++;
+       }
+
+       if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
+               return -ENOMEM;
+
+       /* modalias is trickier, we add it in 2 steps */
+       if (add_uevent_var(env, "MODALIAS="))
+               return -ENOMEM;
+       sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
+                                   sizeof(env->buf) - env->buflen);
+       if (sl >= (sizeof(env->buf) - env->buflen))
+               return -ENOMEM;
+       env->buflen += sl;
+
+       return 0;
+}
+EXPORT_SYMBOL(of_device_uevent);
diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c
new file mode 100644 (file)
index 0000000..acf4574
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ *    Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
+ *                      <benh@kernel.crashing.org>
+ *    and               Arnd Bergmann, IBM Corp.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+
+#include <linux/errno.h>
+#include <linux/topology.h>
+#include <asm/atomic.h>
+
+struct bus_type of_platform_bus_type = {
+       .uevent = of_device_uevent,
+};
+EXPORT_SYMBOL(of_platform_bus_type);
+
+static int __init of_bus_driver_init(void)
+{
+       return of_bus_type_init(&of_platform_bus_type, "of_platform");
+}
+postcore_initcall(of_bus_driver_init);
+
+struct of_device *of_platform_device_create(struct device_node *np,
+                                           const char *bus_id,
+                                           struct device *parent)
+{
+       struct of_device *dev;
+
+       dev = of_device_alloc(np, bus_id, parent);
+       if (!dev)
+               return NULL;
+
+       dev->dma_mask = 0xffffffffUL;
+       dev->dev.bus = &of_platform_bus_type;
+
+       /* We do not fill the DMA ops for platform devices by default.
+        * This is currently the responsibility of the platform code
+        * to do such, possibly using a device notifier
+        */
+
+       if (of_device_register(dev) != 0) {
+               of_device_free(dev);
+               return NULL;
+       }
+
+       return dev;
+}
+EXPORT_SYMBOL(of_platform_device_create);
+
+/**
+ * of_platform_bus_create - Create an OF device for a bus node and all its
+ * children. Optionally recursively instanciate matching busses.
+ * @bus: device node of the bus to instanciate
+ * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
+ * disallow recursive creation of child busses
+ */
+static int of_platform_bus_create(const struct device_node *bus,
+                                 const struct of_device_id *matches,
+                                 struct device *parent)
+{
+       struct device_node *child;
+       struct of_device *dev;
+       int rc = 0;
+
+       for_each_child_of_node(bus, child) {
+               pr_debug("   create child: %s\n", child->full_name);
+               dev = of_platform_device_create(child, NULL, parent);
+               if (dev == NULL)
+                       rc = -ENOMEM;
+               else if (!of_match_node(matches, child))
+                       continue;
+               if (rc == 0) {
+                       pr_debug("   and sub busses\n");
+                       rc = of_platform_bus_create(child, matches, &dev->dev);
+               }
+               if (rc) {
+                       of_node_put(child);
+                       break;
+               }
+       }
+       return rc;
+}
+
+
+/**
+ * of_platform_bus_probe - Probe the device-tree for platform busses
+ * @root: parent of the first level to probe or NULL for the root of the tree
+ * @matches: match table, NULL to use the default
+ * @parent: parent to hook devices from, NULL for toplevel
+ *
+ * Note that children of the provided root are not instanciated as devices
+ * unless the specified root itself matches the bus list and is not NULL.
+ */
+
+int of_platform_bus_probe(struct device_node *root,
+                         const struct of_device_id *matches,
+                         struct device *parent)
+{
+       struct device_node *child;
+       struct of_device *dev;
+       int rc = 0;
+
+       if (matches == NULL)
+               matches = of_default_bus_ids;
+       if (matches == OF_NO_DEEP_PROBE)
+               return -EINVAL;
+       if (root == NULL)
+               root = of_find_node_by_path("/");
+       else
+               of_node_get(root);
+
+       pr_debug("of_platform_bus_probe()\n");
+       pr_debug(" starting at: %s\n", root->full_name);
+
+       /* Do a self check of bus type, if there's a match, create
+        * children
+        */
+       if (of_match_node(matches, root)) {
+               pr_debug(" root match, create all sub devices\n");
+               dev = of_platform_device_create(root, NULL, parent);
+               if (dev == NULL) {
+                       rc = -ENOMEM;
+                       goto bail;
+               }
+               pr_debug(" create all sub busses\n");
+               rc = of_platform_bus_create(root, matches, &dev->dev);
+               goto bail;
+       }
+       for_each_child_of_node(root, child) {
+               if (!of_match_node(matches, child))
+                       continue;
+
+               pr_debug("  match: %s\n", child->full_name);
+               dev = of_platform_device_create(child, NULL, parent);
+               if (dev == NULL)
+                       rc = -ENOMEM;
+               else
+                       rc = of_platform_bus_create(child, matches, &dev->dev);
+               if (rc) {
+                       of_node_put(child);
+                       break;
+               }
+       }
+ bail:
+       of_node_put(root);
+       return rc;
+}
+EXPORT_SYMBOL(of_platform_bus_probe);
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+       return to_of_device(dev)->node == data;
+}
+
+struct of_device *of_find_device_by_node(struct device_node *np)
+{
+       struct device *dev;
+
+       dev = bus_find_device(&of_platform_bus_type,
+                             NULL, np, of_dev_node_match);
+       if (dev)
+               return to_of_device(dev);
+       return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_node);
+
+static int of_dev_phandle_match(struct device *dev, void *data)
+{
+       phandle *ph = data;
+       return to_of_device(dev)->node->linux_phandle == *ph;
+}
+
+struct of_device *of_find_device_by_phandle(phandle ph)
+{
+       struct device *dev;
+
+       dev = bus_find_device(&of_platform_bus_type,
+                             NULL, &ph, of_dev_phandle_match);
+       if (dev)
+               return to_of_device(dev);
+       return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_phandle);
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
new file mode 100644 (file)
index 0000000..60e9ed7
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/sched.h>
+#include <linux/pm.h>
+#include <linux/tick.h>
+#include <linux/bitops.h>
+#include <asm/system.h>
+#include <asm/pgalloc.h>
+
+void show_regs(struct pt_regs *regs)
+{
+       printk(KERN_INFO " Registers dump: mode=%X\r\n", regs->kernel_mode);
+       printk(KERN_INFO " r1=%08lX, r2=%08lX, r3=%08lX, r4=%08lX\n",
+                               regs->r1, regs->r2, regs->r3, regs->r4);
+       printk(KERN_INFO " r5=%08lX, r6=%08lX, r7=%08lX, r8=%08lX\n",
+                               regs->r5, regs->r6, regs->r7, regs->r8);
+       printk(KERN_INFO " r9=%08lX, r10=%08lX, r11=%08lX, r12=%08lX\n",
+                               regs->r9, regs->r10, regs->r11, regs->r12);
+       printk(KERN_INFO " r13=%08lX, r14=%08lX, r15=%08lX, r16=%08lX\n",
+                               regs->r13, regs->r14, regs->r15, regs->r16);
+       printk(KERN_INFO " r17=%08lX, r18=%08lX, r19=%08lX, r20=%08lX\n",
+                               regs->r17, regs->r18, regs->r19, regs->r20);
+       printk(KERN_INFO " r21=%08lX, r22=%08lX, r23=%08lX, r24=%08lX\n",
+                               regs->r21, regs->r22, regs->r23, regs->r24);
+       printk(KERN_INFO " r25=%08lX, r26=%08lX, r27=%08lX, r28=%08lX\n",
+                               regs->r25, regs->r26, regs->r27, regs->r28);
+       printk(KERN_INFO " r29=%08lX, r30=%08lX, r31=%08lX, rPC=%08lX\n",
+                               regs->r29, regs->r30, regs->r31, regs->pc);
+       printk(KERN_INFO " msr=%08lX, ear=%08lX, esr=%08lX, fsr=%08lX\n",
+                               regs->msr, regs->ear, regs->esr, regs->fsr);
+       while (1)
+               ;
+}
+
+void (*pm_idle)(void);
+void (*pm_power_off)(void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
+
+static int hlt_counter = 1;
+
+void disable_hlt(void)
+{
+       hlt_counter++;
+}
+EXPORT_SYMBOL(disable_hlt);
+
+void enable_hlt(void)
+{
+       hlt_counter--;
+}
+EXPORT_SYMBOL(enable_hlt);
+
+static int __init nohlt_setup(char *__unused)
+{
+       hlt_counter = 1;
+       return 1;
+}
+__setup("nohlt", nohlt_setup);
+
+static int __init hlt_setup(char *__unused)
+{
+       hlt_counter = 0;
+       return 1;
+}
+__setup("hlt", hlt_setup);
+
+void default_idle(void)
+{
+       if (!hlt_counter) {
+               clear_thread_flag(TIF_POLLING_NRFLAG);
+               smp_mb__after_clear_bit();
+               local_irq_disable();
+               while (!need_resched())
+                       cpu_sleep();
+               local_irq_enable();
+               set_thread_flag(TIF_POLLING_NRFLAG);
+       } else
+               while (!need_resched())
+                       cpu_relax();
+}
+
+void cpu_idle(void)
+{
+       set_thread_flag(TIF_POLLING_NRFLAG);
+
+       /* endless idle loop with no priority at all */
+       while (1) {
+               void (*idle)(void) = pm_idle;
+
+               if (!idle)
+                       idle = default_idle;
+
+               tick_nohz_stop_sched_tick(1);
+               while (!need_resched())
+                       idle();
+               tick_nohz_restart_sched_tick();
+
+               preempt_enable_no_resched();
+               schedule();
+               preempt_disable();
+               check_pgt_cache();
+       }
+}
+
+void flush_thread(void)
+{
+}
+
+/* FIXME - here will be a proposed change -> remove nr parameter */
+int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+               unsigned long unused,
+               struct task_struct *p, struct pt_regs *regs)
+{
+       struct pt_regs *childregs = task_pt_regs(p);
+       struct thread_info *ti = task_thread_info(p);
+
+       *childregs = *regs;
+       if (user_mode(regs))
+               childregs->r1 = usp;
+       else
+               childregs->r1 = ((unsigned long) ti) + THREAD_SIZE;
+
+       memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
+       ti->cpu_context.r1 = (unsigned long)childregs;
+       ti->cpu_context.msr = (unsigned long)childregs->msr;
+       ti->cpu_context.r15 = (unsigned long)ret_from_fork - 8;
+
+       if (clone_flags & CLONE_SETTLS)
+               ;
+
+       return 0;
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+       struct cpu_context *ctx =
+               &(((struct thread_info *)(tsk->stack))->cpu_context);
+
+       /* Check whether the thread is blocked in resume() */
+       if (in_sched_functions(ctx->r15))
+               return (unsigned long)ctx->r15;
+       else
+               return ctx->r14;
+}
+
+static void kernel_thread_helper(int (*fn)(void *), void *arg)
+{
+       fn(arg);
+       do_exit(-1);
+}
+
+int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+       struct pt_regs regs;
+       int ret;
+
+       memset(&regs, 0, sizeof(regs));
+       /* store them in non-volatile registers */
+       regs.r5 = (unsigned long)fn;
+       regs.r6 = (unsigned long)arg;
+       local_save_flags(regs.msr);
+       regs.pc = (unsigned long)kernel_thread_helper;
+       regs.kernel_mode = 1;
+
+       ret = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+                       &regs, 0, NULL, NULL);
+
+       return ret;
+}
+
+unsigned long get_wchan(struct task_struct *p)
+{
+/* TBD (used by procfs) */
+       return 0;
+}
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
new file mode 100644 (file)
index 0000000..475b1fa
--- /dev/null
@@ -0,0 +1,1147 @@
+/*
+ * Procedures for creating, accessing and interpreting the device tree.
+ *
+ * Paul Mackerras      August 1996.
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
+ *    {engebret|bergner}@us.ibm.com
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/stringify.h>
+#include <linux/delay.h>
+#include <linux/initrd.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/kexec.h>
+#include <linux/debugfs.h>
+#include <linux/irq.h>
+#include <linux/lmb.h>
+
+#include <asm/prom.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <linux/io.h>
+#include <asm/system.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <linux/pci.h>
+#include <asm/sections.h>
+#include <asm/pci-bridge.h>
+
+static int __initdata dt_root_addr_cells;
+static int __initdata dt_root_size_cells;
+
+typedef u32 cell_t;
+
+static struct boot_param_header *initial_boot_params;
+
+/* export that to outside world */
+struct device_node *of_chosen;
+
+static inline char *find_flat_dt_string(u32 offset)
+{
+       return ((char *)initial_boot_params) +
+               initial_boot_params->off_dt_strings + offset;
+}
+
+/**
+ * This function is used to scan the flattened device-tree, it is
+ * used to extract the memory informations at boot before we can
+ * unflatten the tree
+ */
+int __init of_scan_flat_dt(int (*it)(unsigned long node,
+                                    const char *uname, int depth,
+                                    void *data),
+                          void *data)
+{
+       unsigned long p = ((unsigned long)initial_boot_params) +
+               initial_boot_params->off_dt_struct;
+       int rc = 0;
+       int depth = -1;
+
+       do {
+               u32 tag = *((u32 *)p);
+               char *pathp;
+
+               p += 4;
+               if (tag == OF_DT_END_NODE) {
+                       depth--;
+                       continue;
+               }
+               if (tag == OF_DT_NOP)
+                       continue;
+               if (tag == OF_DT_END)
+                       break;
+               if (tag == OF_DT_PROP) {
+                       u32 sz = *((u32 *)p);
+                       p += 8;
+                       if (initial_boot_params->version < 0x10)
+                               p = _ALIGN(p, sz >= 8 ? 8 : 4);
+                       p += sz;
+                       p = _ALIGN(p, 4);
+                       continue;
+               }
+               if (tag != OF_DT_BEGIN_NODE) {
+                       printk(KERN_WARNING "Invalid tag %x scanning flattened"
+                               " device tree !\n", tag);
+                       return -EINVAL;
+               }
+               depth++;
+               pathp = (char *)p;
+               p = _ALIGN(p + strlen(pathp) + 1, 4);
+               if ((*pathp) == '/') {
+                       char *lp, *np;
+                       for (lp = NULL, np = pathp; *np; np++)
+                               if ((*np) == '/')
+                                       lp = np+1;
+                       if (lp != NULL)
+                               pathp = lp;
+               }
+               rc = it(p, pathp, depth, data);
+               if (rc != 0)
+                       break;
+       } while (1);
+
+       return rc;
+}
+
+unsigned long __init of_get_flat_dt_root(void)
+{
+       unsigned long p = ((unsigned long)initial_boot_params) +
+               initial_boot_params->off_dt_struct;
+
+       while (*((u32 *)p) == OF_DT_NOP)
+               p += 4;
+       BUG_ON(*((u32 *)p) != OF_DT_BEGIN_NODE);
+       p += 4;
+       return _ALIGN(p + strlen((char *)p) + 1, 4);
+}
+
+/**
+ * This function can be used within scan_flattened_dt callback to get
+ * access to properties
+ */
+void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
+                               unsigned long *size)
+{
+       unsigned long p = node;
+
+       do {
+               u32 tag = *((u32 *)p);
+               u32 sz, noff;
+               const char *nstr;
+
+               p += 4;
+               if (tag == OF_DT_NOP)
+                       continue;
+               if (tag != OF_DT_PROP)
+                       return NULL;
+
+               sz = *((u32 *)p);
+               noff = *((u32 *)(p + 4));
+               p += 8;
+               if (initial_boot_params->version < 0x10)
+                       p = _ALIGN(p, sz >= 8 ? 8 : 4);
+
+               nstr = find_flat_dt_string(noff);
+               if (nstr == NULL) {
+                       printk(KERN_WARNING "Can't find property index"
+                               " name !\n");
+                       return NULL;
+               }
+               if (strcmp(name, nstr) == 0) {
+                       if (size)
+                               *size = sz;
+                       return (void *)p;
+               }
+               p += sz;
+               p = _ALIGN(p, 4);
+       } while (1);
+}
+
+int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
+{
+       const char *cp;
+       unsigned long cplen, l;
+
+       cp = of_get_flat_dt_prop(node, "compatible", &cplen);
+       if (cp == NULL)
+               return 0;
+       while (cplen > 0) {
+               if (strncasecmp(cp, compat, strlen(compat)) == 0)
+                       return 1;
+               l = strlen(cp) + 1;
+               cp += l;
+               cplen -= l;
+       }
+
+       return 0;
+}
+
+static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
+                                       unsigned long align)
+{
+       void *res;
+
+       *mem = _ALIGN(*mem, align);
+       res = (void *)*mem;
+       *mem += size;
+
+       return res;
+}
+
+static unsigned long __init unflatten_dt_node(unsigned long mem,
+                                       unsigned long *p,
+                                       struct device_node *dad,
+                                       struct device_node ***allnextpp,
+                                       unsigned long fpsize)
+{
+       struct device_node *np;
+       struct property *pp, **prev_pp = NULL;
+       char *pathp;
+       u32 tag;
+       unsigned int l, allocl;
+       int has_name = 0;
+       int new_format = 0;
+
+       tag = *((u32 *)(*p));
+       if (tag != OF_DT_BEGIN_NODE) {
+               printk("Weird tag at start of node: %x\n", tag);
+               return mem;
+       }
+       *p += 4;
+       pathp = (char *)*p;
+       l = allocl = strlen(pathp) + 1;
+       *p = _ALIGN(*p + l, 4);
+
+       /* version 0x10 has a more compact unit name here instead of the full
+        * path. we accumulate the full path size using "fpsize", we'll rebuild
+        * it later. We detect this because the first character of the name is
+        * not '/'.
+        */
+       if ((*pathp) != '/') {
+               new_format = 1;
+               if (fpsize == 0) {
+                       /* root node: special case. fpsize accounts for path
+                        * plus terminating zero. root node only has '/', so
+                        * fpsize should be 2, but we want to avoid the first
+                        * level nodes to have two '/' so we use fpsize 1 here
+                        */
+                       fpsize = 1;
+                       allocl = 2;
+               } else {
+                       /* account for '/' and path size minus terminal 0
+                        * already in 'l'
+                        */
+                       fpsize += l;
+                       allocl = fpsize;
+               }
+       }
+
+       np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
+                               __alignof__(struct device_node));
+       if (allnextpp) {
+               memset(np, 0, sizeof(*np));
+               np->full_name = ((char *)np) + sizeof(struct device_node);
+               if (new_format) {
+                       char *p2 = np->full_name;
+                       /* rebuild full path for new format */
+                       if (dad && dad->parent) {
+                               strcpy(p2, dad->full_name);
+#ifdef DEBUG
+                               if ((strlen(p2) + l + 1) != allocl) {
+                                       pr_debug("%s: p: %d, l: %d, a: %d\n",
+                                               pathp, (int)strlen(p2),
+                                               l, allocl);
+                               }
+#endif
+                               p2 += strlen(p2);
+                       }
+                       *(p2++) = '/';
+                       memcpy(p2, pathp, l);
+               } else
+                       memcpy(np->full_name, pathp, l);
+               prev_pp = &np->properties;
+               **allnextpp = np;
+               *allnextpp = &np->allnext;
+               if (dad != NULL) {
+                       np->parent = dad;
+                       /* we temporarily use the next field as `last_child'*/
+                       if (dad->next == NULL)
+                               dad->child = np;
+                       else
+                               dad->next->sibling = np;
+                       dad->next = np;
+               }
+               kref_init(&np->kref);
+       }
+       while (1) {
+               u32 sz, noff;
+               char *pname;
+
+               tag = *((u32 *)(*p));
+               if (tag == OF_DT_NOP) {
+                       *p += 4;
+                       continue;
+               }
+               if (tag != OF_DT_PROP)
+                       break;
+               *p += 4;
+               sz = *((u32 *)(*p));
+               noff = *((u32 *)((*p) + 4));
+               *p += 8;
+               if (initial_boot_params->version < 0x10)
+                       *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
+
+               pname = find_flat_dt_string(noff);
+               if (pname == NULL) {
+                       printk(KERN_INFO
+                               "Can't find property name in list !\n");
+                       break;
+               }
+               if (strcmp(pname, "name") == 0)
+                       has_name = 1;
+               l = strlen(pname) + 1;
+               pp = unflatten_dt_alloc(&mem, sizeof(struct property),
+                                       __alignof__(struct property));
+               if (allnextpp) {
+                       if (strcmp(pname, "linux,phandle") == 0) {
+                               np->node = *((u32 *)*p);
+                               if (np->linux_phandle == 0)
+                                       np->linux_phandle = np->node;
+                       }
+                       if (strcmp(pname, "ibm,phandle") == 0)
+                               np->linux_phandle = *((u32 *)*p);
+                       pp->name = pname;
+                       pp->length = sz;
+                       pp->value = (void *)*p;
+                       *prev_pp = pp;
+                       prev_pp = &pp->next;
+               }
+               *p = _ALIGN((*p) + sz, 4);
+       }
+       /* with version 0x10 we may not have the name property, recreate
+        * it here from the unit name if absent
+        */
+       if (!has_name) {
+               char *p1 = pathp, *ps = pathp, *pa = NULL;
+               int sz;
+
+               while (*p1) {
+                       if ((*p1) == '@')
+                               pa = p1;
+                       if ((*p1) == '/')
+                               ps = p1 + 1;
+                       p1++;
+               }
+               if (pa < ps)
+                       pa = p1;
+               sz = (pa - ps) + 1;
+               pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
+                                       __alignof__(struct property));
+               if (allnextpp) {
+                       pp->name = "name";
+                       pp->length = sz;
+                       pp->value = pp + 1;
+                       *prev_pp = pp;
+                       prev_pp = &pp->next;
+                       memcpy(pp->value, ps, sz - 1);
+                       ((char *)pp->value)[sz - 1] = 0;
+                       pr_debug("fixed up name for %s -> %s\n", pathp,
+                               (char *)pp->value);
+               }
+       }
+       if (allnextpp) {
+               *prev_pp = NULL;
+               np->name = of_get_property(np, "name", NULL);
+               np->type = of_get_property(np, "device_type", NULL);
+
+               if (!np->name)
+                       np->name = "<NULL>";
+               if (!np->type)
+                       np->type = "<NULL>";
+       }
+       while (tag == OF_DT_BEGIN_NODE) {
+               mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
+               tag = *((u32 *)(*p));
+       }
+       if (tag != OF_DT_END_NODE) {
+               printk(KERN_INFO "Weird tag at end of node: %x\n", tag);
+               return mem;
+       }
+       *p += 4;
+       return mem;
+}
+
+/**
+ * unflattens the device-tree passed by the firmware, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used (this used to be done by finish_device_tree)
+ */
+void __init unflatten_device_tree(void)
+{
+       unsigned long start, mem, size;
+       struct device_node **allnextp = &allnodes;
+
+       pr_debug(" -> unflatten_device_tree()\n");
+
+       /* First pass, scan for size */
+       start = ((unsigned long)initial_boot_params) +
+               initial_boot_params->off_dt_struct;
+       size = unflatten_dt_node(0, &start, NULL, NULL, 0);
+       size = (size | 3) + 1;
+
+       pr_debug("  size is %lx, allocating...\n", size);
+
+       /* Allocate memory for the expanded device tree */
+       mem = lmb_alloc(size + 4, __alignof__(struct device_node));
+       mem = (unsigned long) __va(mem);
+
+       ((u32 *)mem)[size / 4] = 0xdeadbeef;
+
+       pr_debug("  unflattening %lx...\n", mem);
+
+       /* Second pass, do actual unflattening */
+       start = ((unsigned long)initial_boot_params) +
+               initial_boot_params->off_dt_struct;
+       unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
+       if (*((u32 *)start) != OF_DT_END)
+               printk(KERN_WARNING "Weird tag at end of tree: %08x\n",
+                       *((u32 *)start));
+       if (((u32 *)mem)[size / 4] != 0xdeadbeef)
+               printk(KERN_WARNING "End of tree marker overwritten: %08x\n",
+                       ((u32 *)mem)[size / 4]);
+       *allnextp = NULL;
+
+       /* Get pointer to OF "/chosen" node for use everywhere */
+       of_chosen = of_find_node_by_path("/chosen");
+       if (of_chosen == NULL)
+               of_chosen = of_find_node_by_path("/chosen@0");
+
+       pr_debug(" <- unflatten_device_tree()\n");
+}
+
+#define early_init_dt_scan_drconf_memory(node) 0
+
+static int __init early_init_dt_scan_cpus(unsigned long node,
+                                         const char *uname, int depth,
+                                         void *data)
+{
+       static int logical_cpuid;
+       char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+       const u32 *intserv;
+       int i, nthreads;
+       int found = 0;
+
+       /* We are scanning "cpu" nodes only */
+       if (type == NULL || strcmp(type, "cpu") != 0)
+               return 0;
+
+       /* Get physical cpuid */
+       intserv = of_get_flat_dt_prop(node, "reg", NULL);
+       nthreads = 1;
+
+       /*
+        * Now see if any of these threads match our boot cpu.
+        * NOTE: This must match the parsing done in smp_setup_cpu_maps.
+        */
+       for (i = 0; i < nthreads; i++) {
+               /*
+                * version 2 of the kexec param format adds the phys cpuid of
+                * booted proc.
+                */
+               if (initial_boot_params && initial_boot_params->version >= 2) {
+                       if (intserv[i] ==
+                                       initial_boot_params->boot_cpuid_phys) {
+                               found = 1;
+                               break;
+                       }
+               } else {
+                       /*
+                        * Check if it's the boot-cpu, set it's hw index now,
+                        * unfortunately this format did not support booting
+                        * off secondary threads.
+                        */
+                       if (of_get_flat_dt_prop(node,
+                                       "linux,boot-cpu", NULL) != NULL) {
+                               found = 1;
+                               break;
+                       }
+               }
+
+#ifdef CONFIG_SMP
+               /* logical cpu id is always 0 on UP kernels */
+               logical_cpuid++;
+#endif
+       }
+
+       if (found) {
+               pr_debug("boot cpu: logical %d physical %d\n", logical_cpuid,
+                       intserv[i]);
+               boot_cpuid = logical_cpuid;
+       }
+
+       return 0;
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+static void __init early_init_dt_check_for_initrd(unsigned long node)
+{
+       unsigned long l;
+       u32 *prop;
+
+       pr_debug("Looking for initrd properties... ");
+
+       prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l);
+       if (prop) {
+               initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4));
+
+               prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
+               if (prop) {
+                       initrd_end = (unsigned long)
+                                       __va(of_read_ulong(prop, l/4));
+                       initrd_below_start_ok = 1;
+               } else {
+                       initrd_start = 0;
+               }
+       }
+
+       pr_debug("initrd_start=0x%lx  initrd_end=0x%lx\n",
+                                       initrd_start, initrd_end);
+}
+#else
+static inline void early_init_dt_check_for_initrd(unsigned long node)
+{
+}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+static int __init early_init_dt_scan_chosen(unsigned long node,
+                               const char *uname, int depth, void *data)
+{
+       unsigned long l;
+       char *p;
+
+       pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+
+       if (depth != 1 ||
+               (strcmp(uname, "chosen") != 0 &&
+                               strcmp(uname, "chosen@0") != 0))
+               return 0;
+
+#ifdef CONFIG_KEXEC
+       lprop = (u64 *)of_get_flat_dt_prop(node,
+                               "linux,crashkernel-base", NULL);
+       if (lprop)
+               crashk_res.start = *lprop;
+
+       lprop = (u64 *)of_get_flat_dt_prop(node,
+                               "linux,crashkernel-size", NULL);
+       if (lprop)
+               crashk_res.end = crashk_res.start + *lprop - 1;
+#endif
+
+       early_init_dt_check_for_initrd(node);
+
+       /* Retreive command line */
+       p = of_get_flat_dt_prop(node, "bootargs", &l);
+       if (p != NULL && l > 0)
+               strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE));
+
+#ifdef CONFIG_CMDLINE
+       if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
+               strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+#endif /* CONFIG_CMDLINE */
+
+       pr_debug("Command line is: %s\n", cmd_line);
+
+       /* break now */
+       return 1;
+}
+
+static int __init early_init_dt_scan_root(unsigned long node,
+                               const char *uname, int depth, void *data)
+{
+       u32 *prop;
+
+       if (depth != 0)
+               return 0;
+
+       prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
+       dt_root_size_cells = (prop == NULL) ? 1 : *prop;
+       pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
+
+       prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
+       dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
+       pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
+
+       /* break now */
+       return 1;
+}
+
+static u64 __init dt_mem_next_cell(int s, cell_t **cellp)
+{
+       cell_t *p = *cellp;
+
+       *cellp = p + s;
+       return of_read_number(p, s);
+}
+
+static int __init early_init_dt_scan_memory(unsigned long node,
+                               const char *uname, int depth, void *data)
+{
+       char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+       cell_t *reg, *endp;
+       unsigned long l;
+
+       /* Look for the ibm,dynamic-reconfiguration-memory node */
+/*     if (depth == 1 &&
+               strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0)
+               return early_init_dt_scan_drconf_memory(node);
+*/
+       /* We are scanning "memory" nodes only */
+       if (type == NULL) {
+               /*
+                * The longtrail doesn't have a device_type on the
+                * /memory node, so look for the node called /memory@0.
+                */
+               if (depth != 1 || strcmp(uname, "memory@0") != 0)
+                       return 0;
+       } else if (strcmp(type, "memory") != 0)
+               return 0;
+
+       reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l);
+       if (reg == NULL)
+               reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
+       if (reg == NULL)
+               return 0;
+
+       endp = reg + (l / sizeof(cell_t));
+
+       pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
+               uname, l, reg[0], reg[1], reg[2], reg[3]);
+
+       while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+               u64 base, size;
+
+               base = dt_mem_next_cell(dt_root_addr_cells, &reg);
+               size = dt_mem_next_cell(dt_root_size_cells, &reg);
+
+               if (size == 0)
+                       continue;
+               pr_debug(" - %llx ,  %llx\n", (unsigned long long)base,
+                       (unsigned long long)size);
+
+               lmb_add(base, size);
+       }
+       return 0;
+}
+
+#ifdef CONFIG_PHYP_DUMP
+/**
+ * phyp_dump_calculate_reserve_size() - reserve variable boot area 5% or arg
+ *
+ * Function to find the largest size we need to reserve
+ * during early boot process.
+ *
+ * It either looks for boot param and returns that OR
+ * returns larger of 256 or 5% rounded down to multiples of 256MB.
+ *
+ */
+static inline unsigned long phyp_dump_calculate_reserve_size(void)
+{
+       unsigned long tmp;
+
+       if (phyp_dump_info->reserve_bootvar)
+               return phyp_dump_info->reserve_bootvar;
+
+       /* divide by 20 to get 5% of value */
+       tmp = lmb_end_of_DRAM();
+       do_div(tmp, 20);
+
+       /* round it down in multiples of 256 */
+       tmp = tmp & ~0x0FFFFFFFUL;
+
+       return (tmp > PHYP_DUMP_RMR_END ? tmp : PHYP_DUMP_RMR_END);
+}
+
+/**
+ * phyp_dump_reserve_mem() - reserve all not-yet-dumped mmemory
+ *
+ * This routine may reserve memory regions in the kernel only
+ * if the system is supported and a dump was taken in last
+ * boot instance or if the hardware is supported and the
+ * scratch area needs to be setup. In other instances it returns
+ * without reserving anything. The memory in case of dump being
+ * active is freed when the dump is collected (by userland tools).
+ */
+static void __init phyp_dump_reserve_mem(void)
+{
+       unsigned long base, size;
+       unsigned long variable_reserve_size;
+
+       if (!phyp_dump_info->phyp_dump_configured) {
+               printk(KERN_ERR "Phyp-dump not supported on this hardware\n");
+               return;
+       }
+
+       if (!phyp_dump_info->phyp_dump_at_boot) {
+               printk(KERN_INFO "Phyp-dump disabled at boot time\n");
+               return;
+       }
+
+       variable_reserve_size = phyp_dump_calculate_reserve_size();
+
+       if (phyp_dump_info->phyp_dump_is_active) {
+               /* Reserve *everything* above RMR.Area freed by userland tools*/
+               base = variable_reserve_size;
+               size = lmb_end_of_DRAM() - base;
+
+               /* XXX crashed_ram_end is wrong, since it may be beyond
+                * the memory_limit, it will need to be adjusted. */
+               lmb_reserve(base, size);
+
+               phyp_dump_info->init_reserve_start = base;
+               phyp_dump_info->init_reserve_size = size;
+       } else {
+               size = phyp_dump_info->cpu_state_size +
+                       phyp_dump_info->hpte_region_size +
+                       variable_reserve_size;
+               base = lmb_end_of_DRAM() - size;
+               lmb_reserve(base, size);
+               phyp_dump_info->init_reserve_start = base;
+               phyp_dump_info->init_reserve_size = size;
+       }
+}
+#else
+static inline void __init phyp_dump_reserve_mem(void) {}
+#endif /* CONFIG_PHYP_DUMP  && CONFIG_PPC_RTAS */
+
+#ifdef CONFIG_EARLY_PRINTK
+/* MS this is Microblaze specifig function */
+static int __init early_init_dt_scan_serial(unsigned long node,
+                               const char *uname, int depth, void *data)
+{
+       unsigned long l;
+       char *p;
+       int *addr;
+
+       pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+
+/* find all serial nodes */
+       if (strncmp(uname, "serial", 6) != 0)
+               return 0;
+
+       early_init_dt_check_for_initrd(node);
+
+/* find compatible node with uartlite */
+       p = of_get_flat_dt_prop(node, "compatible", &l);
+       if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
+                       (strncmp(p, "xlnx,opb-uartlite", 17) != 0))
+               return 0;
+
+       addr = of_get_flat_dt_prop(node, "reg", &l);
+       return *addr; /* return address */
+}
+
+/* this function is looking for early uartlite console - Microblaze specific */
+int __init early_uartlite_console(void)
+{
+       return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
+}
+#endif
+
+void __init early_init_devtree(void *params)
+{
+       pr_debug(" -> early_init_devtree(%p)\n", params);
+
+       /* Setup flat device-tree pointer */
+       initial_boot_params = params;
+
+#ifdef CONFIG_PHYP_DUMP
+       /* scan tree to see if dump occured during last boot */
+       of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL);
+#endif
+
+       /* Retrieve various informations from the /chosen node of the
+        * device-tree, including the platform type, initrd location and
+        * size, TCE reserve, and more ...
+        */
+       of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+
+       /* Scan memory nodes and rebuild LMBs */
+       lmb_init();
+       of_scan_flat_dt(early_init_dt_scan_root, NULL);
+       of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+
+       /* Save command line for /proc/cmdline and then parse parameters */
+       strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
+       parse_early_param();
+
+       lmb_analyze();
+
+       pr_debug("Phys. mem: %lx\n", (unsigned long) lmb_phys_mem_size());
+
+       pr_debug("Scanning CPUs ...\n");
+
+       /* Retreive CPU related informations from the flat tree
+        * (altivec support, boot CPU ID, ...)
+        */
+       of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
+
+       pr_debug(" <- early_init_devtree()\n");
+}
+
+/**
+ * Indicates whether the root node has a given value in its
+ * compatible property.
+ */
+int machine_is_compatible(const char *compat)
+{
+       struct device_node *root;
+       int rc = 0;
+
+       root = of_find_node_by_path("/");
+       if (root) {
+               rc = of_device_is_compatible(root, compat);
+               of_node_put(root);
+       }
+       return rc;
+}
+EXPORT_SYMBOL(machine_is_compatible);
+
+/*******
+ *
+ * New implementation of the OF "find" APIs, return a refcounted
+ * object, call of_node_put() when done.  The device tree and list
+ * are protected by a rw_lock.
+ *
+ * Note that property management will need some locking as well,
+ * this isn't dealt with yet.
+ *
+ *******/
+
+/**
+ *     of_find_node_by_phandle - Find a node given a phandle
+ *     @handle:        phandle of the node to find
+ *
+ *     Returns a node pointer with refcount incremented, use
+ *     of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_phandle(phandle handle)
+{
+       struct device_node *np;
+
+       read_lock(&devtree_lock);
+       for (np = allnodes; np != NULL; np = np->allnext)
+               if (np->linux_phandle == handle)
+                       break;
+       of_node_get(np);
+       read_unlock(&devtree_lock);
+       return np;
+}
+EXPORT_SYMBOL(of_find_node_by_phandle);
+
+/**
+ *     of_find_all_nodes - Get next node in global list
+ *     @prev:  Previous node or NULL to start iteration
+ *             of_node_put() will be called on it
+ *
+ *     Returns a node pointer with refcount incremented, use
+ *     of_node_put() on it when done.
+ */
+struct device_node *of_find_all_nodes(struct device_node *prev)
+{
+       struct device_node *np;
+
+       read_lock(&devtree_lock);
+       np = prev ? prev->allnext : allnodes;
+       for (; np != NULL; np = np->allnext)
+               if (of_node_get(np))
+                       break;
+       of_node_put(prev);
+       read_unlock(&devtree_lock);
+       return np;
+}
+EXPORT_SYMBOL(of_find_all_nodes);
+
+/**
+ *     of_node_get - Increment refcount of a node
+ *     @node:  Node to inc refcount, NULL is supported to
+ *             simplify writing of callers
+ *
+ *     Returns node.
+ */
+struct device_node *of_node_get(struct device_node *node)
+{
+       if (node)
+               kref_get(&node->kref);
+       return node;
+}
+EXPORT_SYMBOL(of_node_get);
+
+static inline struct device_node *kref_to_device_node(struct kref *kref)
+{
+       return container_of(kref, struct device_node, kref);
+}
+
+/**
+ *     of_node_release - release a dynamically allocated node
+ *     @kref:  kref element of the node to be released
+ *
+ *     In of_node_put() this function is passed to kref_put()
+ *     as the destructor.
+ */
+static void of_node_release(struct kref *kref)
+{
+       struct device_node *node = kref_to_device_node(kref);
+       struct property *prop = node->properties;
+
+       /* We should never be releasing nodes that haven't been detached. */
+       if (!of_node_check_flag(node, OF_DETACHED)) {
+               printk(KERN_INFO "WARNING: Bad of_node_put() on %s\n",
+                       node->full_name);
+               dump_stack();
+               kref_init(&node->kref);
+               return;
+       }
+
+       if (!of_node_check_flag(node, OF_DYNAMIC))
+               return;
+
+       while (prop) {
+               struct property *next = prop->next;
+               kfree(prop->name);
+               kfree(prop->value);
+               kfree(prop);
+               prop = next;
+
+               if (!prop) {
+                       prop = node->deadprops;
+                       node->deadprops = NULL;
+               }
+       }
+       kfree(node->full_name);
+       kfree(node->data);
+       kfree(node);
+}
+
+/**
+ *     of_node_put - Decrement refcount of a node
+ *     @node:  Node to dec refcount, NULL is supported to
+ *             simplify writing of callers
+ *
+ */
+void of_node_put(struct device_node *node)
+{
+       if (node)
+               kref_put(&node->kref, of_node_release);
+}
+EXPORT_SYMBOL(of_node_put);
+
+/*
+ * Plug a device node into the tree and global list.
+ */
+void of_attach_node(struct device_node *np)
+{
+       unsigned long flags;
+
+       write_lock_irqsave(&devtree_lock, flags);
+       np->sibling = np->parent->child;
+       np->allnext = allnodes;
+       np->parent->child = np;
+       allnodes = np;
+       write_unlock_irqrestore(&devtree_lock, flags);
+}
+
+/*
+ * "Unplug" a node from the device tree.  The caller must hold
+ * a reference to the node.  The memory associated with the node
+ * is not freed until its refcount goes to zero.
+ */
+void of_detach_node(struct device_node *np)
+{
+       struct device_node *parent;
+       unsigned long flags;
+
+       write_lock_irqsave(&devtree_lock, flags);
+
+       parent = np->parent;
+       if (!parent)
+               goto out_unlock;
+
+       if (allnodes == np)
+               allnodes = np->allnext;
+       else {
+               struct device_node *prev;
+               for (prev = allnodes;
+                    prev->allnext != np;
+                    prev = prev->allnext)
+                       ;
+               prev->allnext = np->allnext;
+       }
+
+       if (parent->child == np)
+               parent->child = np->sibling;
+       else {
+               struct device_node *prevsib;
+               for (prevsib = np->parent->child;
+                    prevsib->sibling != np;
+                    prevsib = prevsib->sibling)
+                       ;
+               prevsib->sibling = np->sibling;
+       }
+
+       of_node_set_flag(np, OF_DETACHED);
+
+out_unlock:
+       write_unlock_irqrestore(&devtree_lock, flags);
+}
+
+/*
+ * Add a property to a node
+ */
+int prom_add_property(struct device_node *np, struct property *prop)
+{
+       struct property **next;
+       unsigned long flags;
+
+       prop->next = NULL;
+       write_lock_irqsave(&devtree_lock, flags);
+       next = &np->properties;
+       while (*next) {
+               if (strcmp(prop->name, (*next)->name) == 0) {
+                       /* duplicate ! don't insert it */
+                       write_unlock_irqrestore(&devtree_lock, flags);
+                       return -1;
+               }
+               next = &(*next)->next;
+       }
+       *next = prop;
+       write_unlock_irqrestore(&devtree_lock, flags);
+
+#ifdef CONFIG_PROC_DEVICETREE
+       /* try to add to proc as well if it was initialized */
+       if (np->pde)
+               proc_device_tree_add_prop(np->pde, prop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+       return 0;
+}
+
+/*
+ * Remove a property from a node.  Note that we don't actually
+ * remove it, since we have given out who-knows-how-many pointers
+ * to the data using get-property.  Instead we just move the property
+ * to the "dead properties" list, so it won't be found any more.
+ */
+int prom_remove_property(struct device_node *np, struct property *prop)
+{
+       struct property **next;
+       unsigned long flags;
+       int found = 0;
+
+       write_lock_irqsave(&devtree_lock, flags);
+       next = &np->properties;
+       while (*next) {
+               if (*next == prop) {
+                       /* found the node */
+                       *next = prop->next;
+                       prop->next = np->deadprops;
+                       np->deadprops = prop;
+                       found = 1;
+                       break;
+               }
+               next = &(*next)->next;
+       }
+       write_unlock_irqrestore(&devtree_lock, flags);
+
+       if (!found)
+               return -ENODEV;
+
+#ifdef CONFIG_PROC_DEVICETREE
+       /* try to remove the proc node as well */
+       if (np->pde)
+               proc_device_tree_remove_prop(np->pde, prop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+       return 0;
+}
+
+/*
+ * Update a property in a node.  Note that we don't actually
+ * remove it, since we have given out who-knows-how-many pointers
+ * to the data using get-property.  Instead we just move the property
+ * to the "dead properties" list, and add the new property to the
+ * property list
+ */
+int prom_update_property(struct device_node *np,
+                        struct property *newprop,
+                        struct property *oldprop)
+{
+       struct property **next;
+       unsigned long flags;
+       int found = 0;
+
+       write_lock_irqsave(&devtree_lock, flags);
+       next = &np->properties;
+       while (*next) {
+               if (*next == oldprop) {
+                       /* found the node */
+                       newprop->next = oldprop->next;
+                       *next = newprop;
+                       oldprop->next = np->deadprops;
+                       np->deadprops = oldprop;
+                       found = 1;
+                       break;
+               }
+               next = &(*next)->next;
+       }
+       write_unlock_irqrestore(&devtree_lock, flags);
+
+       if (!found)
+               return -ENODEV;
+
+#ifdef CONFIG_PROC_DEVICETREE
+       /* try to add to proc as well if it was initialized */
+       if (np->pde)
+               proc_device_tree_update_prop(np->pde, newprop, oldprop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+       return 0;
+}
+
+#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
+static struct debugfs_blob_wrapper flat_dt_blob;
+
+static int __init export_flat_device_tree(void)
+{
+       struct dentry *d;
+
+       flat_dt_blob.data = initial_boot_params;
+       flat_dt_blob.size = initial_boot_params->totalsize;
+
+       d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
+                               of_debugfs_root, &flat_dt_blob);
+       if (!d)
+               return 1;
+
+       return 0;
+}
+device_initcall(export_flat_device_tree);
+#endif
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
new file mode 100644 (file)
index 0000000..ae0352e
--- /dev/null
@@ -0,0 +1,1025 @@
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/pci_regs.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/etherdevice.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+
+#define PRu64  "%llx"
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS      4
+#define OF_CHECK_COUNTS(na, ns)        ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
+                       (ns) > 0)
+
+static struct of_bus *of_match_bus(struct device_node *np);
+static int __of_address_to_resource(struct device_node *dev,
+               const u32 *addrp, u64 size, unsigned int flags,
+               struct resource *r);
+
+/* Debug utility */
+#ifdef DEBUG
+static void of_dump_addr(const char *s, const u32 *addr, int na)
+{
+       printk(KERN_INFO "%s", s);
+       while (na--)
+               printk(KERN_INFO " %08x", *(addr++));
+       printk(KERN_INFO "\n");
+}
+#else
+static void of_dump_addr(const char *s, const u32 *addr, int na) { }
+#endif
+
+/* Callbacks for bus specific translators */
+struct of_bus {
+       const char      *name;
+       const char      *addresses;
+       int             (*match)(struct device_node *parent);
+       void            (*count_cells)(struct device_node *child,
+                                       int *addrc, int *sizec);
+       u64             (*map)(u32 *addr, const u32 *range,
+                               int na, int ns, int pna);
+       int             (*translate)(u32 *addr, u64 offset, int na);
+       unsigned int    (*get_flags)(const u32 *addr);
+};
+
+/*
+ * Default translator (generic bus)
+ */
+
+static void of_bus_default_count_cells(struct device_node *dev,
+                                       int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = of_n_addr_cells(dev);
+       if (sizec)
+               *sizec = of_n_size_cells(dev);
+}
+
+static u64 of_bus_default_map(u32 *addr, const u32 *range,
+               int na, int ns, int pna)
+{
+       u64 cp, s, da;
+
+       cp = of_read_number(range, na);
+       s  = of_read_number(range + na + pna, ns);
+       da = of_read_number(addr, na);
+
+       pr_debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
+               cp, s, da);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_default_translate(u32 *addr, u64 offset, int na)
+{
+       u64 a = of_read_number(addr, na);
+       memset(addr, 0, na * 4);
+       a += offset;
+       if (na > 1)
+               addr[na - 2] = a >> 32;
+       addr[na - 1] = a & 0xffffffffu;
+
+       return 0;
+}
+
+static unsigned int of_bus_default_get_flags(const u32 *addr)
+{
+       return IORESOURCE_MEM;
+}
+
+#ifdef CONFIG_PCI
+/*
+ * PCI bus specific translator
+ */
+
+static int of_bus_pci_match(struct device_node *np)
+{
+       /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
+       return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
+}
+
+static void of_bus_pci_count_cells(struct device_node *np,
+                               int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = 3;
+       if (sizec)
+               *sizec = 2;
+}
+
+static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+{
+       u64 cp, s, da;
+
+       /* Check address type match */
+       if ((addr[0] ^ range[0]) & 0x03000000)
+               return OF_BAD_ADDR;
+
+       /* Read address values, skipping high cell */
+       cp = of_read_number(range + 1, na - 1);
+       s  = of_read_number(range + na + pna, ns);
+       da = of_read_number(addr + 1, na - 1);
+
+       pr_debug("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
+{
+       return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static unsigned int of_bus_pci_get_flags(const u32 *addr)
+{
+       unsigned int flags = 0;
+       u32 w = addr[0];
+
+       switch ((w >> 24) & 0x03) {
+       case 0x01:
+               flags |= IORESOURCE_IO;
+               break;
+       case 0x02: /* 32 bits */
+       case 0x03: /* 64 bits */
+               flags |= IORESOURCE_MEM;
+               break;
+       }
+       if (w & 0x40000000)
+               flags |= IORESOURCE_PREFETCH;
+       return flags;
+}
+
+const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
+                       unsigned int *flags)
+{
+       const u32 *prop;
+       unsigned int psize;
+       struct device_node *parent;
+       struct of_bus *bus;
+       int onesize, i, na, ns;
+
+       /* Get parent & match bus type */
+       parent = of_get_parent(dev);
+       if (parent == NULL)
+               return NULL;
+       bus = of_match_bus(parent);
+       if (strcmp(bus->name, "pci")) {
+               of_node_put(parent);
+               return NULL;
+       }
+       bus->count_cells(dev, &na, &ns);
+       of_node_put(parent);
+       if (!OF_CHECK_COUNTS(na, ns))
+               return NULL;
+
+       /* Get "reg" or "assigned-addresses" property */
+       prop = of_get_property(dev, bus->addresses, &psize);
+       if (prop == NULL)
+               return NULL;
+       psize /= 4;
+
+       onesize = na + ns;
+       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+               if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
+                       if (size)
+                               *size = of_read_number(prop + na, ns);
+                       if (flags)
+                               *flags = bus->get_flags(prop);
+                       return prop;
+               }
+       return NULL;
+}
+EXPORT_SYMBOL(of_get_pci_address);
+
+int of_pci_address_to_resource(struct device_node *dev, int bar,
+                               struct resource *r)
+{
+       const u32       *addrp;
+       u64             size;
+       unsigned int    flags;
+
+       addrp = of_get_pci_address(dev, bar, &size, &flags);
+       if (addrp == NULL)
+               return -EINVAL;
+       return __of_address_to_resource(dev, addrp, size, flags, r);
+}
+EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+
+static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
+{
+       return (((pin - 1) + slot) % 4) + 1;
+}
+
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
+{
+       struct device_node *dn, *ppnode;
+       struct pci_dev *ppdev;
+       u32 lspec;
+       u32 laddr[3];
+       u8 pin;
+       int rc;
+
+       /* Check if we have a device node, if yes, fallback to standard OF
+        * parsing
+        */
+       dn = pci_device_to_OF_node(pdev);
+       if (dn)
+               return of_irq_map_one(dn, 0, out_irq);
+
+       /* Ok, we don't, time to have fun. Let's start by building up an
+        * interrupt spec.  we assume #interrupt-cells is 1, which is standard
+        * for PCI. If you do different, then don't use that routine.
+        */
+       rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+       if (rc != 0)
+               return rc;
+       /* No pin, exit */
+       if (pin == 0)
+               return -ENODEV;
+
+       /* Now we walk up the PCI tree */
+       lspec = pin;
+       for (;;) {
+               /* Get the pci_dev of our parent */
+               ppdev = pdev->bus->self;
+
+               /* Ouch, it's a host bridge... */
+               if (ppdev == NULL) {
+                       struct pci_controller *host;
+                       host = pci_bus_to_host(pdev->bus);
+                       ppnode = host ? host->arch_data : NULL;
+                       /* No node for host bridge ? give up */
+                       if (ppnode == NULL)
+                               return -EINVAL;
+               } else
+                       /* We found a P2P bridge, check if it has a node */
+                       ppnode = pci_device_to_OF_node(ppdev);
+
+               /* Ok, we have found a parent with a device-node, hand over to
+                * the OF parsing code.
+                * We build a unit address from the linux device to be used for
+                * resolution. Note that we use the linux bus number which may
+                * not match your firmware bus numbering.
+                * Fortunately, in most cases, interrupt-map-mask doesn't
+                * include the bus number as part of the matching.
+                * You should still be careful about that though if you intend
+                * to rely on this function (you ship  a firmware that doesn't
+                * create device nodes for all PCI devices).
+                */
+               if (ppnode)
+                       break;
+
+               /* We can only get here if we hit a P2P bridge with no node,
+                * let's do standard swizzling and try again
+                */
+               lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
+               pdev = ppdev;
+       }
+
+       laddr[0] = (pdev->bus->number << 16)
+               | (pdev->devfn << 8);
+       laddr[1]  = laddr[2] = 0;
+       return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
+}
+EXPORT_SYMBOL_GPL(of_irq_map_pci);
+#endif /* CONFIG_PCI */
+
+/*
+ * ISA bus specific translator
+ */
+
+static int of_bus_isa_match(struct device_node *np)
+{
+       return !strcmp(np->name, "isa");
+}
+
+static void of_bus_isa_count_cells(struct device_node *child,
+                               int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = 2;
+       if (sizec)
+               *sizec = 1;
+}
+
+static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+{
+       u64 cp, s, da;
+
+       /* Check address type match */
+       if ((addr[0] ^ range[0]) & 0x00000001)
+               return OF_BAD_ADDR;
+
+       /* Read address values, skipping high cell */
+       cp = of_read_number(range + 1, na - 1);
+       s  = of_read_number(range + na + pna, ns);
+       da = of_read_number(addr + 1, na - 1);
+
+       pr_debug("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
+{
+       return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static unsigned int of_bus_isa_get_flags(const u32 *addr)
+{
+       unsigned int flags = 0;
+       u32 w = addr[0];
+
+       if (w & 1)
+               flags |= IORESOURCE_IO;
+       else
+               flags |= IORESOURCE_MEM;
+       return flags;
+}
+
+/*
+ * Array of bus specific translators
+ */
+
+static struct of_bus of_busses[] = {
+#ifdef CONFIG_PCI
+       /* PCI */
+       {
+               .name = "pci",
+               .addresses = "assigned-addresses",
+               .match = of_bus_pci_match,
+               .count_cells = of_bus_pci_count_cells,
+               .map = of_bus_pci_map,
+               .translate = of_bus_pci_translate,
+               .get_flags = of_bus_pci_get_flags,
+       },
+#endif /* CONFIG_PCI */
+       /* ISA */
+       {
+               .name = "isa",
+               .addresses = "reg",
+               .match = of_bus_isa_match,
+               .count_cells = of_bus_isa_count_cells,
+               .map = of_bus_isa_map,
+               .translate = of_bus_isa_translate,
+               .get_flags = of_bus_isa_get_flags,
+       },
+       /* Default */
+       {
+               .name = "default",
+               .addresses = "reg",
+               .match = NULL,
+               .count_cells = of_bus_default_count_cells,
+               .map = of_bus_default_map,
+               .translate = of_bus_default_translate,
+               .get_flags = of_bus_default_get_flags,
+       },
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(of_busses); i++)
+               if (!of_busses[i].match || of_busses[i].match(np))
+                       return &of_busses[i];
+       BUG();
+       return NULL;
+}
+
+static int of_translate_one(struct device_node *parent, struct of_bus *bus,
+                       struct of_bus *pbus, u32 *addr,
+                       int na, int ns, int pna)
+{
+       const u32 *ranges;
+       unsigned int rlen;
+       int rone;
+       u64 offset = OF_BAD_ADDR;
+
+       /* Normally, an absence of a "ranges" property means we are
+        * crossing a non-translatable boundary, and thus the addresses
+        * below the current not cannot be converted to CPU physical ones.
+        * Unfortunately, while this is very clear in the spec, it's not
+        * what Apple understood, and they do have things like /uni-n or
+        * /ht nodes with no "ranges" property and a lot of perfectly
+        * useable mapped devices below them. Thus we treat the absence of
+        * "ranges" as equivalent to an empty "ranges" property which means
+        * a 1:1 translation at that level. It's up to the caller not to try
+        * to translate addresses that aren't supposed to be translated in
+        * the first place. --BenH.
+        */
+       ranges = of_get_property(parent, "ranges", (int *) &rlen);
+       if (ranges == NULL || rlen == 0) {
+               offset = of_read_number(addr, na);
+               memset(addr, 0, pna * 4);
+               pr_debug("OF: no ranges, 1:1 translation\n");
+               goto finish;
+       }
+
+       pr_debug("OF: walking ranges...\n");
+
+       /* Now walk through the ranges */
+       rlen /= 4;
+       rone = na + pna + ns;
+       for (; rlen >= rone; rlen -= rone, ranges += rone) {
+               offset = bus->map(addr, ranges, na, ns, pna);
+               if (offset != OF_BAD_ADDR)
+                       break;
+       }
+       if (offset == OF_BAD_ADDR) {
+               pr_debug("OF: not found !\n");
+               return 1;
+       }
+       memcpy(addr, ranges + na, 4 * pna);
+
+ finish:
+       of_dump_addr("OF: parent translation for:", addr, pna);
+       pr_debug("OF: with offset: "PRu64"\n", offset);
+
+       /* Translate it into parent bus space */
+       return pbus->translate(addr, offset, pna);
+}
+
+/*
+ * Translate an address from the device-tree into a CPU physical address,
+ * this walks up the tree and applies the various bus mappings on the
+ * way.
+ *
+ * Note: We consider that crossing any level with #size-cells == 0 to mean
+ * that translation is impossible (that is we are not dealing with a value
+ * that can be mapped to a cpu physical address). This is not really specified
+ * that way, but this is traditionally the way IBM at least do things
+ */
+u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
+{
+       struct device_node *parent = NULL;
+       struct of_bus *bus, *pbus;
+       u32 addr[OF_MAX_ADDR_CELLS];
+       int na, ns, pna, pns;
+       u64 result = OF_BAD_ADDR;
+
+       pr_debug("OF: ** translation for device %s **\n", dev->full_name);
+
+       /* Increase refcount at current level */
+       of_node_get(dev);
+
+       /* Get parent & match bus type */
+       parent = of_get_parent(dev);
+       if (parent == NULL)
+               goto bail;
+       bus = of_match_bus(parent);
+
+       /* Cound address cells & copy address locally */
+       bus->count_cells(dev, &na, &ns);
+       if (!OF_CHECK_COUNTS(na, ns)) {
+               printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+                       dev->full_name);
+               goto bail;
+       }
+       memcpy(addr, in_addr, na * 4);
+
+       pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
+               bus->name, na, ns, parent->full_name);
+       of_dump_addr("OF: translating address:", addr, na);
+
+       /* Translate */
+       for (;;) {
+               /* Switch to parent bus */
+               of_node_put(dev);
+               dev = parent;
+               parent = of_get_parent(dev);
+
+               /* If root, we have finished */
+               if (parent == NULL) {
+                       pr_debug("OF: reached root node\n");
+                       result = of_read_number(addr, na);
+                       break;
+               }
+
+               /* Get new parent bus and counts */
+               pbus = of_match_bus(parent);
+               pbus->count_cells(dev, &pna, &pns);
+               if (!OF_CHECK_COUNTS(pna, pns)) {
+                       printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+                               dev->full_name);
+                       break;
+               }
+
+               pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
+                       pbus->name, pna, pns, parent->full_name);
+
+               /* Apply bus translation */
+               if (of_translate_one(dev, bus, pbus, addr, na, ns, pna))
+                       break;
+
+               /* Complete the move up one level */
+               na = pna;
+               ns = pns;
+               bus = pbus;
+
+               of_dump_addr("OF: one level translation:", addr, na);
+       }
+ bail:
+       of_node_put(parent);
+       of_node_put(dev);
+
+       return result;
+}
+EXPORT_SYMBOL(of_translate_address);
+
+const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
+                       unsigned int *flags)
+{
+       const u32 *prop;
+       unsigned int psize;
+       struct device_node *parent;
+       struct of_bus *bus;
+       int onesize, i, na, ns;
+
+       /* Get parent & match bus type */
+       parent = of_get_parent(dev);
+       if (parent == NULL)
+               return NULL;
+       bus = of_match_bus(parent);
+       bus->count_cells(dev, &na, &ns);
+       of_node_put(parent);
+       if (!OF_CHECK_COUNTS(na, ns))
+               return NULL;
+
+       /* Get "reg" or "assigned-addresses" property */
+       prop = of_get_property(dev, bus->addresses, (int *) &psize);
+       if (prop == NULL)
+               return NULL;
+       psize /= 4;
+
+       onesize = na + ns;
+       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+               if (i == index) {
+                       if (size)
+                               *size = of_read_number(prop + na, ns);
+                       if (flags)
+                               *flags = bus->get_flags(prop);
+                       return prop;
+               }
+       return NULL;
+}
+EXPORT_SYMBOL(of_get_address);
+
+static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
+                               u64 size, unsigned int flags,
+                               struct resource *r)
+{
+       u64 taddr;
+
+       if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+               return -EINVAL;
+       taddr = of_translate_address(dev, addrp);
+       if (taddr == OF_BAD_ADDR)
+               return -EINVAL;
+       memset(r, 0, sizeof(struct resource));
+       if (flags & IORESOURCE_IO) {
+               unsigned long port;
+               port = -1; /* pci_address_to_pio(taddr); */
+               if (port == (unsigned long)-1)
+                       return -EINVAL;
+               r->start = port;
+               r->end = port + size - 1;
+       } else {
+               r->start = taddr;
+               r->end = taddr + size - 1;
+       }
+       r->flags = flags;
+       r->name = dev->name;
+       return 0;
+}
+
+int of_address_to_resource(struct device_node *dev, int index,
+                       struct resource *r)
+{
+       const u32       *addrp;
+       u64             size;
+       unsigned int    flags;
+
+       addrp = of_get_address(dev, index, &size, &flags);
+       if (addrp == NULL)
+               return -EINVAL;
+       return __of_address_to_resource(dev, addrp, size, flags, r);
+}
+EXPORT_SYMBOL_GPL(of_address_to_resource);
+
+void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
+               unsigned long *busno, unsigned long *phys, unsigned long *size)
+{
+       const u32 *dma_window;
+       u32 cells;
+       const unsigned char *prop;
+
+       dma_window = dma_window_prop;
+
+       /* busno is always one cell */
+       *busno = *(dma_window++);
+
+       prop = of_get_property(dn, "ibm,#dma-address-cells", NULL);
+       if (!prop)
+               prop = of_get_property(dn, "#address-cells", NULL);
+
+       cells = prop ? *(u32 *)prop : of_n_addr_cells(dn);
+       *phys = of_read_number(dma_window, cells);
+
+       dma_window += cells;
+
+       prop = of_get_property(dn, "ibm,#dma-size-cells", NULL);
+       cells = prop ? *(u32 *)prop : of_n_size_cells(dn);
+       *size = of_read_number(dma_window, cells);
+}
+
+/*
+ * Interrupt remapper
+ */
+
+static unsigned int of_irq_workarounds;
+static struct device_node *of_irq_dflt_pic;
+
+static struct device_node *of_irq_find_parent(struct device_node *child)
+{
+       struct device_node *p;
+       const phandle *parp;
+
+       if (!of_node_get(child))
+               return NULL;
+
+       do {
+               parp = of_get_property(child, "interrupt-parent", NULL);
+               if (parp == NULL)
+                       p = of_get_parent(child);
+               else {
+                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
+                               p = of_node_get(of_irq_dflt_pic);
+                       else
+                               p = of_find_node_by_phandle(*parp);
+               }
+               of_node_put(child);
+               child = p;
+       } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
+
+       return p;
+}
+
+/* This doesn't need to be called if you don't have any special workaround
+ * flags to pass
+ */
+void of_irq_map_init(unsigned int flags)
+{
+       of_irq_workarounds = flags;
+
+       /* OldWorld, don't bother looking at other things */
+       if (flags & OF_IMAP_OLDWORLD_MAC)
+               return;
+
+       /* If we don't have phandles, let's try to locate a default interrupt
+        * controller (happens when booting with BootX). We do a first match
+        * here, hopefully, that only ever happens on machines with one
+        * controller.
+        */
+       if (flags & OF_IMAP_NO_PHANDLE) {
+               struct device_node *np;
+
+               for (np = NULL; (np = of_find_all_nodes(np)) != NULL;) {
+                       if (of_get_property(np, "interrupt-controller", NULL)
+                               == NULL)
+                               continue;
+                       /* Skip /chosen/interrupt-controller */
+                       if (strcmp(np->name, "chosen") == 0)
+                               continue;
+                       /* It seems like at least one person on this planet
+                        * wants to use BootX on a machine with an AppleKiwi
+                        * controller which happens to pretend to be an
+                        * interrupt controller too.
+                        */
+                       if (strcmp(np->name, "AppleKiwi") == 0)
+                               continue;
+                       /* I think we found one ! */
+                       of_irq_dflt_pic = np;
+                       break;
+               }
+       }
+
+}
+
+int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
+               const u32 *addr, struct of_irq *out_irq)
+{
+       struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
+       const u32 *tmp, *imap, *imask;
+       u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
+       int imaplen, match, i;
+
+       pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],"
+               "ointsize=%d\n",
+               parent->full_name, intspec[0], intspec[1], ointsize);
+
+       ipar = of_node_get(parent);
+
+       /* First get the #interrupt-cells property of the current cursor
+        * that tells us how to interpret the passed-in intspec. If there
+        * is none, we are nice and just walk up the tree
+        */
+       do {
+               tmp = of_get_property(ipar, "#interrupt-cells", NULL);
+               if (tmp != NULL) {
+                       intsize = *tmp;
+                       break;
+               }
+               tnode = ipar;
+               ipar = of_irq_find_parent(ipar);
+               of_node_put(tnode);
+       } while (ipar);
+       if (ipar == NULL) {
+               pr_debug(" -> no parent found !\n");
+               goto fail;
+       }
+
+       pr_debug("of_irq_map_raw: ipar=%s, size=%d\n",
+                       ipar->full_name, intsize);
+
+       if (ointsize != intsize)
+               return -EINVAL;
+
+       /* Look for this #address-cells. We have to implement the old linux
+        * trick of looking for the parent here as some device-trees rely on it
+        */
+       old = of_node_get(ipar);
+       do {
+               tmp = of_get_property(old, "#address-cells", NULL);
+               tnode = of_get_parent(old);
+               of_node_put(old);
+               old = tnode;
+       } while (old && tmp == NULL);
+       of_node_put(old);
+       old = NULL;
+       addrsize = (tmp == NULL) ? 2 : *tmp;
+
+       pr_debug(" -> addrsize=%d\n", addrsize);
+
+       /* Now start the actual "proper" walk of the interrupt tree */
+       while (ipar != NULL) {
+               /* Now check if cursor is an interrupt-controller and if it is
+                * then we are done
+                */
+               if (of_get_property(ipar, "interrupt-controller", NULL) !=
+                               NULL) {
+                       pr_debug(" -> got it !\n");
+                       memcpy(out_irq->specifier, intspec,
+                               intsize * sizeof(u32));
+                       out_irq->size = intsize;
+                       out_irq->controller = ipar;
+                       of_node_put(old);
+                       return 0;
+               }
+
+               /* Now look for an interrupt-map */
+               imap = of_get_property(ipar, "interrupt-map", &imaplen);
+               /* No interrupt map, check for an interrupt parent */
+               if (imap == NULL) {
+                       pr_debug(" -> no map, getting parent\n");
+                       newpar = of_irq_find_parent(ipar);
+                       goto skiplevel;
+               }
+               imaplen /= sizeof(u32);
+
+               /* Look for a mask */
+               imask = of_get_property(ipar, "interrupt-map-mask", NULL);
+
+               /* If we were passed no "reg" property and we attempt to parse
+                * an interrupt-map, then #address-cells must be 0.
+                * Fail if it's not.
+                */
+               if (addr == NULL && addrsize != 0) {
+                       pr_debug(" -> no reg passed in when needed !\n");
+                       goto fail;
+               }
+
+               /* Parse interrupt-map */
+               match = 0;
+               while (imaplen > (addrsize + intsize + 1) && !match) {
+                       /* Compare specifiers */
+                       match = 1;
+                       for (i = 0; i < addrsize && match; ++i) {
+                               u32 mask = imask ? imask[i] : 0xffffffffu;
+                               match = ((addr[i] ^ imap[i]) & mask) == 0;
+                       }
+                       for (; i < (addrsize + intsize) && match; ++i) {
+                               u32 mask = imask ? imask[i] : 0xffffffffu;
+                               match =
+                                       ((intspec[i-addrsize] ^ imap[i])
+                                               & mask) == 0;
+                       }
+                       imap += addrsize + intsize;
+                       imaplen -= addrsize + intsize;
+
+                       pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
+
+                       /* Get the interrupt parent */
+                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
+                               newpar = of_node_get(of_irq_dflt_pic);
+                       else
+                               newpar =
+                                       of_find_node_by_phandle((phandle)*imap);
+                       imap++;
+                       --imaplen;
+
+                       /* Check if not found */
+                       if (newpar == NULL) {
+                               pr_debug(" -> imap parent not found !\n");
+                               goto fail;
+                       }
+
+                       /* Get #interrupt-cells and #address-cells of new
+                        * parent
+                        */
+                       tmp = of_get_property(newpar, "#interrupt-cells", NULL);
+                       if (tmp == NULL) {
+                               pr_debug(" -> parent lacks "
+                                               "#interrupt-cells!\n");
+                               goto fail;
+                       }
+                       newintsize = *tmp;
+                       tmp = of_get_property(newpar, "#address-cells", NULL);
+                       newaddrsize = (tmp == NULL) ? 0 : *tmp;
+
+                       pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
+                               newintsize, newaddrsize);
+
+                       /* Check for malformed properties */
+                       if (imaplen < (newaddrsize + newintsize))
+                               goto fail;
+
+                       imap += newaddrsize + newintsize;
+                       imaplen -= newaddrsize + newintsize;
+
+                       pr_debug(" -> imaplen=%d\n", imaplen);
+               }
+               if (!match)
+                       goto fail;
+
+               of_node_put(old);
+               old = of_node_get(newpar);
+               addrsize = newaddrsize;
+               intsize = newintsize;
+               intspec = imap - intsize;
+               addr = intspec - addrsize;
+
+skiplevel:
+               /* Iterate again with new parent */
+               pr_debug(" -> new parent: %s\n",
+                               newpar ? newpar->full_name : "<>");
+               of_node_put(ipar);
+               ipar = newpar;
+               newpar = NULL;
+       }
+fail:
+       of_node_put(ipar);
+       of_node_put(old);
+       of_node_put(newpar);
+
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(of_irq_map_raw);
+
+int of_irq_map_one(struct device_node *device,
+                       int index, struct of_irq *out_irq)
+{
+       struct device_node *p;
+       const u32 *intspec, *tmp, *addr;
+       u32 intsize, intlen;
+       int res;
+
+       pr_debug("of_irq_map_one: dev=%s, index=%d\n",
+                       device->full_name, index);
+
+       /* Get the interrupts property */
+       intspec = of_get_property(device, "interrupts", (int *) &intlen);
+       if (intspec == NULL)
+               return -EINVAL;
+       intlen /= sizeof(u32);
+
+       pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen);
+
+       /* Get the reg property (if any) */
+       addr = of_get_property(device, "reg", NULL);
+
+       /* Look for the interrupt parent. */
+       p = of_irq_find_parent(device);
+       if (p == NULL)
+               return -EINVAL;
+
+       /* Get size of interrupt specifier */
+       tmp = of_get_property(p, "#interrupt-cells", NULL);
+       if (tmp == NULL) {
+               of_node_put(p);
+               return -EINVAL;
+       }
+       intsize = *tmp;
+
+       pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
+
+       /* Check index */
+       if ((index + 1) * intsize > intlen)
+               return -EINVAL;
+
+       /* Get new specifier and map it */
+       res = of_irq_map_raw(p, intspec + index * intsize, intsize,
+                               addr, out_irq);
+       of_node_put(p);
+       return res;
+}
+EXPORT_SYMBOL_GPL(of_irq_map_one);
+
+/**
+ * Search the device tree for the best MAC address to use.  'mac-address' is
+ * checked first, because that is supposed to contain to "most recent" MAC
+ * address. If that isn't set, then 'local-mac-address' is checked next,
+ * because that is the default address.  If that isn't set, then the obsolete
+ * 'address' is checked, just in case we're using an old device tree.
+ *
+ * Note that the 'address' property is supposed to contain a virtual address of
+ * the register set, but some DTS files have redefined that property to be the
+ * MAC address.
+ *
+ * All-zero MAC addresses are rejected, because those could be properties that
+ * exist in the device tree, but were not set by U-Boot.  For example, the
+ * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
+ * addresses.  Some older U-Boots only initialized 'local-mac-address'.  In
+ * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
+ * but is all zeros.
+*/
+const void *of_get_mac_address(struct device_node *np)
+{
+       struct property *pp;
+
+       pp = of_find_property(np, "mac-address", NULL);
+       if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+               return pp->value;
+
+       pp = of_find_property(np, "local-mac-address", NULL);
+       if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+               return pp->value;
+
+       pp = of_find_property(np, "address", NULL);
+       if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+               return pp->value;
+
+       return NULL;
+}
+EXPORT_SYMBOL(of_get_mac_address);
+
+int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
+{
+       struct of_irq out_irq;
+       int irq;
+       int res;
+
+       res = of_irq_map_one(dev, index, &out_irq);
+
+       /* Get irq for the device */
+       if (res) {
+               pr_debug("IRQ not found... code = %d", res);
+               return NO_IRQ;
+       }
+       /* Assuming single interrupt controller... */
+       irq = out_irq.specifier[0];
+
+       pr_debug("IRQ found = %d", irq);
+
+       /* Only dereference the resource if both the
+        * resource and the irq are valid. */
+       if (r && irq != NO_IRQ) {
+               r->start = r->end = irq;
+               r->flags = IORESOURCE_IRQ;
+       }
+
+       return irq;
+}
+EXPORT_SYMBOL_GPL(of_irq_to_resource);
+
+void __iomem *of_iomap(struct device_node *np, int index)
+{
+       struct resource res;
+
+       if (of_address_to_resource(np, index, &res))
+               return NULL;
+
+       return ioremap(res.start, 1 + res.end - res.start);
+}
+EXPORT_SYMBOL(of_iomap);
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c
new file mode 100644 (file)
index 0000000..3171e39
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * `ptrace' system call
+ *
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2004-2007 John Williams <john.williams@petalogix.com>
+ *
+ * derived from arch/v850/kernel/ptrace.c
+ *
+ * Copyright (C) 2002,03 NEC Electronics Corporation
+ * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
+ *
+ * Derived from arch/mips/kernel/ptrace.c:
+ *
+ * Copyright (C) 1992 Ross Biro
+ * Copyright (C) Linus Torvalds
+ * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999 MIPS Technologies, Inc.
+ *
+ * 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/mm.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/ptrace.h>
+#include <linux/signal.h>
+
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <asm/processor.h>
+#include <linux/uaccess.h>
+#include <asm/asm-offsets.h>
+
+/* Returns the address where the register at REG_OFFS in P is stashed away. */
+static microblaze_reg_t *reg_save_addr(unsigned reg_offs,
+                                       struct task_struct *t)
+{
+       struct pt_regs *regs;
+
+       /*
+        * Three basic cases:
+        *
+        * (1)  A register normally saved before calling the scheduler, is
+        *      available in the kernel entry pt_regs structure at the top
+        *      of the kernel stack. The kernel trap/irq exit path takes
+        *      care to save/restore almost all registers for ptrace'd
+        *      processes.
+        *
+        * (2)  A call-clobbered register, where the process P entered the
+        *      kernel via [syscall] trap, is not stored anywhere; that's
+        *      OK, because such registers are not expected to be preserved
+        *      when the trap returns anyway (so we don't actually bother to
+        *      test for this case).
+        *
+        * (3)  A few registers not used at all by the kernel, and so
+        *      normally never saved except by context-switches, are in the
+        *      context switch state.
+        */
+
+       /* Register saved during kernel entry (or not available). */
+       regs = task_pt_regs(t);
+
+       return (microblaze_reg_t *)((char *)regs + reg_offs);
+}
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+{
+       int rval;
+       unsigned long val = 0;
+       unsigned long copied;
+
+       switch (request) {
+       case PTRACE_PEEKTEXT: /* read word at location addr. */
+       case PTRACE_PEEKDATA:
+               pr_debug("PEEKTEXT/PEEKDATA at %08lX\n", addr);
+               copied = access_process_vm(child, addr, &val, sizeof(val), 0);
+               rval = -EIO;
+               if (copied != sizeof(val))
+                       break;
+               rval = put_user(val, (unsigned long *)data);
+               break;
+
+       case PTRACE_POKETEXT: /* write the word at location addr. */
+       case PTRACE_POKEDATA:
+               pr_debug("POKETEXT/POKEDATA to %08lX\n", addr);
+               rval = 0;
+               if (access_process_vm(child, addr, &data, sizeof(data), 1)
+                   == sizeof(data))
+                       break;
+               rval = -EIO;
+               break;
+
+       /* Read/write the word at location ADDR in the registers. */
+       case PTRACE_PEEKUSR:
+       case PTRACE_POKEUSR:
+               pr_debug("PEEKUSR/POKEUSR : 0x%08lx\n", addr);
+               rval = 0;
+               if (addr >= PT_SIZE && request == PTRACE_PEEKUSR) {
+                       /*
+                        * Special requests that don't actually correspond
+                        * to offsets in struct pt_regs.
+                        */
+                       if (addr == PT_TEXT_ADDR) {
+                               val = child->mm->start_code;
+                       } else if (addr == PT_DATA_ADDR) {
+                               val = child->mm->start_data;
+                       } else if (addr == PT_TEXT_LEN) {
+                               val = child->mm->end_code
+                                       - child->mm->start_code;
+                       } else {
+                               rval = -EIO;
+                       }
+               } else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
+                       microblaze_reg_t *reg_addr = reg_save_addr(addr, child);
+                       if (request == PTRACE_PEEKUSR)
+                               val = *reg_addr;
+                       else
+                               *reg_addr = data;
+               } else
+                       rval = -EIO;
+
+               if (rval == 0 && request == PTRACE_PEEKUSR)
+                       rval = put_user(val, (unsigned long *)data);
+               break;
+       /* Continue and stop at next (return from) syscall */
+       case PTRACE_SYSCALL:
+               pr_debug("PTRACE_SYSCALL\n");
+       case PTRACE_SINGLESTEP:
+               pr_debug("PTRACE_SINGLESTEP\n");
+       /* Restart after a signal.  */
+       case PTRACE_CONT:
+               pr_debug("PTRACE_CONT\n");
+               rval = -EIO;
+               if (!valid_signal(data))
+                       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;
+               pr_debug("wakeup_process\n");
+               wake_up_process(child);
+               rval = 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:
+               pr_debug("PTRACE_KILL\n");
+               rval = 0;
+               if (child->exit_state == EXIT_ZOMBIE)   /* already dead */
+                       break;
+               child->exit_code = SIGKILL;
+               wake_up_process(child);
+               break;
+
+       case PTRACE_DETACH: /* detach a process that was attached. */
+               pr_debug("PTRACE_DETACH\n");
+               rval = ptrace_detach(child, data);
+               break;
+       default:
+               /* rval = ptrace_request(child, request, addr, data); noMMU */
+               rval = -EIO;
+       }
+       return rval;
+}
+
+void ptrace_disable(struct task_struct *child)
+{
+       /* nothing to do */
+}
diff --git a/arch/microblaze/kernel/selfmod.c b/arch/microblaze/kernel/selfmod.c
new file mode 100644 (file)
index 0000000..89508bd
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009 PetaLogix
+ *
+ * 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/interrupt.h>
+#include <asm/selfmod.h>
+
+#undef DEBUG
+
+#if __GNUC__ > 3
+#error GCC 4 unsupported SELFMOD. Please disable SELFMOD from menuconfig.
+#endif
+
+#define OPCODE_IMM             0xB0000000
+#define OPCODE_LWI             0xE8000000
+#define OPCODE_LWI_MASK                0xEC000000
+#define OPCODE_RTSD            0xB60F0008 /* return from func: rtsd r15, 8 */
+#define OPCODE_ADDIK           0x30000000
+#define OPCODE_ADDIK_MASK      0xFC000000
+
+#define IMM_BASE       (OPCODE_IMM | (BARRIER_BASE_ADDR >> 16))
+#define LWI_BASE       (OPCODE_LWI | (BARRIER_BASE_ADDR & 0x0000ff00))
+#define LWI_BASE_MASK  (OPCODE_LWI_MASK | (BARRIER_BASE_ADDR & 0x0000ff00))
+#define ADDIK_BASE     (OPCODE_ADDIK | (BARRIER_BASE_ADDR & 0x0000ff00))
+#define ADDIK_BASE_MASK        (OPCODE_ADDIK_MASK | (BARRIER_BASE_ADDR & 0x0000ff00))
+
+#define MODIFY_INSTR {                                         \
+       pr_debug("%s: curr instr, (%d):0x%x, next(%d):0x%x\n",          \
+               __func__, i, addr[i], i + 1, addr[i + 1]);              \
+       addr[i] = OPCODE_IMM + (base >> 16);                            \
+       /* keep instruction opcode and add only last 16bits */          \
+       addr[i + 1] = (addr[i + 1] & 0xffff00ff) + (base & 0xffff);     \
+       __invalidate_icache(addr[i]);                                   \
+       __invalidate_icache(addr[i + 1]);                               \
+       pr_debug("%s: hack instr, (%d):0x%x, next(%d):0x%x\n",          \
+               __func__, i, addr[i], i + 1, addr[i + 1]); }
+
+/* NOTE
+ * self-modified part of code for improvement of interrupt controller
+ * save instruction in interrupt rutine
+ */
+void selfmod_function(const int *arr_fce, const unsigned int base)
+{
+       unsigned int flags, i, j, *addr = NULL;
+
+       local_irq_save(flags);
+       __disable_icache();
+
+       /* zero terminated array */
+       for (j = 0; arr_fce[j] != 0; j++) {
+               /* get start address of function */
+               addr = (unsigned int *) arr_fce[j];
+               pr_debug("%s: func(%d) at 0x%x\n",
+                                       __func__, j, (unsigned int) addr);
+               for (i = 0; ; i++) {
+                       pr_debug("%s: instruction code at %d: 0x%x\n",
+                                               __func__, i, addr[i]);
+                       if (addr[i] == IMM_BASE) {
+                               /* detecting of lwi (0xE8) or swi (0xF8) instr
+                                * I can detect both opcode with one mask */
+                               if ((addr[i + 1] & LWI_BASE_MASK) == LWI_BASE) {
+                                       MODIFY_INSTR;
+                               } else /* detection addik for ack */
+                               if ((addr[i + 1] & ADDIK_BASE_MASK) ==
+                                                               ADDIK_BASE) {
+                                       MODIFY_INSTR;
+                               }
+                       } else if (addr[i] == OPCODE_RTSD) {
+                               /* return from function means end of function */
+                               pr_debug("%s: end of array %d\n", __func__, i);
+                               break;
+                       }
+               }
+       }
+       local_irq_restore(flags);
+} /* end of self-modified code */
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
new file mode 100644 (file)
index 0000000..eb6b417
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/init.h>
+#include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/cpu.h>
+#include <linux/initrd.h>
+#include <linux/console.h>
+#include <linux/debugfs.h>
+
+#include <asm/setup.h>
+#include <asm/sections.h>
+#include <asm/page.h>
+#include <linux/io.h>
+#include <linux/bug.h>
+#include <linux/param.h>
+#include <linux/cache.h>
+#include <asm/cacheflush.h>
+#include <asm/entry.h>
+#include <asm/cpuinfo.h>
+
+#include <asm/system.h>
+#include <asm/prom.h>
+#include <asm/pgtable.h>
+
+DEFINE_PER_CPU(unsigned int, KSP);     /* Saved kernel stack pointer */
+DEFINE_PER_CPU(unsigned int, KM);      /* Kernel/user mode */
+DEFINE_PER_CPU(unsigned int, ENTRY_SP);        /* Saved SP on kernel entry */
+DEFINE_PER_CPU(unsigned int, R11_SAVE);        /* Temp variable for entry */
+DEFINE_PER_CPU(unsigned int, CURRENT_SAVE);    /* Saved current pointer */
+
+unsigned int boot_cpuid;
+char cmd_line[COMMAND_LINE_SIZE];
+
+void __init setup_arch(char **cmdline_p)
+{
+#ifdef CONFIG_CMDLINE_FORCE
+       strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+       strlcpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+#endif
+       *cmdline_p = cmd_line;
+
+       console_verbose();
+
+       unflatten_device_tree();
+
+       /* NOTE I think that this function is not necessary to call */
+       /* irq_early_init(); */
+       setup_cpuinfo();
+
+       __invalidate_icache_all();
+       __enable_icache();
+
+       __invalidate_dcache_all();
+       __enable_dcache();
+
+       panic_timeout = 120;
+
+       setup_memory();
+
+#if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER)
+       printk(KERN_NOTICE "Self modified code enable\n");
+#endif
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_XILINX_CONSOLE)
+       conswitchp = &xil_con;
+#elif defined(CONFIG_DUMMY_CONSOLE)
+       conswitchp = &dummy_con;
+#endif
+#endif
+}
+
+#ifdef CONFIG_MTD_UCLINUX
+/* Handle both romfs and cramfs types, without generating unnecessary
+ code (ie no point checking for CRAMFS if it's not even enabled) */
+inline unsigned get_romfs_len(unsigned *addr)
+{
+#ifdef CONFIG_ROMFS_FS
+       if (memcmp(&addr[0], "-rom1fs-", 8) == 0) /* romfs */
+               return be32_to_cpu(addr[2]);
+#endif
+
+#ifdef CONFIG_CRAMFS
+       if (addr[0] == le32_to_cpu(0x28cd3d45)) /* cramfs */
+               return le32_to_cpu(addr[1]);
+#endif
+       return 0;
+}
+#endif /* CONFIG_MTD_UCLINUX_EBSS */
+
+void __init machine_early_init(const char *cmdline, unsigned int ram,
+               unsigned int fdt)
+{
+       unsigned long *src, *dst = (unsigned long *)0x0;
+
+/* clearing bss section */
+       memset(__bss_start, 0, __bss_stop-__bss_start);
+       memset(_ssbss, 0, _esbss-_ssbss);
+
+       /*
+        * Copy command line passed from bootloader, or use default
+        * if none provided, or forced
+        */
+#ifndef CONFIG_CMDLINE_BOOL
+       if (cmdline && cmdline[0] != '\0')
+               strlcpy(cmd_line, cmdline, COMMAND_LINE_SIZE);
+#endif
+
+/* initialize device tree for usage in early_printk */
+       early_init_devtree((void *)_fdt_start);
+
+#ifdef CONFIG_EARLY_PRINTK
+       setup_early_printk(NULL);
+#endif
+
+       early_printk("Ramdisk addr 0x%08x, FDT 0x%08x\n", ram, fdt);
+       printk(KERN_NOTICE "Found FDT at 0x%08x\n", fdt);
+
+#ifdef CONFIG_MTD_UCLINUX
+       {
+               int size;
+               unsigned int romfs_base;
+               romfs_base = (ram ? ram : (unsigned int)&__init_end);
+               /* if CONFIG_MTD_UCLINUX_EBSS is defined, assume ROMFS is at the
+                * end of kernel, which is ROMFS_LOCATION defined above. */
+               size = PAGE_ALIGN(get_romfs_len((unsigned *)romfs_base));
+               early_printk("Found romfs @ 0x%08x (0x%08x)\n",
+                               romfs_base, size);
+               early_printk("#### klimit %p ####\n", klimit);
+               BUG_ON(size < 0); /* What else can we do? */
+
+               /* Use memmove to handle likely case of memory overlap */
+               early_printk("Moving 0x%08x bytes from 0x%08x to 0x%08x\n",
+                       size, romfs_base, (unsigned)&_ebss);
+               memmove(&_ebss, (int *)romfs_base, size);
+
+               /* update klimit */
+               klimit += PAGE_ALIGN(size);
+               early_printk("New klimit: 0x%08x\n", (unsigned)klimit);
+       }
+#endif
+
+       for (src = __ivt_start; src < __ivt_end; src++, dst++)
+               *dst = *src;
+
+       /* Initialize global data */
+       per_cpu(KM, 0) = 0x1;   /* We start in kernel mode */
+       per_cpu(CURRENT_SAVE, 0) = (unsigned long)current;
+}
+
+#ifdef CONFIG_DEBUG_FS
+struct dentry *of_debugfs_root;
+
+static int microblaze_debugfs_init(void)
+{
+       of_debugfs_root = debugfs_create_dir("microblaze", NULL);
+
+       return of_debugfs_root == NULL;
+}
+arch_initcall(microblaze_debugfs_init);
+#endif
+
+void machine_restart(char *cmd)
+{
+       printk(KERN_NOTICE "Machine restart...\n");
+       dump_stack();
+       while (1)
+               ;
+}
+
+void machine_shutdown(void)
+{
+       printk(KERN_NOTICE "Machine shutdown...\n");
+       while (1)
+               ;
+}
+
+void machine_halt(void)
+{
+       printk(KERN_NOTICE "Machine halt...\n");
+       while (1)
+               ;
+}
+
+void machine_power_off(void)
+{
+       printk(KERN_NOTICE "Machine power off...\n");
+       while (1)
+               ;
+}
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
new file mode 100644 (file)
index 0000000..ff347b9
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ * Signal handling
+ *
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2003,2004 John Williams <jwilliams@itee.uq.edu.au>
+ * Copyright (C) 2001 NEC Corporation
+ * Copyright (C) 2001 Miles Bader <miles@gnu.org>
+ * Copyright (C) 1999,2000 Niibe Yutaka & Kaz Kojima
+ * Copyright (C) 1991,1992 Linus Torvalds
+ *
+ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
+ *
+ * This file was was derived from the sh version, arch/sh/kernel/signal.c
+ *
+ * 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/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.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/personality.h>
+#include <linux/percpu.h>
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/ucontext.h>
+#include <linux/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <linux/signal.h>
+#include <linux/syscalls.h>
+#include <asm/cacheflush.h>
+#include <asm/syscalls.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int
+sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs)
+{
+       sigset_t saveset;
+
+       mask &= _BLOCKABLE;
+       spin_lock_irq(&current->sighand->siglock);
+       saveset = current->blocked;
+       siginitset(&current->blocked, mask);
+       recalc_sigpending();
+       spin_unlock_irq(&current->sighand->siglock);
+
+       regs->r3 = -EINTR;
+       while (1) {
+               current->state = TASK_INTERRUPTIBLE;
+               schedule();
+               if (do_signal(regs, &saveset, 1))
+                       return -EINTR;
+       }
+}
+
+asmlinkage int
+sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
+               struct pt_regs *regs)
+{
+       sigset_t saveset, newset;
+
+       /* XXX: Don't preclude handling different sized sigset_t's. */
+       if (sigsetsize != sizeof(sigset_t))
+               return -EINVAL;
+
+       if (copy_from_user(&newset, unewset, sizeof(newset)))
+               return -EFAULT;
+       sigdelsetmask(&newset, ~_BLOCKABLE);
+       spin_lock_irq(&current->sighand->siglock);
+       saveset = current->blocked;
+       current->blocked = newset;
+       recalc_sigpending();
+       spin_unlock_irq(&current->sighand->siglock);
+
+       regs->r3 = -EINTR;
+       while (1) {
+               current->state = TASK_INTERRUPTIBLE;
+               schedule();
+               if (do_signal(regs, &saveset, 1))
+                       return -EINTR;
+       }
+}
+
+asmlinkage int
+sys_sigaction(int sig, const struct old_sigaction *act,
+               struct old_sigaction *oact)
+{
+       struct k_sigaction new_ka, old_ka;
+       int ret;
+
+       if (act) {
+               old_sigset_t mask;
+               if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
+                       __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+                       __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+                       return -EFAULT;
+               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+               __get_user(mask, &act->sa_mask);
+               siginitset(&new_ka.sa.sa_mask, mask);
+       }
+
+       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+       if (!ret && oact) {
+               if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+                       __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+                       __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+                       return -EFAULT;
+               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+       }
+
+       return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
+               struct pt_regs *regs)
+{
+       return do_sigaltstack(uss, uoss, regs->r1);
+}
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+struct sigframe {
+       struct sigcontext sc;
+       unsigned long extramask[_NSIG_WORDS-1];
+       unsigned long tramp[2]; /* signal trampoline */
+};
+
+struct rt_sigframe {
+       struct siginfo info;
+       struct ucontext uc;
+       unsigned long tramp[2]; /* signal trampoline */
+};
+
+static int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *rval_p)
+{
+       unsigned int err = 0;
+
+#define COPY(x)                {err |= __get_user(regs->x, &sc->regs.x); }
+       COPY(r0);
+       COPY(r1);
+       COPY(r2);       COPY(r3);       COPY(r4);       COPY(r5);
+       COPY(r6);       COPY(r7);       COPY(r8);       COPY(r9);
+       COPY(r10);      COPY(r11);      COPY(r12);      COPY(r13);
+       COPY(r14);      COPY(r15);      COPY(r16);      COPY(r17);
+       COPY(r18);      COPY(r19);      COPY(r20);      COPY(r21);
+       COPY(r22);      COPY(r23);      COPY(r24);      COPY(r25);
+       COPY(r26);      COPY(r27);      COPY(r28);      COPY(r29);
+       COPY(r30);      COPY(r31);
+       COPY(pc);       COPY(ear);      COPY(esr);      COPY(fsr);
+#undef COPY
+
+       *rval_p = regs->r3;
+
+       return err;
+}
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs)
+{
+       struct sigframe *frame = (struct sigframe *)regs->r1;
+       sigset_t set;
+       int rval;
+
+       if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+               goto badframe;
+
+       if (__get_user(set.sig[0], &frame->sc.oldmask)
+               || (_NSIG_WORDS > 1
+               && __copy_from_user(&set.sig[1], &frame->extramask,
+                                       sizeof(frame->extramask))))
+               goto badframe;
+
+       sigdelsetmask(&set, ~_BLOCKABLE);
+
+       spin_lock_irq(&current->sighand->siglock);
+       current->blocked = set;
+       recalc_sigpending();
+       spin_unlock_irq(&current->sighand->siglock);
+
+       if (restore_sigcontext(regs, &frame->sc, &rval))
+               goto badframe;
+       return rval;
+
+badframe:
+       force_sig(SIGSEGV, current);
+       return 0;
+}
+
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+{
+       struct rt_sigframe *frame = (struct rt_sigframe *)regs->r1;
+       sigset_t set;
+       stack_t st;
+       int rval;
+
+       if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+               goto badframe;
+
+       if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+               goto badframe;
+
+       sigdelsetmask(&set, ~_BLOCKABLE);
+       spin_lock_irq(&current->sighand->siglock);
+       current->blocked = set;
+       recalc_sigpending();
+       spin_unlock_irq(&current->sighand->siglock);
+
+       if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
+               goto badframe;
+
+       if (__copy_from_user((void *)&st, &frame->uc.uc_stack, sizeof(st)))
+               goto badframe;
+       /* It is more difficult to avoid calling this function than to
+        call it and ignore errors. */
+       do_sigaltstack(&st, NULL, regs->r1);
+
+       return rval;
+
+badframe:
+       force_sig(SIGSEGV, current);
+       return 0;
+}
+
+/*
+ * Set up a signal frame.
+ */
+
+static int
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+               unsigned long mask)
+{
+       int err = 0;
+
+#define COPY(x)                {err |= __put_user(regs->x, &sc->regs.x); }
+       COPY(r0);
+       COPY(r1);
+       COPY(r2);       COPY(r3);       COPY(r4);       COPY(r5);
+       COPY(r6);       COPY(r7);       COPY(r8);       COPY(r9);
+       COPY(r10);      COPY(r11);      COPY(r12);      COPY(r13);
+       COPY(r14);      COPY(r15);      COPY(r16);      COPY(r17);
+       COPY(r18);      COPY(r19);      COPY(r20);      COPY(r21);
+       COPY(r22);      COPY(r23);      COPY(r24);      COPY(r25);
+       COPY(r26);      COPY(r27);      COPY(r28);      COPY(r29);
+       COPY(r30);      COPY(r31);
+       COPY(pc);       COPY(ear);      COPY(esr);      COPY(fsr);
+#undef COPY
+
+       err |= __put_user(mask, &sc->oldmask);
+
+       return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+       /* Default to using normal stack */
+       unsigned long sp = regs->r1;
+
+       if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
+               sp = current->sas_ss_sp + current->sas_ss_size;
+
+       return (void *)((sp - frame_size) & -8UL);
+}
+
+static void setup_frame(int sig, struct k_sigaction *ka,
+                       sigset_t *set, struct pt_regs *regs)
+{
+       struct sigframe *frame;
+       int err = 0;
+       int signal;
+
+       frame = get_sigframe(ka, regs, sizeof(*frame));
+
+       if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+               goto give_sigsegv;
+
+       signal = current_thread_info()->exec_domain
+               && current_thread_info()->exec_domain->signal_invmap
+               && sig < 32
+               ? current_thread_info()->exec_domain->signal_invmap[sig]
+               : sig;
+
+       err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
+
+       if (_NSIG_WORDS > 1) {
+               err |= __copy_to_user(frame->extramask, &set->sig[1],
+                                       sizeof(frame->extramask));
+       }
+
+       /* Set up to return from userspace. If provided, use a stub
+        already in userspace. */
+       /* minus 8 is offset to cater for "rtsd r15,8" offset */
+       if (ka->sa.sa_flags & SA_RESTORER) {
+               regs->r15 = ((unsigned long)ka->sa.sa_restorer)-8;
+       } else {
+               /* Note, these encodings are _big endian_! */
+
+               /* addi r12, r0, __NR_sigreturn */
+               err |= __put_user(0x31800000 | __NR_sigreturn ,
+                               frame->tramp + 0);
+               /* brki r14, 0x8 */
+               err |= __put_user(0xb9cc0008, frame->tramp + 1);
+
+               /* Return from sighandler will jump to the tramp.
+                Negative 8 offset because return is rtsd r15, 8 */
+               regs->r15 = ((unsigned long)frame->tramp)-8;
+
+               __invalidate_cache_sigtramp((unsigned long)frame->tramp);
+       }
+
+       if (err)
+               goto give_sigsegv;
+
+       /* Set up registers for signal handler */
+       regs->r1 = (unsigned long) frame;
+       /* Signal handler args: */
+       regs->r5 = signal; /* Arg 0: signum */
+       regs->r6 = (unsigned long) &frame->sc; /* arg 1: sigcontext */
+
+       /* Offset of 4 to handle microblaze rtid r14, 0 */
+       regs->pc = (unsigned long)ka->sa.sa_handler;
+
+       set_fs(USER_DS);
+
+#ifdef DEBUG_SIG
+       printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
+               current->comm, current->pid, frame, regs->pc);
+#endif
+
+       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;
+       int signal;
+
+       frame = get_sigframe(ka, regs, sizeof(*frame));
+
+       if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+               goto give_sigsegv;
+
+       signal = current_thread_info()->exec_domain
+               && current_thread_info()->exec_domain->signal_invmap
+               && sig < 32
+               ? current_thread_info()->exec_domain->signal_invmap[sig]
+               : sig;
+
+       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->r1),
+                       &frame->uc.uc_stack.ss_flags);
+       err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+       err |= setup_sigcontext(&frame->uc.uc_mcontext,
+                       regs, set->sig[0]);
+       err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+       /* Set up to return from userspace. If provided, use a stub
+        already in userspace. */
+       /* minus 8 is offset to cater for "rtsd r15,8" */
+       if (ka->sa.sa_flags & SA_RESTORER) {
+               regs->r15 = ((unsigned long)ka->sa.sa_restorer)-8;
+       } else {
+               /* addi r12, r0, __NR_sigreturn */
+               err |= __put_user(0x31800000 | __NR_rt_sigreturn ,
+                               frame->tramp + 0);
+               /* brki r14, 0x8 */
+               err |= __put_user(0xb9cc0008, frame->tramp + 1);
+
+               /* Return from sighandler will jump to the tramp.
+                Negative 8 offset because return is rtsd r15, 8 */
+               regs->r15 = ((unsigned long)frame->tramp)-8;
+
+               __invalidate_cache_sigtramp((unsigned long)frame->tramp);
+       }
+
+       if (err)
+               goto give_sigsegv;
+
+       /* Set up registers for signal handler */
+       regs->r1 = (unsigned long) frame;
+       /* Signal handler args: */
+       regs->r5 = signal; /* arg 0: signum */
+       regs->r6 = (unsigned long) &frame->info; /* arg 1: siginfo */
+       regs->r7 = (unsigned long) &frame->uc; /* arg2: ucontext */
+       /* Offset to handle microblaze rtid r14, 0 */
+       regs->pc = (unsigned long)ka->sa.sa_handler;
+
+       set_fs(USER_DS);
+
+#ifdef DEBUG_SIG
+       printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
+               current->comm, current->pid, frame, regs->pc);
+#endif
+
+       return;
+
+give_sigsegv:
+       if (sig == SIGSEGV)
+               ka->sa.sa_handler = SIG_DFL;
+       force_sig(SIGSEGV, current);
+}
+
+/* Handle restarting system calls */
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+       switch (regs->r3) {
+       case -ERESTART_RESTARTBLOCK:
+       case -ERESTARTNOHAND:
+               if (!has_handler)
+                       goto do_restart;
+               regs->r3 = -EINTR;
+               break;
+       case -ERESTARTSYS:
+               if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+                       regs->r3 = -EINTR;
+                       break;
+       }
+       /* fallthrough */
+       case -ERESTARTNOINTR:
+do_restart:
+               /* offset of 4 bytes to re-execute trap (brki) instruction */
+               regs->pc -= 4;
+               break;
+       }
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+               siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
+{
+       /* Set up the stack frame */
+       if (ka->sa.sa_flags & SA_SIGINFO)
+               setup_rt_frame(sig, ka, info, oldset, regs);
+       else
+               setup_frame(sig, ka, oldset, regs);
+
+       if (ka->sa.sa_flags & SA_ONESHOT)
+               ka->sa.sa_handler = SIG_DFL;
+
+       if (!(ka->sa.sa_flags & SA_NODEFER)) {
+               spin_lock_irq(&current->sighand->siglock);
+               sigorsets(&current->blocked,
+                               &current->blocked, &ka->sa.sa_mask);
+               sigaddset(&current->blocked, sig);
+               recalc_sigpending();
+               spin_unlock_irq(&current->sighand->siglock);
+       }
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals that
+ * the kernel can handle, and then we build all the user-level signal handling
+ * stack-frames in one go after that.
+ */
+int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
+{
+       siginfo_t info;
+       int signr;
+       struct k_sigaction ka;
+#ifdef DEBUG_SIG
+       printk(KERN_INFO "do signal: %p %p %d\n", regs, oldset, in_syscall);
+       printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
+                       regs->r12, current_thread_info()->flags);
+#endif
+       /*
+        * 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 (kernel_mode(regs))
+               return 1;
+
+       if (!oldset)
+               oldset = &current->blocked;
+
+       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+       if (signr > 0) {
+               /* Whee! Actually deliver the signal. */
+               if (in_syscall)
+                       handle_restart(regs, &ka, 1);
+               handle_signal(signr, &ka, &info, oldset, regs);
+               return 1;
+       }
+
+       if (in_syscall)
+               handle_restart(regs, NULL, 0);
+
+       /* Did we come from a system call? */
+       return 0;
+}
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
new file mode 100644 (file)
index 0000000..d90b548
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *     Yasushi SHOJI <yashi@atmark-techno.com>
+ *     Tetsuya OHKAWA <tetsuya@atmark-techno.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/errno.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/syscalls.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/sys.h>
+#include <linux/ipc.h>
+#include <linux/utsname.h>
+#include <linux/file.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/ipc.h>
+#include <linux/semaphore.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+#include <linux/unistd.h>
+
+#include <asm/syscalls.h>
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly. This will be remove with new toolchain.
+ */
+asmlinkage int
+sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth)
+{
+       int version, ret;
+
+       version = call >> 16; /* hack for backward compatibility */
+       call &= 0xffff;
+
+       ret = -EINVAL;
+       switch (call) {
+       case SEMOP:
+               ret = sys_semop(first, (struct sembuf *)ptr, second);
+               break;
+       case SEMGET:
+               ret = sys_semget(first, second, third);
+               break;
+       case SEMCTL:
+       {
+               union semun fourth;
+
+               if (!ptr)
+                       break;
+               ret = (access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT)
+                               || (get_user(fourth.__pad, (void **)ptr)) ;
+               if (ret)
+                       break;
+               ret = sys_semctl(first, second, third, fourth);
+               break;
+       }
+       case MSGSND:
+               ret = sys_msgsnd(first, (struct msgbuf *) ptr, second, third);
+               break;
+       case MSGRCV:
+               switch (version) {
+               case 0: {
+                       struct ipc_kludge tmp;
+
+                       if (!ptr)
+                               break;
+                       ret = (access_ok(VERIFY_READ, ptr, sizeof(tmp))
+                               ? 0 : -EFAULT) || copy_from_user(&tmp,
+                               (struct ipc_kludge *) ptr, sizeof(tmp));
+                       if (ret)
+                               break;
+                       ret = sys_msgrcv(first, tmp.msgp, second, tmp.msgtyp,
+                                       third);
+                       break;
+                       }
+               default:
+                       ret = sys_msgrcv(first, (struct msgbuf *) ptr,
+                                       second, fifth, third);
+                       break;
+               }
+               break;
+       case MSGGET:
+               ret = sys_msgget((key_t) first, second);
+               break;
+       case MSGCTL:
+               ret = sys_msgctl(first, second, (struct msqid_ds *) ptr);
+               break;
+       case SHMAT:
+               switch (version) {
+               default: {
+                       ulong raddr;
+                       ret = access_ok(VERIFY_WRITE, (ulong *) third,
+                                       sizeof(ulong)) ? 0 : -EFAULT;
+                       if (ret)
+                               break;
+                       ret = do_shmat(first, (char *) ptr, second, &raddr);
+                       if (ret)
+                               break;
+                       ret = put_user(raddr, (ulong *) third);
+                       break;
+                       }
+               case 1: /* iBCS2 emulator entry point */
+                       if (!segment_eq(get_fs(), get_ds()))
+                               break;
+                       ret = do_shmat(first, (char *) ptr, second,
+                                       (ulong *) third);
+                       break;
+               }
+               break;
+       case SHMDT:
+               ret = sys_shmdt((char *)ptr);
+               break;
+       case SHMGET:
+               ret = sys_shmget(first, second, third);
+               break;
+       case SHMCTL:
+               ret = sys_shmctl(first, second, (struct shmid_ds *) ptr);
+               break;
+       }
+       return -EINVAL;
+}
+
+asmlinkage int sys_vfork(struct pt_regs *regs)
+{
+       return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r1,
+                                               regs, 0, NULL, NULL);
+}
+
+asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs)
+{
+       if (!stack)
+               stack = regs->r1;
+       return do_fork(flags, stack, regs, 0, NULL, NULL);
+}
+
+asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv,
+                       char __user *__user *envp, struct pt_regs *regs)
+{
+       int error;
+       char *filename;
+
+       filename = getname(filenamei);
+       error = PTR_ERR(filename);
+       if (IS_ERR(filename))
+               goto out;
+       error = do_execve(filename, argv, envp, regs);
+       putname(filename);
+out:
+       return error;
+}
+
+asmlinkage unsigned long
+sys_mmap2(unsigned long addr, size_t len,
+       unsigned long prot, unsigned long flags,
+       unsigned long fd, unsigned long pgoff)
+{
+       struct file *file = NULL;
+       int ret = -EBADF;
+
+       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+       if (!(flags & MAP_ANONYMOUS)) {
+               file = fget(fd);
+               if (!file) {
+                       printk(KERN_INFO "no fd in mmap\r\n");
+                       goto out;
+               }
+       }
+
+       down_write(&current->mm->mmap_sem);
+       ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+       up_write(&current->mm->mmap_sem);
+       if (file)
+               fput(file);
+out:
+       return ret;
+}
+
+asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
+                       unsigned long prot, unsigned long flags,
+                       unsigned long fd, off_t offset)
+{
+       int err = -EINVAL;
+
+       if (offset & ~PAGE_MASK) {
+               printk(KERN_INFO "no pagemask in mmap\r\n");
+               goto out;
+       }
+
+       err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+out:
+       return err;
+}
+
+/*
+ * 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 const char *__a __asm__("r5") = filename;
+       register const void *__b __asm__("r6") = argv;
+       register const void *__c __asm__("r7") = envp;
+       register unsigned long __syscall __asm__("r12") = __NR_execve;
+       register unsigned long __ret __asm__("r3");
+       __asm__ __volatile__ ("brki r14, 0x8"
+                       : "=r" (__ret), "=r" (__syscall)
+                       : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)
+                       : "r4", "r8", "r9",
+                       "r10", "r11", "r14", "cc", "memory");
+       return __ret;
+}
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
new file mode 100644 (file)
index 0000000..529b0db
--- /dev/null
@@ -0,0 +1,365 @@
+ENTRY(sys_call_table)
+       .long sys_restart_syscall       /* 0 - old "setup()" system call,
+                                        * used for restarting */
+       .long sys_exit
+       .long sys_ni_syscall            /* was 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_wrapper
+       .long sys_chdir
+       .long sys_time
+       .long sys_mknod
+       .long sys_chmod                 /* 15 */
+       .long sys_lchown
+       .long sys_ni_syscall            /* old break syscall holder */
+       .long sys_ni_syscall            /* old stat */
+       .long sys_lseek
+       .long sys_getpid                /* 20 */
+       .long sys_mount
+       .long sys_oldumount
+       .long sys_setuid
+       .long sys_getuid
+       .long sys_stime                 /* 25 */
+       .long sys_ptrace
+       .long sys_alarm
+       .long sys_ni_syscall            /* oldfstat */
+       .long sys_pause
+       .long sys_utime                 /* 30 */
+       .long sys_ni_syscall            /* old stty syscall holder */
+       .long sys_ni_syscall            /* old gtty syscall holder */
+       .long sys_access
+       .long sys_nice
+       .long sys_ni_syscall            /* 35 - old ftime syscall holder */
+       .long sys_sync
+       .long sys_kill
+       .long sys_rename
+       .long sys_mkdir
+       .long sys_rmdir                 /* 40 */
+       .long sys_dup
+       .long sys_pipe
+       .long sys_times
+       .long sys_ni_syscall            /* old prof syscall holder */
+       .long sys_brk                   /* 45 */
+       .long sys_setgid
+       .long sys_getgid
+       .long sys_signal
+       .long sys_geteuid
+       .long sys_getegid               /* 50 */
+       .long sys_acct
+       .long sys_umount                /* recycled never used phys() */
+       .long sys_ni_syscall            /* old lock syscall holder */
+       .long sys_ioctl
+       .long sys_fcntl                 /* 55 */
+       .long sys_ni_syscall            /* old mpx syscall holder */
+       .long sys_setpgid
+       .long sys_ni_syscall            /* old ulimit syscall holder */
+       .long sys_ni_syscall            /* olduname */
+       .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_setreuid              /* 70 */
+       .long sys_setregid
+       .long sys_sigsuspend_wrapper
+       .long sys_sigpending
+       .long sys_sethostname
+       .long sys_setrlimit             /* 75 */
+       .long sys_ni_syscall            /* old_getrlimit */
+       .long sys_getrusage
+       .long sys_gettimeofday
+       .long sys_settimeofday
+       .long sys_getgroups             /* 80 */
+       .long sys_setgroups
+       .long sys_ni_syscall            /* old_select */
+       .long sys_symlink
+       .long sys_ni_syscall            /* oldlstat */
+       .long sys_readlink              /* 85 */
+       .long sys_uselib
+       .long sys_swapon
+       .long sys_reboot
+       .long sys_ni_syscall            /* old_readdir */
+       .long sys_mmap                  /* 90 */ /* old_mmap */
+       .long sys_munmap
+       .long sys_truncate
+       .long sys_ftruncate
+       .long sys_fchmod
+       .long sys_fchown                /* 95 */
+       .long sys_getpriority
+       .long sys_setpriority
+       .long sys_ni_syscall            /* old profil syscall holder */
+       .long sys_statfs
+       .long sys_fstatfs               /* 100 */
+       .long sys_ni_syscall            /* ioperm */
+       .long sys_socketcall
+       .long sys_syslog                /* operation with system console */
+       .long sys_setitimer
+       .long sys_getitimer             /* 105 */
+       .long sys_newstat
+       .long sys_newlstat
+       .long sys_newfstat
+       .long sys_ni_syscall            /* uname */
+       .long sys_ni_syscall            /* 110 */ /* iopl */
+       .long sys_vhangup
+       .long sys_ni_syscall            /* old "idle" system call */
+       .long sys_ni_syscall            /* old sys_vm86old */
+       .long sys_wait4
+       .long sys_swapoff               /* 115 */
+       .long sys_sysinfo
+       .long sys_ipc
+       .long sys_fsync
+       .long sys_sigreturn_wrapper
+       .long sys_clone_wrapper         /* 120 */
+       .long sys_setdomainname
+       .long sys_newuname
+       .long sys_ni_syscall            /* modify_ldt */
+       .long sys_adjtimex
+       .long sys_mprotect              /* 125: sys_mprotect */
+       .long sys_sigprocmask
+       .long sys_ni_syscall            /* old "create_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            /* reserved for afs_syscall */
+       .long sys_setfsuid
+       .long sys_setfsgid
+       .long sys_llseek                /* 140 */
+       .long sys_getdents
+       .long sys_select
+       .long sys_flock
+       .long sys_msync
+       .long sys_readv                 /* 145 */
+       .long sys_writev
+       .long sys_getsid
+       .long sys_fdatasync
+       .long sys_sysctl
+       .long sys_mlock         /* 150: sys_mlock */
+       .long sys_munlock
+       .long sys_mlockall
+       .long sys_munlockall
+       .long sys_sched_setparam
+       .long sys_sched_getparam        /* 155 */
+       .long sys_sched_setscheduler
+       .long sys_sched_getscheduler
+       .long sys_sched_yield
+       .long sys_sched_get_priority_max
+       .long sys_sched_get_priority_min        /* 160 */
+       .long sys_sched_rr_get_interval
+       .long sys_nanosleep
+       .long sys_mremap
+       .long sys_setresuid
+       .long sys_getresuid             /* 165 */
+       .long sys_ni_syscall            /* sys_vm86 */
+       .long sys_ni_syscall            /* Old sys_query_module */
+       .long sys_poll
+       .long sys_nfsservctl
+       .long sys_setresgid             /* 170 */
+       .long sys_getresgid
+       .long sys_prctl
+       .long sys_rt_sigreturn_wrapper
+       .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_wrapper
+       .long sys_pread64               /* 180 */
+       .long sys_pwrite64
+       .long sys_chown
+       .long sys_getcwd
+       .long sys_capget
+       .long sys_capset                /* 185 */
+       .long sys_ni_syscall            /* sigaltstack */
+       .long sys_sendfile
+       .long sys_ni_syscall            /* reserved for streams1 */
+       .long sys_ni_syscall            /* reserved for streams2 */
+       .long sys_vfork_wrapper         /* 190 */
+       .long sys_getrlimit
+       .long sys_mmap2                 /* mmap2 */
+       .long sys_truncate64
+       .long sys_ftruncate64
+       .long sys_stat64                /* 195 */
+       .long sys_lstat64
+       .long sys_fstat64
+       .long sys_lchown
+       .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_chown
+       .long sys_setuid
+       .long sys_setgid
+       .long sys_setfsuid              /* 215 */
+       .long sys_setfsgid
+       .long sys_pivot_root
+       .long sys_mincore
+       .long sys_madvise
+       .long sys_getdents64            /* 220 */
+       .long sys_fcntl64
+       .long sys_ni_syscall            /* reserved for TUX */
+       .long sys_ni_syscall
+       .long sys_gettid
+       .long sys_readahead             /* 225 */
+       .long sys_setxattr
+       .long sys_lsetxattr
+       .long sys_fsetxattr
+       .long sys_getxattr
+       .long sys_lgetxattr             /* 230 */
+       .long sys_fgetxattr
+       .long sys_listxattr
+       .long sys_llistxattr
+       .long sys_flistxattr
+       .long sys_removexattr           /* 235 */
+       .long sys_lremovexattr
+       .long sys_fremovexattr
+       .long sys_tkill
+       .long sys_sendfile64
+       .long sys_futex                 /* 240 */
+       .long sys_sched_setaffinity
+       .long sys_sched_getaffinity
+       .long sys_ni_syscall            /* set_thread_area */
+       .long sys_ni_syscall            /* get_thread_area */
+       .long sys_io_setup              /* 245 */
+       .long sys_io_destroy
+       .long sys_io_getevents
+       .long sys_io_submit
+       .long sys_io_cancel
+       .long sys_fadvise64             /* 250 */
+       .long sys_ni_syscall
+       .long sys_exit_group
+       .long sys_lookup_dcookie
+       .long sys_epoll_create
+       .long sys_epoll_ctl             /* 255 */
+       .long sys_epoll_wait
+       .long sys_remap_file_pages
+       .long sys_set_tid_address
+       .long sys_timer_create
+       .long sys_timer_settime         /* 260 */
+       .long sys_timer_gettime
+       .long sys_timer_getoverrun
+       .long sys_timer_delete
+       .long sys_clock_settime
+       .long sys_clock_gettime         /* 265 */
+       .long sys_clock_getres
+       .long sys_clock_nanosleep
+       .long sys_statfs64
+       .long sys_fstatfs64
+       .long sys_tgkill                /* 270 */
+       .long sys_utimes
+       .long sys_fadvise64_64
+       .long sys_ni_syscall            /* sys_vserver */
+       .long sys_mbind
+       .long sys_get_mempolicy
+       .long sys_set_mempolicy
+       .long sys_mq_open
+       .long sys_mq_unlink
+       .long sys_mq_timedsend
+       .long sys_mq_timedreceive       /* 280 */
+       .long sys_mq_notify
+       .long sys_mq_getsetattr
+       .long sys_kexec_load
+       .long sys_waitid
+       .long sys_ni_syscall            /* 285 */ /* available */
+       .long sys_add_key
+       .long sys_request_key
+       .long sys_keyctl
+       .long sys_ioprio_set
+       .long sys_ioprio_get            /* 290 */
+       .long sys_inotify_init
+       .long sys_inotify_add_watch
+       .long sys_inotify_rm_watch
+       .long sys_ni_syscall            /* sys_migrate_pages */
+       .long sys_openat        /* 295 */
+       .long sys_mkdirat
+       .long sys_mknodat
+       .long sys_fchownat
+       .long sys_ni_syscall
+       .long sys_fstatat64             /* 300 */
+       .long sys_unlinkat
+       .long sys_renameat
+       .long sys_linkat
+       .long sys_symlinkat
+       .long sys_readlinkat            /* 305 */
+       .long sys_fchmodat
+       .long sys_faccessat
+       .long sys_ni_syscall /* pselect6 */
+       .long sys_ni_syscall /* sys_ppoll */
+       .long sys_unshare               /* 310 */
+       .long sys_set_robust_list
+       .long sys_get_robust_list
+       .long sys_splice
+       .long sys_sync_file_range
+       .long sys_tee                   /* 315 */
+       .long sys_vmsplice
+       .long sys_move_pages
+       .long sys_getcpu
+       .long sys_epoll_pwait
+       .long sys_utimensat             /* 320 */
+       .long sys_signalfd
+       .long sys_timerfd_create
+       .long sys_eventfd
+       .long sys_fallocate
+       .long sys_semtimedop            /* 325 */
+       .long sys_timerfd_settime
+       .long sys_timerfd_gettime
+       .long sys_semctl
+       .long sys_semget
+       .long sys_semop                 /* 330 */
+       .long sys_msgctl
+       .long sys_msgget
+       .long sys_msgrcv
+       .long sys_msgsnd
+       .long sys_shmat                 /* 335 */
+       .long sys_shmctl
+       .long sys_shmdt
+       .long sys_shmget
+       .long sys_signalfd4     /* new syscall */
+       .long sys_eventfd2              /* 340 */
+       .long sys_epoll_create1
+       .long sys_dup3
+       .long sys_pipe2
+       .long sys_inotify_init1
+       .long sys_socket                /* 345 */
+       .long sys_socketpair
+       .long sys_bind
+       .long sys_listen
+       .long sys_accept
+       .long sys_connect               /* 350 */
+       .long sys_getsockname
+       .long sys_getpeername
+       .long sys_sendto
+       .long sys_send
+       .long sys_recvfrom              /* 355 */
+       .long sys_recv
+       .long sys_setsockopt
+       .long sys_getsockopt
+       .long sys_shutdown
+       .long sys_sendmsg               /* 360 */
+       .long sys_recvmsg
+       .long sys_ni_syscall
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
new file mode 100644 (file)
index 0000000..05a497e
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/interrupt.h>
+#include <linux/profile.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <asm/cpuinfo.h>
+#include <asm/setup.h>
+#include <asm/prom.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_SELFMOD_TIMER
+#include <asm/selfmod.h>
+#define TIMER_BASE     BARRIER_BASE_ADDR
+#else
+static unsigned int timer_baseaddr;
+#define TIMER_BASE     timer_baseaddr
+#endif
+
+#define TCSR0  (0x00)
+#define TLR0   (0x04)
+#define TCR0   (0x08)
+#define TCSR1  (0x10)
+#define TLR1   (0x14)
+#define TCR1   (0x18)
+
+#define TCSR_MDT       (1<<0)
+#define TCSR_UDT       (1<<1)
+#define TCSR_GENT      (1<<2)
+#define TCSR_CAPT      (1<<3)
+#define TCSR_ARHT      (1<<4)
+#define TCSR_LOAD      (1<<5)
+#define TCSR_ENIT      (1<<6)
+#define TCSR_ENT       (1<<7)
+#define TCSR_TINT      (1<<8)
+#define TCSR_PWMA      (1<<9)
+#define TCSR_ENALL     (1<<10)
+
+static inline void microblaze_timer0_stop(void)
+{
+       out_be32(TIMER_BASE + TCSR0, in_be32(TIMER_BASE + TCSR0) & ~TCSR_ENT);
+}
+
+static inline void microblaze_timer0_start_periodic(unsigned long load_val)
+{
+       if (!load_val)
+               load_val = 1;
+       out_be32(TIMER_BASE + TLR0, load_val); /* loading value to timer reg */
+
+       /* load the initial value */
+       out_be32(TIMER_BASE + TCSR0, TCSR_LOAD);
+
+       /* see timer data sheet for detail
+        * !ENALL - don't enable 'em all
+        * !PWMA - disable pwm
+        * TINT - clear interrupt status
+        * ENT- enable timer itself
+        * EINT - enable interrupt
+        * !LOAD - clear the bit to let go
+        * ARHT - auto reload
+        * !CAPT - no external trigger
+        * !GENT - no external signal
+        * UDT - set the timer as down counter
+        * !MDT0 - generate mode
+        */
+       out_be32(TIMER_BASE + TCSR0,
+                       TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT);
+}
+
+static inline void microblaze_timer0_start_oneshot(unsigned long load_val)
+{
+       if (!load_val)
+               load_val = 1;
+       out_be32(TIMER_BASE + TLR0, load_val); /* loading value to timer reg */
+
+       /* load the initial value */
+       out_be32(TIMER_BASE + TCSR0, TCSR_LOAD);
+
+       out_be32(TIMER_BASE + TCSR0,
+                       TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT);
+}
+
+static int microblaze_timer_set_next_event(unsigned long delta,
+                                       struct clock_event_device *dev)
+{
+       pr_debug("%s: next event, delta %x\n", __func__, (u32)delta);
+       microblaze_timer0_start_oneshot(delta);
+       return 0;
+}
+
+static void microblaze_timer_set_mode(enum clock_event_mode mode,
+                               struct clock_event_device *evt)
+{
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               printk(KERN_INFO "%s: periodic\n", __func__);
+               microblaze_timer0_start_periodic(cpuinfo.freq_div_hz);
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+               printk(KERN_INFO "%s: oneshot\n", __func__);
+               break;
+       case CLOCK_EVT_MODE_UNUSED:
+               printk(KERN_INFO "%s: unused\n", __func__);
+               break;
+       case CLOCK_EVT_MODE_SHUTDOWN:
+               printk(KERN_INFO "%s: shutdown\n", __func__);
+               microblaze_timer0_stop();
+               break;
+       case CLOCK_EVT_MODE_RESUME:
+               printk(KERN_INFO "%s: resume\n", __func__);
+               break;
+       }
+}
+
+static struct clock_event_device clockevent_microblaze_timer = {
+       .name           = "microblaze_clockevent",
+       .features       = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
+       .shift          = 24,
+       .rating         = 300,
+       .set_next_event = microblaze_timer_set_next_event,
+       .set_mode       = microblaze_timer_set_mode,
+};
+
+static inline void timer_ack(void)
+{
+       out_be32(TIMER_BASE + TCSR0, in_be32(TIMER_BASE + TCSR0));
+}
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = &clockevent_microblaze_timer;
+#ifdef CONFIG_HEART_BEAT
+       heartbeat();
+#endif
+       timer_ack();
+       evt->event_handler(evt);
+       return IRQ_HANDLED;
+}
+
+static struct irqaction timer_irqaction = {
+       .handler = timer_interrupt,
+       .flags = IRQF_DISABLED | IRQF_TIMER,
+       .name = "timer",
+       .dev_id = &clockevent_microblaze_timer,
+};
+
+static __init void microblaze_clockevent_init(void)
+{
+       clockevent_microblaze_timer.mult =
+               div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC,
+                               clockevent_microblaze_timer.shift);
+       clockevent_microblaze_timer.max_delta_ns =
+               clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
+       clockevent_microblaze_timer.min_delta_ns =
+               clockevent_delta2ns(1, &clockevent_microblaze_timer);
+       clockevent_microblaze_timer.cpumask = cpumask_of(0);
+       clockevents_register_device(&clockevent_microblaze_timer);
+}
+
+static cycle_t microblaze_read(void)
+{
+       /* reading actual value of timer 1 */
+       return (cycle_t) (in_be32(TIMER_BASE + TCR1));
+}
+
+static struct clocksource clocksource_microblaze = {
+       .name           = "microblaze_clocksource",
+       .rating         = 300,
+       .read           = microblaze_read,
+       .mask           = CLOCKSOURCE_MASK(32),
+       .shift          = 24, /* I can shift it */
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init microblaze_clocksource_init(void)
+{
+       clocksource_microblaze.mult =
+                       clocksource_hz2mult(cpuinfo.cpu_clock_freq,
+                                               clocksource_microblaze.shift);
+       if (clocksource_register(&clocksource_microblaze))
+               panic("failed to register clocksource");
+
+       /* stop timer1 */
+       out_be32(TIMER_BASE + TCSR1, in_be32(TIMER_BASE + TCSR1) & ~TCSR_ENT);
+       /* start timer1 - up counting without interrupt */
+       out_be32(TIMER_BASE + TCSR1, TCSR_TINT|TCSR_ENT|TCSR_ARHT);
+       return 0;
+}
+
+void __init time_init(void)
+{
+       u32 irq, i = 0;
+       u32 timer_num = 1;
+       struct device_node *timer = NULL;
+#ifdef CONFIG_SELFMOD_TIMER
+       unsigned int timer_baseaddr = 0;
+       int arr_func[] = {
+                               (int)&microblaze_read,
+                               (int)&timer_interrupt,
+                               (int)&microblaze_clocksource_init,
+                               (int)&microblaze_timer_set_mode,
+                               (int)&microblaze_timer_set_next_event,
+                               0
+                       };
+#endif
+       char *timer_list[] = {
+                               "xlnx,xps-timer-1.00.a",
+                               "xlnx,opb-timer-1.00.b",
+                               "xlnx,opb-timer-1.00.a",
+                               NULL
+                       };
+
+       for (i = 0; timer_list[i] != NULL; i++) {
+               timer = of_find_compatible_node(NULL, NULL, timer_list[i]);
+               if (timer)
+                       break;
+       }
+
+       timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL);
+       timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
+       irq = *(int *) of_get_property(timer, "interrupts", NULL);
+       timer_num =
+               *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL);
+       if (timer_num) {
+               printk(KERN_EMERG "Please enable two timers in HW\n");
+               BUG();
+       }
+
+#ifdef CONFIG_SELFMOD_TIMER
+       selfmod_function((int *) arr_func, timer_baseaddr);
+#endif
+       printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
+               timer_list[i], timer_baseaddr, irq);
+
+       cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ;
+
+       setup_irq(irq, &timer_irqaction);
+#ifdef CONFIG_HEART_BEAT
+       setup_heartbeat();
+#endif
+       microblaze_clocksource_init();
+       microblaze_clockevent_init();
+}
diff --git a/arch/microblaze/kernel/traps.c b/arch/microblaze/kernel/traps.c
new file mode 100644 (file)
index 0000000..fbdc533
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/kallsyms.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/debug_locks.h>
+
+#include <asm/exceptions.h>
+#include <asm/system.h>
+
+void trap_init(void)
+{
+       __enable_hw_exceptions();
+}
+
+void __bad_xchg(volatile void *ptr, int size)
+{
+       printk(KERN_INFO "xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
+               __builtin_return_address(0), ptr, size);
+       BUG();
+}
+EXPORT_SYMBOL(__bad_xchg);
+
+static int kstack_depth_to_print = 24;
+
+static int __init kstack_setup(char *s)
+{
+       kstack_depth_to_print = strict_strtoul(s, 0, 0);
+
+       return 1;
+}
+__setup("kstack=", kstack_setup);
+
+void show_trace(struct task_struct *task, unsigned long *stack)
+{
+       unsigned long addr;
+
+       if (!stack)
+               stack = (unsigned long *)&stack;
+
+       printk(KERN_NOTICE "Call Trace: ");
+#ifdef CONFIG_KALLSYMS
+       printk(KERN_NOTICE "\n");
+#endif
+       while (!kstack_end(stack)) {
+               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 (kernel_text_address(addr))
+                       print_ip_sym(addr);
+       }
+       printk(KERN_NOTICE "\n");
+
+       if (!task)
+               task = current;
+
+       debug_show_held_locks(task);
+}
+
+void show_stack(struct task_struct *task, unsigned long *sp)
+{
+       unsigned long *stack;
+       int i;
+
+       if (sp == NULL) {
+               if (task)
+                       sp = (unsigned long *) ((struct thread_info *)
+                                               (task->stack))->cpu_context.r1;
+               else
+                       sp = (unsigned long *)&sp;
+       }
+
+       stack = sp;
+
+       printk(KERN_INFO "\nStack:\n  ");
+
+       for (i = 0; i < kstack_depth_to_print; i++) {
+               if (kstack_end(sp))
+                       break;
+               if (i && ((i % 8) == 0))
+                       printk("\n  ");
+               printk("%08lx ", *sp++);
+       }
+       printk("\n");
+       show_trace(task, stack);
+}
+
+void dump_stack(void)
+{
+       show_stack(NULL, NULL);
+}
+EXPORT_SYMBOL(dump_stack);
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
new file mode 100644 (file)
index 0000000..840385e
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
+OUTPUT_ARCH(microblaze)
+ENTRY(_start)
+
+#include <asm-generic/vmlinux.lds.h>
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+       . = CONFIG_KERNEL_BASE_ADDR;
+
+       .text : {
+               _text = . ;
+               _stext = . ;
+               *(.text .text.*)
+               *(.fixup)
+
+               *(.exitcall.exit)
+               SCHED_TEXT
+               LOCK_TEXT
+               KPROBES_TEXT
+               . = ALIGN (4) ;
+               _etext = . ;
+       }
+
+       . = ALIGN (4) ;
+       _fdt_start = . ; /* place for fdt blob */
+       . = . + 0x4000;
+       _fdt_end = . ;
+
+       . = ALIGN(16);
+       RODATA
+       . = ALIGN(16);
+       __ex_table : {
+               __start___ex_table = .;
+               *(__ex_table)
+               __stop___ex_table = .;
+       }
+
+       /*
+        * sdata2 section can go anywhere, but must be word aligned
+        * and SDA2_BASE must point to the middle of it
+        */
+       .sdata2 : {
+               _ssrw = .;
+               . = ALIGN(4096); /* page aligned when MMU used - origin 0x8 */
+               *(.sdata2)
+       . = ALIGN(8);
+       _essrw = .;
+       _ssrw_size = _essrw - _ssrw;
+       _KERNEL_SDA2_BASE_ = _ssrw + (_ssrw_size / 2);
+       }
+
+       _sdata = . ;
+       .data ALIGN (4096) : { /* page aligned when MMU used - origin 0x4 */
+               *(.data)
+       }
+       . = ALIGN(32);
+       .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+       _edata = . ;
+
+       /* Reserve some low RAM for r0 based memory references */
+       . = ALIGN(0x4) ;
+       r0_ram = . ;
+       . = . +  4096;  /* a page should be enough */
+
+       /* The initial task */
+       . = ALIGN(8192);
+       .data.init_task : { *(.data.init_task) }
+
+       /* Under the microblaze ABI, .sdata and .sbss must be contiguous */
+       . = ALIGN(8);
+       .sdata : {
+               _ssro = .;
+               *(.sdata)
+       }
+
+       .sbss : {
+               _ssbss = .;
+               *(.sbss)
+               _esbss = .;
+               _essro = .;
+               _ssro_size = _essro - _ssro ;
+               _KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2) ;
+       }
+
+       __init_begin = .;
+
+       . = ALIGN(4096);
+       .init.text : {
+               _sinittext = . ;
+               *(.init.text)
+               *(.exit.text)
+               *(.exit.data)
+               _einittext = .;
+       }
+
+       .init.data : { *(.init.data) }
+
+       . = ALIGN(4);
+       .init.ivt : {
+               __ivt_start = .;
+               *(.init.ivt)
+               __ivt_end = .;
+       }
+
+       .init.setup : {
+               __setup_start = .;
+               *(.init.setup)
+               __setup_end = .;
+       }
+
+       .initcall.init : {
+               __initcall_start = .;
+               INITCALLS
+               __initcall_end = .;
+       }
+
+       .con_initcall.init : {
+               __con_initcall_start = .;
+               *(.con_initcall.init)
+               __con_initcall_end = .;
+       }
+
+       __init_end_before_initramfs = .;
+
+       .init.ramfs ALIGN(4096) : {
+               __initramfs_start = .;
+               *(.init.ramfs)
+               __initramfs_end = .;
+               . = ALIGN(4);
+               LONG(0);
+/*
+ * FIXME this can break initramfs for MMU.
+ * Pad init.ramfs up to page boundary,
+ * so that __init_end == __bss_start. This will make image.elf
+ * consistent with the image.bin
+ */
+               /* . = ALIGN(4096); */
+       }
+       __init_end = .;
+
+       .bss ALIGN (4096) : { /* page aligned when MMU used */
+               __bss_start = . ;
+                       *(.bss*)
+                       *(COMMON)
+               . = ALIGN (4) ;
+               __bss_stop = . ;
+               _ebss = . ;
+       }
+       . = ALIGN(4096);
+       _end = .;
+}
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile
new file mode 100644 (file)
index 0000000..d27126b
--- /dev/null
@@ -0,0 +1,13 @@
+#
+# Makefile
+#
+
+lib-y :=  memset.o checksum.o
+
+ifeq ($(CONFIG_OPT_LIB_ASM),y)
+lib-y += fastcopy.o
+else
+lib-y += memcpy.o memmove.o
+endif
+
+lib-y +=  uaccess.o
diff --git a/arch/microblaze/lib/checksum.c b/arch/microblaze/lib/checksum.c
new file mode 100644 (file)
index 0000000..8093400
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ *
+ * INET                An implementation of the TCP/IP protocol suite for the LINUX
+ *             operating system.  INET is implemented using the  BSD Socket
+ *             interface as the means of communication with the user level.
+ *
+ *             IP/TCP/UDP checksumming routines
+ *
+ * Authors:    Jorge Cwik, <jorge@laser.satlink.net>
+ *             Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *             Tom May, <ftom@netcom.com>
+ *             Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
+ *             Lots of code moved from tcp.c and ip.c; see those files
+ *             for more names.
+ *
+ * 03/02/96    Jes Sorensen, Andreas Schwab, Roman Hodek:
+ *             Fixed some nasty bugs, causing some horrible crashes.
+ *             A: At some points, the sum (%0) was used as
+ *             length-counter instead of the length counter
+ *             (%1). Thanks to Roman Hodek for pointing this out.
+ *             B: GCC seems to mess up if one uses too many
+ *             data-registers to hold input values and one tries to
+ *             specify d0 and d1 as scratch registers. Letting gcc
+ *             choose these registers itself solves the problem.
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or (at your option) any later version.
+ */
+
+/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access
+ kills, so most of the assembly has to go. */
+
+#include <net/checksum.h>
+#include <asm/checksum.h>
+#include <linux/module.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+       /* add up 16-bit and 16-bit for 16+c bit */
+       x = (x & 0xffff) + (x >> 16);
+       /* add up carry.. */
+       x = (x & 0xffff) + (x >> 16);
+       return x;
+}
+
+static unsigned int do_csum(const unsigned char *buff, int len)
+{
+       int odd, count;
+       unsigned long result = 0;
+
+       if (len <= 0)
+               goto out;
+       odd = 1 & (unsigned long) buff;
+       if (odd) {
+               result = *buff;
+               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 << 8);
+       result = from32to16(result);
+       if (odd)
+               result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+       return result;
+}
+
+/*
+ *     This is a version of ip_compute_csum() optimized for IP headers,
+ *     which always checksum on 4 octet boundaries.
+ */
+__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+       return (__force __sum16)~do_csum(iph, ihl*4);
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+__wsum csum_partial(const void *buff, int len, __wsum sum)
+{
+       unsigned int result = do_csum(buff, len);
+
+       /* add in old sum, and carry.. */
+       result += sum;
+       if (sum > result)
+               result += 1;
+       return result;
+}
+EXPORT_SYMBOL(csum_partial);
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+__sum16 ip_compute_csum(const unsigned char *buff, int len)
+{
+       return ~do_csum(buff, len);
+}
+EXPORT_SYMBOL(ip_compute_csum);
+
+/*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+__wsum
+csum_partial_copy_from_user(const char __user *src, char *dst, int len,
+                                               int sum, int *csum_err)
+{
+       if (csum_err)
+               *csum_err = 0;
+       memcpy(dst, src, len);
+       return csum_partial(dst, len, sum);
+}
+EXPORT_SYMBOL(csum_partial_copy_from_user);
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+__wsum
+csum_partial_copy(const char *src, char *dst, int len, int sum)
+{
+       memcpy(dst, src, len);
+       return csum_partial(dst, len, sum);
+}
+EXPORT_SYMBOL(csum_partial_copy);
diff --git a/arch/microblaze/lib/fastcopy.S b/arch/microblaze/lib/fastcopy.S
new file mode 100644 (file)
index 0000000..02e3ab4
--- /dev/null
@@ -0,0 +1,662 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2008 Jim Law - Iris LP  All rights reserved.
+ *
+ * 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 Jim Law <jlaw@irispower.com>
+ *
+ * intended to replace:
+ *     memcpy in memcpy.c and
+ *     memmove in memmove.c
+ * ... in arch/microblaze/lib
+ *
+ *
+ * assly_fastcopy.S
+ *
+ * Attempt at quicker memcpy and memmove for MicroBlaze
+ *     Input : Operand1 in Reg r5 - destination address
+ *             Operand2 in Reg r6 - source address
+ *             Operand3 in Reg r7 - number of bytes to transfer
+ *     Output: Result in Reg r3 - starting destinaition address
+ *
+ *
+ * Explanation:
+ *     Perform (possibly unaligned) copy of a block of memory
+ *     between mem locations with size of xfer spec'd in bytes
+ */
+
+#include <linux/linkage.h>
+
+       .globl  memcpy
+       .ent    memcpy
+
+memcpy:
+fast_memcpy_ascending:
+       /* move d to return register as value of function */
+       addi    r3, r5, 0
+
+       addi    r4, r0, 4       /* n = 4 */
+       cmpu    r4, r4, r7      /* n = c - n  (unsigned) */
+       blti    r4, a_xfer_end  /* if n < 0, less than one word to transfer */
+
+       /* transfer first 0~3 bytes to get aligned dest address */
+       andi    r4, r5, 3               /* n = d & 3 */
+       /* if zero, destination already aligned */
+       beqi    r4, a_dalign_done
+       /* n = 4 - n (yields 3, 2, 1 transfers for 1, 2, 3 addr offset) */
+       rsubi   r4, r4, 4
+       rsub    r7, r4, r7              /* c = c - n adjust c */
+
+a_xfer_first_loop:
+       /* if no bytes left to transfer, transfer the bulk */
+       beqi    r4, a_dalign_done
+       lbui    r11, r6, 0              /* h = *s */
+       sbi     r11, r5, 0              /* *d = h */
+       addi    r6, r6, 1               /* s++ */
+       addi    r5, r5, 1               /* d++ */
+       brid    a_xfer_first_loop       /* loop */
+       addi    r4, r4, -1              /* n-- (IN DELAY SLOT) */
+
+a_dalign_done:
+       addi    r4, r0, 32              /* n = 32 */
+       cmpu    r4, r4, r7              /* n = c - n  (unsigned) */
+       /* if n < 0, less than one block to transfer */
+       blti    r4, a_block_done
+
+a_block_xfer:
+       andi    r4, r7, 0xffffffe0      /* n = c & ~31 */
+       rsub    r7, r4, r7              /* c = c - n */
+
+       andi    r9, r6, 3               /* t1 = s & 3 */
+       /* if temp != 0, unaligned transfers needed */
+       bnei    r9, a_block_unaligned
+
+a_block_aligned:
+       lwi     r9, r6, 0               /* t1 = *(s + 0) */
+       lwi     r10, r6, 4              /* t2 = *(s + 4) */
+       lwi     r11, r6, 8              /* t3 = *(s + 8) */
+       lwi     r12, r6, 12             /* t4 = *(s + 12) */
+       swi     r9, r5, 0               /* *(d + 0) = t1 */
+       swi     r10, r5, 4              /* *(d + 4) = t2 */
+       swi     r11, r5, 8              /* *(d + 8) = t3 */
+       swi     r12, r5, 12             /* *(d + 12) = t4 */
+       lwi     r9, r6, 16              /* t1 = *(s + 16) */
+       lwi     r10, r6, 20             /* t2 = *(s + 20) */
+       lwi     r11, r6, 24             /* t3 = *(s + 24) */
+       lwi     r12, r6, 28             /* t4 = *(s + 28) */
+       swi     r9, r5, 16              /* *(d + 16) = t1 */
+       swi     r10, r5, 20             /* *(d + 20) = t2 */
+       swi     r11, r5, 24             /* *(d + 24) = t3 */
+       swi     r12, r5, 28             /* *(d + 28) = t4 */
+       addi    r6, r6, 32              /* s = s + 32 */
+       addi    r4, r4, -32             /* n = n - 32 */
+       bneid   r4, a_block_aligned     /* while (n) loop */
+       addi    r5, r5, 32              /* d = d + 32 (IN DELAY SLOT) */
+       bri     a_block_done
+
+a_block_unaligned:
+       andi    r8, r6, 0xfffffffc      /* as = s & ~3 */
+       add     r6, r6, r4              /* s = s + n */
+       lwi     r11, r8, 0              /* h = *(as + 0) */
+
+       addi    r9, r9, -1
+       beqi    r9, a_block_u1          /* t1 was 1 => 1 byte offset */
+       addi    r9, r9, -1
+       beqi    r9, a_block_u2          /* t1 was 2 => 2 byte offset */
+
+a_block_u3:
+       bslli   r11, r11, 24    /* h = h << 24 */
+a_bu3_loop:
+       lwi     r12, r8, 4      /* v = *(as + 4) */
+       bsrli   r9, r12, 8      /* t1 = v >> 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 0       /* *(d + 0) = t1 */
+       bslli   r11, r12, 24    /* h = v << 24 */
+       lwi     r12, r8, 8      /* v = *(as + 8) */
+       bsrli   r9, r12, 8      /* t1 = v >> 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 4       /* *(d + 4) = t1 */
+       bslli   r11, r12, 24    /* h = v << 24 */
+       lwi     r12, r8, 12     /* v = *(as + 12) */
+       bsrli   r9, r12, 8      /* t1 = v >> 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 8       /* *(d + 8) = t1 */
+       bslli   r11, r12, 24    /* h = v << 24 */
+       lwi     r12, r8, 16     /* v = *(as + 16) */
+       bsrli   r9, r12, 8      /* t1 = v >> 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 12      /* *(d + 12) = t1 */
+       bslli   r11, r12, 24    /* h = v << 24 */
+       lwi     r12, r8, 20     /* v = *(as + 20) */
+       bsrli   r9, r12, 8      /* t1 = v >> 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 16      /* *(d + 16) = t1 */
+       bslli   r11, r12, 24    /* h = v << 24 */
+       lwi     r12, r8, 24     /* v = *(as + 24) */
+       bsrli   r9, r12, 8      /* t1 = v >> 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 20      /* *(d + 20) = t1 */
+       bslli   r11, r12, 24    /* h = v << 24 */
+       lwi     r12, r8, 28     /* v = *(as + 28) */
+       bsrli   r9, r12, 8      /* t1 = v >> 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 24      /* *(d + 24) = t1 */
+       bslli   r11, r12, 24    /* h = v << 24 */
+       lwi     r12, r8, 32     /* v = *(as + 32) */
+       bsrli   r9, r12, 8      /* t1 = v >> 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 28      /* *(d + 28) = t1 */
+       bslli   r11, r12, 24    /* h = v << 24 */
+       addi    r8, r8, 32      /* as = as + 32 */
+       addi    r4, r4, -32     /* n = n - 32 */
+       bneid   r4, a_bu3_loop  /* while (n) loop */
+       addi    r5, r5, 32      /* d = d + 32 (IN DELAY SLOT) */
+       bri     a_block_done
+
+a_block_u1:
+       bslli   r11, r11, 8     /* h = h << 8 */
+a_bu1_loop:
+       lwi     r12, r8, 4      /* v = *(as + 4) */
+       bsrli   r9, r12, 24     /* t1 = v >> 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 0       /* *(d + 0) = t1 */
+       bslli   r11, r12, 8     /* h = v << 8 */
+       lwi     r12, r8, 8      /* v = *(as + 8) */
+       bsrli   r9, r12, 24     /* t1 = v >> 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 4       /* *(d + 4) = t1 */
+       bslli   r11, r12, 8     /* h = v << 8 */
+       lwi     r12, r8, 12     /* v = *(as + 12) */
+       bsrli   r9, r12, 24     /* t1 = v >> 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 8       /* *(d + 8) = t1 */
+       bslli   r11, r12, 8     /* h = v << 8 */
+       lwi     r12, r8, 16     /* v = *(as + 16) */
+       bsrli   r9, r12, 24     /* t1 = v >> 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 12      /* *(d + 12) = t1 */
+       bslli   r11, r12, 8     /* h = v << 8 */
+       lwi     r12, r8, 20     /* v = *(as + 20) */
+       bsrli   r9, r12, 24     /* t1 = v >> 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 16      /* *(d + 16) = t1 */
+       bslli   r11, r12, 8     /* h = v << 8 */
+       lwi     r12, r8, 24     /* v = *(as + 24) */
+       bsrli   r9, r12, 24     /* t1 = v >> 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 20      /* *(d + 20) = t1 */
+       bslli   r11, r12, 8     /* h = v << 8 */
+       lwi     r12, r8, 28     /* v = *(as + 28) */
+       bsrli   r9, r12, 24     /* t1 = v >> 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 24      /* *(d + 24) = t1 */
+       bslli   r11, r12, 8     /* h = v << 8 */
+       lwi     r12, r8, 32     /* v = *(as + 32) */
+       bsrli   r9, r12, 24     /* t1 = v >> 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 28      /* *(d + 28) = t1 */
+       bslli   r11, r12, 8     /* h = v << 8 */
+       addi    r8, r8, 32      /* as = as + 32 */
+       addi    r4, r4, -32     /* n = n - 32 */
+       bneid   r4, a_bu1_loop  /* while (n) loop */
+       addi    r5, r5, 32      /* d = d + 32 (IN DELAY SLOT) */
+       bri     a_block_done
+
+a_block_u2:
+       bslli   r11, r11, 16    /* h = h << 16 */
+a_bu2_loop:
+       lwi     r12, r8, 4      /* v = *(as + 4) */
+       bsrli   r9, r12, 16     /* t1 = v >> 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 0       /* *(d + 0) = t1 */
+       bslli   r11, r12, 16    /* h = v << 16 */
+       lwi     r12, r8, 8      /* v = *(as + 8) */
+       bsrli   r9, r12, 16     /* t1 = v >> 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 4       /* *(d + 4) = t1 */
+       bslli   r11, r12, 16    /* h = v << 16 */
+       lwi     r12, r8, 12     /* v = *(as + 12) */
+       bsrli   r9, r12, 16     /* t1 = v >> 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 8       /* *(d + 8) = t1 */
+       bslli   r11, r12, 16    /* h = v << 16 */
+       lwi     r12, r8, 16     /* v = *(as + 16) */
+       bsrli   r9, r12, 16     /* t1 = v >> 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 12      /* *(d + 12) = t1 */
+       bslli   r11, r12, 16    /* h = v << 16 */
+       lwi     r12, r8, 20     /* v = *(as + 20) */
+       bsrli   r9, r12, 16     /* t1 = v >> 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 16      /* *(d + 16) = t1 */
+       bslli   r11, r12, 16    /* h = v << 16 */
+       lwi     r12, r8, 24     /* v = *(as + 24) */
+       bsrli   r9, r12, 16     /* t1 = v >> 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 20      /* *(d + 20) = t1 */
+       bslli   r11, r12, 16    /* h = v << 16 */
+       lwi     r12, r8, 28     /* v = *(as + 28) */
+       bsrli   r9, r12, 16     /* t1 = v >> 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 24      /* *(d + 24) = t1 */
+       bslli   r11, r12, 16    /* h = v << 16 */
+       lwi     r12, r8, 32     /* v = *(as + 32) */
+       bsrli   r9, r12, 16     /* t1 = v >> 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 28      /* *(d + 28) = t1 */
+       bslli   r11, r12, 16    /* h = v << 16 */
+       addi    r8, r8, 32      /* as = as + 32 */
+       addi    r4, r4, -32     /* n = n - 32 */
+       bneid   r4, a_bu2_loop  /* while (n) loop */
+       addi    r5, r5, 32      /* d = d + 32 (IN DELAY SLOT) */
+
+a_block_done:
+       addi    r4, r0, 4       /* n = 4 */
+       cmpu    r4, r4, r7      /* n = c - n  (unsigned) */
+       blti    r4, a_xfer_end  /* if n < 0, less than one word to transfer */
+
+a_word_xfer:
+       andi    r4, r7, 0xfffffffc      /* n = c & ~3 */
+       addi    r10, r0, 0              /* offset = 0 */
+
+       andi    r9, r6, 3               /* t1 = s & 3 */
+       /* if temp != 0, unaligned transfers needed */
+       bnei    r9, a_word_unaligned
+
+a_word_aligned:
+       lw      r9, r6, r10             /* t1 = *(s+offset) */
+       sw      r9, r5, r10             /* *(d+offset) = t1 */
+       addi    r4, r4,-4               /* n-- */
+       bneid   r4, a_word_aligned      /* loop */
+       addi    r10, r10, 4             /* offset++ (IN DELAY SLOT) */
+
+       bri     a_word_done
+
+a_word_unaligned:
+       andi    r8, r6, 0xfffffffc      /* as = s & ~3 */
+       lwi     r11, r8, 0              /* h = *(as + 0) */
+       addi    r8, r8, 4               /* as = as + 4 */
+
+       addi    r9, r9, -1
+       beqi    r9, a_word_u1           /* t1 was 1 => 1 byte offset */
+       addi    r9, r9, -1
+       beqi    r9, a_word_u2           /* t1 was 2 => 2 byte offset */
+
+a_word_u3:
+       bslli   r11, r11, 24    /* h = h << 24 */
+a_wu3_loop:
+       lw      r12, r8, r10    /* v = *(as + offset) */
+       bsrli   r9, r12, 8      /* t1 = v >> 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       sw      r9, r5, r10     /* *(d + offset) = t1 */
+       bslli   r11, r12, 24    /* h = v << 24 */
+       addi    r4, r4,-4       /* n = n - 4 */
+       bneid   r4, a_wu3_loop  /* while (n) loop */
+       addi    r10, r10, 4     /* offset = ofset + 4 (IN DELAY SLOT) */
+
+       bri     a_word_done
+
+a_word_u1:
+       bslli   r11, r11, 8     /* h = h << 8 */
+a_wu1_loop:
+       lw      r12, r8, r10    /* v = *(as + offset) */
+       bsrli   r9, r12, 24     /* t1 = v >> 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       sw      r9, r5, r10     /* *(d + offset) = t1 */
+       bslli   r11, r12, 8     /* h = v << 8 */
+       addi    r4, r4,-4       /* n = n - 4 */
+       bneid   r4, a_wu1_loop  /* while (n) loop */
+       addi    r10, r10, 4     /* offset = ofset + 4 (IN DELAY SLOT) */
+
+       bri     a_word_done
+
+a_word_u2:
+       bslli   r11, r11, 16    /* h = h << 16 */
+a_wu2_loop:
+       lw      r12, r8, r10    /* v = *(as + offset) */
+       bsrli   r9, r12, 16     /* t1 = v >> 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       sw      r9, r5, r10     /* *(d + offset) = t1 */
+       bslli   r11, r12, 16    /* h = v << 16 */
+       addi    r4, r4,-4       /* n = n - 4 */
+       bneid   r4, a_wu2_loop  /* while (n) loop */
+       addi    r10, r10, 4     /* offset = ofset + 4 (IN DELAY SLOT) */
+
+a_word_done:
+       add     r5, r5, r10     /* d = d + offset */
+       add     r6, r6, r10     /* s = s + offset */
+       rsub    r7, r10, r7     /* c = c - offset */
+
+a_xfer_end:
+a_xfer_end_loop:
+       beqi    r7, a_done              /* while (c) */
+       lbui    r9, r6, 0               /* t1 = *s */
+       addi    r6, r6, 1               /* s++ */
+       sbi     r9, r5, 0               /* *d = t1 */
+       addi    r7, r7, -1              /* c-- */
+       brid    a_xfer_end_loop         /* loop */
+       addi    r5, r5, 1               /* d++ (IN DELAY SLOT) */
+
+a_done:
+       rtsd    r15, 8
+       nop
+
+.end memcpy
+/*----------------------------------------------------------------------------*/
+       .globl  memmove
+       .ent    memmove
+
+memmove:
+       cmpu    r4, r5, r6      /* n = s - d */
+       bgei    r4,fast_memcpy_ascending
+
+fast_memcpy_descending:
+       /* move d to return register as value of function */
+       addi    r3, r5, 0
+
+       add     r5, r5, r7      /* d = d + c */
+       add     r6, r6, r7      /* s = s + c */
+
+       addi    r4, r0, 4       /* n = 4 */
+       cmpu    r4, r4, r7      /* n = c - n  (unsigned) */
+       blti    r4,d_xfer_end   /* if n < 0, less than one word to transfer */
+
+       /* transfer first 0~3 bytes to get aligned dest address */
+       andi    r4, r5, 3               /* n = d & 3 */
+       /* if zero, destination already aligned */
+       beqi    r4,d_dalign_done
+       rsub    r7, r4, r7              /* c = c - n adjust c */
+
+d_xfer_first_loop:
+       /* if no bytes left to transfer, transfer the bulk */
+       beqi    r4,d_dalign_done
+       addi    r6, r6, -1              /* s-- */
+       addi    r5, r5, -1              /* d-- */
+       lbui    r11, r6, 0              /* h = *s */
+       sbi     r11, r5, 0              /* *d = h */
+       brid    d_xfer_first_loop       /* loop */
+       addi    r4, r4, -1              /* n-- (IN DELAY SLOT) */
+
+d_dalign_done:
+       addi    r4, r0, 32      /* n = 32 */
+       cmpu    r4, r4, r7      /* n = c - n  (unsigned) */
+       /* if n < 0, less than one block to transfer */
+       blti    r4, d_block_done
+
+d_block_xfer:
+       andi    r4, r7, 0xffffffe0      /* n = c & ~31 */
+       rsub    r7, r4, r7              /* c = c - n */
+
+       andi    r9, r6, 3               /* t1 = s & 3 */
+       /* if temp != 0, unaligned transfers needed */
+       bnei    r9, d_block_unaligned
+
+d_block_aligned:
+       addi    r6, r6, -32             /* s = s - 32 */
+       addi    r5, r5, -32             /* d = d - 32 */
+       lwi     r9, r6, 28              /* t1 = *(s + 28) */
+       lwi     r10, r6, 24             /* t2 = *(s + 24) */
+       lwi     r11, r6, 20             /* t3 = *(s + 20) */
+       lwi     r12, r6, 16             /* t4 = *(s + 16) */
+       swi     r9, r5, 28              /* *(d + 28) = t1 */
+       swi     r10, r5, 24             /* *(d + 24) = t2 */
+       swi     r11, r5, 20             /* *(d + 20) = t3 */
+       swi     r12, r5, 16             /* *(d + 16) = t4 */
+       lwi     r9, r6, 12              /* t1 = *(s + 12) */
+       lwi     r10, r6, 8              /* t2 = *(s + 8) */
+       lwi     r11, r6, 4              /* t3 = *(s + 4) */
+       lwi     r12, r6, 0              /* t4 = *(s + 0) */
+       swi     r9, r5, 12              /* *(d + 12) = t1 */
+       swi     r10, r5, 8              /* *(d + 8) = t2 */
+       swi     r11, r5, 4              /* *(d + 4) = t3 */
+       addi    r4, r4, -32             /* n = n - 32 */
+       bneid   r4, d_block_aligned     /* while (n) loop */
+       swi     r12, r5, 0              /* *(d + 0) = t4 (IN DELAY SLOT) */
+       bri     d_block_done
+
+d_block_unaligned:
+       andi    r8, r6, 0xfffffffc      /* as = s & ~3 */
+       rsub    r6, r4, r6              /* s = s - n */
+       lwi     r11, r8, 0              /* h = *(as + 0) */
+
+       addi    r9, r9, -1
+       beqi    r9,d_block_u1           /* t1 was 1 => 1 byte offset */
+       addi    r9, r9, -1
+       beqi    r9,d_block_u2           /* t1 was 2 => 2 byte offset */
+
+d_block_u3:
+       bsrli   r11, r11, 8     /* h = h >> 8 */
+d_bu3_loop:
+       addi    r8, r8, -32     /* as = as - 32 */
+       addi    r5, r5, -32     /* d = d - 32 */
+       lwi     r12, r8, 28     /* v = *(as + 28) */
+       bslli   r9, r12, 24     /* t1 = v << 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 28      /* *(d + 28) = t1 */
+       bsrli   r11, r12, 8     /* h = v >> 8 */
+       lwi     r12, r8, 24     /* v = *(as + 24) */
+       bslli   r9, r12, 24     /* t1 = v << 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 24      /* *(d + 24) = t1 */
+       bsrli   r11, r12, 8     /* h = v >> 8 */
+       lwi     r12, r8, 20     /* v = *(as + 20) */
+       bslli   r9, r12, 24     /* t1 = v << 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 20      /* *(d + 20) = t1 */
+       bsrli   r11, r12, 8     /* h = v >> 8 */
+       lwi     r12, r8, 16     /* v = *(as + 16) */
+       bslli   r9, r12, 24     /* t1 = v << 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 16      /* *(d + 16) = t1 */
+       bsrli   r11, r12, 8     /* h = v >> 8 */
+       lwi     r12, r8, 12     /* v = *(as + 12) */
+       bslli   r9, r12, 24     /* t1 = v << 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 12      /* *(d + 112) = t1 */
+       bsrli   r11, r12, 8     /* h = v >> 8 */
+       lwi     r12, r8, 8      /* v = *(as + 8) */
+       bslli   r9, r12, 24     /* t1 = v << 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 8       /* *(d + 8) = t1 */
+       bsrli   r11, r12, 8     /* h = v >> 8 */
+       lwi     r12, r8, 4      /* v = *(as + 4) */
+       bslli   r9, r12, 24     /* t1 = v << 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 4       /* *(d + 4) = t1 */
+       bsrli   r11, r12, 8     /* h = v >> 8 */
+       lwi     r12, r8, 0      /* v = *(as + 0) */
+       bslli   r9, r12, 24     /* t1 = v << 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 0       /* *(d + 0) = t1 */
+       addi    r4, r4, -32     /* n = n - 32 */
+       bneid   r4, d_bu3_loop  /* while (n) loop */
+       bsrli   r11, r12, 8     /* h = v >> 8 (IN DELAY SLOT) */
+       bri     d_block_done
+
+d_block_u1:
+       bsrli   r11, r11, 24    /* h = h >> 24 */
+d_bu1_loop:
+       addi    r8, r8, -32     /* as = as - 32 */
+       addi    r5, r5, -32     /* d = d - 32 */
+       lwi     r12, r8, 28     /* v = *(as + 28) */
+       bslli   r9, r12, 8      /* t1 = v << 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 28      /* *(d + 28) = t1 */
+       bsrli   r11, r12, 24    /* h = v >> 24 */
+       lwi     r12, r8, 24     /* v = *(as + 24) */
+       bslli   r9, r12, 8      /* t1 = v << 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 24      /* *(d + 24) = t1 */
+       bsrli   r11, r12, 24    /* h = v >> 24 */
+       lwi     r12, r8, 20     /* v = *(as + 20) */
+       bslli   r9, r12, 8      /* t1 = v << 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 20      /* *(d + 20) = t1 */
+       bsrli   r11, r12, 24    /* h = v >> 24 */
+       lwi     r12, r8, 16     /* v = *(as + 16) */
+       bslli   r9, r12, 8      /* t1 = v << 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 16      /* *(d + 16) = t1 */
+       bsrli   r11, r12, 24    /* h = v >> 24 */
+       lwi     r12, r8, 12     /* v = *(as + 12) */
+       bslli   r9, r12, 8      /* t1 = v << 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 12      /* *(d + 112) = t1 */
+       bsrli   r11, r12, 24    /* h = v >> 24 */
+       lwi     r12, r8, 8      /* v = *(as + 8) */
+       bslli   r9, r12, 8      /* t1 = v << 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 8       /* *(d + 8) = t1 */
+       bsrli   r11, r12, 24    /* h = v >> 24 */
+       lwi     r12, r8, 4      /* v = *(as + 4) */
+       bslli   r9, r12, 8      /* t1 = v << 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 4       /* *(d + 4) = t1 */
+       bsrli   r11, r12, 24    /* h = v >> 24 */
+       lwi     r12, r8, 0      /* v = *(as + 0) */
+       bslli   r9, r12, 8      /* t1 = v << 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 0       /* *(d + 0) = t1 */
+       addi    r4, r4, -32     /* n = n - 32 */
+       bneid   r4, d_bu1_loop  /* while (n) loop */
+       bsrli   r11, r12, 24    /* h = v >> 24 (IN DELAY SLOT) */
+       bri     d_block_done
+
+d_block_u2:
+       bsrli   r11, r11, 16    /* h = h >> 16 */
+d_bu2_loop:
+       addi    r8, r8, -32     /* as = as - 32 */
+       addi    r5, r5, -32     /* d = d - 32 */
+       lwi     r12, r8, 28     /* v = *(as + 28) */
+       bslli   r9, r12, 16     /* t1 = v << 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 28      /* *(d + 28) = t1 */
+       bsrli   r11, r12, 16    /* h = v >> 16 */
+       lwi     r12, r8, 24     /* v = *(as + 24) */
+       bslli   r9, r12, 16     /* t1 = v << 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 24      /* *(d + 24) = t1 */
+       bsrli   r11, r12, 16    /* h = v >> 16 */
+       lwi     r12, r8, 20     /* v = *(as + 20) */
+       bslli   r9, r12, 16     /* t1 = v << 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 20      /* *(d + 20) = t1 */
+       bsrli   r11, r12, 16    /* h = v >> 16 */
+       lwi     r12, r8, 16     /* v = *(as + 16) */
+       bslli   r9, r12, 16     /* t1 = v << 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 16      /* *(d + 16) = t1 */
+       bsrli   r11, r12, 16    /* h = v >> 16 */
+       lwi     r12, r8, 12     /* v = *(as + 12) */
+       bslli   r9, r12, 16     /* t1 = v << 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 12      /* *(d + 112) = t1 */
+       bsrli   r11, r12, 16    /* h = v >> 16 */
+       lwi     r12, r8, 8      /* v = *(as + 8) */
+       bslli   r9, r12, 16     /* t1 = v << 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 8       /* *(d + 8) = t1 */
+       bsrli   r11, r12, 16    /* h = v >> 16 */
+       lwi     r12, r8, 4      /* v = *(as + 4) */
+       bslli   r9, r12, 16     /* t1 = v << 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 4       /* *(d + 4) = t1 */
+       bsrli   r11, r12, 16    /* h = v >> 16 */
+       lwi     r12, r8, 0      /* v = *(as + 0) */
+       bslli   r9, r12, 16     /* t1 = v << 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       swi     r9, r5, 0       /* *(d + 0) = t1 */
+       addi    r4, r4, -32     /* n = n - 32 */
+       bneid   r4, d_bu2_loop  /* while (n) loop */
+       bsrli   r11, r12, 16    /* h = v >> 16 (IN DELAY SLOT) */
+
+d_block_done:
+       addi    r4, r0, 4       /* n = 4 */
+       cmpu    r4, r4, r7      /* n = c - n  (unsigned) */
+       blti    r4,d_xfer_end   /* if n < 0, less than one word to transfer */
+
+d_word_xfer:
+       andi    r4, r7, 0xfffffffc      /* n = c & ~3 */
+       rsub    r5, r4, r5              /* d = d - n */
+       rsub    r6, r4, r6              /* s = s - n */
+       rsub    r7, r4, r7              /* c = c - n */
+
+       andi    r9, r6, 3               /* t1 = s & 3 */
+       /* if temp != 0, unaligned transfers needed */
+       bnei    r9, d_word_unaligned
+
+d_word_aligned:
+       addi    r4, r4,-4               /* n-- */
+       lw      r9, r6, r4              /* t1 = *(s+n) */
+       bneid   r4, d_word_aligned      /* loop */
+       sw      r9, r5, r4              /* *(d+n) = t1 (IN DELAY SLOT) */
+
+       bri     d_word_done
+
+d_word_unaligned:
+       andi    r8, r6, 0xfffffffc      /* as = s & ~3 */
+       lw      r11, r8, r4             /* h = *(as + n) */
+
+       addi    r9, r9, -1
+       beqi    r9,d_word_u1            /* t1 was 1 => 1 byte offset */
+       addi    r9, r9, -1
+       beqi    r9,d_word_u2            /* t1 was 2 => 2 byte offset */
+
+d_word_u3:
+       bsrli   r11, r11, 8     /* h = h >> 8 */
+d_wu3_loop:
+       addi    r4, r4,-4       /* n = n - 4 */
+       lw      r12, r8, r4     /* v = *(as + n) */
+       bslli   r9, r12, 24     /* t1 = v << 24 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       sw      r9, r5, r4      /* *(d + n) = t1 */
+       bneid   r4, d_wu3_loop  /* while (n) loop */
+       bsrli   r11, r12, 8     /* h = v >> 8 (IN DELAY SLOT) */
+
+       bri     d_word_done
+
+d_word_u1:
+       bsrli   r11, r11, 24    /* h = h >> 24 */
+d_wu1_loop:
+       addi    r4, r4,-4       /* n = n - 4 */
+       lw      r12, r8, r4     /* v = *(as + n) */
+       bslli   r9, r12, 8      /* t1 = v << 8 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       sw      r9, r5, r4      /* *(d + n) = t1 */
+       bneid   r4, d_wu1_loop  /* while (n) loop */
+       bsrli   r11, r12, 24    /* h = v >> 24 (IN DELAY SLOT) */
+
+       bri     d_word_done
+
+d_word_u2:
+       bsrli   r11, r11, 16    /* h = h >> 16 */
+d_wu2_loop:
+       addi    r4, r4,-4       /* n = n - 4 */
+       lw      r12, r8, r4     /* v = *(as + n) */
+       bslli   r9, r12, 16     /* t1 = v << 16 */
+       or      r9, r11, r9     /* t1 = h | t1 */
+       sw      r9, r5, r4      /* *(d + n) = t1 */
+       bneid   r4, d_wu2_loop  /* while (n) loop */
+       bsrli   r11, r12, 16    /* h = v >> 16 (IN DELAY SLOT) */
+
+d_word_done:
+
+d_xfer_end:
+d_xfer_end_loop:
+       beqi    r7, a_done              /* while (c) */
+       addi    r6, r6, -1              /* s-- */
+       lbui    r9, r6, 0               /* t1 = *s */
+       addi    r5, r5, -1              /* d-- */
+       sbi     r9, r5, 0               /* *d = t1 */
+       brid    d_xfer_end_loop         /* loop */
+       addi    r7, r7, -1              /* c-- (IN DELAY SLOT) */
+
+d_done:
+       rtsd    r15, 8
+       nop
+
+.end memmove
diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c
new file mode 100644 (file)
index 0000000..5880119
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2007 John Williams
+ *
+ * Reasonably optimised generic C-code for memcpy on Microblaze
+ * This is generic C code to do efficient, alignment-aware memcpy.
+ *
+ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
+ * http://www.embedded.com/showArticle.jhtml?articleID=19205567
+ *
+ * Attempts were made, unsuccesfully, to contact the original
+ * author of this code (Michael Morrow, Intel).  Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+
+#include <linux/string.h>
+#include <asm/system.h>
+
+#ifdef __HAVE_ARCH_MEMCPY
+void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
+{
+       const char *src = v_src;
+       char *dst = v_dst;
+#ifndef CONFIG_OPT_LIB_FUNCTION
+       /* Simple, byte oriented memcpy. */
+       while (c--)
+               *dst++ = *src++;
+
+       return v_dst;
+#else
+       /* The following code tries to optimize the copy by using unsigned
+        * alignment. This will work fine if both source and destination are
+        * aligned on the same boundary. However, if they are aligned on
+        * different boundaries shifts will be necessary. This might result in
+        * bad performance on MicroBlaze systems without a barrel shifter.
+        */
+       const uint32_t *i_src;
+       uint32_t *i_dst;
+
+       if (c >= 4) {
+               unsigned  value, buf_hold;
+
+               /* Align the dstination to a word boundry. */
+               /* This is done in an endian independant manner. */
+               switch ((unsigned long)dst & 3) {
+               case 1:
+                       *dst++ = *src++;
+                       --c;
+               case 2:
+                       *dst++ = *src++;
+                       --c;
+               case 3:
+                       *dst++ = *src++;
+                       --c;
+               }
+
+               i_dst = (void *)dst;
+
+               /* Choose a copy scheme based on the source */
+               /* alignment relative to dstination. */
+               switch ((unsigned long)src & 3) {
+               case 0x0:       /* Both byte offsets are aligned */
+                       i_src  = (const void *)src;
+
+                       for (; c >= 4; c -= 4)
+                               *i_dst++ = *i_src++;
+
+                       src  = (const void *)i_src;
+                       break;
+               case 0x1:       /* Unaligned - Off by 1 */
+                       /* Word align the source */
+                       i_src = (const void *) ((unsigned)src & ~3);
+
+                       /* Load the holding buffer */
+                       buf_hold = *i_src++ << 8;
+
+                       for (; c >= 4; c -= 4) {
+                               value = *i_src++;
+                               *i_dst++ = buf_hold | value >> 24;
+                               buf_hold = value << 8;
+                       }
+
+                       /* Realign the source */
+                       src = (const void *)i_src;
+                       src -= 3;
+                       break;
+               case 0x2:       /* Unaligned - Off by 2 */
+                       /* Word align the source */
+                       i_src = (const void *) ((unsigned)src & ~3);
+
+                       /* Load the holding buffer */
+                       buf_hold = *i_src++ << 16;
+
+                       for (; c >= 4; c -= 4) {
+                               value = *i_src++;
+                               *i_dst++ = buf_hold | value >> 16;
+                               buf_hold = value << 16;
+                       }
+
+                       /* Realign the source */
+                       src = (const void *)i_src;
+                       src -= 2;
+                       break;
+               case 0x3:       /* Unaligned - Off by 3 */
+                       /* Word align the source */
+                       i_src = (const void *) ((unsigned)src & ~3);
+
+                       /* Load the holding buffer */
+                       buf_hold = *i_src++ << 24;
+
+                       for (; c >= 4; c -= 4) {
+                               value = *i_src++;
+                               *i_dst++ = buf_hold | value >> 8;
+                               buf_hold = value << 24;
+                       }
+
+                       /* Realign the source */
+                       src = (const void *)i_src;
+                       src -= 1;
+                       break;
+               }
+               dst = (void *)i_dst;
+       }
+
+       /* Finish off any remaining bytes */
+       /* simple fast copy, ... unless a cache boundry is crossed */
+       switch (c) {
+       case 3:
+               *dst++ = *src++;
+       case 2:
+               *dst++ = *src++;
+       case 1:
+               *dst++ = *src++;
+       }
+
+       return v_dst;
+#endif
+}
+EXPORT_SYMBOL(memcpy);
+#endif /* __HAVE_ARCH_MEMCPY */
+
+void *cacheable_memcpy(void *d, const void *s, __kernel_size_t c)
+{
+       return memcpy(d, s, c);
+}
diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c
new file mode 100644 (file)
index 0000000..d4e9f49
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2007 John Williams
+ *
+ * Reasonably optimised generic C-code for memcpy on Microblaze
+ * This is generic C code to do efficient, alignment-aware memmove.
+ *
+ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
+ * http://www.embedded.com/showArticle.jhtml?articleID=19205567
+ *
+ * Attempts were made, unsuccesfully, to contact the original
+ * author of this code (Michael Morrow, Intel).  Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#ifdef __HAVE_ARCH_MEMMOVE
+void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
+{
+       const char *src = v_src;
+       char *dst = v_dst;
+
+#ifdef CONFIG_OPT_LIB_FUNCTION
+       const uint32_t *i_src;
+       uint32_t *i_dst;
+#endif
+
+       if (!c)
+               return v_dst;
+
+       /* Use memcpy when source is higher than dest */
+       if (v_dst <= v_src)
+               return memcpy(v_dst, v_src, c);
+
+#ifndef CONFIG_OPT_LIB_FUNCTION
+       /* copy backwards, from end to beginning */
+       src += c;
+       dst += c;
+
+       /* Simple, byte oriented memmove. */
+       while (c--)
+               *--dst = *--src;
+
+       return v_dst;
+#else
+       /* The following code tries to optimize the copy by using unsigned
+        * alignment. This will work fine if both source and destination are
+        * aligned on the same boundary. However, if they are aligned on
+        * different boundaries shifts will be necessary. This might result in
+        * bad performance on MicroBlaze systems without a barrel shifter.
+        */
+       /* FIXME this part needs more test */
+       /* Do a descending copy - this is a bit trickier! */
+       dst += c;
+       src += c;
+
+       if (c >= 4) {
+               unsigned  value, buf_hold;
+
+               /* Align the destination to a word boundry. */
+               /* This is done in an endian independant manner. */
+
+               switch ((unsigned long)dst & 3) {
+               case 3:
+                       *--dst = *--src;
+                       --c;
+               case 2:
+                       *--dst = *--src;
+                       --c;
+               case 1:
+                       *--dst = *--src;
+                       --c;
+               }
+
+               i_dst = (void *)dst;
+               /* Choose a copy scheme based on the source */
+               /* alignment relative to dstination. */
+               switch ((unsigned long)src & 3) {
+               case 0x0:       /* Both byte offsets are aligned */
+
+                       i_src  = (const void *)src;
+
+                       for (; c >= 4; c -= 4)
+                               *--i_dst = *--i_src;
+
+                       src  = (const void *)i_src;
+                       break;
+               case 0x1:       /* Unaligned - Off by 1 */
+                       /* Word align the source */
+                       i_src = (const void *) (((unsigned)src + 4) & ~3);
+
+                       /* Load the holding buffer */
+                       buf_hold = *--i_src >> 24;
+
+                       for (; c >= 4; c -= 4) {
+                               value = *--i_src;
+                               *--i_dst = buf_hold << 8 | value;
+                               buf_hold = value >> 24;
+                       }
+
+                       /* Realign the source */
+                       src = (const void *)i_src;
+                       src += 1;
+                       break;
+               case 0x2:       /* Unaligned - Off by 2 */
+                       /* Word align the source */
+                       i_src = (const void *) (((unsigned)src + 4) & ~3);
+
+                       /* Load the holding buffer */
+                       buf_hold = *--i_src >> 16;
+
+                       for (; c >= 4; c -= 4) {
+                               value = *--i_src;
+                               *--i_dst = buf_hold << 16 | value;
+                               buf_hold = value >> 16;
+                       }
+
+                       /* Realign the source */
+                       src = (const void *)i_src;
+                       src += 2;
+                       break;
+               case 0x3:       /* Unaligned - Off by 3 */
+                       /* Word align the source */
+                       i_src = (const void *) (((unsigned)src + 4) & ~3);
+
+                       /* Load the holding buffer */
+                       buf_hold = *--i_src >> 8;
+
+                       for (; c >= 4; c -= 4) {
+                               value = *--i_src;
+                               *--i_dst = buf_hold << 24 | value;
+                               buf_hold = value >> 8;
+                       }
+
+                       /* Realign the source */
+                       src = (const void *)i_src;
+                       src += 3;
+                       break;
+               }
+               dst = (void *)i_dst;
+       }
+
+       /* simple fast copy, ... unless a cache boundry is crossed */
+       /* Finish off any remaining bytes */
+       switch (c) {
+       case 4:
+               *--dst = *--src;
+       case 3:
+               *--dst = *--src;
+       case 2:
+               *--dst = *--src;
+       case 1:
+               *--dst = *--src;
+       }
+       return v_dst;
+#endif
+}
+EXPORT_SYMBOL(memmove);
+#endif /* __HAVE_ARCH_MEMMOVE */
diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c
new file mode 100644 (file)
index 0000000..941dc8f
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2007 John Williams
+ *
+ * Reasonably optimised generic C-code for memset on Microblaze
+ * This is generic C code to do efficient, alignment-aware memcpy.
+ *
+ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
+ * http://www.embedded.com/showArticle.jhtml?articleID=19205567
+ *
+ * Attempts were made, unsuccesfully, to contact the original
+ * author of this code (Michael Morrow, Intel).  Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#ifdef __HAVE_ARCH_MEMSET
+void *memset(void *v_src, int c, __kernel_size_t n)
+{
+
+       char *src = v_src;
+#ifdef CONFIG_OPT_LIB_FUNCTION
+       uint32_t *i_src;
+       uint32_t w32;
+#endif
+       /* Truncate c to 8 bits */
+       c = (c & 0xFF);
+
+#ifdef CONFIG_OPT_LIB_FUNCTION
+       /* Make a repeating word out of it */
+       w32 = c;
+       w32 |= w32 << 8;
+       w32 |= w32 << 16;
+
+       if (n >= 4) {
+               /* Align the destination to a word boundary */
+               /* This is done in an endian independant manner */
+               switch ((unsigned) src & 3) {
+               case 1:
+                       *src++ = c;
+                       --n;
+               case 2:
+                       *src++ = c;
+                       --n;
+               case 3:
+                       *src++ = c;
+                       --n;
+               }
+
+               i_src  = (void *)src;
+
+               /* Do as many full-word copies as we can */
+               for (; n >= 4; n -= 4)
+                       *i_src++ = w32;
+
+               src  = (void *)i_src;
+       }
+#endif
+       /* Simple, byte oriented memset or the rest of count. */
+       while (n--)
+               *src++ = c;
+
+       return v_src;
+}
+EXPORT_SYMBOL(memset);
+#endif /* __HAVE_ARCH_MEMSET */
diff --git a/arch/microblaze/lib/uaccess.c b/arch/microblaze/lib/uaccess.c
new file mode 100644 (file)
index 0000000..8eb9df5
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/string.h>
+#include <asm/uaccess.h>
+
+#include <asm/bug.h>
+
+long strnlen_user(const char __user *src, long count)
+{
+       return strlen(src) + 1;
+}
+
+#define __do_strncpy_from_user(dst, src, count, res)                   \
+       do {                                                            \
+               char *tmp;                                              \
+               strncpy(dst, src, count);                               \
+               for (tmp = dst; *tmp && count > 0; tmp++, count--)      \
+                       ;                                               \
+               res = (tmp - dst);                                      \
+       } while (0)
+
+long __strncpy_from_user(char *dst, const char __user *src, long count)
+{
+       long res;
+       __do_strncpy_from_user(dst, src, count, res);
+       return res;
+}
+
+long strncpy_from_user(char *dst, const char __user *src, long count)
+{
+       long res = -EFAULT;
+       if (access_ok(VERIFY_READ, src, 1))
+               __do_strncpy_from_user(dst, src, count, res);
+       return res;
+}
diff --git a/arch/microblaze/mm/Makefile b/arch/microblaze/mm/Makefile
new file mode 100644 (file)
index 0000000..bf9e447
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile
+#
+
+obj-y := init.o
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
new file mode 100644 (file)
index 0000000..b0c8213
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/bootmem.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/lmb.h>
+#include <linux/mm.h> /* mem_init */
+#include <linux/initrd.h>
+#include <linux/pagemap.h>
+#include <linux/pfn.h>
+#include <linux/swap.h>
+
+#include <asm/page.h>
+#include <asm/mmu_context.h>
+#include <asm/pgalloc.h>
+#include <asm/sections.h>
+#include <asm/tlb.h>
+
+unsigned int __page_offset;
+/* EXPORT_SYMBOL(__page_offset); */
+
+char *klimit = _end;
+
+/*
+ * Initialize the bootmem system and give it all the memory we
+ * have available.
+ */
+unsigned int memory_start;
+unsigned int memory_end; /* due to mm/nommu.c */
+unsigned int memory_size;
+
+/*
+ * paging_init() sets up the page tables - in fact we've already done this.
+ */
+static void __init paging_init(void)
+{
+       int i;
+       unsigned long zones_size[MAX_NR_ZONES];
+
+       /*
+        * old: we can DMA to/from any address.put all page into ZONE_DMA
+        * We use only ZONE_NORMAL
+        */
+       zones_size[ZONE_NORMAL] = max_mapnr;
+
+       /* every other zones are empty */
+       for (i = 1; i < MAX_NR_ZONES; i++)
+               zones_size[i] = 0;
+
+       free_area_init(zones_size);
+}
+
+void __init setup_memory(void)
+{
+       int i;
+       unsigned long map_size;
+       u32 kernel_align_start, kernel_align_size;
+
+       /* Find main memory where is the kernel */
+       for (i = 0; i < lmb.memory.cnt; i++) {
+               memory_start = (u32) lmb.memory.region[i].base;
+               memory_end = (u32) lmb.memory.region[i].base
+                               + (u32) lmb.memory.region[i].size;
+               if ((memory_start <= (u32)_text) &&
+                                       ((u32)_text <= memory_end)) {
+                       memory_size = memory_end - memory_start;
+                       PAGE_OFFSET = memory_start;
+                       printk(KERN_INFO "%s: Main mem: 0x%x-0x%x, "
+                               "size 0x%08x\n", __func__, memory_start,
+                                               memory_end, memory_size);
+                       break;
+               }
+       }
+
+       if (!memory_start || !memory_end) {
+               panic("%s: Missing memory setting 0x%08x-0x%08x\n",
+                       __func__, memory_start, memory_end);
+       }
+
+       /* reservation of region where is the kernel */
+       kernel_align_start = PAGE_DOWN((u32)_text);
+       /* ALIGN can be remove because _end in vmlinux.lds.S is align */
+       kernel_align_size = PAGE_UP((u32)klimit) - kernel_align_start;
+       lmb_reserve(kernel_align_start, kernel_align_size);
+       printk(KERN_INFO "%s: kernel addr=0x%08x-0x%08x size=0x%08x\n",
+               __func__, kernel_align_start, kernel_align_start
+                       + kernel_align_size, kernel_align_size);
+
+       /*
+        * Kernel:
+        * start: base phys address of kernel - page align
+        * end: base phys address of kernel - page align
+        *
+        * min_low_pfn - the first page (mm/bootmem.c - node_boot_start)
+        * max_low_pfn
+        * max_mapnr - the first unused page (mm/bootmem.c - node_low_pfn)
+        * num_physpages - number of all pages
+        */
+
+       /* memory start is from the kernel end (aligned) to higher addr */
+       min_low_pfn = memory_start >> PAGE_SHIFT; /* minimum for allocation */
+       /* RAM is assumed contiguous */
+       num_physpages = max_mapnr = memory_size >> PAGE_SHIFT;
+       max_pfn = max_low_pfn = memory_end >> PAGE_SHIFT;
+
+       printk(KERN_INFO "%s: max_mapnr: %#lx\n", __func__, max_mapnr);
+       printk(KERN_INFO "%s: min_low_pfn: %#lx\n", __func__, min_low_pfn);
+       printk(KERN_INFO "%s: max_low_pfn: %#lx\n", __func__, max_low_pfn);
+
+       /*
+        * Find an area to use for the bootmem bitmap.
+        * We look for the first area which is at least
+        * 128kB in length (128kB is enough for a bitmap
+        * for 4GB of memory, using 4kB pages), plus 1 page
+        * (in case the address isn't page-aligned).
+        */
+       map_size = init_bootmem_node(NODE_DATA(0), PFN_UP(TOPHYS((u32)_end)),
+                                       min_low_pfn, max_low_pfn);
+
+       lmb_reserve(PFN_UP(TOPHYS((u32)_end)) << PAGE_SHIFT, map_size);
+
+       /* free bootmem is whole main memory */
+       free_bootmem(memory_start, memory_size);
+
+       /* reserve allocate blocks */
+       for (i = 0; i < lmb.reserved.cnt; i++) {
+               pr_debug("reserved %d - 0x%08x-0x%08x\n", i,
+                       (u32) lmb.reserved.region[i].base,
+                       (u32) lmb_size_bytes(&lmb.reserved, i));
+               reserve_bootmem(lmb.reserved.region[i].base,
+                       lmb_size_bytes(&lmb.reserved, i) - 1, BOOTMEM_DEFAULT);
+       }
+       paging_init();
+}
+
+void free_init_pages(char *what, unsigned long begin, unsigned long end)
+{
+       unsigned long addr;
+
+       for (addr = begin; addr < end; addr += PAGE_SIZE) {
+               ClearPageReserved(virt_to_page(addr));
+               init_page_count(virt_to_page(addr));
+               memset((void *)addr, 0xcc, PAGE_SIZE);
+               free_page(addr);
+               totalram_pages++;
+       }
+       printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void 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)
+{
+       free_init_pages("unused kernel memory",
+                       (unsigned long)(&__init_begin),
+                       (unsigned long)(&__init_end));
+}
+
+/* FIXME from arch/powerpc/mm/mem.c*/
+void show_mem(void)
+{
+       printk(KERN_NOTICE "%s\n", __func__);
+}
+
+void __init mem_init(void)
+{
+       high_memory = (void *)__va(memory_end);
+       /* this will put all memory onto the freelists */
+       totalram_pages += free_all_bootmem();
+
+       printk(KERN_INFO "Memory: %luk/%luk available\n",
+              (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+              num_physpages << (PAGE_SHIFT-10));
+}
+
+/* Check against bounds of physical memory */
+int ___range_ok(unsigned long addr, unsigned long size)
+{
+       return ((addr < memory_start) ||
+               ((addr + size) > memory_end));
+}
diff --git a/arch/microblaze/platform/Kconfig.platform b/arch/microblaze/platform/Kconfig.platform
new file mode 100644 (file)
index 0000000..8e9b475
--- /dev/null
@@ -0,0 +1,85 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+# Platform selection Kconfig menu for MicroBlaze targets
+#
+
+menu "Platform options"
+choice
+       prompt "Platform"
+       default PLATFORM_MICROBLAZE_AUTO
+       help
+         Choose which hardware board/platform you are targeting.
+
+config PLATFORM_GENERIC
+       bool "Generic"
+       help
+         Choose this option for the Generic platform.
+
+endchoice
+
+config SELFMOD
+       bool "Use self modified code for intc/timer"
+       depends on EXPERIMENTAL && NO_MMU
+       default n
+       help
+         This choice enables self-modified code for interrupt controller
+         and timer.
+
+config SELFMOD_INTC
+       bool "Use self modified code for intc"
+       depends on SELFMOD
+       default y
+       help
+         This choice enables self-modified code for interrupt controller.
+
+config SELFMOD_TIMER
+       bool "Use self modified code for timer"
+       depends on SELFMOD
+       default y
+       help
+         This choice enables self-modified code for timer.
+
+config OPT_LIB_FUNCTION
+       bool "Optimalized lib function"
+       default y
+       help
+         Allows turn on optimalized library function (memcpy and memmove).
+         They are optimized by using word alignment. This will work
+         fine if both source and destination are aligned on the same
+         boundary. However, if they are aligned on different boundaries
+         shifts will be necessary. This might result in bad performance
+         on MicroBlaze systems without a barrel shifter.
+
+config OPT_LIB_ASM
+       bool "Optimalized lib function ASM"
+       depends on OPT_LIB_FUNCTION
+       default n
+       help
+         Allows turn on optimalized library function (memcpy and memmove).
+         Function are written in asm code.
+
+# This is still a bit broken - disabling for now JW 20070504
+config ALLOW_EDIT_AUTO
+       bool "Permit Display/edit of Kconfig.auto platform settings"
+       default n
+       help
+         Allows the editing of auto-generated platform settings from
+         the Kconfig.auto file. Obviously this does not change the
+         underlying hardware, so be very careful if you go editing
+         these settings.
+
+         Also, if you enable this, and edit various Kconfig.auto
+         settings, YOUR CHANGES WILL BE LOST if you then disable it
+         again. You have been warned!
+
+         If unsure, say no.
+
+comment "Automatic platform settings from Kconfig.auto"
+       depends on ALLOW_EDIT_AUTO
+
+if PLATFORM_GENERIC=y
+       source "arch/microblaze/platform/generic/Kconfig.auto"
+endif
+
+endmenu
diff --git a/arch/microblaze/platform/Makefile b/arch/microblaze/platform/Makefile
new file mode 100644 (file)
index 0000000..ea1b75c
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for arch/microblaze/platform directory
+#
+#obj-$(CONFIG_PLATFORM_GENERIC) += generic/
+
+obj-y  += platform.o
diff --git a/arch/microblaze/platform/generic/Kconfig.auto b/arch/microblaze/platform/generic/Kconfig.auto
new file mode 100644 (file)
index 0000000..fbca22d
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# (C) Copyright 2007 Michal Simek
+#
+# Michal SIMEK <monstr@monstr.eu>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in 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
+#
+
+# Definitions for MICROBLAZE0
+comment "Definitions for MICROBLAZE0"
+       depends on ALLOW_EDIT_AUTO
+
+config KERNEL_BASE_ADDR
+       hex "Physical address where Linux Kernel is"
+       default "0x90000000"
+       help
+         BASE Address for kernel
+
+config XILINX_MICROBLAZE0_FAMILY
+       string "Targetted FPGA family" if ALLOW_EDIT_AUTO
+       default "virtex5"
+
+config XILINX_MICROBLAZE0_USE_MSR_INSTR
+       int "USE_MSR_INSTR range (0:1)" if ALLOW_EDIT_AUTO
+       default 1
+
+config XILINX_MICROBLAZE0_USE_PCMP_INSTR
+       int "USE_PCMP_INSTR range (0:1)" if ALLOW_EDIT_AUTO
+       default 1
+
+config XILINX_MICROBLAZE0_USE_BARREL
+       int "USE_BARREL range (0:1)" if ALLOW_EDIT_AUTO
+       default 1
+
+config XILINX_MICROBLAZE0_USE_DIV
+       int "USE_DIV range (0:1)" if ALLOW_EDIT_AUTO
+       default 1
+
+config XILINX_MICROBLAZE0_USE_HW_MUL
+       int "USE_HW_MUL values (0=NONE, 1=MUL32, 2=MUL64)" if ALLOW_EDIT_AUTO
+       default 2
+
+config XILINX_MICROBLAZE0_USE_FPU
+       int "USE_FPU values (0=NONE, 1=BASIC, 2=EXTENDED)" if ALLOW_EDIT_AUTO
+       default 2
+
+config XILINX_MICROBLAZE0_HW_VER
+       string "Core version number" if ALLOW_EDIT_AUTO
+       default 7.10.d
diff --git a/arch/microblaze/platform/generic/Makefile b/arch/microblaze/platform/generic/Makefile
new file mode 100644 (file)
index 0000000..9a8b1bd
--- /dev/null
@@ -0,0 +1,3 @@
+#
+# Empty Makefile to keep make clean happy
+#
diff --git a/arch/microblaze/platform/generic/system.dts b/arch/microblaze/platform/generic/system.dts
new file mode 100644 (file)
index 0000000..29993f6
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * Device Tree Generator version: 1.1
+ *
+ * (C) Copyright 2007-2008 Xilinx, Inc.
+ * (C) Copyright 2007-2009 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in 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
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 10.1.03 EDK_K_SP3.6
+ *
+ * XPS project directory: Xilinx-ML505-ll_temac-sgdma-MMU-FDT-edk101
+ */
+
+/dts-v1/;
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "xlnx,microblaze";
+       model = "testing";
+       DDR2_SDRAM: memory@90000000 {
+               device_type = "memory";
+               reg = < 0x90000000 0x10000000 >;
+       } ;
+       chosen {
+               bootargs = "console=ttyUL0,115200 highres=on";
+               linux,stdout-path = "/plb@0/serial@84000000";
+       } ;
+       cpus {
+               #address-cells = <1>;
+               #cpus = <0x1>;
+               #size-cells = <0>;
+               microblaze_0: cpu@0 {
+                       clock-frequency = <125000000>;
+                       compatible = "xlnx,microblaze-7.10.d";
+                       d-cache-baseaddr = <0x90000000>;
+                       d-cache-highaddr = <0x9fffffff>;
+                       d-cache-line-size = <0x10>;
+                       d-cache-size = <0x2000>;
+                       device_type = "cpu";
+                       i-cache-baseaddr = <0x90000000>;
+                       i-cache-highaddr = <0x9fffffff>;
+                       i-cache-line-size = <0x10>;
+                       i-cache-size = <0x2000>;
+                       model = "microblaze,7.10.d";
+                       reg = <0>;
+                       timebase-frequency = <125000000>;
+                       xlnx,addr-tag-bits = <0xf>;
+                       xlnx,allow-dcache-wr = <0x1>;
+                       xlnx,allow-icache-wr = <0x1>;
+                       xlnx,area-optimized = <0x0>;
+                       xlnx,cache-byte-size = <0x2000>;
+                       xlnx,d-lmb = <0x1>;
+                       xlnx,d-opb = <0x0>;
+                       xlnx,d-plb = <0x1>;
+                       xlnx,data-size = <0x20>;
+                       xlnx,dcache-addr-tag = <0xf>;
+                       xlnx,dcache-always-used = <0x1>;
+                       xlnx,dcache-byte-size = <0x2000>;
+                       xlnx,dcache-line-len = <0x4>;
+                       xlnx,dcache-use-fsl = <0x1>;
+                       xlnx,debug-enabled = <0x1>;
+                       xlnx,div-zero-exception = <0x1>;
+                       xlnx,dopb-bus-exception = <0x0>;
+                       xlnx,dynamic-bus-sizing = <0x1>;
+                       xlnx,edge-is-positive = <0x1>;
+                       xlnx,family = "virtex5";
+                       xlnx,fpu-exception = <0x1>;
+                       xlnx,fsl-data-size = <0x20>;
+                       xlnx,fsl-exception = <0x0>;
+                       xlnx,fsl-links = <0x0>;
+                       xlnx,i-lmb = <0x1>;
+                       xlnx,i-opb = <0x0>;
+                       xlnx,i-plb = <0x1>;
+                       xlnx,icache-always-used = <0x1>;
+                       xlnx,icache-line-len = <0x4>;
+                       xlnx,icache-use-fsl = <0x1>;
+                       xlnx,ill-opcode-exception = <0x1>;
+                       xlnx,instance = "microblaze_0";
+                       xlnx,interconnect = <0x1>;
+                       xlnx,interrupt-is-edge = <0x0>;
+                       xlnx,iopb-bus-exception = <0x0>;
+                       xlnx,mmu-dtlb-size = <0x4>;
+                       xlnx,mmu-itlb-size = <0x2>;
+                       xlnx,mmu-tlb-access = <0x3>;
+                       xlnx,mmu-zones = <0x10>;
+                       xlnx,number-of-pc-brk = <0x1>;
+                       xlnx,number-of-rd-addr-brk = <0x0>;
+                       xlnx,number-of-wr-addr-brk = <0x0>;
+                       xlnx,opcode-0x0-illegal = <0x1>;
+                       xlnx,pvr = <0x2>;
+                       xlnx,pvr-user1 = <0x0>;
+                       xlnx,pvr-user2 = <0x0>;
+                       xlnx,reset-msr = <0x0>;
+                       xlnx,sco = <0x0>;
+                       xlnx,unaligned-exceptions = <0x1>;
+                       xlnx,use-barrel = <0x1>;
+                       xlnx,use-dcache = <0x1>;
+                       xlnx,use-div = <0x1>;
+                       xlnx,use-ext-brk = <0x1>;
+                       xlnx,use-ext-nm-brk = <0x1>;
+                       xlnx,use-extended-fsl-instr = <0x0>;
+                       xlnx,use-fpu = <0x2>;
+                       xlnx,use-hw-mul = <0x2>;
+                       xlnx,use-icache = <0x1>;
+                       xlnx,use-interrupt = <0x1>;
+                       xlnx,use-mmu = <0x3>;
+                       xlnx,use-msr-instr = <0x1>;
+                       xlnx,use-pcmp-instr = <0x1>;
+               } ;
+       } ;
+       mb_plb: plb@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "xlnx,plb-v46-1.03.a", "simple-bus";
+               ranges ;
+               FLASH: flash@a0000000 {
+                       bank-width = <2>;
+                       compatible = "xlnx,xps-mch-emc-2.00.a", "cfi-flash";
+                       reg = < 0xa0000000 0x2000000 >;
+                       xlnx,family = "virtex5";
+                       xlnx,include-datawidth-matching-0 = <0x1>;
+                       xlnx,include-datawidth-matching-1 = <0x0>;
+                       xlnx,include-datawidth-matching-2 = <0x0>;
+                       xlnx,include-datawidth-matching-3 = <0x0>;
+                       xlnx,include-negedge-ioregs = <0x0>;
+                       xlnx,include-plb-ipif = <0x1>;
+                       xlnx,include-wrbuf = <0x1>;
+                       xlnx,max-mem-width = <0x10>;
+                       xlnx,mch-native-dwidth = <0x20>;
+                       xlnx,mch-plb-clk-period-ps = <0x1f40>;
+                       xlnx,mch-splb-awidth = <0x20>;
+                       xlnx,mch0-accessbuf-depth = <0x10>;
+                       xlnx,mch0-protocol = <0x0>;
+                       xlnx,mch0-rddatabuf-depth = <0x10>;
+                       xlnx,mch1-accessbuf-depth = <0x10>;
+                       xlnx,mch1-protocol = <0x0>;
+                       xlnx,mch1-rddatabuf-depth = <0x10>;
+                       xlnx,mch2-accessbuf-depth = <0x10>;
+                       xlnx,mch2-protocol = <0x0>;
+                       xlnx,mch2-rddatabuf-depth = <0x10>;
+                       xlnx,mch3-accessbuf-depth = <0x10>;
+                       xlnx,mch3-protocol = <0x0>;
+                       xlnx,mch3-rddatabuf-depth = <0x10>;
+                       xlnx,mem0-width = <0x10>;
+                       xlnx,mem1-width = <0x20>;
+                       xlnx,mem2-width = <0x20>;
+                       xlnx,mem3-width = <0x20>;
+                       xlnx,num-banks-mem = <0x1>;
+                       xlnx,num-channels = <0x0>;
+                       xlnx,priority-mode = <0x0>;
+                       xlnx,synch-mem-0 = <0x0>;
+                       xlnx,synch-mem-1 = <0x0>;
+                       xlnx,synch-mem-2 = <0x0>;
+                       xlnx,synch-mem-3 = <0x0>;
+                       xlnx,synch-pipedelay-0 = <0x2>;
+                       xlnx,synch-pipedelay-1 = <0x2>;
+                       xlnx,synch-pipedelay-2 = <0x2>;
+                       xlnx,synch-pipedelay-3 = <0x2>;
+                       xlnx,tavdv-ps-mem-0 = <0x1adb0>;
+                       xlnx,tavdv-ps-mem-1 = <0x3a98>;
+                       xlnx,tavdv-ps-mem-2 = <0x3a98>;
+                       xlnx,tavdv-ps-mem-3 = <0x3a98>;
+                       xlnx,tcedv-ps-mem-0 = <0x1adb0>;
+                       xlnx,tcedv-ps-mem-1 = <0x3a98>;
+                       xlnx,tcedv-ps-mem-2 = <0x3a98>;
+                       xlnx,tcedv-ps-mem-3 = <0x3a98>;
+                       xlnx,thzce-ps-mem-0 = <0x88b8>;
+                       xlnx,thzce-ps-mem-1 = <0x1b58>;
+                       xlnx,thzce-ps-mem-2 = <0x1b58>;
+                       xlnx,thzce-ps-mem-3 = <0x1b58>;
+                       xlnx,thzoe-ps-mem-0 = <0x1b58>;
+                       xlnx,thzoe-ps-mem-1 = <0x1b58>;
+                       xlnx,thzoe-ps-mem-2 = <0x1b58>;
+                       xlnx,thzoe-ps-mem-3 = <0x1b58>;
+                       xlnx,tlzwe-ps-mem-0 = <0x88b8>;
+                       xlnx,tlzwe-ps-mem-1 = <0x0>;
+                       xlnx,tlzwe-ps-mem-2 = <0x0>;
+                       xlnx,tlzwe-ps-mem-3 = <0x0>;
+                       xlnx,twc-ps-mem-0 = <0x2af8>;
+                       xlnx,twc-ps-mem-1 = <0x3a98>;
+                       xlnx,twc-ps-mem-2 = <0x3a98>;
+                       xlnx,twc-ps-mem-3 = <0x3a98>;
+                       xlnx,twp-ps-mem-0 = <0x11170>;
+                       xlnx,twp-ps-mem-1 = <0x2ee0>;
+                       xlnx,twp-ps-mem-2 = <0x2ee0>;
+                       xlnx,twp-ps-mem-3 = <0x2ee0>;
+                       xlnx,xcl0-linesize = <0x4>;
+                       xlnx,xcl0-writexfer = <0x1>;
+                       xlnx,xcl1-linesize = <0x4>;
+                       xlnx,xcl1-writexfer = <0x1>;
+                       xlnx,xcl2-linesize = <0x4>;
+                       xlnx,xcl2-writexfer = <0x1>;
+                       xlnx,xcl3-linesize = <0x4>;
+                       xlnx,xcl3-writexfer = <0x1>;
+               } ;
+               Hard_Ethernet_MAC: xps-ll-temac@81c00000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "xlnx,compound";
+                       ethernet@81c00000 {
+                               compatible = "xlnx,xps-ll-temac-1.01.b";
+                               device_type = "network";
+                               interrupt-parent = <&xps_intc_0>;
+                               interrupts = < 5 2 >;
+                               llink-connected = <&PIM3>;
+                               local-mac-address = [ 02 00 00 00 00 00 ];
+                               reg = < 0x81c00000 0x40 >;
+                               xlnx,bus2core-clk-ratio = <0x1>;
+                               xlnx,phy-type = <0x1>;
+                               xlnx,phyaddr = <0x1>;
+                               xlnx,rxcsum = <0x0>;
+                               xlnx,rxfifo = <0x1000>;
+                               xlnx,temac-type = <0x0>;
+                               xlnx,txcsum = <0x0>;
+                               xlnx,txfifo = <0x1000>;
+                       } ;
+               } ;
+               IIC_EEPROM: i2c@81600000 {
+                       compatible = "xlnx,xps-iic-2.00.a";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 6 2 >;
+                       reg = < 0x81600000 0x10000 >;
+                       xlnx,clk-freq = <0x7735940>;
+                       xlnx,family = "virtex5";
+                       xlnx,gpo-width = <0x1>;
+                       xlnx,iic-freq = <0x186a0>;
+                       xlnx,scl-inertial-delay = <0x0>;
+                       xlnx,sda-inertial-delay = <0x0>;
+                       xlnx,ten-bit-adr = <0x0>;
+               } ;
+               LEDs_8Bit: gpio@81400000 {
+                       compatible = "xlnx,xps-gpio-1.00.a";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 7 2 >;
+                       reg = < 0x81400000 0x10000 >;
+                       xlnx,all-inputs = <0x0>;
+                       xlnx,all-inputs-2 = <0x0>;
+                       xlnx,dout-default = <0x0>;
+                       xlnx,dout-default-2 = <0x0>;
+                       xlnx,family = "virtex5";
+                       xlnx,gpio-width = <0x8>;
+                       xlnx,interrupt-present = <0x1>;
+                       xlnx,is-bidir = <0x1>;
+                       xlnx,is-bidir-2 = <0x1>;
+                       xlnx,is-dual = <0x0>;
+                       xlnx,tri-default = <0xffffffff>;
+                       xlnx,tri-default-2 = <0xffffffff>;
+               } ;
+               RS232_Uart_1: serial@84000000 {
+                       clock-frequency = <125000000>;
+                       compatible = "xlnx,xps-uartlite-1.00.a";
+                       current-speed = <115200>;
+                       device_type = "serial";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 8 0 >;
+                       port-number = <0>;
+                       reg = < 0x84000000 0x10000 >;
+                       xlnx,baudrate = <0x1c200>;
+                       xlnx,data-bits = <0x8>;
+                       xlnx,family = "virtex5";
+                       xlnx,odd-parity = <0x0>;
+                       xlnx,use-parity = <0x0>;
+               } ;
+               SysACE_CompactFlash: sysace@83600000 {
+                       compatible = "xlnx,xps-sysace-1.00.a";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 4 2 >;
+                       reg = < 0x83600000 0x10000 >;
+                       xlnx,family = "virtex5";
+                       xlnx,mem-width = <0x10>;
+               } ;
+               debug_module: debug@84400000 {
+                       compatible = "xlnx,mdm-1.00.d";
+                       reg = < 0x84400000 0x10000 >;
+                       xlnx,family = "virtex5";
+                       xlnx,interconnect = <0x1>;
+                       xlnx,jtag-chain = <0x2>;
+                       xlnx,mb-dbg-ports = <0x1>;
+                       xlnx,uart-width = <0x8>;
+                       xlnx,use-uart = <0x1>;
+                       xlnx,write-fsl-ports = <0x0>;
+               } ;
+               mpmc@90000000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "xlnx,mpmc-4.02.a";
+                       PIM3: sdma@84600180 {
+                               compatible = "xlnx,ll-dma-1.00.a";
+                               interrupt-parent = <&xps_intc_0>;
+                               interrupts = < 2 2 1 2 >;
+                               reg = < 0x84600180 0x80 >;
+                       } ;
+               } ;
+               xps_intc_0: interrupt-controller@81800000 {
+                       #interrupt-cells = <0x2>;
+                       compatible = "xlnx,xps-intc-1.00.a";
+                       interrupt-controller ;
+                       reg = < 0x81800000 0x10000 >;
+                       xlnx,kind-of-intr = <0x100>;
+                       xlnx,num-intr-inputs = <0x9>;
+               } ;
+               xps_timer_1: timer@83c00000 {
+                       compatible = "xlnx,xps-timer-1.00.a";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 3 2 >;
+                       reg = < 0x83c00000 0x10000 >;
+                       xlnx,count-width = <0x20>;
+                       xlnx,family = "virtex5";
+                       xlnx,gen0-assert = <0x1>;
+                       xlnx,gen1-assert = <0x1>;
+                       xlnx,one-timer-only = <0x0>;
+                       xlnx,trig0-assert = <0x1>;
+                       xlnx,trig1-assert = <0x1>;
+               } ;
+       } ;
+}  ;
diff --git a/arch/microblaze/platform/platform.c b/arch/microblaze/platform/platform.c
new file mode 100644 (file)
index 0000000..56e0234
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2008 Michal Simek <monstr@monstr.eu>
+ *
+ * based on virtex.c file
+ *
+ * Copyright 2007 Secret Lab Technologies Ltd.
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+static struct of_device_id xilinx_of_bus_ids[] __initdata = {
+       { .compatible = "simple-bus", },
+       { .compatible = "xlnx,plb-v46-1.00.a", },
+       { .compatible = "xlnx,opb-v20-1.10.c", },
+       { .compatible = "xlnx,opb-v20-1.10.b", },
+       { .compatible = "xlnx,compound", },
+       {}
+};
+
+static int __init microblaze_device_probe(void)
+{
+       of_platform_bus_probe(NULL, xilinx_of_bus_ids, NULL);
+       return 0;
+}
+device_initcall(microblaze_device_probe);
index 0328fd4..343e3a3 100644 (file)
@@ -854,7 +854,7 @@ config SERIAL_IMX_CONSOLE
 
 config SERIAL_UARTLITE
        tristate "Xilinx uartlite serial port support"
-       depends on PPC32
+       depends on PPC32 || MICROBLAZE
        select SERIAL_CORE
        help
          Say Y here if you want to use the Xilinx uartlite serial controller.
@@ -1340,7 +1340,7 @@ config SERIAL_NETX_CONSOLE
 
 config SERIAL_OF_PLATFORM
        tristate "Serial port on Open Firmware platform bus"
-       depends on PPC_OF
+       depends on PPC_OF || MICROBLAZE
        depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL
        help
          If you have a PowerPC based system that has serial ports