Browse Source

Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/epip/linux-2.6-unicore32

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/epip/linux-2.6-unicore32: (40 commits)
  unicore32: rewrite arch-specific tlb.h to use asm-generic version
  unicore32: modify io_p2v and io_v2p macros, and adjust PKUNITY_mmio_BASEs
  unicore32: replace unicore32-specific iomap functions with generic lib implementation
  unicore32 machine related: add frame buffer driver for pkunity-v3 soc
  unicore32 machine related files: add i2c bus drivers for pkunity-v3 soc
  unicore32 io: redefine __REG(x) and re-use readl/writel funcs
  unicore32 i8042 upgrade and bugfix: adjust resource request region type
  unicore32 upgrade to v2.6.38-rc5: add one more paramter for pte_alloc_map call
  unicore32 i8042: adjust io funcs of i8042-unicore32io.h
  unicore32: rename PKUNITY_IOSPACE_BASE to PKUNITY_MMIO_BASE
  unicore32: modify function names and parameters for irq_chips
  unicore32: remove unused lines in arch/unicore32/include/asm/irq.h
  unicore32 time.c: change calculate method for clock_event_device
  unicore32: ADD MAINTAINER for unicore32 architecture
  unicore32 machine related files: ps2 driver
  unicore32 machine related files: pci bus handling
  unicore32 machine related files: hardware registers
  unicore32 machine related files: core files
  unicore32 additional architecture files: boot process
  unicore32 additional architecture files: low-level lib: misc
  ...

Acked-by: Arnd Bergmann <arnd@arndb.de>
Linus Torvalds 14 years ago
parent
commit
7b7adc4a01
100 changed files with 9139 additions and 0 deletions
  1. 16 0
      MAINTAINERS
  2. 21 0
      arch/unicore32/.gitignore
  3. 275 0
      arch/unicore32/Kconfig
  4. 68 0
      arch/unicore32/Kconfig.debug
  5. 95 0
      arch/unicore32/Makefile
  6. 47 0
      arch/unicore32/boot/Makefile
  7. 68 0
      arch/unicore32/boot/compressed/Makefile
  8. 204 0
      arch/unicore32/boot/compressed/head.S
  9. 126 0
      arch/unicore32/boot/compressed/misc.c
  10. 6 0
      arch/unicore32/boot/compressed/piggy.S.in
  11. 61 0
      arch/unicore32/boot/compressed/vmlinux.lds.in
  12. 215 0
      arch/unicore32/configs/debug_defconfig
  13. 2 0
      arch/unicore32/include/asm/Kbuild
  14. 131 0
      arch/unicore32/include/asm/assembler.h
  15. 47 0
      arch/unicore32/include/asm/bitops.h
  16. 24 0
      arch/unicore32/include/asm/byteorder.h
  17. 27 0
      arch/unicore32/include/asm/cache.h
  18. 211 0
      arch/unicore32/include/asm/cacheflush.h
  19. 41 0
      arch/unicore32/include/asm/checksum.h
  20. 45 0
      arch/unicore32/include/asm/cpu-single.h
  21. 33 0
      arch/unicore32/include/asm/cputype.h
  22. 52 0
      arch/unicore32/include/asm/delay.h
  23. 124 0
      arch/unicore32/include/asm/dma-mapping.h
  24. 23 0
      arch/unicore32/include/asm/dma.h
  25. 94 0
      arch/unicore32/include/asm/elf.h
  26. 26 0
      arch/unicore32/include/asm/fpstate.h
  27. 53 0
      arch/unicore32/include/asm/fpu-ucf64.h
  28. 143 0
      arch/unicore32/include/asm/futex.h
  29. 104 0
      arch/unicore32/include/asm/gpio.h
  30. 32 0
      arch/unicore32/include/asm/hwcap.h
  31. 55 0
      arch/unicore32/include/asm/io.h
  32. 105 0
      arch/unicore32/include/asm/irq.h
  33. 53 0
      arch/unicore32/include/asm/irqflags.h
  34. 22 0
      arch/unicore32/include/asm/linkage.h
  35. 46 0
      arch/unicore32/include/asm/memblock.h
  36. 123 0
      arch/unicore32/include/asm/memory.h
  37. 17 0
      arch/unicore32/include/asm/mmu.h
  38. 87 0
      arch/unicore32/include/asm/mmu_context.h
  39. 20 0
      arch/unicore32/include/asm/mutex.h
  40. 80 0
      arch/unicore32/include/asm/page.h
  41. 46 0
      arch/unicore32/include/asm/pci.h
  42. 110 0
      arch/unicore32/include/asm/pgalloc.h
  43. 55 0
      arch/unicore32/include/asm/pgtable-hwdef.h
  44. 317 0
      arch/unicore32/include/asm/pgtable.h
  45. 92 0
      arch/unicore32/include/asm/processor.h
  46. 133 0
      arch/unicore32/include/asm/ptrace.h
  47. 29 0
      arch/unicore32/include/asm/sigcontext.h
  48. 31 0
      arch/unicore32/include/asm/stacktrace.h
  49. 38 0
      arch/unicore32/include/asm/string.h
  50. 30 0
      arch/unicore32/include/asm/suspend.h
  51. 161 0
      arch/unicore32/include/asm/system.h
  52. 154 0
      arch/unicore32/include/asm/thread_info.h
  53. 34 0
      arch/unicore32/include/asm/timex.h
  54. 28 0
      arch/unicore32/include/asm/tlb.h
  55. 195 0
      arch/unicore32/include/asm/tlbflush.h
  56. 21 0
      arch/unicore32/include/asm/traps.h
  57. 47 0
      arch/unicore32/include/asm/uaccess.h
  58. 18 0
      arch/unicore32/include/asm/unistd.h
  59. 108 0
      arch/unicore32/include/mach/PKUnity.h
  60. 24 0
      arch/unicore32/include/mach/bitfield.h
  61. 48 0
      arch/unicore32/include/mach/dma.h
  62. 38 0
      arch/unicore32/include/mach/hardware.h
  63. 20 0
      arch/unicore32/include/mach/map.h
  64. 58 0
      arch/unicore32/include/mach/memory.h
  65. 36 0
      arch/unicore32/include/mach/ocd.h
  66. 43 0
      arch/unicore32/include/mach/pm.h
  67. 32 0
      arch/unicore32/include/mach/regs-ac97.h
  68. 81 0
      arch/unicore32/include/mach/regs-dmac.h
  69. 70 0
      arch/unicore32/include/mach/regs-gpio.h
  70. 63 0
      arch/unicore32/include/mach/regs-i2c.h
  71. 28 0
      arch/unicore32/include/mach/regs-intc.h
  72. 79 0
      arch/unicore32/include/mach/regs-nand.h
  73. 92 0
      arch/unicore32/include/mach/regs-ost.h
  74. 94 0
      arch/unicore32/include/mach/regs-pci.h
  75. 126 0
      arch/unicore32/include/mach/regs-pm.h
  76. 20 0
      arch/unicore32/include/mach/regs-ps2.h
  77. 34 0
      arch/unicore32/include/mach/regs-resetc.h
  78. 37 0
      arch/unicore32/include/mach/regs-rtc.h
  79. 156 0
      arch/unicore32/include/mach/regs-sdc.h
  80. 98 0
      arch/unicore32/include/mach/regs-spi.h
  81. 3 0
      arch/unicore32/include/mach/regs-uart.h
  82. 229 0
      arch/unicore32/include/mach/regs-umal.h
  83. 200 0
      arch/unicore32/include/mach/regs-unigfx.h
  84. 34 0
      arch/unicore32/include/mach/uncompress.h
  85. 33 0
      arch/unicore32/kernel/Makefile
  86. 112 0
      arch/unicore32/kernel/asm-offsets.c
  87. 390 0
      arch/unicore32/kernel/clock.c
  88. 93 0
      arch/unicore32/kernel/cpu-ucv2.c
  89. 89 0
      arch/unicore32/kernel/debug-macro.S
  90. 85 0
      arch/unicore32/kernel/debug.S
  91. 183 0
      arch/unicore32/kernel/dma.c
  92. 59 0
      arch/unicore32/kernel/early_printk.c
  93. 38 0
      arch/unicore32/kernel/elf.c
  94. 824 0
      arch/unicore32/kernel/entry.S
  95. 126 0
      arch/unicore32/kernel/fpu-ucf64.c
  96. 122 0
      arch/unicore32/kernel/gpio.c
  97. 252 0
      arch/unicore32/kernel/head.S
  98. 160 0
      arch/unicore32/kernel/hibernate.c
  99. 117 0
      arch/unicore32/kernel/hibernate_asm.S
  100. 44 0
      arch/unicore32/kernel/init_task.c

+ 16 - 0
MAINTAINERS

@@ -4907,6 +4907,15 @@ S:	Maintained
 F:	drivers/block/pktcdvd.c
 F:	include/linux/pktcdvd.h
 
+PKUNITY SOC DRIVERS
+M:	Guan Xuetao <gxt@mprc.pku.edu.cn>
+W:	http://mprc.pku.edu.cn/~guanxuetao/linux
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/epip/linux-2.6-unicore32.git
+F:	drivers/input/serio/i8042-unicore32io.h
+F:	drivers/i2c/busses/i2c-puv3.c
+F:	drivers/video/fb-puv3.c
+
 PMC SIERRA MaxRAID DRIVER
 M:	Anil Ravindranath <anil_ravindranath@pmc-sierra.com>
 L:	linux-scsi@vger.kernel.org
@@ -6270,6 +6279,13 @@ F:	drivers/uwb/
 F:	include/linux/uwb.h
 F:	include/linux/uwb/
 
+UNICORE32 ARCHITECTURE:
+M:	Guan Xuetao <gxt@mprc.pku.edu.cn>
+W:	http://mprc.pku.edu.cn/~guanxuetao/linux
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/epip/linux-2.6-unicore32.git
+F:	arch/unicore32/
+
 UNIFDEF
 M:	Tony Finch <dot@dotat.at>
 W:	http://dotat.at/prog/unifdef

+ 21 - 0
arch/unicore32/.gitignore

@@ -0,0 +1,21 @@
+#
+# Generated include files
+#
+include/generated
+#
+# Generated ld script file
+#
+kernel/vmlinux.lds
+#
+# Generated images in boot
+#
+boot/Image
+boot/zImage
+boot/uImage
+#
+# Generated files in boot/compressed
+#
+boot/compressed/piggy.S
+boot/compressed/piggy.gzip
+boot/compressed/vmlinux
+boot/compressed/vmlinux.lds

+ 275 - 0
arch/unicore32/Kconfig

@@ -0,0 +1,275 @@
+config UNICORE32
+	def_bool y
+	select HAVE_MEMBLOCK
+	select HAVE_GENERIC_DMA_COHERENT
+	select HAVE_GENERIC_HARDIRQS
+	select HAVE_DMA_ATTRS
+	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_BZIP2
+	select HAVE_KERNEL_LZO
+	select HAVE_KERNEL_LZMA
+	select GENERIC_FIND_FIRST_BIT
+	select GENERIC_IRQ_PROBE
+	select GENERIC_HARDIRQS_NO_DEPRECATED
+	select ARCH_WANT_FRAME_POINTERS
+	help
+	  UniCore-32 is 32-bit Instruction Set Architecture,
+	  including a series of low-power-consumption RISC chip
+	  designs licensed by PKUnity Ltd.
+	  Please see web page at <http://www.pkunity.com/>.
+
+config HAVE_PWM
+	bool
+
+config GENERIC_GPIO
+	def_bool y
+
+config GENERIC_CLOCKEVENTS
+	bool
+
+config GENERIC_CSUM
+	def_bool y
+
+config GENERIC_IOMAP
+	def_bool y
+
+config NO_IOPORT
+	bool
+
+config STACKTRACE_SUPPORT
+	def_bool y
+
+config HAVE_LATENCYTOP_SUPPORT
+	def_bool y
+
+config LOCKDEP_SUPPORT
+	def_bool y
+
+config RWSEM_GENERIC_SPINLOCK
+	def_bool y
+
+config RWSEM_XCHGADD_ALGORITHM
+	bool
+
+config ARCH_HAS_ILOG2_U32
+	bool
+
+config ARCH_HAS_ILOG2_U64
+	bool
+
+config ARCH_HAS_CPUFREQ
+	bool
+
+config GENERIC_HWEIGHT
+	def_bool y
+
+config GENERIC_CALIBRATE_DELAY
+	def_bool y
+
+config ARCH_MAY_HAVE_PC_FDC
+	bool
+
+config NEED_DMA_MAP_STATE
+       def_bool y
+
+source "init/Kconfig"
+
+source "kernel/Kconfig.freezer"
+
+menu "System Type"
+
+config MMU
+	def_bool y
+
+config ARCH_FPGA
+	bool
+
+config ARCH_PUV3
+	def_bool y
+	select CPU_UCV2
+	select GENERIC_CLOCKEVENTS
+	select HAVE_CLK
+	select ARCH_REQUIRE_GPIOLIB
+	select ARCH_HAS_CPUFREQ
+
+# CONFIGs for ARCH_PUV3
+
+if ARCH_PUV3
+
+choice
+	prompt "Board Selection"
+	default PUV3_DB0913
+
+config PUV3_FPGA_DLX200
+	select ARCH_FPGA
+	bool "FPGA board"
+
+config PUV3_DB0913
+	bool "DEBUG board (0913)"
+
+config PUV3_NB0916
+	bool "NetBook board (0916)"
+	select HAVE_PWM
+
+config PUV3_SMW0919
+	bool "Security Mini-Workstation board (0919)"
+
+endchoice
+
+config PUV3_PM
+	def_bool y if !ARCH_FPGA
+
+endif
+
+source "arch/unicore32/mm/Kconfig"
+
+comment "Floating poing support"
+
+config UNICORE_FPU_F64
+	def_bool y if !ARCH_FPGA
+
+endmenu
+
+menu "Bus support"
+
+config PCI
+	bool "PCI Support"
+	help
+	  Find out whether you have a PCI motherboard. PCI is the name of a
+	  bus system, i.e. the way the CPU talks to the other stuff inside
+	  your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
+	  VESA. If you have PCI, say Y, otherwise N.
+
+source "drivers/pci/Kconfig"
+
+source "drivers/pcmcia/Kconfig"
+
+endmenu
+
+menu "Kernel Features"
+
+source "kernel/time/Kconfig"
+
+source "kernel/Kconfig.preempt"
+
+source "kernel/Kconfig.hz"
+
+source "mm/Kconfig"
+
+config LEDS
+	def_bool y
+	depends on GENERIC_GPIO
+
+config ALIGNMENT_TRAP
+	def_bool y
+	help
+	  Unicore processors can not fetch/store information which is not
+	  naturally aligned on the bus, i.e., a 4 byte fetch must start at an
+	  address divisible by 4. On 32-bit Unicore processors, these non-aligned
+	  fetch/store instructions will be emulated in software if you say
+	  here, which has a severe performance impact. This is necessary for
+	  correct operation of some network protocols. With an IP-only
+	  configuration it is safe to say N, otherwise say Y.
+
+endmenu
+
+menu "Boot options"
+
+config CMDLINE
+	string "Default kernel command string"
+	default ""
+
+config CMDLINE_FORCE
+	bool "Always use the default kernel command string"
+	depends on CMDLINE != ""
+	help
+	  Always use the default kernel command string, even if the boot
+	  loader passes other arguments to the kernel.
+	  This is useful if you cannot or don't want to change the
+	  command-line options your boot loader passes to the kernel.
+
+	  If unsure, say N.
+
+endmenu
+
+menu "Userspace binary formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+menu "Power management options"
+
+source "kernel/power/Kconfig"
+
+if ARCH_HAS_CPUFREQ
+source "drivers/cpufreq/Kconfig"
+endif
+
+config ARCH_SUSPEND_POSSIBLE
+	def_bool y if !ARCH_FPGA
+
+config ARCH_HIBERNATION_POSSIBLE
+	def_bool y if !ARCH_FPGA
+
+endmenu
+
+source "net/Kconfig"
+
+if ARCH_PUV3
+
+config PUV3_GPIO
+	bool
+	depends on !ARCH_FPGA
+	select GENERIC_GPIO
+	select GPIO_SYSFS if EXPERIMENTAL
+	default y
+
+config PUV3_PWM
+	tristate
+	default BACKLIGHT_PWM
+	help
+	  Enable support for NB0916 PWM controllers
+
+config PUV3_RTC
+	tristate "PKUnity v3 RTC Support"
+	depends on !ARCH_FPGA
+
+if PUV3_NB0916
+
+menu "PKUnity NetBook-0916 Features"
+
+config I2C_BATTERY_BQ27200
+	tristate "I2C Battery BQ27200 Support"
+	select PUV3_I2C
+	select POWER_SUPPLY
+	select BATTERY_BQ27x00
+
+config I2C_EEPROM_AT24
+	tristate "I2C EEPROMs AT24 support"
+	select PUV3_I2C
+	select MISC_DEVICES
+	select EEPROM_AT24
+
+config LCD_BACKLIGHT
+	tristate "LCD Backlight support"
+	select BACKLIGHT_LCD_SUPPORT
+	select BACKLIGHT_PWM
+
+endmenu
+
+endif
+
+endif
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/unicore32/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"

+ 68 - 0
arch/unicore32/Kconfig.debug

@@ -0,0 +1,68 @@
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config STRICT_DEVMEM
+	bool "Filter access to /dev/mem"
+	depends on MMU
+	---help---
+	  If this option is disabled, you allow userspace (root) access to all
+	  of memory, including kernel and userspace memory. Accidental
+	  access to this is obviously disastrous, but specific access can
+	  be used by people debugging the kernel.
+
+	  If this option is switched on, the /dev/mem file only allows
+	  userspace access to memory mapped peripherals.
+
+          If in doubt, say Y.
+
+config EARLY_PRINTK
+	def_bool DEBUG_OCD
+	help
+	  Write kernel log output directly into the ocd or to a serial port.
+
+	  This is useful for kernel debugging when your machine crashes very
+	  early before the console code is initialized. For normal operation
+	  it is not recommended because it looks ugly and doesn't cooperate
+	  with klogd/syslogd or the X server. You should normally N here,
+	  unless you want to debug such a crash.
+
+config DEBUG_STACK_USAGE
+	bool "Enable stack utilization instrumentation"
+	depends on DEBUG_KERNEL
+	help
+	  Enables the display of the minimum amount of free stack which each
+	  task has ever had available in the sysrq-T output.
+
+# These options are only for real kernel hackers who want to get their hands dirty.
+config DEBUG_LL
+	bool "Kernel low-level debugging functions"
+	depends on DEBUG_KERNEL
+	help
+	  Say Y here to include definitions of printascii, printch, printhex
+	  in the kernel.  This is helpful if you are debugging code that
+	  executes before the console is initialized.
+
+config DEBUG_OCD
+	bool "Kernel low-level debugging via On-Chip-Debugger"
+	depends on DEBUG_LL
+	default y
+	help
+	  Say Y here if you want the debug print routines to direct their
+	  output to the UniCore On-Chip-Debugger channel using CP #1.
+
+config DEBUG_OCD_BREAKPOINT
+	bool "Breakpoint support via On-Chip-Debugger"
+	depends on DEBUG_OCD
+
+config DEBUG_UART
+	int "Kernel low-level debugging messages via serial port"
+	depends on DEBUG_LL
+	range 0 1
+	default "0"
+	help
+	  Choice for UART for kernel low-level using PKUnity UARTS,
+	  should be between zero and one. The port must have been
+	  initialised by the boot-loader before use.
+
+endmenu

+ 95 - 0
arch/unicore32/Makefile

@@ -0,0 +1,95 @@
+#
+# arch/unicore32/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies.
+#
+# 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) 2002~2010 by Guan Xue-tao
+#
+ifneq ($(SUBARCH),$(ARCH))
+	ifeq ($(CROSS_COMPILE),)
+		CROSS_COMPILE := $(call cc-cross-prefix, unicore32-linux-)
+	endif
+endif
+
+LDFLAGS_vmlinux		:= -p --no-undefined -X
+
+OBJCOPYFLAGS		:= -O binary -R .note -R .note.gnu.build-id -R .comment -S
+
+# Never generate .eh_frame
+KBUILD_CFLAGS		+= $(call cc-option,-fno-dwarf2-cfi-asm)
+
+# Never use hard float in kernel
+KBUILD_CFLAGS		+= -msoft-float
+
+ifeq ($(CONFIG_FRAME_POINTER),y)
+KBUILD_CFLAGS		+= -mno-sched-prolog
+endif
+
+CHECKFLAGS		+= -D__unicore32__
+
+head-y			:= arch/unicore32/kernel/head.o
+head-y			+= arch/unicore32/kernel/init_task.o
+
+core-y			+= arch/unicore32/kernel/
+core-y			+= arch/unicore32/mm/
+
+libs-y			+= arch/unicore32/lib/
+
+ASM_GENERATED_DIR	:= $(srctree)/arch/unicore32/include/generated
+LINUXINCLUDE		+= -I$(ASM_GENERATED_DIR)
+
+ASM_GENERIC_HEADERS	:= atomic.h auxvec.h
+ASM_GENERIC_HEADERS	+= bitsperlong.h bug.h bugs.h
+ASM_GENERIC_HEADERS	+= cputime.h current.h
+ASM_GENERIC_HEADERS	+= device.h div64.h
+ASM_GENERIC_HEADERS	+= emergency-restart.h errno.h
+ASM_GENERIC_HEADERS	+= fb.h fcntl.h ftrace.h
+ASM_GENERIC_HEADERS	+= hardirq.h hw_irq.h
+ASM_GENERIC_HEADERS	+= ioctl.h ioctls.h ipcbuf.h irq_regs.h
+ASM_GENERIC_HEADERS	+= kdebug.h kmap_types.h
+ASM_GENERIC_HEADERS	+= local.h
+ASM_GENERIC_HEADERS	+= mman.h module.h msgbuf.h
+ASM_GENERIC_HEADERS	+= param.h parport.h percpu.h poll.h posix_types.h
+ASM_GENERIC_HEADERS	+= resource.h
+ASM_GENERIC_HEADERS	+= scatterlist.h sections.h segment.h sembuf.h serial.h
+ASM_GENERIC_HEADERS	+= setup.h shmbuf.h shmparam.h
+ASM_GENERIC_HEADERS	+= siginfo.h signal.h sizes.h
+ASM_GENERIC_HEADERS	+= socket.h sockios.h stat.h statfs.h swab.h syscalls.h
+ASM_GENERIC_HEADERS	+= termbits.h termios.h topology.h types.h
+ASM_GENERIC_HEADERS	+= ucontext.h unaligned.h user.h
+ASM_GENERIC_HEADERS	+= vga.h
+ASM_GENERIC_HEADERS	+= xor.h
+
+archprepare:
+ifneq ($(ASM_GENERATED_DIR), $(wildcard $(ASM_GENERATED_DIR)))
+	$(Q)mkdir -p $(ASM_GENERATED_DIR)/asm
+	$(Q)$(foreach a, $(ASM_GENERIC_HEADERS),	\
+		echo '#include <asm-generic/$a>'	\
+			> $(ASM_GENERATED_DIR)/asm/$a; )
+endif
+
+boot			:= arch/unicore32/boot
+
+# Default target when executing plain make
+KBUILD_IMAGE		:= zImage
+
+all:	$(KBUILD_IMAGE)
+
+zImage Image uImage: vmlinux
+	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+MRPROPER_DIRS		+= $(ASM_GENERATED_DIR)
+
+archclean:
+	$(Q)$(MAKE) $(clean)=$(boot)
+
+define archhelp
+  echo  '* zImage        - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
+  echo  '  Image         - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
+  echo  '  uImage        - U-Boot wrapped zImage'
+endef

+ 47 - 0
arch/unicore32/boot/Makefile

@@ -0,0 +1,47 @@
+#
+# arch/unicore32/boot/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies.
+#
+# 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) 2001~2010 GUAN Xue-tao
+#
+
+MKIMAGE := $(srctree)/scripts/mkuboot.sh
+
+targets := Image zImage uImage
+
+$(obj)/Image: vmlinux FORCE
+	$(call if_changed,objcopy)
+	@echo '  Kernel: $@ is ready'
+
+$(obj)/compressed/vmlinux: $(obj)/Image FORCE
+	$(Q)$(MAKE) $(build)=$(obj)/compressed $@
+
+$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
+	$(call if_changed,objcopy)
+	@echo '  Kernel: $@ is ready'
+
+quiet_cmd_uimage = UIMAGE  $@
+      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A unicore -O linux -T kernel \
+		   -C none -a $(LOADADDR) -e $(STARTADDR) \
+		   -n 'Linux-$(KERNELRELEASE)' -d $< $@
+
+$(obj)/uImage: LOADADDR=0x0
+
+$(obj)/uImage: STARTADDR=$(LOADADDR)
+
+$(obj)/uImage: $(obj)/zImage FORCE
+	$(call if_changed,uimage)
+	@echo '  Image $@ is ready'
+
+PHONY += initrd FORCE
+initrd:
+	@test "$(INITRD)" != "" || \
+	(echo You must specify INITRD; exit -1)
+
+subdir- := compressed

+ 68 - 0
arch/unicore32/boot/compressed/Makefile

@@ -0,0 +1,68 @@
+#
+# linux/arch/unicore32/boot/compressed/Makefile
+#
+# create a compressed vmlinuz image from the original vmlinux
+#
+# 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) 2001~2010 GUAN Xue-tao
+#
+
+EXTRA_CFLAGS	:= -fpic -fno-builtin
+EXTRA_AFLAGS	:= -Wa,-march=all
+
+OBJS		:= misc.o
+
+# font.c and font.o
+CFLAGS_font.o	:= -Dstatic=
+$(obj)/font.c: $(srctree)/drivers/video/console/font_8x8.c
+	$(call cmd,shipped)
+
+# piggy.S and piggy.o
+suffix_$(CONFIG_KERNEL_GZIP)	:= gzip
+suffix_$(CONFIG_KERNEL_BZIP2)	:= bz2
+suffix_$(CONFIG_KERNEL_LZO)	:= lzo
+suffix_$(CONFIG_KERNEL_LZMA)	:= lzma
+
+$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE
+	$(call if_changed,$(suffix_y))
+
+SEDFLAGS_piggy	= s/DECOMP_SUFFIX/$(suffix_y)/
+$(obj)/piggy.S: $(obj)/piggy.S.in
+	@sed "$(SEDFLAGS_piggy)" < $< > $@
+
+$(obj)/piggy.o:  $(obj)/piggy.$(suffix_y) $(obj)/piggy.S FORCE
+
+targets		:= vmlinux vmlinux.lds font.o font.c head.o misc.o \
+			piggy.$(suffix_y) piggy.o piggy.S \
+
+# Make sure files are removed during clean
+extra-y		+= piggy.gzip piggy.bz2 piggy.lzo piggy.lzma
+
+# ?
+LDFLAGS_vmlinux += -p
+# Report unresolved symbol references
+LDFLAGS_vmlinux += --no-undefined
+# Delete all temporary local symbols
+LDFLAGS_vmlinux += -X
+# Next argument is a linker script
+LDFLAGS_vmlinux += -T
+
+# For uidivmod
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/head.o $(obj)/piggy.o \
+		$(obj)/misc.o FORCE
+	$(call if_changed,ld)
+	@:
+
+# We now have a PIC decompressor implementation.  Decompressors running
+# from RAM should not define ZTEXTADDR.  Decompressors running directly
+# from ROM or Flash must define ZTEXTADDR (preferably via the config)
+ZTEXTADDR	:= 0
+ZBSSADDR	:= ALIGN(4)
+
+SEDFLAGS_lds	= s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
+$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/unicore32/boot/Makefile $(KCONFIG_CONFIG)
+	@sed "$(SEDFLAGS_lds)" < $< > $@
+

+ 204 - 0
arch/unicore32/boot/compressed/head.S

@@ -0,0 +1,204 @@
+/*
+ * linux/arch/unicore32/boot/compressed/head.S
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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/linkage.h>
+#include <mach/memory.h>
+
+#define csub	cmpsub
+#define cand	cmpand
+#define nop8	nop; nop; nop; nop; nop; nop; nop; nop
+
+		.section ".start", #alloc, #execinstr
+		.text
+start:
+		.type	start,#function
+
+		/* Initialize ASR, PRIV mode and INTR off */
+		mov	r0, #0xD3
+		mov.a	asr, r0
+
+		adr	r0, LC0
+		ldm	(r1, r2, r3, r5, r6, r7, r8), [r0]+
+		ldw	sp, [r0+], #28
+		sub.a	r0, r0, r1		@ calculate the delta offset
+
+		/*
+		 * if delta is zero, we are running at the address
+		 * we were linked at.
+		 */
+		beq	not_relocated
+
+		/*
+		 * We're running at a different address.  We need to fix
+		 * up various pointers:
+		 *   r5 - zImage base address (_start)
+		 *   r7 - GOT start
+		 *   r8 - GOT end
+		 */
+		add	r5, r5, r0
+		add	r7, r7, r0
+		add	r8, r8, r0
+
+		/*
+		 * we need to fix up pointers into the BSS region.
+		 *   r2 - BSS start
+		 *   r3 - BSS end
+		 *   sp - stack pointer
+		 */
+		add	r2, r2, r0
+		add	r3, r3, r0
+		add	sp, sp, r0
+
+		/*
+		 * Relocate all entries in the GOT table.
+		 * This fixes up the C references.
+		 *   r7 - GOT start
+		 *   r8 - GOT end
+		 */
+1001:		ldw	r1, [r7+], #0
+		add	r1, r1, r0
+		stw.w	r1, [r7]+, #4
+		csub.a	r7, r8
+		bub	1001b
+
+not_relocated:
+		/*
+		 * Clear BSS region.
+		 *   r2 - BSS start
+		 *   r3 - BSS end
+		 */
+		mov	r0, #0
+1002:		stw.w	r0, [r2]+, #4
+		csub.a	r2, r3
+		bub	1002b
+
+		/*
+		 * Turn on the cache.
+		 */
+                mov     r0, #0
+                movc    p0.c5, r0, #28		@ cache invalidate all
+                nop8
+                movc    p0.c6, r0, #6		@ tlb invalidate all
+                nop8
+
+                mov     r0, #0x1c		@ en icache and wb dcache
+                movc    p0.c1, r0, #0
+                nop8
+
+		/*
+		 * Set up some pointers, for starting decompressing.
+		 */
+
+		mov	r1, sp			@ malloc space above stack
+		add	r2, sp, #0x10000	@ 64k max
+
+		/*
+		 * Check to see if we will overwrite ourselves.
+		 *   r4 = final kernel address
+		 *   r5 = start of this image
+		 *   r6 = size of decompressed image
+		 *   r2 = end of malloc space (and therefore this image)
+		 * We basically want:
+		 *   r4 >= r2 -> OK
+		 *   r4 + image length <= r5 -> OK
+		 */
+		ldw	r4, =KERNEL_IMAGE_START
+		csub.a	r4, r2
+		bea	wont_overwrite
+		add	r0, r4, r6
+		csub.a	r0, r5
+		beb	wont_overwrite
+
+		/*
+		 * If overwrite, just print error message
+		 */
+		b	__error_overwrite
+
+		/*
+		 * We're not in danger of overwriting ourselves.
+		 * Do this the simple way.
+		 */
+wont_overwrite:
+		/*
+		 * decompress_kernel:
+		 *   r0: output_start
+		 *   r1: free_mem_ptr_p
+		 *   r2: free_mem_ptr_end_p
+		 */
+		mov	r0, r4
+		b.l	decompress_kernel	@ C functions
+
+		/*
+		 * Clean and flush the cache to maintain consistency.
+		 */
+		mov	r0, #0
+                movc    p0.c5, r0, #14		@ flush dcache
+		nop8
+                movc    p0.c5, r0, #20		@ icache invalidate all
+                nop8
+
+		/*
+		 * Turn off the Cache and MMU.
+		 */
+		mov	r0, #0			@ disable i/d cache and MMU
+		movc	p0.c1, r0, #0
+                nop8
+
+		mov	r0, #0			@ must be zero
+		ldw	r4, =KERNEL_IMAGE_START
+		mov	pc, r4			@ call kernel
+
+
+		.align	2
+		.type	LC0, #object
+LC0:		.word	LC0			@ r1
+		.word	__bss_start		@ r2
+		.word	_end			@ r3
+		.word	_start			@ r5
+		.word	_image_size		@ r6
+		.word	_got_start		@ r7
+		.word	_got_end		@ r8
+		.word	decompress_stack_end	@ sp
+		.size	LC0, . - LC0
+
+print_string:
+#ifdef CONFIG_DEBUG_OCD
+2001:		ldb.w	r1, [r0]+, #1
+		csub.a	r1, #0
+		bne	2002f
+		mov	pc, lr
+2002:
+		movc	r2, p1.c0, #0
+		cand.a	r2, #2
+		bne	2002b
+		movc	p1.c1, r1, #1
+		csub.a	r1, #'\n'
+		cmoveq	r1, #'\r'
+		beq	2002b
+		b	2001b
+#else
+		mov	pc, lr
+#endif
+
+__error_overwrite:
+		adr	r0, str_error
+		b.l	print_string
+2001:		nop8
+		b	2001b
+str_error:	.asciz	"\nError: Kernel address OVERWRITE\n"
+		.align
+
+		.ltorg
+
+		.align	4
+		.section ".stack", "aw", %nobits
+decompress_stack:	.space	4096
+decompress_stack_end:

+ 126 - 0
arch/unicore32/boot/compressed/misc.c

@@ -0,0 +1,126 @@
+/*
+ * linux/arch/unicore32/boot/compressed/misc.c
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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 <asm/unaligned.h>
+#include <mach/uncompress.h>
+
+/*
+ * gzip delarations
+ */
+unsigned char *output_data;
+unsigned long output_ptr;
+
+unsigned int free_mem_ptr;
+unsigned int free_mem_end_ptr;
+
+#define STATIC static
+#define STATIC_RW_DATA	/* non-static please */
+
+/*
+ * arch-dependent implementations
+ */
+#ifndef ARCH_HAVE_DECOMP_ERROR
+#define arch_decomp_error(x)
+#endif
+
+#ifndef ARCH_HAVE_DECOMP_SETUP
+#define arch_decomp_setup()
+#endif
+
+#ifndef ARCH_HAVE_DECOMP_PUTS
+#define arch_decomp_puts(p)
+#endif
+
+void *memcpy(void *dest, const void *src, size_t n)
+{
+	int i = 0;
+	unsigned char *d = (unsigned char *)dest, *s = (unsigned char *)src;
+
+	for (i = n >> 3; i > 0; i--) {
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+	}
+
+	if (n & 1 << 2) {
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+	}
+
+	if (n & 1 << 1) {
+		*d++ = *s++;
+		*d++ = *s++;
+	}
+
+	if (n & 1)
+		*d++ = *s++;
+
+	return dest;
+}
+
+void error(char *x)
+{
+	arch_decomp_puts("\n\n");
+	arch_decomp_puts(x);
+	arch_decomp_puts("\n\n -- System halted");
+
+	arch_decomp_error(x);
+
+	for (;;)
+		; /* Halt */
+}
+
+/* Heap size should be adjusted for different decompress method */
+#ifdef CONFIG_KERNEL_GZIP
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_BZIP2
+#include "../../../../lib/decompress_bunzip2.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZMA
+#include "../../../../lib/decompress_unlzma.c"
+#endif
+
+unsigned long decompress_kernel(unsigned long output_start,
+		unsigned long free_mem_ptr_p,
+		unsigned long free_mem_ptr_end_p)
+{
+	unsigned char *tmp;
+
+	output_data		= (unsigned char *)output_start;
+	free_mem_ptr		= free_mem_ptr_p;
+	free_mem_end_ptr	= free_mem_ptr_end_p;
+
+	arch_decomp_setup();
+
+	tmp = (unsigned char *) (((unsigned long)input_data_end) - 4);
+	output_ptr = get_unaligned_le32(tmp);
+
+	arch_decomp_puts("Uncompressing Linux...");
+	decompress(input_data, input_data_end - input_data, NULL, NULL,
+			output_data, NULL, error);
+	arch_decomp_puts(" done, booting the kernel.\n");
+	return output_ptr;
+}

+ 6 - 0
arch/unicore32/boot/compressed/piggy.S.in

@@ -0,0 +1,6 @@
+	.section .piggydata,#alloc
+	.globl	input_data
+input_data:
+	.incbin	"arch/unicore32/boot/compressed/piggy.DECOMP_SUFFIX"
+	.globl	input_data_end
+input_data_end:

+ 61 - 0
arch/unicore32/boot/compressed/vmlinux.lds.in

@@ -0,0 +1,61 @@
+/*
+ * linux/arch/unicore/boot/compressed/vmlinux.lds.in
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+OUTPUT_ARCH(unicore32)
+ENTRY(_start)
+SECTIONS
+{
+  /DISCARD/ : {
+    /*
+     * Discard any r/w data - this produces a link error if we have any,
+     * which is required for PIC decompression.  Local data generates
+     * GOTOFF relocations, which prevents it being relocated independently
+     * of the text/got segments.
+     */
+    *(.data)
+  }
+
+  . = TEXT_START;
+  _text = .;
+
+  .text : {
+    _start = .;
+    *(.start)
+    *(.text)
+    *(.text.*)
+    *(.fixup)
+    *(.gnu.warning)
+    *(.rodata)
+    *(.rodata.*)
+    *(.piggydata)
+    . = ALIGN(4);
+  }
+
+  _etext = .;
+
+  /* Assume size of decompressed image is 4x the compressed image */
+  _image_size = (_etext - _text) * 4;
+
+  _got_start = .;
+  .got			: { *(.got) }
+  _got_end = .;
+  .got.plt		: { *(.got.plt) }
+  _edata = .;
+
+  . = BSS_START;
+  __bss_start = .;
+  .bss			: { *(.bss) }
+  _end = .;
+
+  .stack		: { *(.stack) }
+  .comment 0		: { *(.comment) }
+}
+

+ 215 - 0
arch/unicore32/configs/debug_defconfig

@@ -0,0 +1,215 @@
+### General setup
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-debug"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_HOTPLUG=y
+#	Initial RAM filesystem and RAM disk (initramfs/initrd) support
+#CONFIG_BLK_DEV_INITRD=y
+#CONFIG_INITRAMFS_SOURCE="arch/unicore/ramfs/ramfs_config"
+
+### Enable loadable module support
+CONFIG_MODULES=n
+CONFIG_MODULE_UNLOAD=y
+
+### System Type
+CONFIG_ARCH_PUV3=y
+#	Board Selection
+CONFIG_PUV3_NB0916=y
+#	Processor Features
+CONFIG_CPU_DCACHE_LINE_DISABLE=y
+CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE=n
+
+### Bus support
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY=n
+
+### Boot options
+#	for debug, adding: earlyprintk=ocd,keep initcall_debug
+#	others support: test_suspend=mem root=/dev/sda
+#	hibernate support: resume=/dev/sda3
+CONFIG_CMDLINE="earlyprintk=ocd,keep ignore_loglevel"
+# TODO: mem=512M video=unifb:1024x600-16@75
+# for nfs: root=/dev/nfs rw nfsroot=192.168.10.88:/home/udb/nfs/,rsize=1024,wsize=1024
+#	ip=192.168.10.83:192.168.10.88:192.168.10.1:255.255.255.0::eth0:off
+CONFIG_CMDLINE_FORCE=y
+
+### Power management options
+CONFIG_PM=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_STD_PARTITION="/dev/sda3"
+CONFIG_CPU_FREQ=n
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+
+### Networking support
+CONFIG_NET=y
+#	Networking options
+CONFIG_PACKET=m
+CONFIG_UNIX=m
+#	TCP/IP networking
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IPV6=n
+#	Wireless
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_MAC80211=m
+
+### PKUnity SoC Features
+CONFIG_USB_WLAN_HED_AQ3=n
+CONFIG_USB_CMMB_INNOFIDEI=n
+CONFIG_I2C_BATTERY_BQ27200=n
+CONFIG_I2C_EEPROM_AT24=n
+CONFIG_LCD_BACKLIGHT=n
+
+CONFIG_PUV3_RTC=y
+CONFIG_PUV3_UMAL=y
+CONFIG_PUV3_MUSB=n
+CONFIG_PUV3_AC97=n
+CONFIG_PUV3_NAND=n
+CONFIG_PUV3_MMC=n
+CONFIG_PUV3_UART=n
+
+### Device Drivers
+#	Memory Technology Device (MTD) support
+CONFIG_MTD=m
+CONFIG_MTD_UBI=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=m
+#	RAM/ROM/Flash chip drivers
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_CFI_AMDSTD=m
+#	Mapping drivers for chip access
+CONFIG_MTD_PHYSMAP=m
+
+#	Block devices
+CONFIG_BLK_DEV_LOOP=m
+
+#	SCSI device support
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+
+#	Serial ATA (prod) and Parallel ATA (experimental) drivers
+CONFIG_ATA=y
+CONFIG_SATA_VIA=y
+
+#	Network device support
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NETDEV_1000=y
+#	Wireless LAN
+CONFIG_WLAN_80211=n
+CONFIG_RT2X00=n
+CONFIG_RT73USB=n
+
+#	Input device support
+CONFIG_INPUT_EVDEV=m
+#	Keyboards
+CONFIG_KEYBOARD_GPIO=m
+
+#	I2C support
+CONFIG_I2C=y
+CONFIG_I2C_PUV3=y
+
+#	Hardware Monitoring support
+#CONFIG_SENSORS_LM75=m
+#	Generic Thermal sysfs driver
+#CONFIG_THERMAL=m
+#CONFIG_THERMAL_HWMON=y
+
+#	Multimedia support
+CONFIG_MEDIA_SUPPORT=n
+CONFIG_VIDEO_DEV=n
+CONFIG_USB_VIDEO_CLASS=n
+
+#	Graphics support
+CONFIG_FB=y
+CONFIG_FB_PUV3_UNIGFX=y
+#	Console display driver support
+CONFIG_VGA_CONSOLE=n
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+#	Bootup logo
+CONFIG_LOGO=n
+
+#	Sound card support
+CONFIG_SOUND=m
+#	Advanced Linux Sound Architecture
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+
+#	USB support
+CONFIG_USB_ARCH_HAS_HCD=n
+CONFIG_USB=n
+CONFIG_USB_DEVICEFS=n
+CONFIG_USB_PRINTER=n
+CONFIG_USB_STORAGE=n
+#	Inventra Highspeed Dual Role Controller
+CONFIG_USB_MUSB_HDRC=n
+
+#	LED Support
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+#	LED Triggers
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+
+#	Real Time Clock
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+### File systems
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=m
+#	CD-ROM/DVD Filesystems
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+#	DOS/FAT/NT Filesystems
+CONFIG_VFAT_FS=m
+#	Pseudo filesystems
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+#	Miscellaneous filesystems
+CONFIG_MISC_FILESYSTEMS=y
+CONFIG_JFFS2_FS=m
+CONFIG_UBIFS_FS=m
+#	Network File Systems
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+#	Partition Types
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MSDOS_PARTITION=y
+#	Native language support
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_UTF8=m
+
+### Kernel hacking
+CONFIG_FRAME_WARN=8096
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_PROVE_LOCKING=n
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_LL=y
+

+ 2 - 0
arch/unicore32/include/asm/Kbuild

@@ -0,0 +1,2 @@
+include include/asm-generic/Kbuild.asm
+

+ 131 - 0
arch/unicore32/include/asm/assembler.h

@@ -0,0 +1,131 @@
+/*
+ * linux/arch/unicore32/include/asm/assembler.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ *
+ *  Do not include any C declarations in this file - it is included by
+ *  assembler source.
+ */
+#ifndef __ASSEMBLY__
+#error "Only include this from assembly code"
+#endif
+
+#include <asm/ptrace.h>
+
+/*
+ * Little Endian independent macros for shifting bytes within registers.
+ */
+#define pull            >>
+#define push            <<
+#define get_byte_0      << #0
+#define get_byte_1	>> #8
+#define get_byte_2	>> #16
+#define get_byte_3	>> #24
+#define put_byte_0      << #0
+#define put_byte_1	<< #8
+#define put_byte_2	<< #16
+#define put_byte_3	<< #24
+
+#define cadd		cmpadd
+#define cand		cmpand
+#define csub		cmpsub
+#define cxor		cmpxor
+
+/*
+ * Enable and disable interrupts
+ */
+	.macro disable_irq, temp
+	mov	\temp, asr
+	andn     \temp, \temp, #0xFF
+	or	\temp, \temp, #PSR_I_BIT | PRIV_MODE
+	mov.a	asr, \temp
+	.endm
+
+	.macro enable_irq, temp
+	mov	\temp, asr
+	andn     \temp, \temp, #0xFF
+	or	\temp, \temp, #PRIV_MODE
+	mov.a	asr, \temp
+	.endm
+
+#define USER(x...)				\
+9999:	x;					\
+	.pushsection __ex_table, "a";		\
+	.align	3;				\
+	.long	9999b, 9001f;			\
+	.popsection
+
+	.macro	notcond, cond, nexti = .+8
+	.ifc	\cond, eq
+		bne	\nexti
+	.else;	.ifc	\cond, ne
+		beq	\nexti
+	.else;	.ifc	\cond, ea
+		bub	\nexti
+	.else;	.ifc	\cond, ub
+		bea	\nexti
+	.else;	.ifc	\cond, fs
+		bns	\nexti
+	.else;	.ifc	\cond, ns
+		bfs	\nexti
+	.else;	.ifc	\cond, fv
+		bnv	\nexti
+	.else;	.ifc	\cond, nv
+		bfv	\nexti
+	.else;	.ifc	\cond, ua
+		beb	\nexti
+	.else;	.ifc	\cond, eb
+		bua	\nexti
+	.else;	.ifc	\cond, eg
+		bsl	\nexti
+	.else;	.ifc	\cond, sl
+		beg	\nexti
+	.else;	.ifc	\cond, sg
+		bel	\nexti
+	.else;	.ifc	\cond, el
+		bsg	\nexti
+	.else;	.ifnc	\cond, al
+		.error  "Unknown cond in notcond macro argument"
+	.endif;	.endif;	.endif;	.endif;	.endif;	.endif;	.endif
+	.endif;	.endif;	.endif;	.endif;	.endif;	.endif;	.endif
+	.endif
+	.endm
+
+	.macro	usracc, instr, reg, ptr, inc, cond, rept, abort
+	.rept	\rept
+	notcond	\cond, .+8
+9999 :
+	.if	\inc == 1
+	\instr\()b.u \reg, [\ptr], #\inc
+	.elseif	\inc == 4
+	\instr\()w.u \reg, [\ptr], #\inc
+	.else
+	.error	"Unsupported inc macro argument"
+	.endif
+
+	.pushsection __ex_table, "a"
+	.align	3
+	.long	9999b, \abort
+	.popsection
+	.endr
+	.endm
+
+	.macro	strusr, reg, ptr, inc, cond = al, rept = 1, abort = 9001f
+	usracc	st, \reg, \ptr, \inc, \cond, \rept, \abort
+	.endm
+
+	.macro	ldrusr, reg, ptr, inc, cond = al, rept = 1, abort = 9001f
+	usracc	ld, \reg, \ptr, \inc, \cond, \rept, \abort
+	.endm
+
+	.macro	nop8
+	.rept	8
+		nop
+	.endr
+	.endm

+ 47 - 0
arch/unicore32/include/asm/bitops.h

@@ -0,0 +1,47 @@
+/*
+ * linux/arch/unicore32/include/asm/bitops.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+#ifndef __UNICORE_BITOPS_H__
+#define __UNICORE_BITOPS_H__
+
+#define find_next_bit		__uc32_find_next_bit
+#define find_next_zero_bit	__uc32_find_next_zero_bit
+
+#define find_first_bit		__uc32_find_first_bit
+#define find_first_zero_bit	__uc32_find_first_zero_bit
+
+#define _ASM_GENERIC_BITOPS_FLS_H_
+#define _ASM_GENERIC_BITOPS___FLS_H_
+#define _ASM_GENERIC_BITOPS_FFS_H_
+#define _ASM_GENERIC_BITOPS___FFS_H_
+/*
+ * On UNICORE, those functions can be implemented around
+ * the cntlz instruction for much better code efficiency.
+ */
+
+static inline int fls(int x)
+{
+	int ret;
+
+	asm("cntlz\t%0, %1" : "=r" (ret) : "r" (x) : "cc");
+	ret = 32 - ret;
+
+	return ret;
+}
+
+#define __fls(x) (fls(x) - 1)
+#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
+#define __ffs(x) (ffs(x) - 1)
+
+#include <asm-generic/bitops.h>
+
+#endif /* __UNICORE_BITOPS_H__ */

+ 24 - 0
arch/unicore32/include/asm/byteorder.h

@@ -0,0 +1,24 @@
+/*
+ * linux/arch/unicore32/include/asm/byteorder.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ *
+ * UniCore ONLY support Little Endian mode, the data bus is connected such
+ * that byte accesses appear as:
+ *  0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31
+ * and word accesses (data or instruction) appear as:
+ *  d0...d31
+ */
+#ifndef __UNICORE_BYTEORDER_H__
+#define __UNICORE_BYTEORDER_H__
+
+#include <linux/byteorder/little_endian.h>
+
+#endif
+

+ 27 - 0
arch/unicore32/include/asm/cache.h

@@ -0,0 +1,27 @@
+/*
+ * linux/arch/unicore32/include/asm/cache.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_CACHE_H__
+#define __UNICORE_CACHE_H__
+
+#define L1_CACHE_SHIFT		(5)
+#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
+
+/*
+ * Memory returned by kmalloc() may be used for DMA, so we must make
+ * sure that all such allocations are cache aligned. Otherwise,
+ * unrelated code may cause parts of the buffer to be read into the
+ * cache before the transfer is done, causing old data to be seen by
+ * the CPU.
+ */
+#define ARCH_DMA_MINALIGN	L1_CACHE_BYTES
+
+#endif

+ 211 - 0
arch/unicore32/include/asm/cacheflush.h

@@ -0,0 +1,211 @@
+/*
+ * linux/arch/unicore32/include/asm/cacheflush.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_CACHEFLUSH_H__
+#define __UNICORE_CACHEFLUSH_H__
+
+#include <linux/mm.h>
+
+#include <asm/shmparam.h>
+
+#define CACHE_COLOUR(vaddr)	((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
+
+/*
+ * This flag is used to indicate that the page pointed to by a pte is clean
+ * and does not require cleaning before returning it to the user.
+ */
+#define PG_dcache_clean PG_arch_1
+
+/*
+ *	MM Cache Management
+ *	===================
+ *
+ *	The arch/unicore32/mm/cache.S files implement these methods.
+ *
+ *	Start addresses are inclusive and end addresses are exclusive;
+ *	start addresses should be rounded down, end addresses up.
+ *
+ *	See Documentation/cachetlb.txt for more information.
+ *	Please note that the implementation of these, and the required
+ *	effects are cache-type (VIVT/VIPT/PIPT) specific.
+ *
+ *	flush_icache_all()
+ *
+ *		Unconditionally clean and invalidate the entire icache.
+ *		Currently only needed for cache-v6.S and cache-v7.S, see
+ *		__flush_icache_all for the generic implementation.
+ *
+ *	flush_kern_all()
+ *
+ *		Unconditionally clean and invalidate the entire cache.
+ *
+ *	flush_user_all()
+ *
+ *		Clean and invalidate all user space cache entries
+ *		before a change of page tables.
+ *
+ *	flush_user_range(start, end, flags)
+ *
+ *		Clean and invalidate a range of cache entries in the
+ *		specified address space before a change of page tables.
+ *		- start - user start address (inclusive, page aligned)
+ *		- end   - user end address   (exclusive, page aligned)
+ *		- flags - vma->vm_flags field
+ *
+ *	coherent_kern_range(start, end)
+ *
+ *		Ensure coherency between the Icache and the Dcache in the
+ *		region described by start, end.  If you have non-snooping
+ *		Harvard caches, you need to implement this function.
+ *		- start  - virtual start address
+ *		- end    - virtual end address
+ *
+ *	coherent_user_range(start, end)
+ *
+ *		Ensure coherency between the Icache and the Dcache in the
+ *		region described by start, end.  If you have non-snooping
+ *		Harvard caches, you need to implement this function.
+ *		- start  - virtual start address
+ *		- end    - virtual end address
+ *
+ *	flush_kern_dcache_area(kaddr, size)
+ *
+ *		Ensure that the data held in page is written back.
+ *		- kaddr  - page address
+ *		- size   - region size
+ *
+ *	DMA Cache Coherency
+ *	===================
+ *
+ *	dma_flush_range(start, end)
+ *
+ *		Clean and invalidate the specified virtual address range.
+ *		- start  - virtual start address
+ *		- end    - virtual end address
+ */
+
+extern void __cpuc_flush_icache_all(void);
+extern void __cpuc_flush_kern_all(void);
+extern void __cpuc_flush_user_all(void);
+extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
+extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
+extern void __cpuc_coherent_user_range(unsigned long, unsigned long);
+extern void __cpuc_flush_dcache_area(void *, size_t);
+extern void __cpuc_flush_kern_dcache_area(void *addr, size_t size);
+
+/*
+ * These are private to the dma-mapping API.  Do not use directly.
+ * Their sole purpose is to ensure that data held in the cache
+ * is visible to DMA, or data written by DMA to system memory is
+ * visible to the CPU.
+ */
+extern void __cpuc_dma_clean_range(unsigned long, unsigned long);
+extern void __cpuc_dma_flush_range(unsigned long, unsigned long);
+
+/*
+ * Copy user data from/to a page which is mapped into a different
+ * processes address space.  Really, we want to allow our "user
+ * space" model to handle this.
+ */
+extern void copy_to_user_page(struct vm_area_struct *, struct page *,
+	unsigned long, void *, const void *, unsigned long);
+#define copy_from_user_page(vma, page, vaddr, dst, src, len)	\
+	do {							\
+		memcpy(dst, src, len);				\
+	} while (0)
+
+/*
+ * Convert calls to our calling convention.
+ */
+/* Invalidate I-cache */
+static inline void __flush_icache_all(void)
+{
+	asm("movc	p0.c5, %0, #20;\n"
+	    "nop; nop; nop; nop; nop; nop; nop; nop\n"
+	    :
+	    : "r" (0));
+}
+
+#define flush_cache_all()		__cpuc_flush_kern_all()
+
+extern void flush_cache_mm(struct mm_struct *mm);
+extern void flush_cache_range(struct vm_area_struct *vma,
+		unsigned long start, unsigned long end);
+extern void flush_cache_page(struct vm_area_struct *vma,
+		unsigned long user_addr, unsigned long pfn);
+
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
+
+/*
+ * flush_cache_user_range is used when we want to ensure that the
+ * Harvard caches are synchronised for the user space address range.
+ * This is used for the UniCore private sys_cacheflush system call.
+ */
+#define flush_cache_user_range(vma, start, end) \
+	__cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end))
+
+/*
+ * Perform necessary cache operations to ensure that data previously
+ * stored within this range of addresses can be executed by the CPU.
+ */
+#define flush_icache_range(s, e)	__cpuc_coherent_kern_range(s, e)
+
+/*
+ * Perform necessary cache operations to ensure that the TLB will
+ * see data written in the specified area.
+ */
+#define clean_dcache_area(start, size)	cpu_dcache_clean_area(start, size)
+
+/*
+ * flush_dcache_page is used when the kernel has written to the page
+ * cache page at virtual address page->virtual.
+ *
+ * If this page isn't mapped (ie, page_mapping == NULL), or it might
+ * have userspace mappings, then we _must_ always clean + invalidate
+ * the dcache entries associated with the kernel mapping.
+ *
+ * Otherwise we can defer the operation, and clean the cache when we are
+ * about to change to user space.  This is the same method as used on SPARC64.
+ * See update_mmu_cache for the user space part.
+ */
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
+extern void flush_dcache_page(struct page *);
+
+#define flush_dcache_mmap_lock(mapping)			\
+	spin_lock_irq(&(mapping)->tree_lock)
+#define flush_dcache_mmap_unlock(mapping)		\
+	spin_unlock_irq(&(mapping)->tree_lock)
+
+#define flush_icache_user_range(vma, page, addr, len)	\
+	flush_dcache_page(page)
+
+/*
+ * We don't appear to need to do anything here.  In fact, if we did, we'd
+ * duplicate cache flushing elsewhere performed by flush_dcache_page().
+ */
+#define flush_icache_page(vma, page)	do { } while (0)
+
+/*
+ * flush_cache_vmap() is used when creating mappings (eg, via vmap,
+ * vmalloc, ioremap etc) in kernel space for pages.  On non-VIPT
+ * caches, since the direct-mappings of these pages may contain cached
+ * data, we need to do a full cache flush to ensure that writebacks
+ * don't corrupt data placed into these pages via the new mappings.
+ */
+static inline void flush_cache_vmap(unsigned long start, unsigned long end)
+{
+}
+
+static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
+{
+}
+
+#endif

+ 41 - 0
arch/unicore32/include/asm/checksum.h

@@ -0,0 +1,41 @@
+/*
+ * linux/arch/unicore32/include/asm/checksum.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ *
+ * IP checksum routines
+ */
+#ifndef __UNICORE_CHECKSUM_H__
+#define __UNICORE_CHECKSUM_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.a	%0, %1, %2\n"
+	"addc.a	%0, %0, %3\n"
+	"addc.a	%0, %0, %4 << #8\n"
+	"addc.a	%0, %0, %5\n"
+	"addc	%0, %0, #0\n"
+	: "=&r"(sum)
+	: "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto))
+	: "cc");
+	return sum;
+}
+#define csum_tcpudp_nofold	csum_tcpudp_nofold
+
+#include <asm-generic/checksum.h>
+
+#endif

+ 45 - 0
arch/unicore32/include/asm/cpu-single.h

@@ -0,0 +1,45 @@
+/*
+ * linux/arch/unicore32/include/asm/cpu-single.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_CPU_SINGLE_H__
+#define __UNICORE_CPU_SINGLE_H__
+
+#include <asm/page.h>
+#include <asm/memory.h>
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#define cpu_switch_mm(pgd, mm) cpu_do_switch_mm(virt_to_phys(pgd), mm)
+
+#define cpu_get_pgd()					\
+	({						\
+		unsigned long pg;			\
+		__asm__("movc	%0, p0.c2, #0"		\
+			 : "=r" (pg) : : "cc");		\
+		pg &= ~0x0fff;				\
+		(pgd_t *)phys_to_virt(pg);		\
+	})
+
+struct mm_struct;
+
+/* declare all the functions as extern */
+extern void cpu_proc_fin(void);
+extern int cpu_do_idle(void);
+extern void cpu_dcache_clean_area(void *, int);
+extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
+extern void cpu_set_pte(pte_t *ptep, pte_t pte);
+extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
+
+#endif /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+
+#endif /* __UNICORE_CPU_SINGLE_H__ */

+ 33 - 0
arch/unicore32/include/asm/cputype.h

@@ -0,0 +1,33 @@
+/*
+ * linux/arch/unicore32/include/asm/cputype.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_CPUTYPE_H__
+#define __UNICORE_CPUTYPE_H__
+
+#include <linux/stringify.h>
+
+#define CPUID_CPUID	0
+#define CPUID_CACHETYPE	1
+
+#define read_cpuid(reg)							\
+	({								\
+		unsigned int __val;					\
+		asm("movc	%0, p0.c0, #" __stringify(reg)		\
+		    : "=r" (__val)					\
+		    :							\
+		    : "cc");						\
+		__val;							\
+	})
+
+#define uc32_cpuid		read_cpuid(CPUID_CPUID)
+#define uc32_cachetype		read_cpuid(CPUID_CACHETYPE)
+
+#endif

+ 52 - 0
arch/unicore32/include/asm/delay.h

@@ -0,0 +1,52 @@
+/*
+ * linux/arch/unicore32/include/asm/delay.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ *
+ * Delay routines, using a pre-computed "loops_per_second" value.
+ */
+#ifndef __UNICORE_DELAY_H__
+#define __UNICORE_DELAY_H__
+
+#include <asm/param.h>	/* HZ */
+
+extern void __delay(int loops);
+
+/*
+ * This function intentionally does not exist; if you see references to
+ * it, it means that you're calling udelay() with an out of range value.
+ *
+ * With currently imposed limits, this means that we support a max delay
+ * of 2000us. Further limits: HZ<=1000 and bogomips<=3355
+ */
+extern void __bad_udelay(void);
+
+/*
+ * division by multiplication: you don't have to worry about
+ * loss of precision.
+ *
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)
+ */
+extern void __udelay(unsigned long usecs);
+extern void __const_udelay(unsigned long);
+
+#define MAX_UDELAY_MS 2
+
+#define udelay(n)							\
+	(__builtin_constant_p(n) ?					\
+	  ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() :		\
+			__const_udelay((n) * ((2199023U*HZ)>>11))) :	\
+	  __udelay(n))
+
+#endif /* __UNICORE_DELAY_H__ */
+

+ 124 - 0
arch/unicore32/include/asm/dma-mapping.h

@@ -0,0 +1,124 @@
+/*
+ * linux/arch/unicore32/include/asm/dma-mapping.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_DMA_MAPPING_H__
+#define __UNICORE_DMA_MAPPING_H__
+
+#ifdef __KERNEL__
+
+#include <linux/mm_types.h>
+#include <linux/scatterlist.h>
+#include <linux/swiotlb.h>
+
+#include <asm-generic/dma-coherent.h>
+
+#include <asm/memory.h>
+#include <asm/cacheflush.h>
+
+extern struct dma_map_ops swiotlb_dma_map_ops;
+
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+	return &swiotlb_dma_map_ops;
+}
+
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+	struct dma_map_ops *dma_ops = get_dma_ops(dev);
+
+	if (unlikely(dma_ops == NULL))
+		return 0;
+
+	return dma_ops->dma_supported(dev, mask);
+}
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	struct dma_map_ops *dma_ops = get_dma_ops(dev);
+
+	if (dma_ops->mapping_error)
+		return dma_ops->mapping_error(dev, dma_addr);
+
+	return 0;
+}
+
+#include <asm-generic/dma-mapping-common.h>
+
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+	if (dev && dev->dma_mask)
+		return addr + size - 1 <= *dev->dma_mask;
+
+	return 1;
+}
+
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+	return paddr;
+}
+
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+	return daddr;
+}
+
+static inline void dma_mark_clean(void *addr, size_t size) {}
+
+static inline int dma_set_mask(struct device *dev, u64 dma_mask)
+{
+	if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+		return -EIO;
+
+	*dev->dma_mask = dma_mask;
+
+	return 0;
+}
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+				       dma_addr_t *dma_handle, gfp_t flag)
+{
+	struct dma_map_ops *dma_ops = get_dma_ops(dev);
+
+	return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+				     void *cpu_addr, dma_addr_t dma_handle)
+{
+	struct dma_map_ops *dma_ops = get_dma_ops(dev);
+
+	dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
+}
+
+#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)
+
+static inline void dma_cache_sync(struct device *dev, void *vaddr,
+		size_t size, enum dma_data_direction direction)
+{
+	unsigned long start = (unsigned long)vaddr;
+	unsigned long end   = start + size;
+
+	switch (direction) {
+	case DMA_NONE:
+		BUG();
+	case DMA_FROM_DEVICE:
+	case DMA_BIDIRECTIONAL:	/* writeback and invalidate */
+		__cpuc_dma_flush_range(start, end);
+		break;
+	case DMA_TO_DEVICE:		/* writeback only */
+		__cpuc_dma_clean_range(start, end);
+		break;
+	}
+}
+
+#endif /* __KERNEL__ */
+#endif

+ 23 - 0
arch/unicore32/include/asm/dma.h

@@ -0,0 +1,23 @@
+/*
+ * linux/arch/unicore32/include/asm/dma.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+#ifndef __UNICORE_DMA_H__
+#define __UNICORE_DMA_H__
+
+#include <asm/memory.h>
+#include <asm-generic/dma.h>
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#endif
+
+#endif /* __UNICORE_DMA_H__ */

+ 94 - 0
arch/unicore32/include/asm/elf.h

@@ -0,0 +1,94 @@
+/*
+ * linux/arch/unicore32/include/asm/elf.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+#ifndef __UNICORE_ELF_H__
+#define __UNICORE_ELF_H__
+
+#include <asm/hwcap.h>
+
+/*
+ * ELF register definitions..
+ */
+#include <asm/ptrace.h>
+
+typedef unsigned long elf_greg_t;
+typedef unsigned long elf_freg_t[3];
+
+#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct fp_state elf_fpregset_t;
+
+#define EM_UNICORE		110
+
+#define R_UNICORE_NONE		0
+#define R_UNICORE_PC24		1
+#define R_UNICORE_ABS32		2
+#define R_UNICORE_CALL		28
+#define R_UNICORE_JUMP24	29
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2LSB
+#define ELF_ARCH	EM_UNICORE
+
+/*
+ * This yields a string that ld.so will use to load implementation
+ * specific libraries for optimization.  This is more specific in
+ * intent than poking at uname or /proc/cpuinfo.
+ *
+ */
+#define ELF_PLATFORM_SIZE 8
+#define ELF_PLATFORM	(elf_platform)
+
+extern char elf_platform[];
+
+struct elf32_hdr;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+extern int elf_check_arch(const struct elf32_hdr *);
+#define elf_check_arch elf_check_arch
+
+struct task_struct;
+int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
+#define ELF_CORE_COPY_TASK_REGS dump_task_regs
+
+#define ELF_EXEC_PAGESIZE	4096
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE	(2 * TASK_SIZE / 3)
+
+/* When the program starts, a1 contains a pointer to a function to be
+   registered with atexit, as per the SVR4 ABI.  A value of 0 means we
+   have no such handler.  */
+#define ELF_PLAT_INIT(_r, load_addr)	{(_r)->UCreg_00 = 0; }
+
+extern void elf_set_personality(const struct elf32_hdr *);
+#define SET_PERSONALITY(ex)	elf_set_personality(&(ex))
+
+struct mm_struct;
+extern unsigned long arch_randomize_brk(struct mm_struct *mm);
+#define arch_randomize_brk arch_randomize_brk
+
+extern int vectors_user_mapping(void);
+#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping()
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
+
+#endif

+ 26 - 0
arch/unicore32/include/asm/fpstate.h

@@ -0,0 +1,26 @@
+/*
+ * linux/arch/unicore32/include/asm/fpstate.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+#ifndef __UNICORE_FPSTATE_H__
+#define __UNICORE_FPSTATE_H__
+
+#ifndef __ASSEMBLY__
+
+#define FP_REGS_NUMBER		33
+
+struct fp_state {
+	unsigned int regs[FP_REGS_NUMBER];
+} __attribute__((aligned(8)));
+
+#endif
+
+#endif

+ 53 - 0
arch/unicore32/include/asm/fpu-ucf64.h

@@ -0,0 +1,53 @@
+/*
+ * linux/arch/unicore32/include/asm/fpu-ucf64.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
+ *	Copyright (C) 2001-2010 Guan Xuetao
+ *
+ * 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.
+ */
+#define FPSCR			s31
+
+/* FPSCR bits */
+#define FPSCR_DEFAULT_NAN	(1<<25)
+
+#define FPSCR_CMPINSTR_BIT	(1<<31)
+
+#define FPSCR_CON		(1<<29)
+#define FPSCR_TRAP		(1<<27)
+
+/* RND mode */
+#define FPSCR_ROUND_NEAREST	(0<<0)
+#define FPSCR_ROUND_PLUSINF	(2<<0)
+#define FPSCR_ROUND_MINUSINF	(3<<0)
+#define FPSCR_ROUND_TOZERO	(1<<0)
+#define FPSCR_RMODE_BIT		(0)
+#define FPSCR_RMODE_MASK	(7 << FPSCR_RMODE_BIT)
+
+/* trap enable */
+#define FPSCR_IOE		(1<<16)
+#define FPSCR_OFE		(1<<14)
+#define FPSCR_UFE		(1<<13)
+#define FPSCR_IXE		(1<<12)
+#define FPSCR_HIE		(1<<11)
+#define FPSCR_NDE		(1<<10)	/* non denomal */
+
+/* flags */
+#define FPSCR_IDC		(1<<24)
+#define FPSCR_HIC		(1<<23)
+#define FPSCR_IXC		(1<<22)
+#define FPSCR_OFC		(1<<21)
+#define FPSCR_UFC		(1<<20)
+#define FPSCR_IOC		(1<<19)
+
+/* stick bits */
+#define FPSCR_IOS		(1<<9)
+#define FPSCR_OFS		(1<<7)
+#define FPSCR_UFS		(1<<6)
+#define FPSCR_IXS		(1<<5)
+#define FPSCR_HIS		(1<<4)
+#define FPSCR_NDS		(1<<3)	/*non denomal */

+ 143 - 0
arch/unicore32/include/asm/futex.h

@@ -0,0 +1,143 @@
+/*
+ * linux/arch/unicore32/include/asm/futex.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+#ifndef __UNICORE_FUTEX_H__
+#define __UNICORE_FUTEX_H__
+
+#ifdef __KERNEL__
+
+#include <linux/futex.h>
+#include <linux/preempt.h>
+#include <linux/uaccess.h>
+#include <linux/errno.h>
+
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)	\
+	__asm__ __volatile__(					\
+	"1:	ldw.u	%1, [%2]\n"				\
+	"	" insn "\n"					\
+	"2:	stw.u	%0, [%2]\n"				\
+	"	mov	%0, #0\n"				\
+	"3:\n"							\
+	"	.pushsection __ex_table,\"a\"\n"		\
+	"	.align	3\n"					\
+	"	.long	1b, 4f, 2b, 4f\n"			\
+	"	.popsection\n"					\
+	"	.pushsection .fixup,\"ax\"\n"			\
+	"4:	mov	%0, %4\n"				\
+	"	b	3b\n"					\
+	"	.popsection"					\
+	: "=&r" (ret), "=&r" (oldval)				\
+	: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)		\
+	: "cc", "memory")
+
+static inline int
+futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
+{
+	int op = (encoded_op >> 28) & 7;
+	int cmp = (encoded_op >> 24) & 15;
+	int oparg = (encoded_op << 8) >> 20;
+	int cmparg = (encoded_op << 20) >> 20;
+	int oldval = 0, ret;
+
+	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+		oparg = 1 << oparg;
+
+	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+		return -EFAULT;
+
+	pagefault_disable();	/* implies preempt_disable() */
+
+	switch (op) {
+	case FUTEX_OP_SET:
+		__futex_atomic_op("mov	%0, %3", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_ADD:
+		__futex_atomic_op("add	%0, %1, %3", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_OR:
+		__futex_atomic_op("or	%0, %1, %3", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_ANDN:
+		__futex_atomic_op("and	%0, %1, %3",
+				ret, oldval, uaddr, ~oparg);
+		break;
+	case FUTEX_OP_XOR:
+		__futex_atomic_op("xor	%0, %1, %3", ret, oldval, uaddr, oparg);
+		break;
+	default:
+		ret = -ENOSYS;
+	}
+
+	pagefault_enable();	/* subsumes preempt_enable() */
+
+	if (!ret) {
+		switch (cmp) {
+		case FUTEX_OP_CMP_EQ:
+			ret = (oldval == cmparg);
+			break;
+		case FUTEX_OP_CMP_NE:
+			ret = (oldval != cmparg);
+			break;
+		case FUTEX_OP_CMP_LT:
+			ret = (oldval <  cmparg);
+			break;
+		case FUTEX_OP_CMP_GE:
+			ret = (oldval >= cmparg);
+			break;
+		case FUTEX_OP_CMP_LE:
+			ret = (oldval <= cmparg);
+			break;
+		case FUTEX_OP_CMP_GT:
+			ret = (oldval >  cmparg);
+			break;
+		default:
+			ret = -ENOSYS;
+		}
+	}
+	return ret;
+}
+
+static inline int
+futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
+{
+	int val;
+
+	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+		return -EFAULT;
+
+	pagefault_disable();	/* implies preempt_disable() */
+
+	__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
+	"1:	ldw.u	%0, [%3]\n"
+	"	cmpxor.a	%0, %1\n"
+	"	bne	3f\n"
+	"2:	stw.u	%2, [%3]\n"
+	"3:\n"
+	"	.pushsection __ex_table,\"a\"\n"
+	"	.align	3\n"
+	"	.long	1b, 4f, 2b, 4f\n"
+	"	.popsection\n"
+	"	.pushsection .fixup,\"ax\"\n"
+	"4:	mov	%0, %4\n"
+	"	b	3b\n"
+	"	.popsection"
+	: "=&r" (val)
+	: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
+	: "cc", "memory");
+
+	pagefault_enable();	/* subsumes preempt_enable() */
+
+	return val;
+}
+
+#endif /* __KERNEL__ */
+#endif /* __UNICORE_FUTEX_H__ */

+ 104 - 0
arch/unicore32/include/asm/gpio.h

@@ -0,0 +1,104 @@
+/*
+ * linux/arch/unicore32/include/asm/gpio.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+#ifndef __UNICORE_GPIO_H__
+#define __UNICORE_GPIO_H__
+
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <asm-generic/gpio.h>
+
+#define GPI_OTP_INT             0
+#define GPI_PCI_INTA            1
+#define GPI_PCI_INTB            2
+#define GPI_PCI_INTC            3
+#define GPI_PCI_INTD            4
+#define GPI_BAT_DET             5
+#define GPI_SD_CD               6
+#define GPI_SOFF_REQ            7
+#define GPI_SD_WP               8
+#define GPI_LCD_CASE_OFF        9
+#define GPO_WIFI_EN             10
+#define GPO_HDD_LED             11
+#define GPO_VGA_EN              12
+#define GPO_LCD_EN              13
+#define GPO_LED_DATA            14
+#define GPO_LED_CLK             15
+#define GPO_CAM_PWR_EN          16
+#define GPO_LCD_VCC_EN          17
+#define GPO_SOFT_OFF            18
+#define GPO_BT_EN               19
+#define GPO_FAN_ON              20
+#define GPO_SPKR                21
+#define GPO_SET_V1              23
+#define GPO_SET_V2              24
+#define GPO_CPU_HEALTH          25
+#define GPO_LAN_SEL             26
+
+#ifdef CONFIG_PUV3_NB0916
+#define GPI_BTN_TOUCH		14
+#define GPIO_IN			0x000043ff /* 1 for input */
+#define GPIO_OUT		0x0fffbc00 /* 1 for output */
+#endif	/* CONFIG_PUV3_NB0916 */
+
+#ifdef CONFIG_PUV3_SMW0919
+#define GPIO_IN			0x000003ff /* 1 for input */
+#define GPIO_OUT		0x0ffffc00 /* 1 for output */
+#endif  /* CONFIG_PUV3_SMW0919 */
+
+#ifdef CONFIG_PUV3_DB0913
+#define GPIO_IN			0x000001df /* 1 for input */
+#define GPIO_OUT		0x03fee800 /* 1 for output */
+#endif  /* CONFIG_PUV3_DB0913 */
+
+#define GPIO_DIR                (~((GPIO_IN) | 0xf0000000))
+				/* 0 input, 1 output */
+
+static inline int gpio_get_value(unsigned gpio)
+{
+	if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX))
+		return readl(GPIO_GPLR) & GPIO_GPIO(gpio);
+	else
+		return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+	if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX))
+		if (value)
+			writel(GPIO_GPIO(gpio), GPIO_GPSR);
+		else
+			writel(GPIO_GPIO(gpio), GPIO_GPCR);
+	else
+		__gpio_set_value(gpio, value);
+}
+
+#define gpio_cansleep	__gpio_cansleep
+
+static inline unsigned gpio_to_irq(unsigned gpio)
+{
+	if ((gpio < IRQ_GPIOHIGH) && (FIELD(1, 1, gpio) & readl(GPIO_GPIR)))
+		return IRQ_GPIOLOW0 + gpio;
+	else
+		return IRQ_GPIO0 + gpio;
+}
+
+static inline unsigned irq_to_gpio(unsigned irq)
+{
+	if (irq < IRQ_GPIOHIGH)
+		return irq - IRQ_GPIOLOW0;
+	else
+		return irq - IRQ_GPIO0;
+}
+
+#endif /* __UNICORE_GPIO_H__ */

+ 32 - 0
arch/unicore32/include/asm/hwcap.h

@@ -0,0 +1,32 @@
+/*
+ * linux/arch/unicore32/include/asm/hwcap.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_HWCAP_H__
+#define __UNICORE_HWCAP_H__
+
+/*
+ * HWCAP flags
+ */
+#define HWCAP_MSP		1
+#define HWCAP_UNICORE16		2
+#define HWCAP_CMOV		4
+#define HWCAP_UNICORE_F64       8
+#define HWCAP_TLS		0x80
+
+#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
+/*
+ * This yields a mask that user programs can use to figure out what
+ * instruction set this cpu supports.
+ */
+#define ELF_HWCAP		(HWCAP_CMOV | HWCAP_UNICORE_F64)
+#endif
+
+#endif

+ 55 - 0
arch/unicore32/include/asm/io.h

@@ -0,0 +1,55 @@
+/*
+ * linux/arch/unicore32/include/asm/io.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_IO_H__
+#define __UNICORE_IO_H__
+
+#ifdef __KERNEL__
+
+#include <asm/byteorder.h>
+#include <asm/memory.h>
+#include <asm/system.h>
+
+#define PCI_IOBASE	PKUNITY_PCILIO_BASE
+#include <asm-generic/io.h>
+
+/*
+ * __uc32_ioremap and __uc32_ioremap_cached takes CPU physical address.
+ */
+extern void __iomem *__uc32_ioremap(unsigned long, size_t);
+extern void __iomem *__uc32_ioremap_cached(unsigned long, size_t);
+extern void __uc32_iounmap(volatile void __iomem *addr);
+
+/*
+ * ioremap and friends.
+ *
+ * ioremap takes a PCI memory address, as specified in
+ * Documentation/IO-mapping.txt.
+ *
+ */
+#define ioremap(cookie, size)		__uc32_ioremap(cookie, size)
+#define ioremap_cached(cookie, size)	__uc32_ioremap_cached(cookie, size)
+#define iounmap(cookie)			__uc32_iounmap(cookie)
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#undef xlate_dev_mem_ptr
+#define xlate_dev_mem_ptr(p)	__va(p)
+
+#define HAVE_ARCH_PIO_SIZE
+#define PIO_OFFSET		(unsigned int)(PCI_IOBASE)
+#define PIO_MASK		(unsigned int)(IO_SPACE_LIMIT)
+#define PIO_RESERVED		(PIO_OFFSET + PIO_MASK + 1)
+
+#endif	/* __KERNEL__ */
+#endif	/* __UNICORE_IO_H__ */

+ 105 - 0
arch/unicore32/include/asm/irq.h

@@ -0,0 +1,105 @@
+/*
+ * linux/arch/unicore32/include/asm/irq.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_IRQ_H__
+#define __UNICORE_IRQ_H__
+
+#include <asm-generic/irq.h>
+
+#define	IRQ_GPIOLOW0		0x00
+#define	IRQ_GPIOLOW1		0x01
+#define	IRQ_GPIOLOW2		0x02
+#define	IRQ_GPIOLOW3		0x03
+#define	IRQ_GPIOLOW4		0x04
+#define	IRQ_GPIOLOW5		0x05
+#define	IRQ_GPIOLOW6		0x06
+#define	IRQ_GPIOLOW7		0x07
+#define IRQ_GPIOHIGH		0x08
+#define IRQ_USB			0x09
+#define IRQ_SDC			0x0a
+#define IRQ_AC97		0x0b
+#define IRQ_SATA		0x0c
+#define IRQ_MME			0x0d
+#define IRQ_PCI_BRIDGE		0x0e
+#define	IRQ_DDR			0x0f
+#define	IRQ_SPI			0x10
+#define	IRQ_UNIGFX		0x11
+#define	IRQ_I2C			0x11
+#define	IRQ_UART1		0x12
+#define	IRQ_UART0		0x13
+#define IRQ_UMAL		0x14
+#define IRQ_NAND		0x15
+#define IRQ_PS2_KBD		0x16
+#define IRQ_PS2_AUX		0x17
+#define IRQ_DMA			0x18
+#define IRQ_DMAERR		0x19
+#define	IRQ_TIMER0		0x1a
+#define	IRQ_TIMER1		0x1b
+#define	IRQ_TIMER2		0x1c
+#define	IRQ_TIMER3		0x1d
+#define	IRQ_RTC			0x1e
+#define	IRQ_RTCAlarm		0x1f
+
+#define	IRQ_GPIO0		0x20
+#define	IRQ_GPIO1		0x21
+#define	IRQ_GPIO2		0x22
+#define	IRQ_GPIO3		0x23
+#define	IRQ_GPIO4		0x24
+#define	IRQ_GPIO5		0x25
+#define	IRQ_GPIO6		0x26
+#define	IRQ_GPIO7		0x27
+#define IRQ_GPIO8		0x28
+#define IRQ_GPIO9		0x29
+#define IRQ_GPIO10		0x2a
+#define IRQ_GPIO11		0x2b
+#define IRQ_GPIO12		0x2c
+#define IRQ_GPIO13		0x2d
+#define IRQ_GPIO14		0x2e
+#define IRQ_GPIO15		0x2f
+#define IRQ_GPIO16		0x30
+#define IRQ_GPIO17		0x31
+#define IRQ_GPIO18		0x32
+#define IRQ_GPIO19		0x33
+#define IRQ_GPIO20		0x34
+#define IRQ_GPIO21		0x35
+#define IRQ_GPIO22		0x36
+#define IRQ_GPIO23		0x37
+#define IRQ_GPIO24		0x38
+#define IRQ_GPIO25		0x39
+#define IRQ_GPIO26		0x3a
+#define IRQ_GPIO27		0x3b
+
+#ifdef CONFIG_ARCH_FPGA
+#define IRQ_PCIINTA             IRQ_GPIOLOW2
+#define IRQ_PCIINTB             IRQ_GPIOLOW1
+#define IRQ_PCIINTC             IRQ_GPIOLOW0
+#define IRQ_PCIINTD             IRQ_GPIOLOW6
+#endif
+
+#if defined(CONFIG_PUV3_DB0913) || defined(CONFIG_PUV3_NB0916)	\
+	|| defined(CONFIG_PUV3_SMW0919)
+#define IRQ_PCIINTA             IRQ_GPIOLOW1
+#define IRQ_PCIINTB             IRQ_GPIOLOW2
+#define IRQ_PCIINTC             IRQ_GPIOLOW3
+#define IRQ_PCIINTD             IRQ_GPIOLOW4
+#endif
+
+#define IRQ_SD_CD               IRQ_GPIO6 /* falling or rising trigger */
+
+#ifndef __ASSEMBLY__
+struct pt_regs;
+
+extern void asm_do_IRQ(unsigned int, struct pt_regs *);
+
+#endif
+
+#endif
+

+ 53 - 0
arch/unicore32/include/asm/irqflags.h

@@ -0,0 +1,53 @@
+/*
+ * linux/arch/unicore32/include/asm/irqflags.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_IRQFLAGS_H__
+#define __UNICORE_IRQFLAGS_H__
+
+#ifdef __KERNEL__
+
+#include <asm/ptrace.h>
+
+#define ARCH_IRQ_DISABLED	(PRIV_MODE | PSR_I_BIT)
+#define ARCH_IRQ_ENABLED	(PRIV_MODE)
+
+/*
+ * Save the current interrupt enable state.
+ */
+static inline unsigned long arch_local_save_flags(void)
+{
+	unsigned long temp;
+
+	asm volatile("mov %0, asr" : "=r" (temp) : : "memory", "cc");
+
+	return temp & PSR_c;
+}
+
+/*
+ * restore saved IRQ state
+ */
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+	unsigned long temp;
+
+	asm volatile(
+		"mov	%0, asr\n"
+		"mov.a	asr, %1\n"
+		"mov.f	asr, %0"
+		: "=&r" (temp)
+		: "r" (flags)
+		: "memory", "cc");
+}
+
+#include <asm-generic/irqflags.h>
+
+#endif
+#endif

+ 22 - 0
arch/unicore32/include/asm/linkage.h

@@ -0,0 +1,22 @@
+/*
+ * linux/arch/unicore32/include/asm/linkage.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_LINKAGE_H__
+#define __UNICORE_LINKAGE_H__
+
+#define __ALIGN .align 0
+#define __ALIGN_STR ".align 0"
+
+#define ENDPROC(name) \
+	.type name, %function; \
+	END(name)
+
+#endif

+ 46 - 0
arch/unicore32/include/asm/memblock.h

@@ -0,0 +1,46 @@
+/*
+ * linux/arch/unicore32/include/asm/memblock.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+#ifndef __UNICORE_MEMBLOCK_H__
+#define __UNICORE_MEMBLOCK_H__
+
+/*
+ * Memory map description
+ */
+# define NR_BANKS 8
+
+struct membank {
+	unsigned long start;
+	unsigned long size;
+	unsigned int highmem;
+};
+
+struct meminfo {
+	int nr_banks;
+	struct membank bank[NR_BANKS];
+};
+
+extern struct meminfo meminfo;
+
+#define for_each_bank(iter, mi)				\
+	for (iter = 0; iter < (mi)->nr_banks; iter++)
+
+#define bank_pfn_start(bank)	__phys_to_pfn((bank)->start)
+#define bank_pfn_end(bank)	__phys_to_pfn((bank)->start + (bank)->size)
+#define bank_pfn_size(bank)	((bank)->size >> PAGE_SHIFT)
+#define bank_phys_start(bank)	((bank)->start)
+#define bank_phys_end(bank)	((bank)->start + (bank)->size)
+#define bank_phys_size(bank)	((bank)->size)
+
+extern void uc32_memblock_init(struct meminfo *);
+
+#endif

+ 123 - 0
arch/unicore32/include/asm/memory.h

@@ -0,0 +1,123 @@
+/*
+ * linux/arch/unicore32/include/asm/memory.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ *
+ *  Note: this file should not be included by non-asm/.h files
+ */
+#ifndef __UNICORE_MEMORY_H__
+#define __UNICORE_MEMORY_H__
+
+#include <linux/compiler.h>
+#include <linux/const.h>
+#include <asm/sizes.h>
+#include <mach/memory.h>
+
+/*
+ * Allow for constants defined here to be used from assembly code
+ * by prepending the UL suffix only with actual C code compilation.
+ */
+#define UL(x) _AC(x, UL)
+
+/*
+ * PAGE_OFFSET - the virtual address of the start of the kernel image
+ * TASK_SIZE - the maximum size of a user space task.
+ * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
+ */
+#define PAGE_OFFSET		UL(0xC0000000)
+#define TASK_SIZE		(PAGE_OFFSET - UL(0x41000000))
+#define TASK_UNMAPPED_BASE	(PAGE_OFFSET / 3)
+
+/*
+ * The module space lives between the addresses given by TASK_SIZE
+ * and PAGE_OFFSET - it must be within 32MB of the kernel text.
+ */
+#define MODULES_VADDR		(PAGE_OFFSET - 16*1024*1024)
+#if TASK_SIZE > MODULES_VADDR
+#error Top of user space clashes with start of module space
+#endif
+
+#define MODULES_END		(PAGE_OFFSET)
+
+/*
+ * Allow 16MB-aligned ioremap pages
+ */
+#define IOREMAP_MAX_ORDER	24
+
+/*
+ * Physical vs virtual RAM address space conversion.  These are
+ * private definitions which should NOT be used outside memory.h
+ * files.  Use virt_to_phys/phys_to_virt/__pa/__va instead.
+ */
+#ifndef __virt_to_phys
+#define __virt_to_phys(x)	((x) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt(x)	((x) - PHYS_OFFSET + PAGE_OFFSET)
+#endif
+
+/*
+ * Convert a physical address to a Page Frame Number and back
+ */
+#define	__phys_to_pfn(paddr)	((paddr) >> PAGE_SHIFT)
+#define	__pfn_to_phys(pfn)	((pfn) << PAGE_SHIFT)
+
+/*
+ * Convert a page to/from a physical address
+ */
+#define page_to_phys(page)	(__pfn_to_phys(page_to_pfn(page)))
+#define phys_to_page(phys)	(pfn_to_page(__phys_to_pfn(phys)))
+
+#ifndef __ASSEMBLY__
+
+#ifndef arch_adjust_zones
+#define arch_adjust_zones(size, holes) do { } while (0)
+#endif
+
+/*
+ * PFNs are used to describe any physical page; this means
+ * PFN 0 == physical address 0.
+ *
+ * This is the PFN of the first RAM page in the kernel
+ * direct-mapped view.  We assume this is the first page
+ * of RAM in the mem_map as well.
+ */
+#define PHYS_PFN_OFFSET	(PHYS_OFFSET >> PAGE_SHIFT)
+
+/*
+ * Drivers should NOT use these either.
+ */
+#define __pa(x)			__virt_to_phys((unsigned long)(x))
+#define __va(x)			((void *)__phys_to_virt((unsigned long)(x)))
+#define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
+
+/*
+ * Conversion between a struct page and a physical address.
+ *
+ * Note: when converting an unknown physical address to a
+ * struct page, the resulting pointer must be validated
+ * using VALID_PAGE().  It must return an invalid struct page
+ * for any physical address not corresponding to a system
+ * RAM address.
+ *
+ *  page_to_pfn(page)	convert a struct page * to a PFN number
+ *  pfn_to_page(pfn)	convert a _valid_ PFN number to struct page *
+ *
+ *  virt_to_page(k)	convert a _valid_ virtual address to struct page *
+ *  virt_addr_valid(k)	indicates whether a virtual address is valid
+ */
+#define ARCH_PFN_OFFSET		PHYS_PFN_OFFSET
+
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_addr_valid(kaddr)	((unsigned long)(kaddr) >= PAGE_OFFSET && \
+		(unsigned long)(kaddr) < (unsigned long)high_memory)
+
+#endif
+
+#include <asm-generic/memory_model.h>
+
+#endif

+ 17 - 0
arch/unicore32/include/asm/mmu.h

@@ -0,0 +1,17 @@
+/*
+ * linux/arch/unicore32/include/asm/mmu.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_MMU_H__
+#define __UNICORE_MMU_H__
+
+typedef	unsigned long mm_context_t;
+
+#endif

+ 87 - 0
arch/unicore32/include/asm/mmu_context.h

@@ -0,0 +1,87 @@
+/*
+ * linux/arch/unicore32/include/asm/mmu_context.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_MMU_CONTEXT_H__
+#define __UNICORE_MMU_CONTEXT_H__
+
+#include <linux/compiler.h>
+#include <linux/sched.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cpu-single.h>
+
+#define init_new_context(tsk, mm)	0
+
+#define destroy_context(mm)		do { } while (0)
+
+/*
+ * This is called when "tsk" is about to enter lazy TLB mode.
+ *
+ * mm:  describes the currently active mm context
+ * tsk: task which is entering lazy tlb
+ * cpu: cpu number which is entering lazy tlb
+ *
+ * tsk->mm will be NULL
+ */
+static inline void
+enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+/*
+ * This is the actual mm switch as far as the scheduler
+ * is concerned.  No registers are touched.  We avoid
+ * calling the CPU specific function when the mm hasn't
+ * actually changed.
+ */
+static inline void
+switch_mm(struct mm_struct *prev, struct mm_struct *next,
+	  struct task_struct *tsk)
+{
+	unsigned int cpu = smp_processor_id();
+
+	if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next)
+		cpu_switch_mm(next->pgd, next);
+}
+
+#define deactivate_mm(tsk, mm)	do { } while (0)
+#define activate_mm(prev, next)	switch_mm(prev, next, NULL)
+
+/*
+ * We are inserting a "fake" vma for the user-accessible vector page so
+ * gdb and friends can get to it through ptrace and /proc/<pid>/mem.
+ * But we also want to remove it before the generic code gets to see it
+ * during process exit or the unmapping of it would  cause total havoc.
+ * (the macro is used as remove_vma() is static to mm/mmap.c)
+ */
+#define arch_exit_mmap(mm) \
+do { \
+	struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \
+	if (high_vma) { \
+		BUG_ON(high_vma->vm_next);  /* it should be last */ \
+		if (high_vma->vm_prev) \
+			high_vma->vm_prev->vm_next = NULL; \
+		else \
+			mm->mmap = NULL; \
+		rb_erase(&high_vma->vm_rb, &mm->mm_rb); \
+		mm->mmap_cache = NULL; \
+		mm->map_count--; \
+		remove_vma(high_vma); \
+	} \
+} while (0)
+
+static inline void arch_dup_mmap(struct mm_struct *oldmm,
+				 struct mm_struct *mm)
+{
+}
+
+#endif

+ 20 - 0
arch/unicore32/include/asm/mutex.h

@@ -0,0 +1,20 @@
+/*
+ * linux/arch/unicore32/include/asm/mutex.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ *
+ * UniCore optimized mutex locking primitives
+ *
+ * Please look into asm-generic/mutex-xchg.h for a formal definition.
+ */
+#ifndef __UNICORE_MUTEX_H__
+#define __UNICORE_MUTEX_H__
+
+# include <asm-generic/mutex-xchg.h>
+#endif

+ 80 - 0
arch/unicore32/include/asm/page.h

@@ -0,0 +1,80 @@
+/*
+ * linux/arch/unicore32/include/asm/page.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_PAGE_H__
+#define __UNICORE_PAGE_H__
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT		12
+#define PAGE_SIZE		(_AC(1, UL) << PAGE_SHIFT)
+#define PAGE_MASK		(~(PAGE_SIZE-1))
+
+#ifndef __ASSEMBLY__
+
+struct page;
+struct vm_area_struct;
+
+#define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
+extern void copy_page(void *to, const void *from);
+
+#define clear_user_page(page, vaddr, pg)	clear_page(page)
+#define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
+
+#undef STRICT_MM_TYPECHECKS
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)      ((x).pte)
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)   ((x).pgprot)
+
+#define __pte(x)        ((pte_t) { (x) })
+#define __pgd(x)	((pgd_t) { (x) })
+#define __pgprot(x)     ((pgprot_t) { (x) })
+
+#else
+/*
+ * .. while these make it easier on the compiler
+ */
+typedef unsigned long pte_t;
+typedef unsigned long pgd_t;
+typedef unsigned long pgprot_t;
+
+#define pte_val(x)      (x)
+#define pgd_val(x)      (x)
+#define pgprot_val(x)   (x)
+
+#define __pte(x)        (x)
+#define __pgd(x)	(x)
+#define __pgprot(x)     (x)
+
+#endif /* STRICT_MM_TYPECHECKS */
+
+typedef struct page *pgtable_t;
+
+extern int pfn_valid(unsigned long);
+
+#include <asm/memory.h>
+
+#endif /* !__ASSEMBLY__ */
+
+#define VM_DATA_DEFAULT_FLAGS \
+	(VM_READ | VM_WRITE | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#include <asm-generic/getorder.h>
+
+#endif

+ 46 - 0
arch/unicore32/include/asm/pci.h

@@ -0,0 +1,46 @@
+/*
+ * linux/arch/unicore32/include/asm/pci.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_PCI_H__
+#define __UNICORE_PCI_H__
+
+#ifdef __KERNEL__
+#include <asm-generic/pci-dma-compat.h>
+#include <asm-generic/pci.h>
+#include <mach/hardware.h> /* for PCIBIOS_MIN_* */
+
+static inline void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
+static inline void pcibios_penalize_isa_irq(int irq, int active)
+{
+	/* We don't do dynamic PCI IRQ allocation */
+}
+
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
+#define HAVE_PCI_MMAP
+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+	enum pci_mmap_state mmap_state, int write_combine);
+
+#endif /* __KERNEL__ */
+
+#endif

+ 110 - 0
arch/unicore32/include/asm/pgalloc.h

@@ -0,0 +1,110 @@
+/*
+ * linux/arch/unicore32/include/asm/pgalloc.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_PGALLOC_H__
+#define __UNICORE_PGALLOC_H__
+
+#include <asm/pgtable-hwdef.h>
+#include <asm/processor.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+
+#define check_pgt_cache()		do { } while (0)
+
+#define _PAGE_USER_TABLE	(PMD_TYPE_TABLE | PMD_PRESENT)
+#define _PAGE_KERNEL_TABLE	(PMD_TYPE_TABLE | PMD_PRESENT)
+
+extern pgd_t *get_pgd_slow(struct mm_struct *mm);
+extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
+
+#define pgd_alloc(mm)			get_pgd_slow(mm)
+#define pgd_free(mm, pgd)		free_pgd_slow(mm, pgd)
+
+#define PGALLOC_GFP	(GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
+
+/*
+ * Allocate one PTE table.
+ */
+static inline pte_t *
+pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
+{
+	pte_t *pte;
+
+	pte = (pte_t *)__get_free_page(PGALLOC_GFP);
+	if (pte)
+		clean_dcache_area(pte, PTRS_PER_PTE * sizeof(pte_t));
+
+	return pte;
+}
+
+static inline pgtable_t
+pte_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+	struct page *pte;
+
+	pte = alloc_pages(PGALLOC_GFP, 0);
+	if (pte) {
+		if (!PageHighMem(pte)) {
+			void *page = page_address(pte);
+			clean_dcache_area(page, PTRS_PER_PTE * sizeof(pte_t));
+		}
+		pgtable_page_ctor(pte);
+	}
+
+	return pte;
+}
+
+/*
+ * Free one PTE table.
+ */
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+	if (pte)
+		free_page((unsigned long)pte);
+}
+
+static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
+{
+	pgtable_page_dtor(pte);
+	__free_page(pte);
+}
+
+static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
+{
+	set_pmd(pmdp, __pmd(pmdval));
+	flush_pmd_entry(pmdp);
+}
+
+/*
+ * Populate the pmdp entry with a pointer to the pte.  This pmd is part
+ * of the mm address space.
+ */
+static inline void
+pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
+{
+	unsigned long pte_ptr = (unsigned long)ptep;
+
+	/*
+	 * The pmd must be loaded with the physical
+	 * address of the PTE table
+	 */
+	__pmd_populate(pmdp, __pa(pte_ptr) | _PAGE_KERNEL_TABLE);
+}
+
+static inline void
+pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
+{
+	__pmd_populate(pmdp,
+			page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE);
+}
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+#endif

+ 55 - 0
arch/unicore32/include/asm/pgtable-hwdef.h

@@ -0,0 +1,55 @@
+/*
+ * linux/arch/unicore32/include/asm/pgtable-hwdef.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_PGTABLE_HWDEF_H__
+#define __UNICORE_PGTABLE_HWDEF_H__
+
+/*
+ * Hardware page table definitions.
+ *
+ * + Level 1 descriptor (PMD)
+ *   - common
+ */
+#define PMD_TYPE_MASK		(3 << 0)
+#define PMD_TYPE_TABLE		(0 << 0)
+/*#define PMD_TYPE_LARGE	(1 << 0) */
+#define PMD_TYPE_INVALID	(2 << 0)
+#define PMD_TYPE_SECT		(3 << 0)
+
+#define PMD_PRESENT		(1 << 2)
+#define PMD_YOUNG		(1 << 3)
+
+/*#define PMD_SECT_DIRTY	(1 << 4) */
+#define PMD_SECT_CACHEABLE	(1 << 5)
+#define PMD_SECT_EXEC		(1 << 6)
+#define PMD_SECT_WRITE		(1 << 7)
+#define PMD_SECT_READ		(1 << 8)
+
+/*
+ * + Level 2 descriptor (PTE)
+ *   - common
+ */
+#define PTE_TYPE_MASK		(3 << 0)
+#define PTE_TYPE_SMALL		(0 << 0)
+#define PTE_TYPE_MIDDLE		(1 << 0)
+#define PTE_TYPE_LARGE		(2 << 0)
+#define PTE_TYPE_INVALID	(3 << 0)
+
+#define PTE_PRESENT		(1 << 2)
+#define PTE_FILE		(1 << 3)	/* only when !PRESENT */
+#define PTE_YOUNG		(1 << 3)
+#define PTE_DIRTY		(1 << 4)
+#define PTE_CACHEABLE		(1 << 5)
+#define PTE_EXEC		(1 << 6)
+#define PTE_WRITE		(1 << 7)
+#define PTE_READ		(1 << 8)
+
+#endif

+ 317 - 0
arch/unicore32/include/asm/pgtable.h

@@ -0,0 +1,317 @@
+/*
+ * linux/arch/unicore32/include/asm/pgtable.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_PGTABLE_H__
+#define __UNICORE_PGTABLE_H__
+
+#include <asm-generic/pgtable-nopmd.h>
+#include <asm/cpu-single.h>
+
+#include <asm/memory.h>
+#include <asm/pgtable-hwdef.h>
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ *
+ * Note that platforms may override VMALLOC_START, but they must provide
+ * VMALLOC_END.  VMALLOC_END defines the (exclusive) limit of this space,
+ * which may not overlap IO space.
+ */
+#ifndef VMALLOC_START
+#define VMALLOC_OFFSET		SZ_8M
+#define VMALLOC_START		(((unsigned long)high_memory + VMALLOC_OFFSET) \
+					& ~(VMALLOC_OFFSET-1))
+#define VMALLOC_END		(0xff000000UL)
+#endif
+
+#define PTRS_PER_PTE		1024
+#define PTRS_PER_PGD		1024
+
+/*
+ * PGDIR_SHIFT determines what a third-level page table entry can map
+ */
+#define PGDIR_SHIFT		22
+
+#ifndef __ASSEMBLY__
+extern void __pte_error(const char *file, int line, unsigned long val);
+extern void __pgd_error(const char *file, int line, unsigned long val);
+
+#define pte_ERROR(pte)		__pte_error(__FILE__, __LINE__, pte_val(pte))
+#define pgd_ERROR(pgd)		__pgd_error(__FILE__, __LINE__, pgd_val(pgd))
+#endif /* !__ASSEMBLY__ */
+
+#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK		(~(PGDIR_SIZE-1))
+
+/*
+ * This is the lowest virtual address we can permit any user space
+ * mapping to be mapped at.  This is particularly important for
+ * non-high vector CPUs.
+ */
+#define FIRST_USER_ADDRESS	PAGE_SIZE
+
+#define FIRST_USER_PGD_NR	1
+#define USER_PTRS_PER_PGD	((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR)
+
+/*
+ * section address mask and size definitions.
+ */
+#define SECTION_SHIFT		22
+#define SECTION_SIZE		(1UL << SECTION_SHIFT)
+#define SECTION_MASK		(~(SECTION_SIZE-1))
+
+#ifndef __ASSEMBLY__
+
+/*
+ * The pgprot_* and protection_map entries will be fixed up in runtime
+ * to include the cachable bits based on memory policy, as well as any
+ * architecture dependent bits.
+ */
+#define _PTE_DEFAULT		(PTE_PRESENT | PTE_YOUNG | PTE_CACHEABLE)
+
+extern pgprot_t pgprot_user;
+extern pgprot_t pgprot_kernel;
+
+#define PAGE_NONE		pgprot_user
+#define PAGE_SHARED		__pgprot(pgprot_val(pgprot_user | PTE_READ \
+								| PTE_WRITE)
+#define PAGE_SHARED_EXEC	__pgprot(pgprot_val(pgprot_user | PTE_READ \
+								| PTE_WRITE \
+								| PTE_EXEC)
+#define PAGE_COPY		__pgprot(pgprot_val(pgprot_user | PTE_READ)
+#define PAGE_COPY_EXEC		__pgprot(pgprot_val(pgprot_user | PTE_READ \
+								| PTE_EXEC)
+#define PAGE_READONLY		__pgprot(pgprot_val(pgprot_user | PTE_READ)
+#define PAGE_READONLY_EXEC	__pgprot(pgprot_val(pgprot_user | PTE_READ \
+								| PTE_EXEC)
+#define PAGE_KERNEL		pgprot_kernel
+#define PAGE_KERNEL_EXEC	__pgprot(pgprot_val(pgprot_kernel | PTE_EXEC))
+
+#define __PAGE_NONE		__pgprot(_PTE_DEFAULT)
+#define __PAGE_SHARED		__pgprot(_PTE_DEFAULT | PTE_READ \
+							| PTE_WRITE)
+#define __PAGE_SHARED_EXEC	__pgprot(_PTE_DEFAULT | PTE_READ \
+							| PTE_WRITE \
+							| PTE_EXEC)
+#define __PAGE_COPY		__pgprot(_PTE_DEFAULT | PTE_READ)
+#define __PAGE_COPY_EXEC	__pgprot(_PTE_DEFAULT | PTE_READ \
+							| PTE_EXEC)
+#define __PAGE_READONLY		__pgprot(_PTE_DEFAULT | PTE_READ)
+#define __PAGE_READONLY_EXEC	__pgprot(_PTE_DEFAULT | PTE_READ \
+							| PTE_EXEC)
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * The table below defines the page protection levels that we insert into our
+ * Linux page table version.  These get translated into the best that the
+ * architecture can perform.  Note that on UniCore hardware:
+ *  1) We cannot do execute protection
+ *  2) If we could do execute protection, then read is implied
+ *  3) write implies read permissions
+ */
+#define __P000  __PAGE_NONE
+#define __P001  __PAGE_READONLY
+#define __P010  __PAGE_COPY
+#define __P011  __PAGE_COPY
+#define __P100  __PAGE_READONLY_EXEC
+#define __P101  __PAGE_READONLY_EXEC
+#define __P110  __PAGE_COPY_EXEC
+#define __P111  __PAGE_COPY_EXEC
+
+#define __S000  __PAGE_NONE
+#define __S001  __PAGE_READONLY
+#define __S010  __PAGE_SHARED
+#define __S011  __PAGE_SHARED
+#define __S100  __PAGE_READONLY_EXEC
+#define __S101  __PAGE_READONLY_EXEC
+#define __S110  __PAGE_SHARED_EXEC
+#define __S111  __PAGE_SHARED_EXEC
+
+#ifndef __ASSEMBLY__
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern struct page *empty_zero_page;
+#define ZERO_PAGE(vaddr)		(empty_zero_page)
+
+#define pte_pfn(pte)			(pte_val(pte) >> PAGE_SHIFT)
+#define pfn_pte(pfn, prot)		(__pte(((pfn) << PAGE_SHIFT) \
+						| pgprot_val(prot)))
+
+#define pte_none(pte)			(!pte_val(pte))
+#define pte_clear(mm, addr, ptep)	set_pte(ptep, __pte(0))
+#define pte_page(pte)			(pfn_to_page(pte_pfn(pte)))
+#define pte_offset_kernel(dir, addr)	(pmd_page_vaddr(*(dir)) \
+						+ __pte_index(addr))
+
+#define pte_offset_map(dir, addr)	(pmd_page_vaddr(*(dir)) \
+						+ __pte_index(addr))
+#define pte_unmap(pte)			do { } while (0)
+
+#define set_pte(ptep, pte)	cpu_set_pte(ptep, pte)
+
+#define set_pte_at(mm, addr, ptep, pteval)	\
+	do {					\
+		set_pte(ptep, pteval);          \
+	} while (0)
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+#define pte_present(pte)	(pte_val(pte) & PTE_PRESENT)
+#define pte_write(pte)		(pte_val(pte) & PTE_WRITE)
+#define pte_dirty(pte)		(pte_val(pte) & PTE_DIRTY)
+#define pte_young(pte)		(pte_val(pte) & PTE_YOUNG)
+#define pte_exec(pte)		(pte_val(pte) & PTE_EXEC)
+#define pte_special(pte)	(0)
+
+#define PTE_BIT_FUNC(fn, op) \
+static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
+
+PTE_BIT_FUNC(wrprotect, &= ~PTE_WRITE);
+PTE_BIT_FUNC(mkwrite,   |= PTE_WRITE);
+PTE_BIT_FUNC(mkclean,   &= ~PTE_DIRTY);
+PTE_BIT_FUNC(mkdirty,   |= PTE_DIRTY);
+PTE_BIT_FUNC(mkold,     &= ~PTE_YOUNG);
+PTE_BIT_FUNC(mkyoung,   |= PTE_YOUNG);
+
+static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+
+/*
+ * Mark the prot value as uncacheable.
+ */
+#define pgprot_noncached(prot)		\
+	__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
+#define pgprot_writecombine(prot)	\
+	__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
+#define pgprot_dmacoherent(prot)	\
+	__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
+
+#define pmd_none(pmd)		(!pmd_val(pmd))
+#define pmd_present(pmd)	(pmd_val(pmd) & PMD_PRESENT)
+#define pmd_bad(pmd)		(((pmd_val(pmd) &		\
+				(PMD_PRESENT | PMD_TYPE_MASK))	\
+				!= (PMD_PRESENT | PMD_TYPE_TABLE)))
+
+#define set_pmd(pmdpd, pmdval)		\
+	do {				\
+		*(pmdpd) = pmdval;	\
+	} while (0)
+
+#define pmd_clear(pmdp)			\
+	do {				\
+		set_pmd(pmdp, __pmd(0));\
+		clean_pmd_entry(pmdp);	\
+	} while (0)
+
+#define pmd_page_vaddr(pmd) ((pte_t *)__va(pmd_val(pmd) & PAGE_MASK))
+#define pmd_page(pmd)		pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+#define mk_pte(page, prot)	pfn_pte(page_to_pfn(page), prot)
+
+/* to find an entry in a page-table-directory */
+#define pgd_index(addr)		((addr) >> PGDIR_SHIFT)
+
+#define pgd_offset(mm, addr)	((mm)->pgd+pgd_index(addr))
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(addr)	pgd_offset(&init_mm, addr)
+
+/* Find an entry in the third-level page table.. */
+#define __pte_index(addr)	(((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	const unsigned long mask = PTE_EXEC | PTE_WRITE | PTE_READ;
+	pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
+	return pte;
+}
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+/*
+ * Encode and decode a swap entry.  Swap entries are stored in the Linux
+ * page tables as follows:
+ *
+ *   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+ *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ *   <--------------- offset --------------> <--- type --> 0 0 0 0 0
+ *
+ * This gives us up to 127 swap files and 32GB per swap file.  Note that
+ * the offset field is always non-zero.
+ */
+#define __SWP_TYPE_SHIFT	5
+#define __SWP_TYPE_BITS		7
+#define __SWP_TYPE_MASK		((1 << __SWP_TYPE_BITS) - 1)
+#define __SWP_OFFSET_SHIFT	(__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
+
+#define __swp_type(x)		(((x).val >> __SWP_TYPE_SHIFT)		\
+				& __SWP_TYPE_MASK)
+#define __swp_offset(x)		((x).val >> __SWP_OFFSET_SHIFT)
+#define __swp_entry(type, offset) ((swp_entry_t) {			\
+				((type) << __SWP_TYPE_SHIFT) |		\
+				((offset) << __SWP_OFFSET_SHIFT) })
+
+#define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(swp)	((pte_t) { (swp).val })
+
+/*
+ * It is an error for the kernel to have more swap files than we can
+ * encode in the PTEs.  This ensures that we know when MAX_SWAPFILES
+ * is increased beyond what we presently support.
+ */
+#define MAX_SWAPFILES_CHECK()	\
+	BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
+
+/*
+ * Encode and decode a file entry.  File entries are stored in the Linux
+ * page tables as follows:
+ *
+ *   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+ *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ *   <----------------------- offset ----------------------> 1 0 0 0
+ */
+#define pte_file(pte)		(pte_val(pte) & PTE_FILE)
+#define pte_to_pgoff(x)		(pte_val(x) >> 4)
+#define pgoff_to_pte(x)		__pte(((x) << 4) | PTE_FILE)
+
+#define PTE_FILE_MAX_BITS	28
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+/* FIXME: this is not correct */
+#define kern_addr_valid(addr)	(1)
+
+#include <asm-generic/pgtable.h>
+
+/*
+ * remap a physical page `pfn' of size `size' with page protection `prot'
+ * into virtual address `from'
+ */
+#define io_remap_pfn_range(vma, from, pfn, size, prot)	\
+		remap_pfn_range(vma, from, pfn, size, prot)
+
+#define pgtable_cache_init() do { } while (0)
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __UNICORE_PGTABLE_H__ */

+ 92 - 0
arch/unicore32/include/asm/processor.h

@@ -0,0 +1,92 @@
+/*
+ * linux/arch/unicore32/include/asm/processor.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+#ifndef __UNICORE_PROCESSOR_H__
+#define __UNICORE_PROCESSOR_H__
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l; })
+
+#ifdef __KERNEL__
+
+#include <asm/ptrace.h>
+#include <asm/types.h>
+
+#ifdef __KERNEL__
+#define STACK_TOP	TASK_SIZE
+#define STACK_TOP_MAX	TASK_SIZE
+#endif
+
+struct debug_entry {
+	u32			address;
+	u32			insn;
+};
+
+struct debug_info {
+	int			nsaved;
+	struct debug_entry	bp[2];
+};
+
+struct thread_struct {
+							/* fault info	  */
+	unsigned long		address;
+	unsigned long		trap_no;
+	unsigned long		error_code;
+							/* debugging	  */
+	struct debug_info	debug;
+};
+
+#define INIT_THREAD  {	}
+
+#define start_thread(regs, pc, sp)					\
+({									\
+	unsigned long *stack = (unsigned long *)sp;			\
+	set_fs(USER_DS);						\
+	memset(regs->uregs, 0, sizeof(regs->uregs));			\
+	regs->UCreg_asr = USER_MODE;					\
+	regs->UCreg_pc = pc & ~1;	/* pc */                        \
+	regs->UCreg_sp = sp;		/* sp */                        \
+	regs->UCreg_02 = stack[2];	/* r2 (envp) */                 \
+	regs->UCreg_01 = stack[1];	/* r1 (argv) */                 \
+	regs->UCreg_00 = stack[0];	/* r0 (argc) */                 \
+})
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+extern void release_thread(struct task_struct *);
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk)	do { } while (0)
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define cpu_relax()			barrier()
+
+/*
+ * Create a new kernel thread
+ */
+extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+
+#define task_pt_regs(p) \
+	((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
+
+#define KSTK_EIP(tsk)	(task_pt_regs(tsk)->UCreg_pc)
+#define KSTK_ESP(tsk)	(task_pt_regs(tsk)->UCreg_sp)
+
+#endif
+
+#endif /* __UNICORE_PROCESSOR_H__ */

+ 133 - 0
arch/unicore32/include/asm/ptrace.h

@@ -0,0 +1,133 @@
+/*
+ * linux/arch/unicore32/include/asm/ptrace.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_PTRACE_H__
+#define __UNICORE_PTRACE_H__
+
+#define PTRACE_GET_THREAD_AREA	22
+
+/*
+ * PSR bits
+ */
+#define USER_MODE	0x00000010
+#define REAL_MODE	0x00000011
+#define INTR_MODE	0x00000012
+#define PRIV_MODE	0x00000013
+#define ABRT_MODE	0x00000017
+#define EXTN_MODE	0x0000001b
+#define SUSR_MODE	0x0000001f
+#define MODE_MASK	0x0000001f
+#define PSR_R_BIT	0x00000040
+#define PSR_I_BIT	0x00000080
+#define PSR_V_BIT	0x10000000
+#define PSR_C_BIT	0x20000000
+#define PSR_Z_BIT	0x40000000
+#define PSR_S_BIT	0x80000000
+
+/*
+ * Groups of PSR bits
+ */
+#define PSR_f		0xff000000	/* Flags		*/
+#define PSR_c		0x000000ff	/* Control		*/
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This struct defines the way the registers are stored on the
+ * stack during a system call.  Note that sizeof(struct pt_regs)
+ * has to be a multiple of 8.
+ */
+struct pt_regs {
+	unsigned long uregs[34];
+};
+
+#define UCreg_asr		uregs[32]
+#define UCreg_pc		uregs[31]
+#define UCreg_lr		uregs[30]
+#define UCreg_sp		uregs[29]
+#define UCreg_ip		uregs[28]
+#define UCreg_fp		uregs[27]
+#define UCreg_26		uregs[26]
+#define UCreg_25		uregs[25]
+#define UCreg_24		uregs[24]
+#define UCreg_23		uregs[23]
+#define UCreg_22		uregs[22]
+#define UCreg_21		uregs[21]
+#define UCreg_20		uregs[20]
+#define UCreg_19		uregs[19]
+#define UCreg_18		uregs[18]
+#define UCreg_17		uregs[17]
+#define UCreg_16		uregs[16]
+#define UCreg_15		uregs[15]
+#define UCreg_14		uregs[14]
+#define UCreg_13		uregs[13]
+#define UCreg_12		uregs[12]
+#define UCreg_11		uregs[11]
+#define UCreg_10		uregs[10]
+#define UCreg_09		uregs[9]
+#define UCreg_08		uregs[8]
+#define UCreg_07		uregs[7]
+#define UCreg_06		uregs[6]
+#define UCreg_05		uregs[5]
+#define UCreg_04		uregs[4]
+#define UCreg_03		uregs[3]
+#define UCreg_02		uregs[2]
+#define UCreg_01		uregs[1]
+#define UCreg_00		uregs[0]
+#define UCreg_ORIG_00		uregs[33]
+
+#ifdef __KERNEL__
+
+#define user_mode(regs)	\
+	(processor_mode(regs) == USER_MODE)
+
+#define processor_mode(regs) \
+	((regs)->UCreg_asr & MODE_MASK)
+
+#define interrupts_enabled(regs) \
+	(!((regs)->UCreg_asr & PSR_I_BIT))
+
+#define fast_interrupts_enabled(regs) \
+	(!((regs)->UCreg_asr & PSR_R_BIT))
+
+/* Are the current registers suitable for user mode?
+ * (used to maintain security in signal handlers)
+ */
+static inline int valid_user_regs(struct pt_regs *regs)
+{
+	unsigned long mode = regs->UCreg_asr & MODE_MASK;
+
+	/*
+	 * Always clear the R (REAL) bits
+	 */
+	regs->UCreg_asr &= ~(PSR_R_BIT);
+
+	if ((regs->UCreg_asr & PSR_I_BIT) == 0) {
+		if (mode == USER_MODE)
+			return 1;
+	}
+
+	/*
+	 * Force ASR to something logical...
+	 */
+	regs->UCreg_asr &= PSR_f | USER_MODE;
+
+	return 0;
+}
+
+#define instruction_pointer(regs)	((regs)->UCreg_pc)
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
+
+#endif
+

+ 29 - 0
arch/unicore32/include/asm/sigcontext.h

@@ -0,0 +1,29 @@
+/*
+ * linux/arch/unicore32/include/asm/sigcontext.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_SIGCONTEXT_H__
+#define __UNICORE_SIGCONTEXT_H__
+
+#include <asm/ptrace.h>
+/*
+ * Signal context structure - contains all info to do with the state
+ * before the signal handler was invoked.  Note: only add new entries
+ * to the end of the structure.
+ */
+struct sigcontext {
+	unsigned long trap_no;
+	unsigned long error_code;
+	unsigned long oldmask;
+	unsigned long fault_address;
+	struct pt_regs regs;
+};
+
+#endif

+ 31 - 0
arch/unicore32/include/asm/stacktrace.h

@@ -0,0 +1,31 @@
+/*
+ * linux/arch/unicore32/include/asm/stacktrace.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+#ifndef __UNICORE_STACKTRACE_H__
+#define __UNICORE_STACKTRACE_H__
+
+struct stackframe {
+	unsigned long fp;
+	unsigned long sp;
+	unsigned long lr;
+	unsigned long pc;
+};
+
+#ifdef CONFIG_FRAME_POINTER
+extern int unwind_frame(struct stackframe *frame);
+#else
+#define unwind_frame(f) (-EINVAL)
+#endif
+extern void walk_stackframe(struct stackframe *frame,
+			    int (*fn)(struct stackframe *, void *), void *data);
+
+#endif	/* __UNICORE_STACKTRACE_H__ */

+ 38 - 0
arch/unicore32/include/asm/string.h

@@ -0,0 +1,38 @@
+/*
+ * linux/arch/unicore32/include/asm/string.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_STRING_H__
+#define __UNICORE_STRING_H__
+
+/*
+ * We don't do inline string functions, since the
+ * optimised inline asm versions are not small.
+ */
+
+#define __HAVE_ARCH_STRRCHR
+extern char *strrchr(const char *s, int c);
+
+#define __HAVE_ARCH_STRCHR
+extern char *strchr(const char *s, int c);
+
+#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMMOVE
+extern void *memmove(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMCHR
+extern void *memchr(const void *, int, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *, int, __kernel_size_t);
+
+#endif

+ 30 - 0
arch/unicore32/include/asm/suspend.h

@@ -0,0 +1,30 @@
+/*
+ * linux/arch/unicore32/include/asm/suspend.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+#ifndef __UNICORE_SUSPEND_H__
+#define __UNICORE_SUSPEND_H__
+
+#ifndef __ASSEMBLY__
+static inline int arch_prepare_suspend(void) { return 0; }
+
+#include <asm/ptrace.h>
+
+struct swsusp_arch_regs {
+	struct cpu_context_save	cpu_context;	/* cpu context */
+#ifdef CONFIG_UNICORE_FPU_F64
+	struct fp_state		fpstate __attribute__((aligned(8)));
+#endif
+};
+#endif
+
+#endif /* __UNICORE_SUSPEND_H__ */
+

+ 161 - 0
arch/unicore32/include/asm/system.h

@@ -0,0 +1,161 @@
+/*
+ * linux/arch/unicore32/include/asm/system.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_SYSTEM_H__
+#define __UNICORE_SYSTEM_H__
+
+#ifdef __KERNEL__
+
+/*
+ * CR1 bits (CP#0 CR1)
+ */
+#define CR_M	(1 << 0)	/* MMU enable				*/
+#define CR_A	(1 << 1)	/* Alignment abort enable		*/
+#define CR_D	(1 << 2)	/* Dcache enable			*/
+#define CR_I	(1 << 3)	/* Icache enable			*/
+#define CR_B	(1 << 4)	/* Dcache write mechanism: write back	*/
+#define CR_T	(1 << 5)	/* Burst enable				*/
+#define CR_V	(1 << 13)	/* Vectors relocated to 0xffff0000	*/
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <linux/irqflags.h>
+
+struct thread_info;
+struct task_struct;
+
+struct pt_regs;
+
+void die(const char *msg, struct pt_regs *regs, int err);
+
+struct siginfo;
+void uc32_notify_die(const char *str, struct pt_regs *regs,
+		struct siginfo *info, unsigned long err, unsigned long trap);
+
+void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
+				       struct pt_regs *),
+		     int sig, int code, const char *name);
+
+#define xchg(ptr, x) \
+	((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+
+extern asmlinkage void __backtrace(void);
+extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
+
+struct mm_struct;
+extern void show_pte(struct mm_struct *mm, unsigned long addr);
+extern void __show_regs(struct pt_regs *);
+
+extern int cpu_architecture(void);
+extern void cpu_init(void);
+
+#define vectors_high()	(cr_alignment & CR_V)
+
+#define isb() __asm__ __volatile__ ("" : : : "memory")
+#define dsb() __asm__ __volatile__ ("" : : : "memory")
+#define dmb() __asm__ __volatile__ ("" : : : "memory")
+
+#define mb()		barrier()
+#define rmb()		barrier()
+#define wmb()		barrier()
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
+#define read_barrier_depends()		do { } while (0)
+#define smp_read_barrier_depends()	do { } while (0)
+
+#define set_mb(var, value)	do { var = value; smp_mb(); } while (0)
+#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
+
+extern unsigned long cr_no_alignment;	/* defined in entry-unicore.S */
+extern unsigned long cr_alignment;	/* defined in entry-unicore.S */
+
+static inline unsigned int get_cr(void)
+{
+	unsigned int val;
+	asm("movc %0, p0.c1, #0" : "=r" (val) : : "cc");
+	return val;
+}
+
+static inline void set_cr(unsigned int val)
+{
+	asm volatile("movc p0.c1, %0, #0	@set CR"
+	  : : "r" (val) : "cc");
+	isb();
+}
+
+extern void adjust_cr(unsigned long mask, unsigned long set);
+
+/*
+ * switch_to(prev, next) should switch from task `prev' to `next'
+ * `prev' will never be the same as `next'.  schedule() itself
+ * contains the memory barrier to tell GCC not to cache `current'.
+ */
+extern struct task_struct *__switch_to(struct task_struct *,
+		struct thread_info *, struct thread_info *);
+extern void panic(const char *fmt, ...);
+
+#define switch_to(prev, next, last)					\
+do {									\
+	last = __switch_to(prev,					\
+		task_thread_info(prev), task_thread_info(next));	\
+} while (0)
+
+static inline unsigned long
+__xchg(unsigned long x, volatile void *ptr, int size)
+{
+	unsigned long ret;
+
+	switch (size) {
+	case 1:
+		asm volatile("@	__xchg1\n"
+		"	swapb	%0, %1, [%2]"
+			: "=&r" (ret)
+			: "r" (x), "r" (ptr)
+			: "memory", "cc");
+		break;
+	case 4:
+		asm volatile("@	__xchg4\n"
+		"	swapw	%0, %1, [%2]"
+			: "=&r" (ret)
+			: "r" (x), "r" (ptr)
+			: "memory", "cc");
+		break;
+	default:
+		panic("xchg: bad data size: ptr 0x%p, size %d\n",
+			ptr, size);
+	}
+
+	return ret;
+}
+
+#include <asm-generic/cmpxchg-local.h>
+
+/*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+ * them available.
+ */
+#define cmpxchg_local(ptr, o, n)					\
+		((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr),	\
+		(unsigned long)(o), (unsigned long)(n), sizeof(*(ptr))))
+#define cmpxchg64_local(ptr, o, n)					\
+		__cmpxchg64_local_generic((ptr), (o), (n))
+
+#include <asm-generic/cmpxchg.h>
+
+#endif /* __ASSEMBLY__ */
+
+#define arch_align_stack(x) (x)
+
+#endif /* __KERNEL__ */
+
+#endif

+ 154 - 0
arch/unicore32/include/asm/thread_info.h

@@ -0,0 +1,154 @@
+/*
+ * linux/arch/unicore32/include/asm/thread_info.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_THREAD_INFO_H__
+#define __UNICORE_THREAD_INFO_H__
+
+#ifdef __KERNEL__
+
+#include <linux/compiler.h>
+#include <asm/fpstate.h>
+
+#define THREAD_SIZE_ORDER	1
+#define THREAD_SIZE		8192
+#define THREAD_START_SP		(THREAD_SIZE - 8)
+
+#ifndef __ASSEMBLY__
+
+struct task_struct;
+struct exec_domain;
+
+#include <asm/types.h>
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+struct cpu_context_save {
+	__u32	r4;
+	__u32	r5;
+	__u32	r6;
+	__u32	r7;
+	__u32	r8;
+	__u32	r9;
+	__u32	r10;
+	__u32	r11;
+	__u32	r12;
+	__u32	r13;
+	__u32	r14;
+	__u32	r15;
+	__u32	r16;
+	__u32	r17;
+	__u32	r18;
+	__u32	r19;
+	__u32	r20;
+	__u32	r21;
+	__u32	r22;
+	__u32	r23;
+	__u32	r24;
+	__u32	r25;
+	__u32	r26;
+	__u32	fp;
+	__u32	sp;
+	__u32	pc;
+};
+
+/*
+ * low level task data that entry.S needs immediate access to.
+ * __switch_to() assumes cpu_context follows immediately after cpu_domain.
+ */
+struct thread_info {
+	unsigned long		flags;		/* low level flags */
+	int			preempt_count;	/* 0 => preemptable */
+						/* <0 => bug */
+	mm_segment_t		addr_limit;	/* address limit */
+	struct task_struct	*task;		/* main task structure */
+	struct exec_domain	*exec_domain;	/* execution domain */
+	__u32			cpu;		/* cpu */
+	struct cpu_context_save	cpu_context;	/* cpu context */
+	__u32			syscall;	/* syscall number */
+	__u8			used_cp[16];	/* thread used copro */
+#ifdef CONFIG_UNICORE_FPU_F64
+	struct fp_state		fpstate __attribute__((aligned(8)));
+#endif
+	struct restart_block	restart_block;
+};
+
+#define INIT_THREAD_INFO(tsk)						\
+{									\
+	.task		= &tsk,						\
+	.exec_domain	= &default_exec_domain,				\
+	.flags		= 0,						\
+	.preempt_count	= INIT_PREEMPT_COUNT,				\
+	.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) __attribute_const__;
+
+static inline struct thread_info *current_thread_info(void)
+{
+	register unsigned long sp asm ("sp");
+	return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));
+}
+
+#define thread_saved_pc(tsk)	\
+	((unsigned long)(task_thread_info(tsk)->cpu_context.pc))
+#define thread_saved_sp(tsk)	\
+	((unsigned long)(task_thread_info(tsk)->cpu_context.sp))
+#define thread_saved_fp(tsk)	\
+	((unsigned long)(task_thread_info(tsk)->cpu_context.fp))
+
+#endif
+
+/*
+ * We use bit 30 of the preempt_count to indicate that kernel
+ * preemption is occurring.  See <asm/hardirq.h>.
+ */
+#define PREEMPT_ACTIVE	0x40000000
+
+/*
+ * thread information flags:
+ *  TIF_SYSCALL_TRACE	- syscall trace active
+ *  TIF_SIGPENDING	- signal pending
+ *  TIF_NEED_RESCHED	- rescheduling necessary
+ *  TIF_NOTIFY_RESUME	- callback before returning to user
+ */
+#define TIF_SIGPENDING		0
+#define TIF_NEED_RESCHED	1
+#define TIF_NOTIFY_RESUME	2	/* callback before returning to user */
+#define TIF_SYSCALL_TRACE	8
+#define TIF_MEMDIE		18
+#define TIF_FREEZE		19
+#define TIF_RESTORE_SIGMASK	20
+
+#define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
+#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
+#define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
+#define _TIF_FREEZE		(1 << TIF_FREEZE)
+#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
+
+/*
+ * Change these and you break ASM code in entry-common.S
+ */
+#define _TIF_WORK_MASK		0x000000ff
+
+#endif /* __KERNEL__ */
+#endif /* __UNICORE_THREAD_INFO_H__ */

+ 34 - 0
arch/unicore32/include/asm/timex.h

@@ -0,0 +1,34 @@
+/*
+ * linux/arch/unicore32/include/asm/timex.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+#ifndef __UNICORE_TIMEX_H__
+#define __UNICORE_TIMEX_H__
+
+#ifdef	CONFIG_ARCH_FPGA
+
+/* in FPGA, APB clock is 33M, and OST clock is 32K, */
+/* so, 1M is selected for timer interrupt correctly */
+#define	CLOCK_TICK_RATE		(32*1024)
+
+#endif
+
+#if defined(CONFIG_PUV3_DB0913)		\
+	|| defined(CONFIG_PUV3_NB0916)	\
+	|| defined(CONFIG_PUV3_SMW0919)
+
+#define  CLOCK_TICK_RATE         (14318000)
+
+#endif
+
+#include <asm-generic/timex.h>
+
+#endif

+ 28 - 0
arch/unicore32/include/asm/tlb.h

@@ -0,0 +1,28 @@
+/*
+ * linux/arch/unicore32/include/asm/tlb.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_TLB_H__
+#define __UNICORE_TLB_H__
+
+#define tlb_start_vma(tlb, vma)				do { } while (0)
+#define tlb_end_vma(tlb, vma)				do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, ptep, address)	do { } while (0)
+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+
+#define __pte_free_tlb(tlb, pte, addr)				\
+	do {							\
+		pgtable_page_dtor(pte);				\
+		tlb_remove_page((tlb), (pte));			\
+	} while (0)
+
+#include <asm-generic/tlb.h>
+
+#endif

+ 195 - 0
arch/unicore32/include/asm/tlbflush.h

@@ -0,0 +1,195 @@
+/*
+ * linux/arch/unicore32/include/asm/tlbflush.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_TLBFLUSH_H__
+#define __UNICORE_TLBFLUSH_H__
+
+#ifndef __ASSEMBLY__
+
+#include <linux/sched.h>
+
+extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long,
+					struct vm_area_struct *);
+extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long);
+
+/*
+ *	TLB Management
+ *	==============
+ *
+ *	The arch/unicore/mm/tlb-*.S files implement these methods.
+ *
+ *	The TLB specific code is expected to perform whatever tests it
+ *	needs to determine if it should invalidate the TLB for each
+ *	call.  Start addresses are inclusive and end addresses are
+ *	exclusive; it is safe to round these addresses down.
+ *
+ *	flush_tlb_all()
+ *
+ *		Invalidate the entire TLB.
+ *
+ *	flush_tlb_mm(mm)
+ *
+ *		Invalidate all TLB entries in a particular address
+ *		space.
+ *		- mm	- mm_struct describing address space
+ *
+ *	flush_tlb_range(mm,start,end)
+ *
+ *		Invalidate a range of TLB entries in the specified
+ *		address space.
+ *		- mm	- mm_struct describing address space
+ *		- start - start address (may not be aligned)
+ *		- end	- end address (exclusive, may not be aligned)
+ *
+ *	flush_tlb_page(vaddr,vma)
+ *
+ *		Invalidate the specified page in the specified address range.
+ *		- vaddr - virtual address (may not be aligned)
+ *		- vma	- vma_struct describing address range
+ *
+ *	flush_kern_tlb_page(kaddr)
+ *
+ *		Invalidate the TLB entry for the specified page.  The address
+ *		will be in the kernels virtual memory space.  Current uses
+ *		only require the D-TLB to be invalidated.
+ *		- kaddr - Kernel virtual memory address
+ */
+
+static inline void local_flush_tlb_all(void)
+{
+	const int zero = 0;
+
+	/* TLB invalidate all */
+	asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop"
+		: : "r" (zero) : "cc");
+}
+
+static inline void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	const int zero = 0;
+
+	if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) {
+		/* TLB invalidate all */
+		asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop"
+			: : "r" (zero) : "cc");
+	}
+	put_cpu();
+}
+
+static inline void
+local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+{
+	if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
+#ifndef CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE
+		/* iTLB invalidate page */
+		asm("movc p0.c6, %0, #5; nop; nop; nop; nop; nop; nop; nop; nop"
+			: : "r" (uaddr & PAGE_MASK) : "cc");
+		/* dTLB invalidate page */
+		asm("movc p0.c6, %0, #3; nop; nop; nop; nop; nop; nop; nop; nop"
+			: : "r" (uaddr & PAGE_MASK) : "cc");
+#else
+		/* TLB invalidate all */
+		asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop"
+			: : "r" (uaddr & PAGE_MASK) : "cc");
+#endif
+	}
+}
+
+static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
+{
+#ifndef CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE
+	/* iTLB invalidate page */
+	asm("movc p0.c6, %0, #5; nop; nop; nop; nop; nop; nop; nop; nop"
+		: : "r" (kaddr & PAGE_MASK) : "cc");
+	/* dTLB invalidate page */
+	asm("movc p0.c6, %0, #3; nop; nop; nop; nop; nop; nop; nop; nop"
+		: : "r" (kaddr & PAGE_MASK) : "cc");
+#else
+	/* TLB invalidate all */
+	asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop"
+		: : "r" (kaddr & PAGE_MASK) : "cc");
+#endif
+}
+
+/*
+ *	flush_pmd_entry
+ *
+ *	Flush a PMD entry (word aligned, or double-word aligned) to
+ *	RAM if the TLB for the CPU we are running on requires this.
+ *	This is typically used when we are creating PMD entries.
+ *
+ *	clean_pmd_entry
+ *
+ *	Clean (but don't drain the write buffer) if the CPU requires
+ *	these operations.  This is typically used when we are removing
+ *	PMD entries.
+ */
+static inline void flush_pmd_entry(pmd_t *pmd)
+{
+#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
+	/* flush dcache line, see dcacheline_flush in proc-macros.S */
+	asm("mov	r1, %0 << #20\n"
+		"ldw	r2, =_stext\n"
+		"add	r2, r2, r1 >> #20\n"
+		"ldw	r1, [r2+], #0x0000\n"
+		"ldw	r1, [r2+], #0x1000\n"
+		"ldw	r1, [r2+], #0x2000\n"
+		"ldw	r1, [r2+], #0x3000\n"
+		: : "r" (pmd) : "r1", "r2");
+#else
+	/* flush dcache all */
+	asm("movc p0.c5, %0, #14; nop; nop; nop; nop; nop; nop; nop; nop"
+		: : "r" (pmd) : "cc");
+#endif
+}
+
+static inline void clean_pmd_entry(pmd_t *pmd)
+{
+#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
+	/* clean dcache line */
+	asm("movc p0.c5, %0, #11; nop; nop; nop; nop; nop; nop; nop; nop"
+		: : "r" (__pa(pmd) & ~(L1_CACHE_BYTES - 1)) : "cc");
+#else
+	/* clean dcache all */
+	asm("movc p0.c5, %0, #10; nop; nop; nop; nop; nop; nop; nop; nop"
+		: : "r" (pmd) : "cc");
+#endif
+}
+
+/*
+ * Convert calls to our calling convention.
+ */
+#define local_flush_tlb_range(vma, start, end)	\
+	__cpu_flush_user_tlb_range(start, end, vma)
+#define local_flush_tlb_kernel_range(s, e)	\
+	__cpu_flush_kern_tlb_range(s, e)
+
+#define flush_tlb_all		local_flush_tlb_all
+#define flush_tlb_mm		local_flush_tlb_mm
+#define flush_tlb_page		local_flush_tlb_page
+#define flush_tlb_kernel_page	local_flush_tlb_kernel_page
+#define flush_tlb_range		local_flush_tlb_range
+#define flush_tlb_kernel_range	local_flush_tlb_kernel_range
+
+/*
+ * if PG_dcache_clean is not set for the page, we need to ensure that any
+ * cache entries for the kernels virtual memory range are written
+ * back to the page.
+ */
+extern void update_mmu_cache(struct vm_area_struct *vma,
+		unsigned long addr, pte_t *ptep);
+
+extern void do_bad_area(unsigned long addr, unsigned int fsr,
+		struct pt_regs *regs);
+
+#endif
+
+#endif

+ 21 - 0
arch/unicore32/include/asm/traps.h

@@ -0,0 +1,21 @@
+/*
+ * linux/arch/unicore32/include/asm/traps.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_TRAP_H__
+#define __UNICORE_TRAP_H__
+
+extern void __init early_trap_init(void);
+extern void dump_backtrace_entry(unsigned long where,
+		unsigned long from, unsigned long frame);
+
+extern void do_DataAbort(unsigned long addr, unsigned int fsr,
+		 struct pt_regs *regs);
+#endif

+ 47 - 0
arch/unicore32/include/asm/uaccess.h

@@ -0,0 +1,47 @@
+/*
+ * linux/arch/unicore32/include/asm/uaccess.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __UNICORE_UACCESS_H__
+#define __UNICORE_UACCESS_H__
+
+#include <linux/thread_info.h>
+#include <linux/errno.h>
+
+#include <asm/memory.h>
+#include <asm/system.h>
+
+#define __copy_from_user	__copy_from_user
+#define __copy_to_user		__copy_to_user
+#define __strncpy_from_user	__strncpy_from_user
+#define __strnlen_user		__strnlen_user
+#define __clear_user		__clear_user
+
+#define __kernel_ok		(segment_eq(get_fs(), KERNEL_DS))
+#define __user_ok(addr, size)	(((size) <= TASK_SIZE)			\
+				&& ((addr) <= TASK_SIZE - (size)))
+#define __access_ok(addr, size)	(__kernel_ok || __user_ok((addr), (size)))
+
+extern unsigned long __must_check
+__copy_from_user(void *to, const void __user *from, unsigned long n);
+extern unsigned long __must_check
+__copy_to_user(void __user *to, const void *from, unsigned long n);
+extern unsigned long __must_check
+__clear_user(void __user *addr, unsigned long n);
+extern unsigned long __must_check
+__strncpy_from_user(char *to, const char __user *from, unsigned long count);
+extern unsigned long
+__strnlen_user(const char __user *s, long n);
+
+#include <asm-generic/uaccess.h>
+
+extern int fixup_exception(struct pt_regs *regs);
+
+#endif /* __UNICORE_UACCESS_H__ */

+ 18 - 0
arch/unicore32/include/asm/unistd.h

@@ -0,0 +1,18 @@
+/*
+ * linux/arch/unicore32/include/asm/unistd.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#if !defined(__UNICORE_UNISTD_H__) || defined(__SYSCALL)
+#define __UNICORE_UNISTD_H__
+
+/* Use the standard ABI for syscalls. */
+#include <asm-generic/unistd.h>
+
+#endif /* __UNICORE_UNISTD_H__ */

+ 108 - 0
arch/unicore32/include/mach/PKUnity.h

@@ -0,0 +1,108 @@
+/*
+ * linux/arch/unicore32/include/mach/PKUnity.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+/* Be sure that virtual mapping is defined right */
+#ifndef __MACH_PUV3_HARDWARE_H__
+#error You must include hardware.h not PKUnity.h
+#endif
+
+#include "bitfield.h"
+
+/*
+ * Memory Definitions
+ */
+#define PKUNITY_SDRAM_BASE		0x00000000 /* 0x00000000 - 0x7FFFFFFF 2GB */
+#define PKUNITY_MMIO_BASE		0x80000000 /* 0x80000000 - 0xFFFFFFFF 2GB */
+
+/*
+ * PKUNITY Memory Map Addresses: 0x0D000000 - 0x0EFFFFFF (32MB)
+ *	0x0D000000 - 0x0DFFFFFF 16MB: for UVC
+ *	0x0E000000 - 0x0EFFFFFF 16MB: for UNIGFX
+ */
+#define PKUNITY_UVC_MMAP_BASE		0x0D000000
+#define PKUNITY_UVC_MMAP_SIZE		0x01000000 /* 16MB */
+#define PKUNITY_UNIGFX_MMAP_BASE        0x0E000000
+#define PKUNITY_UNIGFX_MMAP_SIZE        0x01000000 /* 16MB */
+
+/*
+ * PKUNITY System Bus Addresses (PCI): 0x80000000 - 0xBFFFFFFF (1GB)
+ * 0x80000000 - 0x8000000B 12B    PCI Configuration regs
+ * 0x80010000 - 0x80010250 592B   PCI Bridge Base
+ * 0x80030000 - 0x8003FFFF 64KB   PCI Legacy IO
+ * 0x90000000 - 0x97FFFFFF 128MB  PCI AHB-PCI MEM-mapping
+ * 0x98000000 - 0x9FFFFFFF 128MB  PCI PCI-AHB MEM-mapping
+ */
+#define PKUNITY_PCI_BASE		io_p2v(0x80000000) /* 0x80000000 - 0xBFFFFFFF 1GB */
+#include "regs-pci.h"
+
+#define PKUNITY_PCICFG_BASE		(PKUNITY_PCI_BASE + 0x0)
+#define PKUNITY_PCIBRI_BASE		(PKUNITY_PCI_BASE + 0x00010000)
+#define PKUNITY_PCILIO_BASE		(PKUNITY_PCI_BASE + 0x00030000)
+#define PKUNITY_PCIMEM_BASE		(PKUNITY_PCI_BASE + 0x10000000)
+#define PKUNITY_PCIAHB_BASE		(PKUNITY_PCI_BASE + 0x18000000)
+
+/*
+ * PKUNITY System Bus Addresses (AHB): 0xC0000000 - 0xEDFFFFFF (640MB)
+ */
+#define PKUNITY_AHB_BASE		io_p2v(0xC0000000)
+
+/* AHB-0 is DDR2 SDRAM */
+/* AHB-1 is PCI Space */
+#define PKUNITY_ARBITER_BASE		(PKUNITY_AHB_BASE + 0x000000) /* AHB-2 */
+#define PKUNITY_DDR2CTRL_BASE		(PKUNITY_AHB_BASE + 0x100000) /* AHB-3 */
+#define PKUNITY_DMAC_BASE		(PKUNITY_AHB_BASE + 0x200000) /* AHB-4 */
+#include "regs-dmac.h"
+#define PKUNITY_UMAL_BASE		(PKUNITY_AHB_BASE + 0x300000) /* AHB-5 */
+#include "regs-umal.h"
+#define PKUNITY_USB_BASE		(PKUNITY_AHB_BASE + 0x400000) /* AHB-6 */
+#define PKUNITY_SATA_BASE		(PKUNITY_AHB_BASE + 0x500000) /* AHB-7 */
+#define PKUNITY_SMC_BASE		(PKUNITY_AHB_BASE + 0x600000) /* AHB-8 */
+/* AHB-9 is for APB bridge */
+#define PKUNITY_MME_BASE		(PKUNITY_AHB_BASE + 0x700000) /* AHB-10 */
+#define PKUNITY_UNIGFX_BASE		(PKUNITY_AHB_BASE + 0x800000) /* AHB-11 */
+#include "regs-unigfx.h"
+#define PKUNITY_NAND_BASE		(PKUNITY_AHB_BASE + 0x900000) /* AHB-12 */
+#include "regs-nand.h"
+#define PKUNITY_H264D_BASE		(PKUNITY_AHB_BASE + 0xA00000) /* AHB-13 */
+#define PKUNITY_H264E_BASE		(PKUNITY_AHB_BASE + 0xB00000) /* AHB-14 */
+
+/*
+ * PKUNITY Peripheral Bus Addresses (APB): 0xEE000000 - 0xEFFFFFFF (128MB)
+ */
+#define PKUNITY_APB_BASE		io_p2v(0xEE000000)
+
+#define PKUNITY_UART0_BASE		(PKUNITY_APB_BASE + 0x000000) /* APB-0 */
+#define PKUNITY_UART1_BASE		(PKUNITY_APB_BASE + 0x100000) /* APB-1 */
+#include "regs-uart.h"
+#define PKUNITY_I2C_BASE		(PKUNITY_APB_BASE + 0x200000) /* APB-2 */
+#include "regs-i2c.h"
+#define PKUNITY_SPI_BASE		(PKUNITY_APB_BASE + 0x300000) /* APB-3 */
+#include "regs-spi.h"
+#define PKUNITY_AC97_BASE		(PKUNITY_APB_BASE + 0x400000) /* APB-4 */
+#include "regs-ac97.h"
+#define PKUNITY_GPIO_BASE		(PKUNITY_APB_BASE + 0x500000) /* APB-5 */
+#include "regs-gpio.h"
+#define PKUNITY_INTC_BASE		(PKUNITY_APB_BASE + 0x600000) /* APB-6 */
+#include "regs-intc.h"
+#define PKUNITY_RTC_BASE		(PKUNITY_APB_BASE + 0x700000) /* APB-7 */
+#include "regs-rtc.h"
+#define PKUNITY_OST_BASE		(PKUNITY_APB_BASE + 0x800000) /* APB-8 */
+#include "regs-ost.h"
+#define PKUNITY_RESETC_BASE		(PKUNITY_APB_BASE + 0x900000) /* APB-9 */
+#include "regs-resetc.h"
+#define PKUNITY_PM_BASE			(PKUNITY_APB_BASE + 0xA00000) /* APB-10 */
+#include "regs-pm.h"
+#define PKUNITY_PS2_BASE		(PKUNITY_APB_BASE + 0xB00000) /* APB-11 */
+#include "regs-ps2.h"
+#define PKUNITY_SDC_BASE		(PKUNITY_APB_BASE + 0xC00000) /* APB-12 */
+#include "regs-sdc.h"
+

+ 24 - 0
arch/unicore32/include/mach/bitfield.h

@@ -0,0 +1,24 @@
+/*
+ * linux/arch/unicore32/include/mach/bitfield.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __MACH_PUV3_BITFIELD_H__
+#define __MACH_PUV3_BITFIELD_H__
+
+#ifndef __ASSEMBLY__
+#define UData(Data)	((unsigned long) (Data))
+#else
+#define UData(Data)	(Data)
+#endif
+
+#define FIELD(val, vmask, vshift)	(((val) & ((UData(1) << (vmask)) - 1)) << (vshift))
+#define FMASK(vmask, vshift)		(((UData(1) << (vmask)) - 1) << (vshift))
+
+#endif /* __MACH_PUV3_BITFIELD_H__ */

+ 48 - 0
arch/unicore32/include/mach/dma.h

@@ -0,0 +1,48 @@
+/*
+ * linux/arch/unicore32/include/mach/dma.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __MACH_PUV3_DMA_H__
+#define __MACH_PUV3_DMA_H__
+
+/*
+ * The PKUnity has six internal DMA channels.
+ */
+#define MAX_DMA_CHANNELS	6
+
+typedef enum {
+	DMA_PRIO_HIGH = 0,
+	DMA_PRIO_MEDIUM = 1,
+	DMA_PRIO_LOW = 2
+} puv3_dma_prio;
+
+/*
+ * DMA registration
+ */
+
+extern int puv3_request_dma(char *name,
+			 puv3_dma_prio prio,
+			 void (*irq_handler)(int, void *),
+			 void (*err_handler)(int, void *),
+			 void *data);
+
+extern void puv3_free_dma(int dma_ch);
+
+static inline void puv3_stop_dma(int ch)
+{
+	writel(readl(DMAC_CONFIG(ch)) & ~DMAC_CONFIG_EN, DMAC_CONFIG(ch));
+}
+
+static inline void puv3_resume_dma(int ch)
+{
+	writel(readl(DMAC_CONFIG(ch)) | DMAC_CONFIG_EN, DMAC_CONFIG(ch));
+}
+
+#endif /* __MACH_PUV3_DMA_H__ */

+ 38 - 0
arch/unicore32/include/mach/hardware.h

@@ -0,0 +1,38 @@
+/*
+ * linux/arch/unicore32/include/mach/hardware.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ *
+ * This file contains the hardware definitions for PKUnity architecture
+ */
+
+#ifndef __MACH_PUV3_HARDWARE_H__
+#define __MACH_PUV3_HARDWARE_H__
+
+#include "PKUnity.h"
+
+#ifndef __ASSEMBLY__
+#define io_p2v(x)	(void __iomem *)((x) - PKUNITY_MMIO_BASE)
+#define io_v2p(x)	(phys_addr_t)((x) + PKUNITY_MMIO_BASE)
+#else
+#define io_p2v(x)	((x) - PKUNITY_MMIO_BASE)
+#define io_v2p(x)	((x) + PKUNITY_MMIO_BASE)
+#endif
+
+#define PCIBIOS_MIN_IO			0x4000 /* should lower than 64KB */
+#define PCIBIOS_MIN_MEM			io_v2p(PKUNITY_PCIMEM_BASE)
+
+/*
+ * We override the standard dma-mask routines for bouncing.
+ */
+#define	HAVE_ARCH_PCI_SET_DMA_MASK
+
+#define pcibios_assign_all_busses()	1
+
+#endif  /* __MACH_PUV3_HARDWARE_H__ */

+ 20 - 0
arch/unicore32/include/mach/map.h

@@ -0,0 +1,20 @@
+/*
+ * linux/arch/unicore32/include/mach/map.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ *
+ *  Page table mapping constructs and function prototypes
+ */
+#define MT_DEVICE		0
+#define MT_DEVICE_CACHED	2
+#define MT_KUSER		7
+#define MT_HIGH_VECTORS		8
+#define MT_MEMORY		9
+#define MT_ROM			10
+

+ 58 - 0
arch/unicore32/include/mach/memory.h

@@ -0,0 +1,58 @@
+/*
+ * linux/arch/unicore32/include/mach/memory.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __MACH_PUV3_MEMORY_H__
+#define __MACH_PUV3_MEMORY_H__
+
+#include <mach/hardware.h>
+
+/* Physical DRAM offset. */
+#define PHYS_OFFSET	UL(0x00000000)
+/* The base address of exception vectors. */
+#define VECTORS_BASE	UL(0xffff0000)
+/* The base address of kuser area. */
+#define KUSER_BASE	UL(0x80000000)
+
+#ifdef __ASSEMBLY__
+/* The byte offset of the kernel image in RAM from the start of RAM. */
+#define KERNEL_IMAGE_START	0x00408000
+#endif
+
+#if !defined(__ASSEMBLY__) && defined(CONFIG_PCI)
+
+void puv3_pci_adjust_zones(unsigned long *size, unsigned long *holes);
+
+#define arch_adjust_zones(size, holes) \
+	puv3_pci_adjust_zones(size, holes)
+
+#endif
+
+/*
+ * PCI controller in PKUnity-3 masks highest 5-bit for upstream channel,
+ * so we must limit the DMA allocation within 128M physical memory for
+ * supporting PCI devices.
+ */
+#define PCI_DMA_THRESHOLD	(PHYS_OFFSET + SZ_128M - 1)
+
+#define is_pcibus_device(dev)	(dev &&			\
+				(strncmp(dev->bus->name, "pci", 3) == 0))
+
+#define __virt_to_pcibus(x)     (__virt_to_phys((x) + PKUNITY_PCIAHB_BASE))
+#define __pcibus_to_virt(x)     (__phys_to_virt(x) - PKUNITY_PCIAHB_BASE)
+
+/* kuser area */
+#define KUSER_VECPAGE_BASE	(KUSER_BASE + UL(0x3fff0000))
+#define KUSER_UNIGFX_BASE	(PAGE_OFFSET + PKUNITY_UNIGFX_MMAP_BASE)
+/* kuser_vecpage (0xbfff0000) is ro, and vectors page (0xffff0000) is rw */
+#define kuser_vecpage_to_vectors(x)	((x) - (KUSER_VECPAGE_BASE)	\
+					+ (VECTORS_BASE))
+
+#endif

+ 36 - 0
arch/unicore32/include/mach/ocd.h

@@ -0,0 +1,36 @@
+/*
+ * linux/arch/unicore32/include/mach/ocd.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+#ifndef __MACH_PUV3_OCD_H__
+#define __MACH_PUV3_OCD_H__
+
+#if defined(CONFIG_DEBUG_OCD)
+static inline void ocd_putc(unsigned int c)
+{
+	int status, i = 0x2000000;
+
+	do {
+		if (--i < 0)
+			return;
+
+		asm volatile ("movc %0, p1.c0, #0" : "=r" (status));
+	} while (status & 2);
+
+	asm("movc p1.c1, %0, #1" : : "r" (c));
+}
+
+#define putc(ch)	ocd_putc(ch)
+#else
+#define putc(ch)
+#endif
+
+#endif

+ 43 - 0
arch/unicore32/include/mach/pm.h

@@ -0,0 +1,43 @@
+/*
+ * linux/arch/unicore/include/mach/pm.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#ifndef __PUV3_PM_H__
+#define __PUV3_PM_H__
+
+#include <linux/suspend.h>
+
+struct puv3_cpu_pm_fns {
+	int	save_count;
+	void	(*save)(unsigned long *);
+	void	(*restore)(unsigned long *);
+	int	(*valid)(suspend_state_t state);
+	void	(*enter)(suspend_state_t state);
+	int	(*prepare)(void);
+	void	(*finish)(void);
+};
+
+extern struct puv3_cpu_pm_fns *puv3_cpu_pm_fns;
+
+/* sleep.S */
+extern void puv3_cpu_suspend(unsigned int);
+
+extern void puv3_cpu_resume(void);
+
+extern int puv3_pm_enter(suspend_state_t state);
+
+/* Defined in hibernate_asm.S */
+extern int restore_image(pgd_t *resume_pg_dir, struct pbe *restore_pblist);
+
+/* References to section boundaries */
+extern const void __nosave_begin, __nosave_end;
+
+extern struct pbe *restore_pblist;
+#endif

+ 32 - 0
arch/unicore32/include/mach/regs-ac97.h

@@ -0,0 +1,32 @@
+/*
+ * PKUnity AC97 Registers
+ */
+
+#define PKUNITY_AC97_CONR		(PKUNITY_AC97_BASE + 0x0000)
+#define PKUNITY_AC97_OCR		(PKUNITY_AC97_BASE + 0x0004)
+#define PKUNITY_AC97_ICR		(PKUNITY_AC97_BASE + 0x0008)
+#define PKUNITY_AC97_CRAC		(PKUNITY_AC97_BASE + 0x000C)
+#define PKUNITY_AC97_INTR		(PKUNITY_AC97_BASE + 0x0010)
+#define PKUNITY_AC97_INTRSTAT		(PKUNITY_AC97_BASE + 0x0014)
+#define PKUNITY_AC97_INTRCLEAR		(PKUNITY_AC97_BASE + 0x0018)
+#define PKUNITY_AC97_ENABLE		(PKUNITY_AC97_BASE + 0x001C)
+#define PKUNITY_AC97_OUT_FIFO		(PKUNITY_AC97_BASE + 0x0020)
+#define PKUNITY_AC97_IN_FIFO		(PKUNITY_AC97_BASE + 0x0030)
+
+#define AC97_CODEC_REG(v)               FIELD((v), 7, 16)
+#define AC97_CODEC_VAL(v)               FIELD((v), 16, 0)
+#define AC97_CODEC_WRITECOMPLETE        FIELD(1, 1, 2)
+
+/*
+ * VAR PLAY SAMPLE RATE
+ */
+#define AC97_CMD_VPSAMPLE		(FIELD(3, 2, 16) | FIELD(3, 2, 0))
+
+/*
+ * FIX CAPTURE SAMPLE RATE
+ */
+#define AC97_CMD_FCSAMPLE		FIELD(7, 3, 0)
+
+#define AC97_CMD_RESET			FIELD(1, 1, 0)
+#define AC97_CMD_ENABLE			FIELD(1, 1, 0)
+#define AC97_CMD_DISABLE		FIELD(0, 1, 0)

+ 81 - 0
arch/unicore32/include/mach/regs-dmac.h

@@ -0,0 +1,81 @@
+/*
+ * PKUnity Direct Memory Access Controller (DMAC)
+ */
+
+/*
+ * Interrupt Status Reg DMAC_ISR.
+ */
+#define DMAC_ISR		(PKUNITY_DMAC_BASE + 0x0020)
+/*
+ * Interrupt Transfer Complete Status Reg DMAC_ITCSR.
+ */
+#define DMAC_ITCSR		(PKUNITY_DMAC_BASE + 0x0050)
+/*
+ * Interrupt Transfer Complete Clear Reg DMAC_ITCCR.
+ */
+#define DMAC_ITCCR		(PKUNITY_DMAC_BASE + 0x0060)
+/*
+ * Interrupt Error Status Reg DMAC_IESR.
+ */
+#define DMAC_IESR		(PKUNITY_DMAC_BASE + 0x0080)
+/*
+ * Interrupt Error Clear Reg DMAC_IECR.
+ */
+#define DMAC_IECR		(PKUNITY_DMAC_BASE + 0x0090)
+/*
+ * Enable Channels Reg DMAC_ENCH.
+ */
+#define DMAC_ENCH		(PKUNITY_DMAC_BASE + 0x00B0)
+
+/*
+ * DMA control reg. Space [byte]
+ */
+#define DMASp                   0x00000100
+
+/*
+ * Source Addr DMAC_SRCADDR(ch).
+ */
+#define DMAC_SRCADDR(ch)	(PKUNITY_DMAC_BASE + (ch)*DMASp + 0x00)
+/*
+ * Destination Addr DMAC_DESTADDR(ch).
+ */
+#define DMAC_DESTADDR(ch)	(PKUNITY_DMAC_BASE + (ch)*DMASp + 0x04)
+/*
+ * Control Reg DMAC_CONTROL(ch).
+ */
+#define DMAC_CONTROL(ch)	(PKUNITY_DMAC_BASE + (ch)*DMASp + 0x0C)
+/*
+ * Configuration Reg DMAC_CONFIG(ch).
+ */
+#define DMAC_CONFIG(ch)		(PKUNITY_DMAC_BASE + (ch)*DMASp + 0x10)
+
+#define DMAC_IR_MASK            FMASK(6, 0)
+/*
+ * select channel (ch)
+ */
+#define DMAC_CHANNEL(ch)	FIELD(1, 1, (ch))
+
+#define DMAC_CONTROL_SIZE_BYTE(v)       (FIELD((v), 12, 14) | \
+					FIELD(0, 3, 9) | FIELD(0, 3, 6))
+#define DMAC_CONTROL_SIZE_HWORD(v)      (FIELD((v) >> 1, 12, 14) | \
+					FIELD(1, 3, 9) | FIELD(1, 3, 6))
+#define DMAC_CONTROL_SIZE_WORD(v)       (FIELD((v) >> 2, 12, 14) | \
+					FIELD(2, 3, 9) | FIELD(2, 3, 6))
+#define DMAC_CONTROL_DI                 FIELD(1, 1, 13)
+#define DMAC_CONTROL_SI                 FIELD(1, 1, 12)
+#define DMAC_CONTROL_BURST_1BYTE        (FIELD(0, 3, 3) | FIELD(0, 3, 0))
+#define DMAC_CONTROL_BURST_4BYTE        (FIELD(3, 3, 3) | FIELD(3, 3, 0))
+#define DMAC_CONTROL_BURST_8BYTE        (FIELD(5, 3, 3) | FIELD(5, 3, 0))
+#define DMAC_CONTROL_BURST_16BYTE       (FIELD(7, 3, 3) | FIELD(7, 3, 0))
+
+#define	DMAC_CONFIG_UART0_WR    (FIELD(2, 4, 11) | FIELD(1, 2, 1))
+#define	DMAC_CONFIG_UART0_RD    (FIELD(2, 4, 7)  | FIELD(2, 2, 1))
+#define	DMAC_CONFIG_UART1_WR    (FIELD(3, 4, 11) | FIELD(1, 2, 1))
+#define	DMAC_CONFIG_UART1RD     (FIELD(3, 4, 7)  | FIELD(2, 2, 1))
+#define	DMAC_CONFIG_AC97WR      (FIELD(4, 4, 11) | FIELD(1, 2, 1))
+#define	DMAC_CONFIG_AC97RD      (FIELD(4, 4, 7)  | FIELD(2, 2, 1))
+#define	DMAC_CONFIG_MMCWR       (FIELD(7, 4, 11) | FIELD(1, 2, 1))
+#define	DMAC_CONFIG_MMCRD       (FIELD(7, 4, 7)  | FIELD(2, 2, 1))
+#define DMAC_CONFIG_MASKITC     FIELD(1, 1, 4)
+#define DMAC_CONFIG_MASKIE      FIELD(1, 1, 3)
+#define DMAC_CONFIG_EN          FIELD(1, 1, 0)

+ 70 - 0
arch/unicore32/include/mach/regs-gpio.h

@@ -0,0 +1,70 @@
+/*
+ * PKUnity General-Purpose Input/Output (GPIO) Registers
+ */
+
+/*
+ * Voltage Status Reg GPIO_GPLR.
+ */
+#define GPIO_GPLR	(PKUNITY_GPIO_BASE + 0x0000)
+/*
+ * Pin Direction Reg GPIO_GPDR.
+ */
+#define GPIO_GPDR	(PKUNITY_GPIO_BASE + 0x0004)
+/*
+ * Output Pin Set Reg GPIO_GPSR.
+ */
+#define GPIO_GPSR	(PKUNITY_GPIO_BASE + 0x0008)
+/*
+ * Output Pin Clear Reg GPIO_GPCR.
+ */
+#define GPIO_GPCR	(PKUNITY_GPIO_BASE + 0x000C)
+/*
+ * Raise Edge Detect Reg GPIO_GRER.
+ */
+#define GPIO_GRER	(PKUNITY_GPIO_BASE + 0x0010)
+/*
+ * Fall Edge Detect Reg GPIO_GFER.
+ */
+#define GPIO_GFER	(PKUNITY_GPIO_BASE + 0x0014)
+/*
+ * Edge Status Reg GPIO_GEDR.
+ */
+#define GPIO_GEDR	(PKUNITY_GPIO_BASE + 0x0018)
+/*
+ * Sepcial Voltage Detect Reg GPIO_GPIR.
+ */
+#define GPIO_GPIR	(PKUNITY_GPIO_BASE + 0x0020)
+
+#define GPIO_MIN	(0)
+#define GPIO_MAX	(27)
+
+#define GPIO_GPIO(Nb)	(0x00000001 << (Nb))	/* GPIO [0..27] */
+#define GPIO_GPIO0	GPIO_GPIO(0)	/* GPIO  [0] */
+#define GPIO_GPIO1	GPIO_GPIO(1)	/* GPIO  [1] */
+#define GPIO_GPIO2	GPIO_GPIO(2)	/* GPIO  [2] */
+#define GPIO_GPIO3	GPIO_GPIO(3)	/* GPIO  [3] */
+#define GPIO_GPIO4	GPIO_GPIO(4)	/* GPIO  [4] */
+#define GPIO_GPIO5	GPIO_GPIO(5)	/* GPIO  [5] */
+#define GPIO_GPIO6	GPIO_GPIO(6)	/* GPIO  [6] */
+#define GPIO_GPIO7	GPIO_GPIO(7)	/* GPIO  [7] */
+#define GPIO_GPIO8	GPIO_GPIO(8)	/* GPIO  [8] */
+#define GPIO_GPIO9	GPIO_GPIO(9)	/* GPIO  [9] */
+#define GPIO_GPIO10	GPIO_GPIO(10)	/* GPIO [10] */
+#define GPIO_GPIO11	GPIO_GPIO(11)	/* GPIO [11] */
+#define GPIO_GPIO12	GPIO_GPIO(12)	/* GPIO [12] */
+#define GPIO_GPIO13	GPIO_GPIO(13)	/* GPIO [13] */
+#define GPIO_GPIO14	GPIO_GPIO(14)	/* GPIO [14] */
+#define GPIO_GPIO15	GPIO_GPIO(15)	/* GPIO [15] */
+#define GPIO_GPIO16	GPIO_GPIO(16)	/* GPIO [16] */
+#define GPIO_GPIO17	GPIO_GPIO(17)	/* GPIO [17] */
+#define GPIO_GPIO18	GPIO_GPIO(18)	/* GPIO [18] */
+#define GPIO_GPIO19	GPIO_GPIO(19)	/* GPIO [19] */
+#define GPIO_GPIO20	GPIO_GPIO(20)	/* GPIO [20] */
+#define GPIO_GPIO21	GPIO_GPIO(21)	/* GPIO [21] */
+#define GPIO_GPIO22	GPIO_GPIO(22)	/* GPIO [22] */
+#define GPIO_GPIO23	GPIO_GPIO(23)	/* GPIO [23] */
+#define GPIO_GPIO24	GPIO_GPIO(24)	/* GPIO [24] */
+#define GPIO_GPIO25	GPIO_GPIO(25)	/* GPIO [25] */
+#define GPIO_GPIO26	GPIO_GPIO(26)	/* GPIO [26] */
+#define GPIO_GPIO27	GPIO_GPIO(27)	/* GPIO [27] */
+

+ 63 - 0
arch/unicore32/include/mach/regs-i2c.h

@@ -0,0 +1,63 @@
+/*
+ * PKUnity Inter-integrated Circuit (I2C) Registers
+ */
+
+/*
+ * Control Reg I2C_CON.
+ */
+#define I2C_CON		(PKUNITY_I2C_BASE + 0x0000)
+/*
+ * Target Address Reg I2C_TAR.
+ */
+#define I2C_TAR		(PKUNITY_I2C_BASE + 0x0004)
+/*
+ * Data buffer and command Reg I2C_DATACMD.
+ */
+#define I2C_DATACMD	(PKUNITY_I2C_BASE + 0x0010)
+/*
+ * Enable Reg I2C_ENABLE.
+ */
+#define I2C_ENABLE	(PKUNITY_I2C_BASE + 0x006C)
+/*
+ * Status Reg I2C_STATUS.
+ */
+#define I2C_STATUS	(PKUNITY_I2C_BASE + 0x0070)
+/*
+ * Tx FIFO Length Reg I2C_TXFLR.
+ */
+#define I2C_TXFLR	(PKUNITY_I2C_BASE + 0x0074)
+/*
+ * Rx FIFO Length Reg I2C_RXFLR.
+ */
+#define I2C_RXFLR	(PKUNITY_I2C_BASE + 0x0078)
+/*
+ * Enable Status Reg I2C_ENSTATUS.
+ */
+#define I2C_ENSTATUS	(PKUNITY_I2C_BASE + 0x009C)
+
+#define I2C_CON_MASTER          FIELD(1, 1, 0)
+#define I2C_CON_SPEED_STD       FIELD(1, 2, 1)
+#define I2C_CON_SPEED_FAST      FIELD(2, 2, 1)
+#define I2C_CON_RESTART         FIELD(1, 1, 5)
+#define I2C_CON_SLAVEDISABLE    FIELD(1, 1, 6)
+
+#define I2C_DATACMD_READ        FIELD(1, 1, 8)
+#define I2C_DATACMD_WRITE       FIELD(0, 1, 8)
+#define I2C_DATACMD_DAT_MASK    FMASK(8, 0)
+#define I2C_DATACMD_DAT(v)      FIELD((v), 8, 0)
+
+#define I2C_ENABLE_ENABLE       FIELD(1, 1, 0)
+#define I2C_ENABLE_DISABLE      FIELD(0, 1, 0)
+
+#define I2C_STATUS_RFF          FIELD(1, 1, 4)
+#define I2C_STATUS_RFNE         FIELD(1, 1, 3)
+#define I2C_STATUS_TFE          FIELD(1, 1, 2)
+#define I2C_STATUS_TFNF         FIELD(1, 1, 1)
+#define I2C_STATUS_ACTIVITY     FIELD(1, 1, 0)
+
+#define I2C_ENSTATUS_ENABLE	FIELD(1, 1, 0)
+
+#define I2C_TAR_THERMAL	0x4f
+#define I2C_TAR_SPD	0x50
+#define I2C_TAR_PWIC    0x55
+#define I2C_TAR_EEPROM	0x57

+ 28 - 0
arch/unicore32/include/mach/regs-intc.h

@@ -0,0 +1,28 @@
+/*
+ * PKUNITY Interrupt Controller (INTC) Registers
+ */
+/*
+ * INTC Level Reg INTC_ICLR.
+ */
+#define INTC_ICLR	(PKUNITY_INTC_BASE + 0x0000)
+/*
+ * INTC Mask Reg INTC_ICMR.
+ */
+#define INTC_ICMR	(PKUNITY_INTC_BASE + 0x0004)
+/*
+ * INTC Pending Reg INTC_ICPR.
+ */
+#define INTC_ICPR	(PKUNITY_INTC_BASE + 0x0008)
+/*
+ * INTC IRQ Pending Reg INTC_ICIP.
+ */
+#define INTC_ICIP	(PKUNITY_INTC_BASE + 0x000C)
+/*
+ * INTC REAL Pending Reg INTC_ICFP.
+ */
+#define INTC_ICFP	(PKUNITY_INTC_BASE + 0x0010)
+/*
+ * INTC Control Reg INTC_ICCR.
+ */
+#define INTC_ICCR	(PKUNITY_INTC_BASE + 0x0014)
+

+ 79 - 0
arch/unicore32/include/mach/regs-nand.h

@@ -0,0 +1,79 @@
+/*
+ * PKUnity NAND Controller Registers
+ */
+/*
+ * ID Reg. 0 NAND_IDR0
+ */
+#define NAND_IDR0	(PKUNITY_NAND_BASE + 0x0000)
+/*
+ * ID Reg. 1 NAND_IDR1
+ */
+#define NAND_IDR1	(PKUNITY_NAND_BASE + 0x0004)
+/*
+ * ID Reg. 2 NAND_IDR2
+ */
+#define NAND_IDR2	(PKUNITY_NAND_BASE + 0x0008)
+/*
+ * ID Reg. 3 NAND_IDR3
+ */
+#define NAND_IDR3	(PKUNITY_NAND_BASE + 0x000C)
+/*
+ * Page Address Reg 0 NAND_PAR0
+ */
+#define NAND_PAR0	(PKUNITY_NAND_BASE + 0x0010)
+/*
+ * Page Address Reg 1 NAND_PAR1
+ */
+#define NAND_PAR1	(PKUNITY_NAND_BASE + 0x0014)
+/*
+ * Page Address Reg 2 NAND_PAR2
+ */
+#define NAND_PAR2	(PKUNITY_NAND_BASE + 0x0018)
+/*
+ * ECC Enable Reg NAND_ECCEN
+ */
+#define NAND_ECCEN	(PKUNITY_NAND_BASE + 0x001C)
+/*
+ * Buffer Reg NAND_BUF
+ */
+#define NAND_BUF	(PKUNITY_NAND_BASE + 0x0020)
+/*
+ * ECC Status Reg NAND_ECCSR
+ */
+#define NAND_ECCSR	(PKUNITY_NAND_BASE + 0x0024)
+/*
+ * Command Reg NAND_CMD
+ */
+#define NAND_CMD	(PKUNITY_NAND_BASE + 0x0028)
+/*
+ * DMA Configure Reg NAND_DMACR
+ */
+#define NAND_DMACR	(PKUNITY_NAND_BASE + 0x002C)
+/*
+ * Interrupt Reg NAND_IR
+ */
+#define NAND_IR		(PKUNITY_NAND_BASE + 0x0030)
+/*
+ * Interrupt Mask Reg NAND_IMR
+ */
+#define NAND_IMR	(PKUNITY_NAND_BASE + 0x0034)
+/*
+ * Chip Enable Reg NAND_CHIPEN
+ */
+#define NAND_CHIPEN	(PKUNITY_NAND_BASE + 0x0038)
+/*
+ * Address Reg NAND_ADDR
+ */
+#define NAND_ADDR	(PKUNITY_NAND_BASE + 0x003C)
+
+/*
+ * Command bits NAND_CMD_CMD_MASK
+ */
+#define NAND_CMD_CMD_MASK		FMASK(4, 4)
+#define NAND_CMD_CMD_READPAGE		FIELD(0x0, 4, 4)
+#define NAND_CMD_CMD_ERASEBLOCK		FIELD(0x6, 4, 4)
+#define NAND_CMD_CMD_READSTATUS		FIELD(0x7, 4, 4)
+#define NAND_CMD_CMD_WRITEPAGE		FIELD(0x8, 4, 4)
+#define NAND_CMD_CMD_READID		FIELD(0x9, 4, 4)
+#define NAND_CMD_CMD_RESET		FIELD(0xf, 4, 4)
+

+ 92 - 0
arch/unicore32/include/mach/regs-ost.h

@@ -0,0 +1,92 @@
+/*
+ * PKUnity Operating System Timer (OST) Registers
+ */
+/*
+ * Match Reg 0 OST_OSMR0
+ */
+#define OST_OSMR0	(PKUNITY_OST_BASE + 0x0000)
+/*
+ * Match Reg 1 OST_OSMR1
+ */
+#define OST_OSMR1	(PKUNITY_OST_BASE + 0x0004)
+/*
+ * Match Reg 2 OST_OSMR2
+ */
+#define OST_OSMR2	(PKUNITY_OST_BASE + 0x0008)
+/*
+ * Match Reg 3 OST_OSMR3
+ */
+#define OST_OSMR3	(PKUNITY_OST_BASE + 0x000C)
+/*
+ * Counter Reg OST_OSCR
+ */
+#define OST_OSCR	(PKUNITY_OST_BASE + 0x0010)
+/*
+ * Status Reg OST_OSSR
+ */
+#define OST_OSSR	(PKUNITY_OST_BASE + 0x0014)
+/*
+ * Watchdog Enable Reg OST_OWER
+ */
+#define OST_OWER	(PKUNITY_OST_BASE + 0x0018)
+/*
+ * Interrupt Enable Reg OST_OIER
+ */
+#define OST_OIER	(PKUNITY_OST_BASE + 0x001C)
+/*
+ * PWM Pulse Width Control Reg OST_PWMPWCR
+ */
+#define OST_PWMPWCR	(PKUNITY_OST_BASE + 0x0080)
+/*
+ * PWM Duty Cycle Control Reg OST_PWMDCCR
+ */
+#define OST_PWMDCCR	(PKUNITY_OST_BASE + 0x0084)
+/*
+ * PWM Period Control Reg OST_PWMPCR
+ */
+#define OST_PWMPCR	(PKUNITY_OST_BASE + 0x0088)
+
+/*
+ * Match detected 0 OST_OSSR_M0
+ */
+#define OST_OSSR_M0		FIELD(1, 1, 0)
+/*
+ * Match detected 1 OST_OSSR_M1
+ */
+#define OST_OSSR_M1		FIELD(1, 1, 1)
+/*
+ * Match detected 2 OST_OSSR_M2
+ */
+#define OST_OSSR_M2		FIELD(1, 1, 2)
+/*
+ * Match detected 3 OST_OSSR_M3
+ */
+#define OST_OSSR_M3		FIELD(1, 1, 3)
+
+/*
+ * Interrupt enable 0 OST_OIER_E0
+ */
+#define OST_OIER_E0		FIELD(1, 1, 0)
+/*
+ * Interrupt enable 1 OST_OIER_E1
+ */
+#define OST_OIER_E1		FIELD(1, 1, 1)
+/*
+ * Interrupt enable 2 OST_OIER_E2
+ */
+#define OST_OIER_E2		FIELD(1, 1, 2)
+/*
+ * Interrupt enable 3 OST_OIER_E3
+ */
+#define OST_OIER_E3		FIELD(1, 1, 3)
+
+/*
+ * Watchdog Match Enable OST_OWER_WME
+ */
+#define OST_OWER_WME		FIELD(1, 1, 0)
+
+/*
+ * PWM Full Duty Cycle OST_PWMDCCR_FDCYCLE
+ */
+#define OST_PWMDCCR_FDCYCLE	FIELD(1, 1, 10)
+

+ 94 - 0
arch/unicore32/include/mach/regs-pci.h

@@ -0,0 +1,94 @@
+/*
+ * PKUnity AHB-PCI Bridge Registers
+ */
+
+/*
+ * AHB/PCI fixed physical address for pci addess configuration
+ */
+/*
+ * PCICFG Bridge Base Reg.
+ */
+#define PCICFG_BRIBASE          (PKUNITY_PCICFG_BASE + 0x0000)
+/*
+ * PCICFG Address Reg.
+ */
+#define PCICFG_ADDR             (PKUNITY_PCICFG_BASE + 0x0004)
+/*
+ * PCICFG Address Reg.
+ */
+#define PCICFG_DATA             (PKUNITY_PCICFG_BASE + 0x0008)
+
+/*
+ * PCI Bridge configuration space
+ */
+#define PCIBRI_ID		(PKUNITY_PCIBRI_BASE + 0x0000)
+#define PCIBRI_CMD		(PKUNITY_PCIBRI_BASE + 0x0004)
+#define PCIBRI_CLASS		(PKUNITY_PCIBRI_BASE + 0x0008)
+#define PCIBRI_LTR		(PKUNITY_PCIBRI_BASE + 0x000C)
+#define PCIBRI_BAR0		(PKUNITY_PCIBRI_BASE + 0x0010)
+#define PCIBRI_BAR1		(PKUNITY_PCIBRI_BASE + 0x0014)
+#define PCIBRI_BAR2		(PKUNITY_PCIBRI_BASE + 0x0018)
+#define PCIBRI_BAR3		(PKUNITY_PCIBRI_BASE + 0x001C)
+#define PCIBRI_BAR4		(PKUNITY_PCIBRI_BASE + 0x0020)
+#define PCIBRI_BAR5		(PKUNITY_PCIBRI_BASE + 0x0024)
+
+#define PCIBRI_PCICTL0		(PKUNITY_PCIBRI_BASE + 0x0100)
+#define PCIBRI_PCIBAR0		(PKUNITY_PCIBRI_BASE + 0x0104)
+#define PCIBRI_PCIAMR0		(PKUNITY_PCIBRI_BASE + 0x0108)
+#define PCIBRI_PCITAR0		(PKUNITY_PCIBRI_BASE + 0x010C)
+#define PCIBRI_PCICTL1		(PKUNITY_PCIBRI_BASE + 0x0110)
+#define PCIBRI_PCIBAR1		(PKUNITY_PCIBRI_BASE + 0x0114)
+#define PCIBRI_PCIAMR1		(PKUNITY_PCIBRI_BASE + 0x0118)
+#define PCIBRI_PCITAR1		(PKUNITY_PCIBRI_BASE + 0x011C)
+#define PCIBRI_PCICTL2		(PKUNITY_PCIBRI_BASE + 0x0120)
+#define PCIBRI_PCIBAR2		(PKUNITY_PCIBRI_BASE + 0x0124)
+#define PCIBRI_PCIAMR2		(PKUNITY_PCIBRI_BASE + 0x0128)
+#define PCIBRI_PCITAR2		(PKUNITY_PCIBRI_BASE + 0x012C)
+#define PCIBRI_PCICTL3		(PKUNITY_PCIBRI_BASE + 0x0130)
+#define PCIBRI_PCIBAR3		(PKUNITY_PCIBRI_BASE + 0x0134)
+#define PCIBRI_PCIAMR3		(PKUNITY_PCIBRI_BASE + 0x0138)
+#define PCIBRI_PCITAR3		(PKUNITY_PCIBRI_BASE + 0x013C)
+#define PCIBRI_PCICTL4		(PKUNITY_PCIBRI_BASE + 0x0140)
+#define PCIBRI_PCIBAR4		(PKUNITY_PCIBRI_BASE + 0x0144)
+#define PCIBRI_PCIAMR4		(PKUNITY_PCIBRI_BASE + 0x0148)
+#define PCIBRI_PCITAR4		(PKUNITY_PCIBRI_BASE + 0x014C)
+#define PCIBRI_PCICTL5		(PKUNITY_PCIBRI_BASE + 0x0150)
+#define PCIBRI_PCIBAR5		(PKUNITY_PCIBRI_BASE + 0x0154)
+#define PCIBRI_PCIAMR5		(PKUNITY_PCIBRI_BASE + 0x0158)
+#define PCIBRI_PCITAR5		(PKUNITY_PCIBRI_BASE + 0x015C)
+
+#define PCIBRI_AHBCTL0		(PKUNITY_PCIBRI_BASE + 0x0180)
+#define PCIBRI_AHBBAR0		(PKUNITY_PCIBRI_BASE + 0x0184)
+#define PCIBRI_AHBAMR0		(PKUNITY_PCIBRI_BASE + 0x0188)
+#define PCIBRI_AHBTAR0		(PKUNITY_PCIBRI_BASE + 0x018C)
+#define PCIBRI_AHBCTL1		(PKUNITY_PCIBRI_BASE + 0x0190)
+#define PCIBRI_AHBBAR1		(PKUNITY_PCIBRI_BASE + 0x0194)
+#define PCIBRI_AHBAMR1		(PKUNITY_PCIBRI_BASE + 0x0198)
+#define PCIBRI_AHBTAR1		(PKUNITY_PCIBRI_BASE + 0x019C)
+#define PCIBRI_AHBCTL2		(PKUNITY_PCIBRI_BASE + 0x01A0)
+#define PCIBRI_AHBBAR2		(PKUNITY_PCIBRI_BASE + 0x01A4)
+#define PCIBRI_AHBAMR2		(PKUNITY_PCIBRI_BASE + 0x01A8)
+#define PCIBRI_AHBTAR2		(PKUNITY_PCIBRI_BASE + 0x01AC)
+#define PCIBRI_AHBCTL3		(PKUNITY_PCIBRI_BASE + 0x01B0)
+#define PCIBRI_AHBBAR3		(PKUNITY_PCIBRI_BASE + 0x01B4)
+#define PCIBRI_AHBAMR3		(PKUNITY_PCIBRI_BASE + 0x01B8)
+#define PCIBRI_AHBTAR3		(PKUNITY_PCIBRI_BASE + 0x01BC)
+#define PCIBRI_AHBCTL4		(PKUNITY_PCIBRI_BASE + 0x01C0)
+#define PCIBRI_AHBBAR4		(PKUNITY_PCIBRI_BASE + 0x01C4)
+#define PCIBRI_AHBAMR4		(PKUNITY_PCIBRI_BASE + 0x01C8)
+#define PCIBRI_AHBTAR4		(PKUNITY_PCIBRI_BASE + 0x01CC)
+#define PCIBRI_AHBCTL5		(PKUNITY_PCIBRI_BASE + 0x01D0)
+#define PCIBRI_AHBBAR5		(PKUNITY_PCIBRI_BASE + 0x01D4)
+#define PCIBRI_AHBAMR5		(PKUNITY_PCIBRI_BASE + 0x01D8)
+#define PCIBRI_AHBTAR5		(PKUNITY_PCIBRI_BASE + 0x01DC)
+
+#define PCIBRI_CTLx_AT          FIELD(1, 1, 2)
+#define PCIBRI_CTLx_PREF        FIELD(1, 1, 1)
+#define PCIBRI_CTLx_MRL         FIELD(1, 1, 0)
+
+#define PCIBRI_BARx_ADDR        FIELD(0xFFFFFFFC, 30, 2)
+#define PCIBRI_BARx_IO          FIELD(1, 1, 0)
+#define PCIBRI_BARx_MEM         FIELD(0, 1, 0)
+
+#define PCIBRI_CMD_IO           FIELD(1, 1, 0)
+#define PCIBRI_CMD_MEM          FIELD(1, 1, 1)

+ 126 - 0
arch/unicore32/include/mach/regs-pm.h

@@ -0,0 +1,126 @@
+/*
+ * PKUNITY Power Manager (PM) Registers
+ */
+/*
+ * PM Control Reg PM_PMCR
+ */
+#define PM_PMCR                 (PKUNITY_PM_BASE + 0x0000)
+/*
+ * PM General Conf. Reg PM_PGCR
+ */
+#define PM_PGCR                 (PKUNITY_PM_BASE + 0x0004)
+/*
+ * PM PLL Conf. Reg PM_PPCR
+ */
+#define PM_PPCR                 (PKUNITY_PM_BASE + 0x0008)
+/*
+ * PM Wakeup Enable Reg PM_PWER
+ */
+#define PM_PWER                 (PKUNITY_PM_BASE + 0x000C)
+/*
+ * PM GPIO Sleep Status Reg PM_PGSR
+ */
+#define PM_PGSR                 (PKUNITY_PM_BASE + 0x0010)
+/*
+ * PM Clock Gate Reg PM_PCGR
+ */
+#define PM_PCGR                 (PKUNITY_PM_BASE + 0x0014)
+/*
+ * PM SYS PLL Conf. Reg PM_PLLSYSCFG
+ */
+#define PM_PLLSYSCFG            (PKUNITY_PM_BASE + 0x0018)
+/*
+ * PM DDR PLL Conf. Reg PM_PLLDDRCFG
+ */
+#define PM_PLLDDRCFG            (PKUNITY_PM_BASE + 0x001C)
+/*
+ * PM VGA PLL Conf. Reg PM_PLLVGACFG
+ */
+#define PM_PLLVGACFG            (PKUNITY_PM_BASE + 0x0020)
+/*
+ * PM Div Conf. Reg PM_DIVCFG
+ */
+#define PM_DIVCFG               (PKUNITY_PM_BASE + 0x0024)
+/*
+ * PM SYS PLL Status Reg PM_PLLSYSSTATUS
+ */
+#define PM_PLLSYSSTATUS         (PKUNITY_PM_BASE + 0x0028)
+/*
+ * PM DDR PLL Status Reg PM_PLLDDRSTATUS
+ */
+#define PM_PLLDDRSTATUS         (PKUNITY_PM_BASE + 0x002C)
+/*
+ * PM VGA PLL Status Reg PM_PLLVGASTATUS
+ */
+#define PM_PLLVGASTATUS         (PKUNITY_PM_BASE + 0x0030)
+/*
+ * PM Div Status Reg PM_DIVSTATUS
+ */
+#define PM_DIVSTATUS            (PKUNITY_PM_BASE + 0x0034)
+/*
+ * PM Software Reset Reg PM_SWRESET
+ */
+#define PM_SWRESET              (PKUNITY_PM_BASE + 0x0038)
+/*
+ * PM DDR2 PAD Start Reg PM_DDR2START
+ */
+#define PM_DDR2START            (PKUNITY_PM_BASE + 0x003C)
+/*
+ * PM DDR2 PAD Status Reg PM_DDR2CAL0
+ */
+#define PM_DDR2CAL0             (PKUNITY_PM_BASE + 0x0040)
+/*
+ * PM PLL DFC Done Reg PM_PLLDFCDONE
+ */
+#define PM_PLLDFCDONE           (PKUNITY_PM_BASE + 0x0044)
+
+#define PM_PMCR_SFB             FIELD(1, 1, 0)
+#define PM_PMCR_IFB             FIELD(1, 1, 1)
+#define PM_PMCR_CFBSYS          FIELD(1, 1, 2)
+#define PM_PMCR_CFBDDR          FIELD(1, 1, 3)
+#define PM_PMCR_CFBVGA          FIELD(1, 1, 4)
+#define PM_PMCR_CFBDIVBCLK      FIELD(1, 1, 5)
+
+/*
+ * GPIO 8~27 wake-up enable PM_PWER_GPIOHIGH
+ */
+#define PM_PWER_GPIOHIGH        FIELD(1, 1, 8)
+/*
+ * RTC alarm wake-up enable PM_PWER_RTC
+ */
+#define PM_PWER_RTC             FIELD(1, 1, 31)
+
+#define PM_PCGR_BCLK64DDR	FIELD(1, 1, 0)
+#define PM_PCGR_BCLK64VGA	FIELD(1, 1, 1)
+#define PM_PCGR_BCLKDDR		FIELD(1, 1, 2)
+#define PM_PCGR_BCLKPCI		FIELD(1, 1, 4)
+#define PM_PCGR_BCLKDMAC	FIELD(1, 1, 5)
+#define PM_PCGR_BCLKUMAL	FIELD(1, 1, 6)
+#define PM_PCGR_BCLKUSB		FIELD(1, 1, 7)
+#define PM_PCGR_BCLKMME		FIELD(1, 1, 10)
+#define PM_PCGR_BCLKNAND	FIELD(1, 1, 11)
+#define PM_PCGR_BCLKH264E	FIELD(1, 1, 12)
+#define PM_PCGR_BCLKVGA		FIELD(1, 1, 13)
+#define PM_PCGR_BCLKH264D	FIELD(1, 1, 14)
+#define PM_PCGR_VECLK		FIELD(1, 1, 15)
+#define PM_PCGR_HECLK		FIELD(1, 1, 16)
+#define PM_PCGR_HDCLK		FIELD(1, 1, 17)
+#define PM_PCGR_NANDCLK		FIELD(1, 1, 18)
+#define PM_PCGR_GECLK		FIELD(1, 1, 19)
+#define PM_PCGR_VGACLK          FIELD(1, 1, 20)
+#define PM_PCGR_PCICLK		FIELD(1, 1, 21)
+#define PM_PCGR_SATACLK		FIELD(1, 1, 25)
+
+/*
+ * [23:20]PM_DIVCFG_VGACLK(v)
+ */
+#define PM_DIVCFG_VGACLK_MASK   FMASK(4, 20)
+#define PM_DIVCFG_VGACLK(v)	FIELD((v), 4, 20)
+
+#define PM_SWRESET_USB          FIELD(1, 1, 6)
+#define PM_SWRESET_VGADIV       FIELD(1, 1, 26)
+#define PM_SWRESET_GEDIV        FIELD(1, 1, 27)
+
+#define PM_PLLDFCDONE_SYSDFC    FIELD(1, 1, 0)
+#define PM_PLLDFCDONE_DDRDFC    FIELD(1, 1, 1)
+#define PM_PLLDFCDONE_VGADFC    FIELD(1, 1, 2)

+ 20 - 0
arch/unicore32/include/mach/regs-ps2.h

@@ -0,0 +1,20 @@
+/*
+ * PKUnity PS2 Controller Registers
+ */
+/*
+ * the same as I8042_DATA_REG PS2_DATA
+ */
+#define PS2_DATA	(PKUNITY_PS2_BASE + 0x0060)
+/*
+ * the same as I8042_COMMAND_REG PS2_COMMAND
+ */
+#define PS2_COMMAND	(PKUNITY_PS2_BASE + 0x0064)
+/*
+ * the same as I8042_STATUS_REG PS2_STATUS
+ */
+#define PS2_STATUS	(PKUNITY_PS2_BASE + 0x0064)
+/*
+ * counter reg PS2_CNT
+ */
+#define PS2_CNT		(PKUNITY_PS2_BASE + 0x0068)
+

+ 34 - 0
arch/unicore32/include/mach/regs-resetc.h

@@ -0,0 +1,34 @@
+/*
+ * PKUnity Reset Controller (RC) Registers
+ */
+/*
+ * Software Reset Register
+ */
+#define RESETC_SWRR	(PKUNITY_RESETC_BASE + 0x0000)
+/*
+ * Reset Status Register
+ */
+#define RESETC_RSSR	(PKUNITY_RESETC_BASE + 0x0004)
+
+/*
+ * Software Reset Bit
+ */
+#define RESETC_SWRR_SRB		FIELD(1, 1, 0)
+
+/*
+ * Hardware Reset
+ */
+#define RESETC_RSSR_HWR		FIELD(1, 1, 0)
+/*
+ * Software Reset
+ */
+#define RESETC_RSSR_SWR		FIELD(1, 1, 1)
+/*
+ * Watchdog Reset
+ */
+#define RESETC_RSSR_WDR		FIELD(1, 1, 2)
+/*
+ * Sleep Mode Reset
+ */
+#define RESETC_RSSR_SMR		FIELD(1, 1, 3)
+

+ 37 - 0
arch/unicore32/include/mach/regs-rtc.h

@@ -0,0 +1,37 @@
+/*
+ * PKUnity Real-Time Clock (RTC) control registers
+ */
+/*
+ * RTC Alarm Reg RTC_RTAR
+ */
+#define RTC_RTAR	(PKUNITY_RTC_BASE + 0x0000)
+/*
+ * RTC Count Reg RTC_RCNR
+ */
+#define RTC_RCNR	(PKUNITY_RTC_BASE + 0x0004)
+/*
+ * RTC Trim Reg RTC_RTTR
+ */
+#define RTC_RTTR	(PKUNITY_RTC_BASE + 0x0008)
+/*
+ * RTC Status Reg RTC_RTSR
+ */
+#define RTC_RTSR	(PKUNITY_RTC_BASE + 0x0010)
+
+/*
+ * ALarm detected RTC_RTSR_AL
+ */
+#define RTC_RTSR_AL		FIELD(1, 1, 0)
+/*
+ * 1 Hz clock detected RTC_RTSR_HZ
+ */
+#define RTC_RTSR_HZ		FIELD(1, 1, 1)
+/*
+ * ALarm interrupt Enable RTC_RTSR_ALE
+ */
+#define RTC_RTSR_ALE		FIELD(1, 1, 2)
+/*
+ * 1 Hz clock interrupt Enable RTC_RTSR_HZE
+ */
+#define RTC_RTSR_HZE		FIELD(1, 1, 3)
+

+ 156 - 0
arch/unicore32/include/mach/regs-sdc.h

@@ -0,0 +1,156 @@
+/*
+ * PKUnity Multi-Media Card and Security Digital Card (MMC/SD) Registers
+ */
+/*
+ * Clock Control Reg SDC_CCR
+ */
+#define SDC_CCR		(PKUNITY_SDC_BASE + 0x0000)
+/*
+ * Software Reset Reg SDC_SRR
+ */
+#define SDC_SRR		(PKUNITY_SDC_BASE + 0x0004)
+/*
+ * Argument Reg SDC_ARGUMENT
+ */
+#define SDC_ARGUMENT	(PKUNITY_SDC_BASE + 0x0008)
+/*
+ * Command Reg SDC_COMMAND
+ */
+#define SDC_COMMAND	(PKUNITY_SDC_BASE + 0x000C)
+/*
+ * Block Size Reg SDC_BLOCKSIZE
+ */
+#define SDC_BLOCKSIZE	(PKUNITY_SDC_BASE + 0x0010)
+/*
+ * Block Cound Reg SDC_BLOCKCOUNT
+ */
+#define SDC_BLOCKCOUNT	(PKUNITY_SDC_BASE + 0x0014)
+/*
+ * Transfer Mode Reg SDC_TMR
+ */
+#define SDC_TMR		(PKUNITY_SDC_BASE + 0x0018)
+/*
+ * Response Reg. 0 SDC_RES0
+ */
+#define SDC_RES0	(PKUNITY_SDC_BASE + 0x001C)
+/*
+ * Response Reg. 1 SDC_RES1
+ */
+#define SDC_RES1	(PKUNITY_SDC_BASE + 0x0020)
+/*
+ * Response Reg. 2 SDC_RES2
+ */
+#define SDC_RES2	(PKUNITY_SDC_BASE + 0x0024)
+/*
+ * Response Reg. 3 SDC_RES3
+ */
+#define SDC_RES3	(PKUNITY_SDC_BASE + 0x0028)
+/*
+ * Read Timeout Control Reg SDC_RTCR
+ */
+#define SDC_RTCR	(PKUNITY_SDC_BASE + 0x002C)
+/*
+ * Interrupt Status Reg SDC_ISR
+ */
+#define SDC_ISR		(PKUNITY_SDC_BASE + 0x0030)
+/*
+ * Interrupt Status Mask Reg SDC_ISMR
+ */
+#define SDC_ISMR	(PKUNITY_SDC_BASE + 0x0034)
+/*
+ * RX FIFO SDC_RXFIFO
+ */
+#define SDC_RXFIFO	(PKUNITY_SDC_BASE + 0x0038)
+/*
+ * TX FIFO SDC_TXFIFO
+ */
+#define SDC_TXFIFO	(PKUNITY_SDC_BASE + 0x003C)
+
+/*
+ * SD Clock Enable SDC_CCR_CLKEN
+ */
+#define SDC_CCR_CLKEN			FIELD(1, 1, 2)
+/*
+ * [15:8] SDC_CCR_PDIV(v)
+ */
+#define SDC_CCR_PDIV(v)			FIELD((v), 8, 8)
+
+/*
+ * Software reset enable SDC_SRR_ENABLE
+ */
+#define SDC_SRR_ENABLE			FIELD(0, 1, 0)
+/*
+ * Software reset disable SDC_SRR_DISABLE
+ */
+#define SDC_SRR_DISABLE			FIELD(1, 1, 0)
+
+/*
+ * Response type SDC_COMMAND_RESTYPE_MASK
+ */
+#define SDC_COMMAND_RESTYPE_MASK	FMASK(2, 0)
+/*
+ * No response SDC_COMMAND_RESTYPE_NONE
+ */
+#define SDC_COMMAND_RESTYPE_NONE	FIELD(0, 2, 0)
+/*
+ * 136-bit long response SDC_COMMAND_RESTYPE_LONG
+ */
+#define SDC_COMMAND_RESTYPE_LONG	FIELD(1, 2, 0)
+/*
+ * 48-bit short response SDC_COMMAND_RESTYPE_SHORT
+ */
+#define SDC_COMMAND_RESTYPE_SHORT	FIELD(2, 2, 0)
+/*
+ * 48-bit short and test if busy response SDC_COMMAND_RESTYPE_SHORTBUSY
+ */
+#define SDC_COMMAND_RESTYPE_SHORTBUSY	FIELD(3, 2, 0)
+/*
+ * data ready SDC_COMMAND_DATAREADY
+ */
+#define SDC_COMMAND_DATAREADY		FIELD(1, 1, 2)
+#define SDC_COMMAND_CMDEN		FIELD(1, 1, 3)
+/*
+ * [10:5] SDC_COMMAND_CMDINDEX(v)
+ */
+#define SDC_COMMAND_CMDINDEX(v)		FIELD((v), 6, 5)
+
+/*
+ * [10:0] SDC_BLOCKSIZE_BSMASK(v)
+ */
+#define SDC_BLOCKSIZE_BSMASK(v)		FIELD((v), 11, 0)
+/*
+ * [11:0] SDC_BLOCKCOUNT_BCMASK(v)
+ */
+#define SDC_BLOCKCOUNT_BCMASK(v)	FIELD((v), 12, 0)
+
+/*
+ * Data Width 1bit SDC_TMR_WTH_1BIT
+ */
+#define SDC_TMR_WTH_1BIT		FIELD(0, 1, 0)
+/*
+ * Data Width 4bit SDC_TMR_WTH_4BIT
+ */
+#define SDC_TMR_WTH_4BIT		FIELD(1, 1, 0)
+/*
+ * Read SDC_TMR_DIR_READ
+ */
+#define SDC_TMR_DIR_READ		FIELD(0, 1, 1)
+/*
+ * Write SDC_TMR_DIR_WRITE
+ */
+#define SDC_TMR_DIR_WRITE		FIELD(1, 1, 1)
+
+#define SDC_IR_MASK			FMASK(13, 0)
+#define SDC_IR_RESTIMEOUT		FIELD(1, 1, 0)
+#define SDC_IR_WRITECRC			FIELD(1, 1, 1)
+#define SDC_IR_READCRC			FIELD(1, 1, 2)
+#define SDC_IR_TXFIFOREAD		FIELD(1, 1, 3)
+#define SDC_IR_RXFIFOWRITE		FIELD(1, 1, 4)
+#define SDC_IR_READTIMEOUT		FIELD(1, 1, 5)
+#define SDC_IR_DATACOMPLETE		FIELD(1, 1, 6)
+#define SDC_IR_CMDCOMPLETE		FIELD(1, 1, 7)
+#define SDC_IR_RXFIFOFULL		FIELD(1, 1, 8)
+#define SDC_IR_RXFIFOEMPTY		FIELD(1, 1, 9)
+#define SDC_IR_TXFIFOFULL		FIELD(1, 1, 10)
+#define SDC_IR_TXFIFOEMPTY		FIELD(1, 1, 11)
+#define SDC_IR_ENDCMDWITHRES		FIELD(1, 1, 12)

+ 98 - 0
arch/unicore32/include/mach/regs-spi.h

@@ -0,0 +1,98 @@
+/*
+ * PKUnity Serial Peripheral Interface (SPI) Registers
+ */
+/*
+ * Control reg. 0 SPI_CR0
+ */
+#define SPI_CR0		(PKUNITY_SPI_BASE + 0x0000)
+/*
+ * Control reg. 1 SPI_CR1
+ */
+#define SPI_CR1		(PKUNITY_SPI_BASE + 0x0004)
+/*
+ * Enable reg SPI_SSIENR
+ */
+#define SPI_SSIENR	(PKUNITY_SPI_BASE + 0x0008)
+/*
+ * Status reg SPI_SR
+ */
+#define SPI_SR		(PKUNITY_SPI_BASE + 0x0028)
+/*
+ * Interrupt Mask reg SPI_IMR
+ */
+#define SPI_IMR		(PKUNITY_SPI_BASE + 0x002C)
+/*
+ * Interrupt Status reg SPI_ISR
+ */
+#define SPI_ISR		(PKUNITY_SPI_BASE + 0x0030)
+
+/*
+ * Enable SPI Controller SPI_SSIENR_EN
+ */
+#define SPI_SSIENR_EN		FIELD(1, 1, 0)
+
+/*
+ * SPI Busy SPI_SR_BUSY
+ */
+#define SPI_SR_BUSY		FIELD(1, 1, 0)
+/*
+ * Transmit FIFO Not Full SPI_SR_TFNF
+ */
+#define SPI_SR_TFNF		FIELD(1, 1, 1)
+/*
+ * Transmit FIFO Empty SPI_SR_TFE
+ */
+#define SPI_SR_TFE		FIELD(1, 1, 2)
+/*
+ * Receive FIFO Not Empty SPI_SR_RFNE
+ */
+#define SPI_SR_RFNE		FIELD(1, 1, 3)
+/*
+ * Receive FIFO Full SPI_SR_RFF
+ */
+#define SPI_SR_RFF		FIELD(1, 1, 4)
+
+/*
+ * Trans. FIFO Empty Interrupt Status SPI_ISR_TXEIS
+ */
+#define SPI_ISR_TXEIS		FIELD(1, 1, 0)
+/*
+ * Trans. FIFO Overflow Interrupt Status SPI_ISR_TXOIS
+ */
+#define SPI_ISR_TXOIS		FIELD(1, 1, 1)
+/*
+ * Receiv. FIFO Underflow Interrupt Status SPI_ISR_RXUIS
+ */
+#define SPI_ISR_RXUIS		FIELD(1, 1, 2)
+/*
+ * Receiv. FIFO Overflow Interrupt Status SPI_ISR_RXOIS
+ */
+#define SPI_ISR_RXOIS		FIELD(1, 1, 3)
+/*
+ * Receiv. FIFO Full Interrupt Status SPI_ISR_RXFIS
+ */
+#define SPI_ISR_RXFIS		FIELD(1, 1, 4)
+#define SPI_ISR_MSTIS		FIELD(1, 1, 5)
+
+/*
+ * Trans. FIFO Empty Interrupt Mask SPI_IMR_TXEIM
+ */
+#define SPI_IMR_TXEIM		FIELD(1, 1, 0)
+/*
+ * Trans. FIFO Overflow Interrupt Mask SPI_IMR_TXOIM
+ */
+#define SPI_IMR_TXOIM		FIELD(1, 1, 1)
+/*
+ * Receiv. FIFO Underflow Interrupt Mask SPI_IMR_RXUIM
+ */
+#define SPI_IMR_RXUIM		FIELD(1, 1, 2)
+/*
+ * Receiv. FIFO Overflow Interrupt Mask SPI_IMR_RXOIM
+ */
+#define SPI_IMR_RXOIM		FIELD(1, 1, 3)
+/*
+ * Receiv. FIFO Full Interrupt Mask SPI_IMR_RXFIM
+ */
+#define SPI_IMR_RXFIM		FIELD(1, 1, 4)
+#define SPI_IMR_MSTIM		FIELD(1, 1, 5)
+

+ 3 - 0
arch/unicore32/include/mach/regs-uart.h

@@ -0,0 +1,3 @@
+/*
+ * PKUnity Universal Asynchronous Receiver/Transmitter (UART) Registers
+ */

+ 229 - 0
arch/unicore32/include/mach/regs-umal.h

@@ -0,0 +1,229 @@
+/*
+ * PKUnity Ultra Media Access Layer (UMAL) Ethernet MAC Registers
+ */
+
+/* MAC module of UMAL */
+/* UMAL's MAC module includes G/MII interface, several additional PHY
+ * interfaces, and MAC control sub-layer, which provides support for control
+ * frames (e.g. PAUSE frames).
+ */
+/*
+ * TX/RX reset and control UMAL_CFG1
+ */
+#define UMAL_CFG1		(PKUNITY_UMAL_BASE + 0x0000)
+/*
+ * MAC interface mode control UMAL_CFG2
+ */
+#define UMAL_CFG2		(PKUNITY_UMAL_BASE + 0x0004)
+/*
+ * Inter Packet/Frame Gap UMAL_IPGIFG
+ */
+#define UMAL_IPGIFG		(PKUNITY_UMAL_BASE + 0x0008)
+/*
+ * Collision retry or backoff UMAL_HALFDUPLEX
+ */
+#define UMAL_HALFDUPLEX		(PKUNITY_UMAL_BASE + 0x000c)
+/*
+ * Maximum Frame Length UMAL_MAXFRAME
+ */
+#define UMAL_MAXFRAME		(PKUNITY_UMAL_BASE + 0x0010)
+/*
+ * Test Regsiter UMAL_TESTREG
+ */
+#define UMAL_TESTREG		(PKUNITY_UMAL_BASE + 0x001c)
+/*
+ * MII Management Configure UMAL_MIICFG
+ */
+#define UMAL_MIICFG		(PKUNITY_UMAL_BASE + 0x0020)
+/*
+ * MII Management Command UMAL_MIICMD
+ */
+#define UMAL_MIICMD		(PKUNITY_UMAL_BASE + 0x0024)
+/*
+ * MII Management Address UMAL_MIIADDR
+ */
+#define UMAL_MIIADDR		(PKUNITY_UMAL_BASE + 0x0028)
+/*
+ * MII Management Control UMAL_MIICTRL
+ */
+#define UMAL_MIICTRL		(PKUNITY_UMAL_BASE + 0x002c)
+/*
+ * MII Management Status UMAL_MIISTATUS
+ */
+#define UMAL_MIISTATUS		(PKUNITY_UMAL_BASE + 0x0030)
+/*
+ * MII Managment Indicator UMAL_MIIIDCT
+ */
+#define UMAL_MIIIDCT		(PKUNITY_UMAL_BASE + 0x0034)
+/*
+ * Interface Control UMAL_IFCTRL
+ */
+#define UMAL_IFCTRL		(PKUNITY_UMAL_BASE + 0x0038)
+/*
+ * Interface Status UMAL_IFSTATUS
+ */
+#define UMAL_IFSTATUS		(PKUNITY_UMAL_BASE + 0x003c)
+/*
+ * MAC address (high 4 bytes) UMAL_STADDR1
+ */
+#define UMAL_STADDR1		(PKUNITY_UMAL_BASE + 0x0040)
+/*
+ * MAC address (low 2 bytes) UMAL_STADDR2
+ */
+#define UMAL_STADDR2		(PKUNITY_UMAL_BASE + 0x0044)
+
+/* FIFO MODULE OF UMAL */
+/* UMAL's FIFO module provides data queuing for increased system level
+ * throughput
+ */
+#define UMAL_FIFOCFG0		(PKUNITY_UMAL_BASE + 0x0048)
+#define UMAL_FIFOCFG1		(PKUNITY_UMAL_BASE + 0x004c)
+#define UMAL_FIFOCFG2		(PKUNITY_UMAL_BASE + 0x0050)
+#define UMAL_FIFOCFG3		(PKUNITY_UMAL_BASE + 0x0054)
+#define UMAL_FIFOCFG4		(PKUNITY_UMAL_BASE + 0x0058)
+#define UMAL_FIFOCFG5		(PKUNITY_UMAL_BASE + 0x005c)
+#define UMAL_FIFORAM0		(PKUNITY_UMAL_BASE + 0x0060)
+#define UMAL_FIFORAM1		(PKUNITY_UMAL_BASE + 0x0064)
+#define UMAL_FIFORAM2		(PKUNITY_UMAL_BASE + 0x0068)
+#define UMAL_FIFORAM3		(PKUNITY_UMAL_BASE + 0x006c)
+#define UMAL_FIFORAM4		(PKUNITY_UMAL_BASE + 0x0070)
+#define UMAL_FIFORAM5		(PKUNITY_UMAL_BASE + 0x0074)
+#define UMAL_FIFORAM6		(PKUNITY_UMAL_BASE + 0x0078)
+#define UMAL_FIFORAM7		(PKUNITY_UMAL_BASE + 0x007c)
+
+/* MAHBE MODUEL OF UMAL */
+/* UMAL's MAHBE module interfaces to the host system through 32-bit AHB Master
+ * and Slave ports.Registers within the M-AHBE provide Control and Status
+ * information concerning these transfers.
+ */
+/*
+ * Transmit Control UMAL_DMATxCtrl
+ */
+#define UMAL_DMATxCtrl		(PKUNITY_UMAL_BASE + 0x0180)
+/*
+ * Pointer to TX Descripter UMAL_DMATxDescriptor
+ */
+#define UMAL_DMATxDescriptor	(PKUNITY_UMAL_BASE + 0x0184)
+/*
+ * Status of Tx Packet Transfers UMAL_DMATxStatus
+ */
+#define UMAL_DMATxStatus	(PKUNITY_UMAL_BASE + 0x0188)
+/*
+ * Receive Control UMAL_DMARxCtrl
+ */
+#define UMAL_DMARxCtrl		(PKUNITY_UMAL_BASE + 0x018c)
+/*
+ * Pointer to Rx Descriptor UMAL_DMARxDescriptor
+ */
+#define UMAL_DMARxDescriptor	(PKUNITY_UMAL_BASE + 0x0190)
+/*
+ * Status of Rx Packet Transfers UMAL_DMARxStatus
+ */
+#define UMAL_DMARxStatus	(PKUNITY_UMAL_BASE + 0x0194)
+/*
+ * Interrupt Mask UMAL_DMAIntrMask
+ */
+#define UMAL_DMAIntrMask	(PKUNITY_UMAL_BASE + 0x0198)
+/*
+ * Interrupts, read only UMAL_DMAInterrupt
+ */
+#define UMAL_DMAInterrupt	(PKUNITY_UMAL_BASE + 0x019c)
+
+/*
+ * Commands for UMAL_CFG1 register
+ */
+#define UMAL_CFG1_TXENABLE	FIELD(1, 1, 0)
+#define UMAL_CFG1_RXENABLE	FIELD(1, 1, 2)
+#define UMAL_CFG1_TXFLOWCTL	FIELD(1, 1, 4)
+#define UMAL_CFG1_RXFLOWCTL	FIELD(1, 1, 5)
+#define UMAL_CFG1_CONFLPBK	FIELD(1, 1, 8)
+#define UMAL_CFG1_RESET		FIELD(1, 1, 31)
+#define UMAL_CFG1_CONFFLCTL	(MAC_TX_FLOW_CTL | MAC_RX_FLOW_CTL)
+
+/*
+ * Commands for UMAL_CFG2 register
+ */
+#define UMAL_CFG2_FULLDUPLEX	FIELD(1, 1, 0)
+#define UMAL_CFG2_CRCENABLE	FIELD(1, 1, 1)
+#define UMAL_CFG2_PADCRC	FIELD(1, 1, 2)
+#define UMAL_CFG2_LENGTHCHECK	FIELD(1, 1, 4)
+#define UMAL_CFG2_MODEMASK	FMASK(2, 8)
+#define UMAL_CFG2_NIBBLEMODE	FIELD(1, 2, 8)
+#define UMAL_CFG2_BYTEMODE	FIELD(2, 2, 8)
+#define UMAL_CFG2_PREAMBLENMASK	FMASK(4, 12)
+#define UMAL_CFG2_DEFPREAMBLEN	FIELD(7, 4, 12)
+#define UMAL_CFG2_FD100		(UMAL_CFG2_DEFPREAMBLEN | UMAL_CFG2_NIBBLEMODE \
+				| UMAL_CFG2_LENGTHCHECK | UMAL_CFG2_PADCRC \
+				| UMAL_CFG2_CRCENABLE | UMAL_CFG2_FULLDUPLEX)
+#define UMAL_CFG2_FD1000	(UMAL_CFG2_DEFPREAMBLEN | UMAL_CFG2_BYTEMODE \
+				| UMAL_CFG2_LENGTHCHECK | UMAL_CFG2_PADCRC \
+				| UMAL_CFG2_CRCENABLE | UMAL_CFG2_FULLDUPLEX)
+#define UMAL_CFG2_HD100		(UMAL_CFG2_DEFPREAMBLEN | UMAL_CFG2_NIBBLEMODE \
+				| UMAL_CFG2_LENGTHCHECK | UMAL_CFG2_PADCRC \
+				| UMAL_CFG2_CRCENABLE)
+
+/*
+ * Command for UMAL_IFCTRL register
+ */
+#define UMAL_IFCTRL_RESET	FIELD(1, 1, 31)
+
+/*
+ * Command for UMAL_MIICFG register
+ */
+#define UMAL_MIICFG_RESET	FIELD(1, 1, 31)
+
+/*
+ * Command for UMAL_MIICMD register
+ */
+#define UMAL_MIICMD_READ	FIELD(1, 1, 0)
+
+/*
+ * Command for UMAL_MIIIDCT register
+ */
+#define UMAL_MIIIDCT_BUSY	FIELD(1, 1, 0)
+#define UMAL_MIIIDCT_NOTVALID	FIELD(1, 1, 2)
+
+/*
+ * Commands for DMATxCtrl regesters
+ */
+#define UMAL_DMA_Enable		FIELD(1, 1, 0)
+
+/*
+ * Commands for DMARxCtrl regesters
+ */
+#define UMAL_DMAIntrMask_ENABLEHALFWORD	FIELD(1, 1, 16)
+
+/*
+ * Command for DMARxStatus
+ */
+#define CLR_RX_BUS_ERR		FIELD(1, 1, 3)
+#define CLR_RX_OVERFLOW		FIELD(1, 1, 2)
+#define CLR_RX_PKT		FIELD(1, 1, 0)
+
+/*
+ * Command for DMATxStatus
+ */
+#define CLR_TX_BUS_ERR		FIELD(1, 1, 3)
+#define CLR_TX_UNDERRUN		FIELD(1, 1, 1)
+#define CLR_TX_PKT		FIELD(1, 1, 0)
+
+/*
+ * Commands for DMAIntrMask and DMAInterrupt register
+ */
+#define INT_RX_MASK		FIELD(0xd, 4, 4)
+#define INT_TX_MASK		FIELD(0xb, 4, 0)
+
+#define INT_RX_BUS_ERR		FIELD(1, 1, 7)
+#define INT_RX_OVERFLOW		FIELD(1, 1, 6)
+#define INT_RX_PKT		FIELD(1, 1, 4)
+#define INT_TX_BUS_ERR		FIELD(1, 1, 3)
+#define INT_TX_UNDERRUN		FIELD(1, 1, 1)
+#define INT_TX_PKT		FIELD(1, 1, 0)
+
+/*
+ * MARCOS of UMAL's descriptors
+ */
+#define UMAL_DESC_PACKETSIZE_EMPTY	FIELD(1, 1, 31)
+#define UMAL_DESC_PACKETSIZE_NONEMPTY	FIELD(0, 1, 31)
+#define UMAL_DESC_PACKETSIZE_SIZEMASK	FMASK(12, 0)
+

+ 200 - 0
arch/unicore32/include/mach/regs-unigfx.h

@@ -0,0 +1,200 @@
+/*
+ * PKUnity UNIGFX Registers
+ */
+
+#define UDE_BASE      (PKUNITY_UNIGFX_BASE + 0x1400)
+#define UGE_BASE      (PKUNITY_UNIGFX_BASE + 0x0000)
+
+/*
+ * command reg for UNIGFX DE
+ */
+/*
+ * control reg UDE_CFG
+ */
+#define UDE_CFG       (UDE_BASE + 0x0000)
+/*
+ * framebuffer start address reg UDE_FSA
+ */
+#define UDE_FSA       (UDE_BASE + 0x0004)
+/*
+ * line size reg UDE_LS
+ */
+#define UDE_LS        (UDE_BASE + 0x0008)
+/*
+ * pitch size reg UDE_PS
+ */
+#define UDE_PS        (UDE_BASE + 0x000C)
+/*
+ * horizontal active time reg UDE_HAT
+ */
+#define UDE_HAT       (UDE_BASE + 0x0010)
+/*
+ * horizontal blank time reg UDE_HBT
+ */
+#define UDE_HBT       (UDE_BASE + 0x0014)
+/*
+ * horizontal sync time reg UDE_HST
+ */
+#define UDE_HST       (UDE_BASE + 0x0018)
+/*
+ * vertival active time reg UDE_VAT
+ */
+#define UDE_VAT       (UDE_BASE + 0x001C)
+/*
+ * vertival blank time reg UDE_VBT
+ */
+#define UDE_VBT       (UDE_BASE + 0x0020)
+/*
+ * vertival sync time reg UDE_VST
+ */
+#define UDE_VST       (UDE_BASE + 0x0024)
+/*
+ * cursor position UDE_CXY
+ */
+#define UDE_CXY       (UDE_BASE + 0x0028)
+/*
+ * cursor front color UDE_CC0
+ */
+#define UDE_CC0       (UDE_BASE + 0x002C)
+/*
+ * cursor background color UDE_CC1
+ */
+#define UDE_CC1       (UDE_BASE + 0x0030)
+/*
+ * video position UDE_VXY
+ */
+#define UDE_VXY       (UDE_BASE + 0x0034)
+/*
+ * video start address reg UDE_VSA
+ */
+#define UDE_VSA       (UDE_BASE + 0x0040)
+/*
+ * video size reg UDE_VS
+ */
+#define UDE_VS        (UDE_BASE + 0x004C)
+
+/*
+ * command reg for UNIGFX GE
+ */
+/*
+ * src xy reg UGE_SRCXY
+ */
+#define UGE_SRCXY     (UGE_BASE + 0x0000)
+/*
+ * dst xy reg UGE_DSTXY
+ */
+#define UGE_DSTXY     (UGE_BASE + 0x0004)
+/*
+ * pitch reg UGE_PITCH
+ */
+#define UGE_PITCH     (UGE_BASE + 0x0008)
+/*
+ * src start reg UGE_SRCSTART
+ */
+#define UGE_SRCSTART  (UGE_BASE + 0x000C)
+/*
+ * dst start reg UGE_DSTSTART
+ */
+#define UGE_DSTSTART  (UGE_BASE + 0x0010)
+/*
+ * width height reg UGE_WIDHEIGHT
+ */
+#define UGE_WIDHEIGHT (UGE_BASE + 0x0014)
+/*
+ * rop alpah reg UGE_ROPALPHA
+ */
+#define UGE_ROPALPHA  (UGE_BASE + 0x0018)
+/*
+ * front color UGE_FCOLOR
+ */
+#define UGE_FCOLOR    (UGE_BASE + 0x001C)
+/*
+ * background color UGE_BCOLOR
+ */
+#define UGE_BCOLOR    (UGE_BASE + 0x0020)
+/*
+ * src color key for high value UGE_SCH
+ */
+#define UGE_SCH       (UGE_BASE + 0x0024)
+/*
+ * dst color key for high value UGE_DCH
+ */
+#define UGE_DCH       (UGE_BASE + 0x0028)
+/*
+ * src color key for low value UGE_SCL
+ */
+#define UGE_SCL       (UGE_BASE + 0x002C)
+/*
+ * dst color key for low value UGE_DCL
+ */
+#define UGE_DCL       (UGE_BASE + 0x0030)
+/*
+ * clip 0 reg UGE_CLIP0
+ */
+#define UGE_CLIP0     (UGE_BASE + 0x0034)
+/*
+ * clip 1 reg UGE_CLIP1
+ */
+#define UGE_CLIP1     (UGE_BASE + 0x0038)
+/*
+ * command reg UGE_COMMAND
+ */
+#define UGE_COMMAND   (UGE_BASE + 0x003C)
+/*
+ * pattern 0 UGE_P0
+ */
+#define UGE_P0        (UGE_BASE + 0x0040)
+#define UGE_P1        (UGE_BASE + 0x0044)
+#define UGE_P2        (UGE_BASE + 0x0048)
+#define UGE_P3        (UGE_BASE + 0x004C)
+#define UGE_P4        (UGE_BASE + 0x0050)
+#define UGE_P5        (UGE_BASE + 0x0054)
+#define UGE_P6        (UGE_BASE + 0x0058)
+#define UGE_P7        (UGE_BASE + 0x005C)
+#define UGE_P8        (UGE_BASE + 0x0060)
+#define UGE_P9        (UGE_BASE + 0x0064)
+#define UGE_P10       (UGE_BASE + 0x0068)
+#define UGE_P11       (UGE_BASE + 0x006C)
+#define UGE_P12       (UGE_BASE + 0x0070)
+#define UGE_P13       (UGE_BASE + 0x0074)
+#define UGE_P14       (UGE_BASE + 0x0078)
+#define UGE_P15       (UGE_BASE + 0x007C)
+#define UGE_P16       (UGE_BASE + 0x0080)
+#define UGE_P17       (UGE_BASE + 0x0084)
+#define UGE_P18       (UGE_BASE + 0x0088)
+#define UGE_P19       (UGE_BASE + 0x008C)
+#define UGE_P20       (UGE_BASE + 0x0090)
+#define UGE_P21       (UGE_BASE + 0x0094)
+#define UGE_P22       (UGE_BASE + 0x0098)
+#define UGE_P23       (UGE_BASE + 0x009C)
+#define UGE_P24       (UGE_BASE + 0x00A0)
+#define UGE_P25       (UGE_BASE + 0x00A4)
+#define UGE_P26       (UGE_BASE + 0x00A8)
+#define UGE_P27       (UGE_BASE + 0x00AC)
+#define UGE_P28       (UGE_BASE + 0x00B0)
+#define UGE_P29       (UGE_BASE + 0x00B4)
+#define UGE_P30       (UGE_BASE + 0x00B8)
+#define UGE_P31       (UGE_BASE + 0x00BC)
+
+#define UDE_CFG_DST_MASK	FMASK(2, 8)
+#define UDE_CFG_DST8            FIELD(0x0, 2, 8)
+#define UDE_CFG_DST16           FIELD(0x1, 2, 8)
+#define UDE_CFG_DST24           FIELD(0x2, 2, 8)
+#define UDE_CFG_DST32           FIELD(0x3, 2, 8)
+
+/*
+ * GDEN enable UDE_CFG_GDEN_ENABLE
+ */
+#define UDE_CFG_GDEN_ENABLE     FIELD(1, 1, 3)
+/*
+ * VDEN enable UDE_CFG_VDEN_ENABLE
+ */
+#define UDE_CFG_VDEN_ENABLE     FIELD(1, 1, 4)
+/*
+ * CDEN enable UDE_CFG_CDEN_ENABLE
+ */
+#define UDE_CFG_CDEN_ENABLE     FIELD(1, 1, 5)
+/*
+ * TIMEUP enable UDE_CFG_TIMEUP_ENABLE
+ */
+#define UDE_CFG_TIMEUP_ENABLE   FIELD(1, 1, 6)

+ 34 - 0
arch/unicore32/include/mach/uncompress.h

@@ -0,0 +1,34 @@
+/*
+ * linux/arch/unicore32/include/mach/uncompress.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+
+#ifndef __MACH_PUV3_UNCOMPRESS_H__
+#define __MACH_PUV3_UNCOMPRESS_H__
+
+#include "hardware.h"
+#include "ocd.h"
+
+extern char input_data[];
+extern char input_data_end[];
+
+static void arch_decomp_puts(const char *ptr)
+{
+	char c;
+
+	while ((c = *ptr++) != '\0') {
+		if (c == '\n')
+			putc('\r');
+		putc(c);
+	}
+}
+#define ARCH_HAVE_DECOMP_PUTS
+
+#endif /* __MACH_PUV3_UNCOMPRESS_H__ */

+ 33 - 0
arch/unicore32/kernel/Makefile

@@ -0,0 +1,33 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+obj-y				:= dma.o elf.o entry.o process.o ptrace.o
+obj-y				+= setup.o signal.o sys.o stacktrace.o traps.o
+
+obj-$(CONFIG_MODULES)		+= ksyms.o module.o
+obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
+
+obj-$(CONFIG_CPU_FREQ)		+= cpu-ucv2.o
+obj-$(CONFIG_UNICORE_FPU_F64)	+= fpu-ucf64.o
+
+# obj-y for architecture PKUnity v3
+obj-$(CONFIG_ARCH_PUV3)		+= clock.o irq.o time.o
+
+obj-$(CONFIG_PUV3_GPIO)		+= gpio.o
+obj-$(CONFIG_PUV3_RTC)		+= rtc.o
+obj-$(CONFIG_PUV3_PWM)		+= pwm.o
+obj-$(CONFIG_PUV3_PM)		+= pm.o sleep.o
+obj-$(CONFIG_HIBERNATION)	+= hibernate.o hibernate_asm.o
+
+obj-$(CONFIG_PCI)		+= pci.o
+
+# obj-y for specific machines
+obj-$(CONFIG_ARCH_PUV3)		+= puv3-core.o
+obj-$(CONFIG_PUV3_NB0916)	+= puv3-nb0916.o
+
+head-y				:= head.o
+obj-$(CONFIG_DEBUG_LL)		+= debug.o
+
+extra-y				:= $(head-y) init_task.o vmlinux.lds

+ 112 - 0
arch/unicore32/kernel/asm-offsets.c

@@ -0,0 +1,112 @@
+/*
+ * linux/arch/unicore32/kernel/asm-offsets.c
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed to extract
+ * and format the required data.
+ *
+ * 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/sched.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/kbuild.h>
+#include <linux/suspend.h>
+#include <linux/thread_info.h>
+#include <asm/memory.h>
+#include <asm/suspend.h>
+
+/*
+ * GCC 3.0, 3.1: general bad code generation.
+ * GCC 3.2.0: incorrect function argument offset calculation.
+ * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c
+ *	(http://gcc.gnu.org/PR8896) and incorrect structure
+ *		initialisation in fs/jffs2/erase.c
+ */
+#if (__GNUC__ < 4)
+#error Your compiler should upgrade to uc4
+#error	Known good compilers: 4.2.2
+#endif
+
+int main(void)
+{
+	DEFINE(TSK_ACTIVE_MM,	offsetof(struct task_struct, active_mm));
+	BLANK();
+	DEFINE(TI_FLAGS,	offsetof(struct thread_info, flags));
+	DEFINE(TI_PREEMPT,	offsetof(struct thread_info, preempt_count));
+	DEFINE(TI_ADDR_LIMIT,	offsetof(struct thread_info, addr_limit));
+	DEFINE(TI_TASK,		offsetof(struct thread_info, task));
+	DEFINE(TI_EXEC_DOMAIN,	offsetof(struct thread_info, exec_domain));
+	DEFINE(TI_CPU,		offsetof(struct thread_info, cpu));
+	DEFINE(TI_CPU_SAVE,	offsetof(struct thread_info, cpu_context));
+	DEFINE(TI_USED_CP,	offsetof(struct thread_info, used_cp));
+#ifdef CONFIG_UNICORE_FPU_F64
+	DEFINE(TI_FPSTATE,	offsetof(struct thread_info, fpstate));
+#endif
+	BLANK();
+	DEFINE(S_R0,		offsetof(struct pt_regs, UCreg_00));
+	DEFINE(S_R1,		offsetof(struct pt_regs, UCreg_01));
+	DEFINE(S_R2,		offsetof(struct pt_regs, UCreg_02));
+	DEFINE(S_R3,		offsetof(struct pt_regs, UCreg_03));
+	DEFINE(S_R4,		offsetof(struct pt_regs, UCreg_04));
+	DEFINE(S_R5,		offsetof(struct pt_regs, UCreg_05));
+	DEFINE(S_R6,		offsetof(struct pt_regs, UCreg_06));
+	DEFINE(S_R7,		offsetof(struct pt_regs, UCreg_07));
+	DEFINE(S_R8,		offsetof(struct pt_regs, UCreg_08));
+	DEFINE(S_R9,		offsetof(struct pt_regs, UCreg_09));
+	DEFINE(S_R10,		offsetof(struct pt_regs, UCreg_10));
+	DEFINE(S_R11,		offsetof(struct pt_regs, UCreg_11));
+	DEFINE(S_R12,		offsetof(struct pt_regs, UCreg_12));
+	DEFINE(S_R13,		offsetof(struct pt_regs, UCreg_13));
+	DEFINE(S_R14,		offsetof(struct pt_regs, UCreg_14));
+	DEFINE(S_R15,		offsetof(struct pt_regs, UCreg_15));
+	DEFINE(S_R16,		offsetof(struct pt_regs, UCreg_16));
+	DEFINE(S_R17,		offsetof(struct pt_regs, UCreg_17));
+	DEFINE(S_R18,		offsetof(struct pt_regs, UCreg_18));
+	DEFINE(S_R19,		offsetof(struct pt_regs, UCreg_19));
+	DEFINE(S_R20,		offsetof(struct pt_regs, UCreg_20));
+	DEFINE(S_R21,		offsetof(struct pt_regs, UCreg_21));
+	DEFINE(S_R22,		offsetof(struct pt_regs, UCreg_22));
+	DEFINE(S_R23,		offsetof(struct pt_regs, UCreg_23));
+	DEFINE(S_R24,		offsetof(struct pt_regs, UCreg_24));
+	DEFINE(S_R25,		offsetof(struct pt_regs, UCreg_25));
+	DEFINE(S_R26,		offsetof(struct pt_regs, UCreg_26));
+	DEFINE(S_FP,		offsetof(struct pt_regs, UCreg_fp));
+	DEFINE(S_IP,		offsetof(struct pt_regs, UCreg_ip));
+	DEFINE(S_SP,		offsetof(struct pt_regs, UCreg_sp));
+	DEFINE(S_LR,		offsetof(struct pt_regs, UCreg_lr));
+	DEFINE(S_PC,		offsetof(struct pt_regs, UCreg_pc));
+	DEFINE(S_PSR,		offsetof(struct pt_regs, UCreg_asr));
+	DEFINE(S_OLD_R0,	offsetof(struct pt_regs, UCreg_ORIG_00));
+	DEFINE(S_FRAME_SIZE,	sizeof(struct pt_regs));
+	BLANK();
+	DEFINE(VMA_VM_MM,	offsetof(struct vm_area_struct, vm_mm));
+	DEFINE(VMA_VM_FLAGS,	offsetof(struct vm_area_struct, vm_flags));
+	BLANK();
+	DEFINE(VM_EXEC,		VM_EXEC);
+	BLANK();
+	DEFINE(PAGE_SZ,		PAGE_SIZE);
+	BLANK();
+	DEFINE(SYS_ERROR0,	0x9f0000);
+	BLANK();
+	DEFINE(PBE_ADDRESS,		offsetof(struct pbe, address));
+	DEFINE(PBE_ORIN_ADDRESS,	offsetof(struct pbe, orig_address));
+	DEFINE(PBE_NEXT,		offsetof(struct pbe, next));
+	DEFINE(SWSUSP_CPU,		offsetof(struct swsusp_arch_regs, \
+							cpu_context));
+#ifdef	CONFIG_UNICORE_FPU_F64
+	DEFINE(SWSUSP_FPSTATE,		offsetof(struct swsusp_arch_regs, \
+							fpstate));
+#endif
+	BLANK();
+	DEFINE(DMA_BIDIRECTIONAL,	DMA_BIDIRECTIONAL);
+	DEFINE(DMA_TO_DEVICE,		DMA_TO_DEVICE);
+	DEFINE(DMA_FROM_DEVICE,		DMA_FROM_DEVICE);
+	return 0;
+}

+ 390 - 0
arch/unicore32/kernel/clock.c

@@ -0,0 +1,390 @@
+/*
+ * linux/arch/unicore32/kernel/clock.c
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
+ *	Copyright (C) 2001-2010 Guan Xuetao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+/*
+ * Very simple clock implementation
+ */
+struct clk {
+	struct list_head	node;
+	unsigned long		rate;
+	const char		*name;
+};
+
+static struct clk clk_ost_clk = {
+	.name		= "OST_CLK",
+	.rate		= CLOCK_TICK_RATE,
+};
+
+static struct clk clk_mclk_clk = {
+	.name		= "MAIN_CLK",
+};
+
+static struct clk clk_bclk32_clk = {
+	.name		= "BUS32_CLK",
+};
+
+static struct clk clk_ddr_clk = {
+	.name		= "DDR_CLK",
+};
+
+static struct clk clk_vga_clk = {
+	.name		= "VGA_CLK",
+};
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	struct clk *p, *clk = ERR_PTR(-ENOENT);
+
+	mutex_lock(&clocks_mutex);
+	list_for_each_entry(p, &clocks, node) {
+		if (strcmp(id, p->name) == 0) {
+			clk = p;
+			break;
+		}
+	}
+	mutex_unlock(&clocks_mutex);
+
+	return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+struct {
+	unsigned long rate;
+	unsigned long cfg;
+	unsigned long div;
+} vga_clk_table[] = {
+	{.rate =  25175000, .cfg = 0x00002001, .div = 0x9},
+	{.rate =  31500000, .cfg = 0x00002001, .div = 0x7},
+	{.rate =  40000000, .cfg = 0x00003801, .div = 0x9},
+	{.rate =  49500000, .cfg = 0x00003801, .div = 0x7},
+	{.rate =  65000000, .cfg = 0x00002c01, .div = 0x4},
+	{.rate =  78750000, .cfg = 0x00002400, .div = 0x7},
+	{.rate = 108000000, .cfg = 0x00002c01, .div = 0x2},
+	{.rate = 106500000, .cfg = 0x00003c01, .div = 0x3},
+	{.rate =  50650000, .cfg = 0x00106400, .div = 0x9},
+	{.rate =  61500000, .cfg = 0x00106400, .div = 0xa},
+	{.rate =  85500000, .cfg = 0x00002800, .div = 0x6},
+};
+
+struct {
+	unsigned long mrate;
+	unsigned long prate;
+} mclk_clk_table[] = {
+	{.mrate = 500000000, .prate = 0x00109801},
+	{.mrate = 525000000, .prate = 0x00104C00},
+	{.mrate = 550000000, .prate = 0x00105000},
+	{.mrate = 575000000, .prate = 0x00105400},
+	{.mrate = 600000000, .prate = 0x00105800},
+	{.mrate = 625000000, .prate = 0x00105C00},
+	{.mrate = 650000000, .prate = 0x00106000},
+	{.mrate = 675000000, .prate = 0x00106400},
+	{.mrate = 700000000, .prate = 0x00106800},
+	{.mrate = 725000000, .prate = 0x00106C00},
+	{.mrate = 750000000, .prate = 0x00107000},
+	{.mrate = 775000000, .prate = 0x00107400},
+	{.mrate = 800000000, .prate = 0x00107800},
+};
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	if (clk == &clk_vga_clk) {
+		unsigned long pll_vgacfg, pll_vgadiv;
+		int ret, i;
+
+		/* lookup vga_clk_table */
+		ret = -EINVAL;
+		for (i = 0; i < ARRAY_SIZE(vga_clk_table); i++) {
+			if (rate == vga_clk_table[i].rate) {
+				pll_vgacfg = vga_clk_table[i].cfg;
+				pll_vgadiv = vga_clk_table[i].div;
+				ret = 0;
+				break;
+			}
+		}
+
+		if (ret)
+			return ret;
+
+		if (readl(PM_PLLVGACFG) == pll_vgacfg)
+			return 0;
+
+		/* set pll vga cfg reg. */
+		writel(pll_vgacfg, PM_PLLVGACFG);
+
+		writel(PM_PMCR_CFBVGA, PM_PMCR);
+		while ((readl(PM_PLLDFCDONE) & PM_PLLDFCDONE_VGADFC)
+				!= PM_PLLDFCDONE_VGADFC)
+			udelay(100); /* about 1ms */
+
+		/* set div cfg reg. */
+		writel(readl(PM_PCGR) | PM_PCGR_VGACLK, PM_PCGR);
+
+		writel((readl(PM_DIVCFG) & ~PM_DIVCFG_VGACLK_MASK)
+				| PM_DIVCFG_VGACLK(pll_vgadiv), PM_DIVCFG);
+
+		writel(readl(PM_SWRESET) | PM_SWRESET_VGADIV, PM_SWRESET);
+		while ((readl(PM_SWRESET) & PM_SWRESET_VGADIV)
+				== PM_SWRESET_VGADIV)
+			udelay(100); /* 65536 bclk32, about 320us */
+
+		writel(readl(PM_PCGR) & ~PM_PCGR_VGACLK, PM_PCGR);
+	}
+#ifdef CONFIG_CPU_FREQ
+	if (clk == &clk_mclk_clk) {
+		u32 pll_rate, divstatus = PM_DIVSTATUS;
+		int ret, i;
+
+		/* lookup mclk_clk_table */
+		ret = -EINVAL;
+		for (i = 0; i < ARRAY_SIZE(mclk_clk_table); i++) {
+			if (rate == mclk_clk_table[i].mrate) {
+				pll_rate = mclk_clk_table[i].prate;
+				clk_mclk_clk.rate = mclk_clk_table[i].mrate;
+				ret = 0;
+				break;
+			}
+		}
+
+		if (ret)
+			return ret;
+
+		if (clk_mclk_clk.rate)
+			clk_bclk32_clk.rate = clk_mclk_clk.rate
+				/ (((divstatus & 0x0000f000) >> 12) + 1);
+
+		/* set pll sys cfg reg. */
+		PM_PLLSYSCFG = pll_rate;
+
+		PM_PMCR = PM_PMCR_CFBSYS;
+		while ((PM_PLLDFCDONE & PM_PLLDFCDONE_SYSDFC)
+				!= PM_PLLDFCDONE_SYSDFC)
+			udelay(100);
+			/* about 1ms */
+	}
+#endif
+	return 0;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_register(struct clk *clk)
+{
+	mutex_lock(&clocks_mutex);
+	list_add(&clk->node, &clocks);
+	mutex_unlock(&clocks_mutex);
+	printk(KERN_DEFAULT "PKUnity PM: %s %lu.%02luM\n", clk->name,
+		(clk->rate)/1000000, (clk->rate)/10000 % 100);
+	return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister(struct clk *clk)
+{
+	mutex_lock(&clocks_mutex);
+	list_del(&clk->node);
+	mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+struct {
+	unsigned long prate;
+	unsigned long rate;
+} pllrate_table[] = {
+	{.prate = 0x00002001, .rate = 250000000},
+	{.prate = 0x00104801, .rate = 250000000},
+	{.prate = 0x00104C01, .rate = 262500000},
+	{.prate = 0x00002401, .rate = 275000000},
+	{.prate = 0x00105001, .rate = 275000000},
+	{.prate = 0x00105401, .rate = 287500000},
+	{.prate = 0x00002801, .rate = 300000000},
+	{.prate = 0x00105801, .rate = 300000000},
+	{.prate = 0x00105C01, .rate = 312500000},
+	{.prate = 0x00002C01, .rate = 325000000},
+	{.prate = 0x00106001, .rate = 325000000},
+	{.prate = 0x00106401, .rate = 337500000},
+	{.prate = 0x00003001, .rate = 350000000},
+	{.prate = 0x00106801, .rate = 350000000},
+	{.prate = 0x00106C01, .rate = 362500000},
+	{.prate = 0x00003401, .rate = 375000000},
+	{.prate = 0x00107001, .rate = 375000000},
+	{.prate = 0x00107401, .rate = 387500000},
+	{.prate = 0x00003801, .rate = 400000000},
+	{.prate = 0x00107801, .rate = 400000000},
+	{.prate = 0x00107C01, .rate = 412500000},
+	{.prate = 0x00003C01, .rate = 425000000},
+	{.prate = 0x00108001, .rate = 425000000},
+	{.prate = 0x00108401, .rate = 437500000},
+	{.prate = 0x00004001, .rate = 450000000},
+	{.prate = 0x00108801, .rate = 450000000},
+	{.prate = 0x00108C01, .rate = 462500000},
+	{.prate = 0x00004401, .rate = 475000000},
+	{.prate = 0x00109001, .rate = 475000000},
+	{.prate = 0x00109401, .rate = 487500000},
+	{.prate = 0x00004801, .rate = 500000000},
+	{.prate = 0x00109801, .rate = 500000000},
+	{.prate = 0x00104C00, .rate = 525000000},
+	{.prate = 0x00002400, .rate = 550000000},
+	{.prate = 0x00105000, .rate = 550000000},
+	{.prate = 0x00105400, .rate = 575000000},
+	{.prate = 0x00002800, .rate = 600000000},
+	{.prate = 0x00105800, .rate = 600000000},
+	{.prate = 0x00105C00, .rate = 625000000},
+	{.prate = 0x00002C00, .rate = 650000000},
+	{.prate = 0x00106000, .rate = 650000000},
+	{.prate = 0x00106400, .rate = 675000000},
+	{.prate = 0x00003000, .rate = 700000000},
+	{.prate = 0x00106800, .rate = 700000000},
+	{.prate = 0x00106C00, .rate = 725000000},
+	{.prate = 0x00003400, .rate = 750000000},
+	{.prate = 0x00107000, .rate = 750000000},
+	{.prate = 0x00107400, .rate = 775000000},
+	{.prate = 0x00003800, .rate = 800000000},
+	{.prate = 0x00107800, .rate = 800000000},
+	{.prate = 0x00107C00, .rate = 825000000},
+	{.prate = 0x00003C00, .rate = 850000000},
+	{.prate = 0x00108000, .rate = 850000000},
+	{.prate = 0x00108400, .rate = 875000000},
+	{.prate = 0x00004000, .rate = 900000000},
+	{.prate = 0x00108800, .rate = 900000000},
+	{.prate = 0x00108C00, .rate = 925000000},
+	{.prate = 0x00004400, .rate = 950000000},
+	{.prate = 0x00109000, .rate = 950000000},
+	{.prate = 0x00109400, .rate = 975000000},
+	{.prate = 0x00004800, .rate = 1000000000},
+	{.prate = 0x00109800, .rate = 1000000000},
+};
+
+struct {
+	unsigned long prate;
+	unsigned long drate;
+} pddr_table[] = {
+	{.prate = 0x00100800, .drate = 44236800},
+	{.prate = 0x00100C00, .drate = 66355200},
+	{.prate = 0x00101000, .drate = 88473600},
+	{.prate = 0x00101400, .drate = 110592000},
+	{.prate = 0x00101800, .drate = 132710400},
+	{.prate = 0x00101C01, .drate = 154828800},
+	{.prate = 0x00102001, .drate = 176947200},
+	{.prate = 0x00102401, .drate = 199065600},
+	{.prate = 0x00102801, .drate = 221184000},
+	{.prate = 0x00102C01, .drate = 243302400},
+	{.prate = 0x00103001, .drate = 265420800},
+	{.prate = 0x00103401, .drate = 287539200},
+	{.prate = 0x00103801, .drate = 309657600},
+	{.prate = 0x00103C01, .drate = 331776000},
+	{.prate = 0x00104001, .drate = 353894400},
+};
+
+static int __init clk_init(void)
+{
+#ifdef CONFIG_PUV3_PM
+	u32 pllrate, divstatus = readl(PM_DIVSTATUS);
+	u32 pcgr_val = readl(PM_PCGR);
+	int i;
+
+	pcgr_val |= PM_PCGR_BCLKMME | PM_PCGR_BCLKH264E | PM_PCGR_BCLKH264D
+			| PM_PCGR_HECLK | PM_PCGR_HDCLK;
+	writel(pcgr_val, PM_PCGR);
+
+	pllrate = readl(PM_PLLSYSSTATUS);
+
+	/* lookup pmclk_table */
+	clk_mclk_clk.rate = 0;
+	for (i = 0; i < ARRAY_SIZE(pllrate_table); i++) {
+		if (pllrate == pllrate_table[i].prate) {
+			clk_mclk_clk.rate = pllrate_table[i].rate;
+			break;
+		}
+	}
+
+	if (clk_mclk_clk.rate)
+		clk_bclk32_clk.rate = clk_mclk_clk.rate /
+			(((divstatus & 0x0000f000) >> 12) + 1);
+
+	pllrate = readl(PM_PLLDDRSTATUS);
+
+	/* lookup pddr_table */
+	clk_ddr_clk.rate = 0;
+	for (i = 0; i < ARRAY_SIZE(pddr_table); i++) {
+		if (pllrate == pddr_table[i].prate) {
+			clk_ddr_clk.rate = pddr_table[i].drate;
+			break;
+		}
+	}
+
+	pllrate = readl(PM_PLLVGASTATUS);
+
+	/* lookup pvga_table */
+	clk_vga_clk.rate = 0;
+	for (i = 0; i < ARRAY_SIZE(pllrate_table); i++) {
+		if (pllrate == pllrate_table[i].prate) {
+			clk_vga_clk.rate = pllrate_table[i].rate;
+			break;
+		}
+	}
+
+	if (clk_vga_clk.rate)
+		clk_vga_clk.rate = clk_vga_clk.rate /
+			(((divstatus & 0x00f00000) >> 20) + 1);
+
+	clk_register(&clk_vga_clk);
+#endif
+#ifdef CONFIG_ARCH_FPGA
+	clk_ddr_clk.rate = 33000000;
+	clk_mclk_clk.rate = 33000000;
+	clk_bclk32_clk.rate = 33000000;
+#endif
+	clk_register(&clk_ddr_clk);
+	clk_register(&clk_mclk_clk);
+	clk_register(&clk_bclk32_clk);
+	clk_register(&clk_ost_clk);
+	return 0;
+}
+core_initcall(clk_init);

+ 93 - 0
arch/unicore32/kernel/cpu-ucv2.c

@@ -0,0 +1,93 @@
+/*
+ * linux/arch/unicore32/kernel/cpu-ucv2.c: clock scaling for the UniCore-II
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
+ *	Copyright (C) 2001-2010 Guan Xuetao
+ *
+ * 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/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+
+#include <mach/hardware.h>
+
+static struct cpufreq_driver ucv2_driver;
+
+/* make sure that only the "userspace" governor is run
+ * -- anything else wouldn't make sense on this platform, anyway.
+ */
+int ucv2_verify_speed(struct cpufreq_policy *policy)
+{
+	if (policy->cpu)
+		return -EINVAL;
+
+	cpufreq_verify_within_limits(policy,
+			policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
+
+	return 0;
+}
+
+static unsigned int ucv2_getspeed(unsigned int cpu)
+{
+	struct clk *mclk = clk_get(NULL, "MAIN_CLK");
+
+	if (cpu)
+		return 0;
+	return clk_get_rate(mclk)/1000;
+}
+
+static int ucv2_target(struct cpufreq_policy *policy,
+			 unsigned int target_freq,
+			 unsigned int relation)
+{
+	unsigned int cur = ucv2_getspeed(0);
+	struct cpufreq_freqs freqs;
+	struct clk *mclk = clk_get(NULL, "MAIN_CLK");
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	if (!clk_set_rate(mclk, target_freq * 1000)) {
+		freqs.old = cur;
+		freqs.new = target_freq;
+		freqs.cpu = 0;
+	}
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	return 0;
+}
+
+static int __init ucv2_cpu_init(struct cpufreq_policy *policy)
+{
+	if (policy->cpu != 0)
+		return -EINVAL;
+	policy->cur = ucv2_getspeed(0);
+	policy->min = policy->cpuinfo.min_freq = 250000;
+	policy->max = policy->cpuinfo.max_freq = 1000000;
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	return 0;
+}
+
+static struct cpufreq_driver ucv2_driver = {
+	.flags		= CPUFREQ_STICKY,
+	.verify		= ucv2_verify_speed,
+	.target		= ucv2_target,
+	.get		= ucv2_getspeed,
+	.init		= ucv2_cpu_init,
+	.name		= "UniCore-II",
+};
+
+static int __init ucv2_cpufreq_init(void)
+{
+	return cpufreq_register_driver(&ucv2_driver);
+}
+
+arch_initcall(ucv2_cpufreq_init);

+ 89 - 0
arch/unicore32/kernel/debug-macro.S

@@ -0,0 +1,89 @@
+/*
+ * linux/arch/unicore32/kernel/debug-macro.S
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ *
+ * Debugging macro include header
+ */
+#include <generated/asm-offsets.h>
+#include <mach/hardware.h>
+
+		.macro	put_word_ocd, rd, rx=r16
+1001:		movc		\rx, p1.c0, #0
+		cand.a	\rx, #2
+		bne	1001b
+		movc		p1.c1, \rd, #1
+		.endm
+
+#ifdef CONFIG_DEBUG_OCD
+		/* debug using UniCore On-Chip-Debugger */
+		.macro	addruart, rx
+		.endm
+
+		.macro	senduart, rd, rx
+		put_word_ocd	\rd, \rx
+		.endm
+
+		.macro	busyuart, rd, rx
+		.endm
+
+		.macro	waituart, rd, rx
+		.endm
+#else
+#define UART_CLK_DEFAULT        3686400 * 20
+	/* Uartclk = MCLK/ 2, The MCLK on my board is 3686400 * 40  */
+#define BAUD_RATE_DEFAULT	115200
+	/* The baud rate of the serial port */
+
+#define UART_DIVISOR_DEFAULT	(UART_CLK_DEFAULT \
+				/ (16 * BAUD_RATE_DEFAULT) - 1)
+
+		.macro	addruart,rx
+		mrc	p0, #0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0xee000000	@ physical base address
+		movne	\rx, #0x6e000000	@ virtual address
+
+		@ We probe for the active serial port here
+		@ However, now we assume UART0 is active:	epip4d
+		@ We assume r1 and r2 can be clobbered.
+
+		movl 	r2, #UART_DIVISOR_DEFAULT
+		mov 	r1, #0x80
+		str	r1, [\rx, #UART_LCR_OFFSET]
+		and	r1, r2, #0xff00
+		mov	r1, r1, lsr #8
+		str	r1, [\rx, #UART_DLH_OFFSET]
+		and	r1, r2, #0xff
+		str	r1, [\rx, #UART_DLL_OFFSET]
+		mov 	r1, #0x7
+		str	r1, [\rx, #UART_FCR_OFFSET]
+		mov 	r1, #0x3
+		str	r1, [\rx, #UART_LCR_OFFSET]
+		mov 	r1, #0x0
+		str	r1, [\rx, #UART_IER_OFFSET]
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #UART_THR_OFFSET]
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #UART_LSR_OFFSET]
+		tst	\rd, #UART_LSR_THRE
+		beq	1001b
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #UART_LSR_OFFSET]
+		tst	\rd, #UART_LSR_TEMT
+		bne	1001b
+		.endm
+#endif
+

+ 85 - 0
arch/unicore32/kernel/debug.S

@@ -0,0 +1,85 @@
+/*
+ * linux/arch/unicore32/kernel/debug.S
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ *
+ *  32-bit debugging code
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+		.text
+
+/*
+ * Some debugging routines (useful if you've got MM problems and
+ * printk isn't working).  For DEBUGGING ONLY!!!  Do not leave
+ * references to these in a production kernel!
+ */
+#include "debug-macro.S"
+
+/*
+ * Useful debugging routines
+ */
+ENTRY(printhex8)
+		mov	r1, #8
+		b	printhex
+ENDPROC(printhex8)
+
+ENTRY(printhex4)
+		mov	r1, #4
+		b	printhex
+ENDPROC(printhex4)
+
+ENTRY(printhex2)
+		mov	r1, #2
+printhex:	adr	r2, hexbuf
+		add	r3, r2, r1
+		mov	r1, #0
+		stb	r1, [r3]
+1:		and	r1, r0, #15
+		mov	r0, r0 >> #4
+		csub.a	r1, #10
+		beg	2f
+		add	r1, r1, #'0' - 'a' + 10
+2:		add	r1, r1, #'a' - 10
+		stb.w	r1, [r3+], #-1
+		cxor.a	r3, r2
+		bne	1b
+		mov	r0, r2
+		b	printascii
+ENDPROC(printhex2)
+
+		.ltorg
+
+ENTRY(printascii)
+		addruart r3
+		b	2f
+1:		waituart r2, r3
+		senduart r1, r3
+		busyuart r2, r3
+		cxor.a	r1, #'\n'
+		cmoveq	r1, #'\r'
+		beq	1b
+2:		cxor.a	r0, #0
+		beq	3f
+		ldb.w	r1, [r0]+, #1
+		cxor.a	r1, #0
+		bne	1b
+3:		mov	pc, lr
+ENDPROC(printascii)
+
+ENTRY(printch)
+		addruart r3
+		mov	r1, r0
+		mov	r0, #0
+		b	1b
+ENDPROC(printch)
+
+hexbuf:		.space 16
+

+ 183 - 0
arch/unicore32/kernel/dma.c

@@ -0,0 +1,183 @@
+/*
+ * linux/arch/unicore32/kernel/dma.c
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
+ *	Copyright (C) 2001-2010 Guan Xuetao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <mach/dma.h>
+
+struct dma_channel {
+	char *name;
+	puv3_dma_prio prio;
+	void (*irq_handler)(int, void *);
+	void (*err_handler)(int, void *);
+	void *data;
+};
+
+static struct dma_channel dma_channels[MAX_DMA_CHANNELS];
+
+int puv3_request_dma(char *name, puv3_dma_prio prio,
+			 void (*irq_handler)(int, void *),
+			 void (*err_handler)(int, void *),
+			 void *data)
+{
+	unsigned long flags;
+	int i, found = 0;
+
+	/* basic sanity checks */
+	if (!name)
+		return -EINVAL;
+
+	local_irq_save(flags);
+
+	do {
+		/* try grabbing a DMA channel with the requested priority */
+		for (i = 0; i < MAX_DMA_CHANNELS; i++) {
+			if ((dma_channels[i].prio == prio) &&
+			    !dma_channels[i].name) {
+				found = 1;
+				break;
+			}
+		}
+		/* if requested prio group is full, try a hier priority */
+	} while (!found && prio--);
+
+	if (found) {
+		dma_channels[i].name = name;
+		dma_channels[i].irq_handler = irq_handler;
+		dma_channels[i].err_handler = err_handler;
+		dma_channels[i].data = data;
+	} else {
+		printk(KERN_WARNING "No more available DMA channels for %s\n",
+				name);
+		i = -ENODEV;
+	}
+
+	local_irq_restore(flags);
+	return i;
+}
+EXPORT_SYMBOL(puv3_request_dma);
+
+void puv3_free_dma(int dma_ch)
+{
+	unsigned long flags;
+
+	if (!dma_channels[dma_ch].name) {
+		printk(KERN_CRIT
+			"%s: trying to free channel %d which is already freed\n",
+			__func__, dma_ch);
+		return;
+	}
+
+	local_irq_save(flags);
+	dma_channels[dma_ch].name = NULL;
+	dma_channels[dma_ch].err_handler = NULL;
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(puv3_free_dma);
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
+{
+	int i, dint;
+
+	dint = readl(DMAC_ITCSR);
+	for (i = 0; i < MAX_DMA_CHANNELS; i++) {
+		if (dint & DMAC_CHANNEL(i)) {
+			struct dma_channel *channel = &dma_channels[i];
+
+			/* Clear TC interrupt of channel i */
+			writel(DMAC_CHANNEL(i), DMAC_ITCCR);
+			writel(0, DMAC_ITCCR);
+
+			if (channel->name && channel->irq_handler) {
+				channel->irq_handler(i, channel->data);
+			} else {
+				/*
+				 * IRQ for an unregistered DMA channel:
+				 * let's clear the interrupts and disable it.
+				 */
+				printk(KERN_WARNING "spurious IRQ for"
+						" DMA channel %d\n", i);
+			}
+		}
+	}
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t dma_err_handler(int irq, void *dev_id)
+{
+	int i, dint;
+
+	dint = readl(DMAC_IESR);
+	for (i = 0; i < MAX_DMA_CHANNELS; i++) {
+		if (dint & DMAC_CHANNEL(i)) {
+			struct dma_channel *channel = &dma_channels[i];
+
+			/* Clear Err interrupt of channel i */
+			writel(DMAC_CHANNEL(i), DMAC_IECR);
+			writel(0, DMAC_IECR);
+
+			if (channel->name && channel->err_handler) {
+				channel->err_handler(i, channel->data);
+			} else {
+				/*
+				 * IRQ for an unregistered DMA channel:
+				 * let's clear the interrupts and disable it.
+				 */
+				printk(KERN_WARNING "spurious IRQ for"
+						" DMA channel %d\n", i);
+			}
+		}
+	}
+	return IRQ_HANDLED;
+}
+
+int __init puv3_init_dma(void)
+{
+	int i, ret;
+
+	/* dma channel priorities on v8 processors:
+	 * ch 0 - 1  <--> (0) DMA_PRIO_HIGH
+	 * ch 2 - 3  <--> (1) DMA_PRIO_MEDIUM
+	 * ch 4 - 5  <--> (2) DMA_PRIO_LOW
+	 */
+	for (i = 0; i < MAX_DMA_CHANNELS; i++) {
+		puv3_stop_dma(i);
+		dma_channels[i].name = NULL;
+		dma_channels[i].prio = min((i & 0x7) >> 1, DMA_PRIO_LOW);
+	}
+
+	ret = request_irq(IRQ_DMA, dma_irq_handler, 0, "DMA", NULL);
+	if (ret) {
+		printk(KERN_CRIT "Can't register IRQ for DMA\n");
+		return ret;
+	}
+
+	ret = request_irq(IRQ_DMAERR, dma_err_handler, 0, "DMAERR", NULL);
+	if (ret) {
+		printk(KERN_CRIT "Can't register IRQ for DMAERR\n");
+		free_irq(IRQ_DMA, "DMA");
+		return ret;
+	}
+
+	return 0;
+}
+
+postcore_initcall(puv3_init_dma);

+ 59 - 0
arch/unicore32/kernel/early_printk.c

@@ -0,0 +1,59 @@
+/*
+ * linux/arch/unicore32/kernel/early_printk.c
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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/console.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <mach/ocd.h>
+
+/* On-Chip-Debugger functions */
+
+static void early_ocd_write(struct console *con, const char *s, unsigned n)
+{
+	while (*s && n-- > 0) {
+		if (*s == '\n')
+			ocd_putc((int)'\r');
+		ocd_putc((int)*s);
+		s++;
+	}
+}
+
+static struct console early_ocd_console = {
+	.name =		"earlyocd",
+	.write =	early_ocd_write,
+	.flags =	CON_PRINTBUFFER,
+	.index =	-1,
+};
+
+/* Direct interface for emergencies */
+static struct console *early_console = &early_ocd_console;
+
+static int __initdata keep_early;
+
+static int __init setup_early_printk(char *buf)
+{
+	if (!buf)
+		return 0;
+
+	if (strstr(buf, "keep"))
+		keep_early = 1;
+
+	if (!strncmp(buf, "ocd", 3))
+		early_console = &early_ocd_console;
+
+	if (keep_early)
+		early_console->flags &= ~CON_BOOT;
+	else
+		early_console->flags |= CON_BOOT;
+	register_console(early_console);
+	return 0;
+}
+early_param("earlyprintk", setup_early_printk);

+ 38 - 0
arch/unicore32/kernel/elf.c

@@ -0,0 +1,38 @@
+/*
+ * linux/arch/unicore32/kernel/elf.c
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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/sched.h>
+#include <linux/personality.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+
+int elf_check_arch(const struct elf32_hdr *x)
+{
+	/* Make sure it's an UniCore executable */
+	if (x->e_machine != EM_UNICORE)
+		return 0;
+
+	/* Make sure the entry address is reasonable */
+	if (x->e_entry & 3)
+		return 0;
+
+	return 1;
+}
+EXPORT_SYMBOL(elf_check_arch);
+
+void elf_set_personality(const struct elf32_hdr *x)
+{
+	unsigned int personality = PER_LINUX;
+
+	set_personality(personality);
+}
+EXPORT_SYMBOL(elf_set_personality);

+ 824 - 0
arch/unicore32/kernel/entry.S

@@ -0,0 +1,824 @@
+/*
+ * linux/arch/unicore32/kernel/entry.S
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ *
+ *  Low-level vector interface routines
+ */
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+#include <asm/thread_info.h>
+#include <asm/memory.h>
+#include <asm/unistd.h>
+#include <generated/asm-offsets.h>
+#include "debug-macro.S"
+
+@
+@ Most of the stack format comes from struct pt_regs, but with
+@ the addition of 8 bytes for storing syscall args 5 and 6.
+@
+#define S_OFF		8
+
+/*
+ * The SWI code relies on the fact that R0 is at the bottom of the stack
+ * (due to slow/fast restore user regs).
+ */
+#if S_R0 != 0
+#error "Please fix"
+#endif
+
+	.macro	zero_fp
+#ifdef CONFIG_FRAME_POINTER
+	mov	fp, #0
+#endif
+	.endm
+
+	.macro	alignment_trap, rtemp
+#ifdef CONFIG_ALIGNMENT_TRAP
+	ldw	\rtemp, .LCcralign
+	ldw	\rtemp, [\rtemp]
+	movc	p0.c1, \rtemp, #0
+#endif
+	.endm
+
+	.macro	load_user_sp_lr, rd, rtemp, offset = 0
+	mov	\rtemp, asr
+	xor	\rtemp, \rtemp, #(PRIV_MODE ^ SUSR_MODE)
+	mov.a	asr, \rtemp			@ switch to the SUSR mode
+
+	ldw	sp, [\rd+], #\offset		@ load sp_user
+	ldw	lr, [\rd+], #\offset + 4	@ load lr_user
+
+	xor	\rtemp, \rtemp, #(PRIV_MODE ^ SUSR_MODE)
+	mov.a	asr, \rtemp			@ switch back to the PRIV mode
+	.endm
+
+	.macro	priv_exit, rpsr
+	mov.a	bsr, \rpsr
+	ldm.w	(r0 - r15), [sp]+
+	ldm.b	(r16 - pc), [sp]+		@ load r0 - pc, asr
+	.endm
+
+	.macro	restore_user_regs, fast = 0, offset = 0
+	ldw	r1, [sp+], #\offset + S_PSR	@ get calling asr
+	ldw	lr, [sp+], #\offset + S_PC	@ get pc
+	mov.a	bsr, r1				@ save in bsr_priv
+	.if	\fast
+	add	sp, sp, #\offset + S_R1		@ r0 is syscall return value
+	ldm.w	(r1 - r15), [sp]+		@ get calling r1 - r15
+	ldur	(r16 - lr), [sp]+		@ get calling r16 - lr
+	.else
+	ldm.w	(r0 - r15), [sp]+		@ get calling r0 - r15
+	ldur	(r16 - lr), [sp]+		@ get calling r16 - lr
+	.endif
+	nop
+	add	sp, sp, #S_FRAME_SIZE - S_R16
+	mov.a	pc, lr				@ return
+						@ and move bsr_priv into asr
+	.endm
+
+	.macro	get_thread_info, rd
+	mov	\rd, sp >> #13
+	mov	\rd, \rd << #13
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+	ldw	\base, =(PKUNITY_INTC_BASE)
+	ldw	\irqstat, [\base+], #0xC	@ INTC_ICIP
+	ldw	\tmp,	  [\base+], #0x4	@ INTC_ICMR
+	and.a	\irqstat, \irqstat, \tmp
+	beq	1001f
+	cntlz	\irqnr, \irqstat
+	rsub	\irqnr, \irqnr, #31
+1001:	/* EQ will be set if no irqs pending */
+	.endm
+
+#ifdef CONFIG_DEBUG_LL
+	.macro	printreg, reg, temp
+		adr	\temp, 901f
+		stm	(r0-r3), [\temp]+
+		stw	lr, [\temp+], #0x10
+		mov	r0, \reg
+		b.l	printhex8
+		mov	r0, #':'
+		b.l	printch
+		mov	r0, pc
+		b.l	printhex8
+		adr	r0, 902f
+		b.l	printascii
+		adr	\temp, 901f
+		ldm	(r0-r3), [\temp]+
+		ldw	lr, [\temp+], #0x10
+		b	903f
+901:	.word	0, 0, 0, 0, 0	@ r0-r3, lr
+902:	.asciz	": epip4d\n"
+	.align
+903:
+	.endm
+#endif
+
+/*
+ * These are the registers used in the syscall handler, and allow us to
+ * have in theory up to 7 arguments to a function - r0 to r6.
+ *
+ * Note that tbl == why is intentional.
+ *
+ * We must set at least "tsk" and "why" when calling ret_with_reschedule.
+ */
+scno	.req	r21		@ syscall number
+tbl	.req	r22		@ syscall table pointer
+why	.req	r22		@ Linux syscall (!= 0)
+tsk	.req	r23		@ current thread_info
+
+/*
+ * Interrupt handling.  Preserves r17, r18, r19
+ */
+	.macro	intr_handler
+1:	get_irqnr_and_base r0, r6, r5, lr
+	beq	2f
+	mov	r1, sp
+	@
+	@ routine called with r0 = irq number, r1 = struct pt_regs *
+	@
+	adr	lr, 1b
+	b	asm_do_IRQ
+2:
+	.endm
+
+/*
+ * PRIV mode handlers
+ */
+	.macro	priv_entry
+	sub	sp, sp, #(S_FRAME_SIZE - 4)
+	stm	(r1 - r15), [sp]+
+	add	r5, sp, #S_R15
+	stm	(r16 - r28), [r5]+
+
+	ldm	(r1 - r3), [r0]+
+	add	r5, sp, #S_SP - 4	@ here for interlock avoidance
+	mov	r4, #-1			@  ""  ""      ""       ""
+	add	r0, sp, #(S_FRAME_SIZE - 4)
+	stw.w	r1, [sp+], #-4		@ save the "real" r0 copied
+					@ from the exception stack
+
+	mov	r1, lr
+
+	@
+	@ We are now ready to fill in the remaining blanks on the stack:
+	@
+	@  r0 - sp_priv
+	@  r1 - lr_priv
+	@  r2 - lr_<exception>, already fixed up for correct return/restart
+	@  r3 - bsr_<exception>
+	@  r4 - orig_r0 (see pt_regs definition in ptrace.h)
+	@
+	stm	(r0 - r4), [r5]+
+	.endm
+
+/*
+ * User mode handlers
+ *
+ */
+	.macro	user_entry
+	sub	sp, sp, #S_FRAME_SIZE
+	stm	(r1 - r15), [sp+]
+	add	r4, sp, #S_R16
+	stm	(r16 - r28), [r4]+
+
+	ldm	(r1 - r3), [r0]+
+	add	r0, sp, #S_PC		@ here for interlock avoidance
+	mov	r4, #-1			@  ""  ""     ""        ""
+
+	stw	r1, [sp]		@ save the "real" r0 copied
+					@ from the exception stack
+
+	@
+	@ We are now ready to fill in the remaining blanks on the stack:
+	@
+	@  r2 - lr_<exception>, already fixed up for correct return/restart
+	@  r3 - bsr_<exception>
+	@  r4 - orig_r0 (see pt_regs definition in ptrace.h)
+	@
+	@ Also, separately save sp_user and lr_user
+	@
+	stm	(r2 - r4), [r0]+
+	stur	(sp, lr), [r0-]
+
+	@
+	@ Enable the alignment trap while in kernel mode
+	@
+	alignment_trap r0
+
+	@
+	@ Clear FP to mark the first stack frame
+	@
+	zero_fp
+	.endm
+
+	.text
+
+@
+@ __invalid - generic code for failed exception
+@			(re-entrant version of handlers)
+@
+__invalid:
+	sub	sp, sp, #S_FRAME_SIZE
+	stm	(r1 - r15), [sp+]
+	add	r1, sp, #S_R16
+	stm	(r16 - r28, sp, lr), [r1]+
+
+	zero_fp
+
+	ldm	(r4 - r6), [r0]+
+	add	r0, sp, #S_PC		@ here for interlock avoidance
+	mov	r7, #-1			@  ""   ""    ""        ""
+	stw	r4, [sp]		@ save preserved r0
+	stm	(r5 - r7), [r0]+	@ lr_<exception>,
+					@ asr_<exception>, "old_r0"
+
+	mov	r0, sp
+	mov	r1, asr
+	b	bad_mode
+ENDPROC(__invalid)
+
+	.align	5
+__dabt_priv:
+	priv_entry
+
+	@
+	@ get ready to re-enable interrupts if appropriate
+	@
+	mov	r17, asr
+	cand.a	r3, #PSR_I_BIT
+	bne	1f
+	andn	r17, r17, #PSR_I_BIT
+1:
+
+	@
+	@ Call the processor-specific abort handler:
+	@
+	@  r2 - aborted context pc
+	@  r3 - aborted context asr
+	@
+	@ The abort handler must return the aborted address in r0, and
+	@ the fault status register in r1.
+	@
+	movc	r1, p0.c3, #0		@ get FSR
+	movc	r0, p0.c4, #0		@ get FAR
+
+	@
+	@ set desired INTR state, then call main handler
+	@
+	mov.a	asr, r17
+	mov	r2, sp
+	b.l	do_DataAbort
+
+	@
+	@ INTRs off again before pulling preserved data off the stack
+	@
+	disable_irq r0
+
+	@
+	@ restore BSR and restart the instruction
+	@
+	ldw	r2, [sp+], #S_PSR
+	priv_exit r2				@ return from exception
+ENDPROC(__dabt_priv)
+
+	.align	5
+__intr_priv:
+	priv_entry
+
+	intr_handler
+
+	mov	r0, #0				@ epip4d
+	movc	p0.c5, r0, #14
+	nop; nop; nop; nop; nop; nop; nop; nop
+
+	ldw	r4, [sp+], #S_PSR		@ irqs are already disabled
+
+	priv_exit r4				@ return from exception
+ENDPROC(__intr_priv)
+
+	.ltorg
+
+	.align	5
+__extn_priv:
+	priv_entry
+
+	mov	r0, sp				@ struct pt_regs *regs
+	mov	r1, asr
+	b	bad_mode			@ not supported
+ENDPROC(__extn_priv)
+
+	.align	5
+__pabt_priv:
+	priv_entry
+
+	@
+	@ re-enable interrupts if appropriate
+	@
+	mov	r17, asr
+	cand.a	r3, #PSR_I_BIT
+	bne	1f
+	andn	r17, r17, #PSR_I_BIT
+1:
+
+	@
+	@ set args, then call main handler
+	@
+	@  r0 - address of faulting instruction
+	@  r1 - pointer to registers on stack
+	@
+	mov	r0, r2			@ pass address of aborted instruction
+	mov	r1, #5
+	mov.a	asr, r17
+	mov	r2, sp			@ regs
+	b.l	do_PrefetchAbort	@ call abort handler
+
+	@
+	@ INTRs off again before pulling preserved data off the stack
+	@
+	disable_irq r0
+
+	@
+	@ restore BSR and restart the instruction
+	@
+	ldw	r2, [sp+], #S_PSR
+	priv_exit r2			@ return from exception
+ENDPROC(__pabt_priv)
+
+	.align	5
+.LCcralign:
+	.word	cr_alignment
+
+	.align	5
+__dabt_user:
+	user_entry
+
+#ifdef CONFIG_UNICORE_FPU_F64
+	cff	ip, s31
+	cand.a	ip, #0x08000000		@ FPU execption traps?
+	beq	209f
+
+	ldw	ip, [sp+], #S_PC
+	add	ip, ip, #4
+	stw	ip, [sp+], #S_PC
+	@
+	@ fall through to the emulation code, which returns using r19 if
+	@ it has emulated the instruction, or the more conventional lr
+	@ if we are to treat this as a real extended instruction
+	@
+	@  r0 - instruction
+	@
+1:	ldw.u	r0, [r2]
+	adr	r19, ret_from_exception
+	adr	lr, 209f
+	@
+	@ fallthrough to call do_uc_f64
+	@
+/*
+ * Check whether the instruction is a co-processor instruction.
+ * If yes, we need to call the relevant co-processor handler.
+ *
+ * Note that we don't do a full check here for the co-processor
+ * instructions; all instructions with bit 27 set are well
+ * defined.  The only instructions that should fault are the
+ * co-processor instructions.
+ *
+ * Emulators may wish to make use of the following registers:
+ *  r0  = instruction opcode.
+ *  r2  = PC
+ *  r19 = normal "successful" return address
+ *  r20 = this threads thread_info structure.
+ *  lr  = unrecognised instruction return address
+ */
+	get_thread_info r20			@ get current thread
+	and	r8, r0, #0x00003c00		@ mask out CP number
+	mov	r7, #1
+	stb	r7, [r20+], #TI_USED_CP + 2	@ set appropriate used_cp[]
+
+	@ F64 hardware support entry point.
+	@  r0  = faulted instruction
+	@  r19 = return address
+	@  r20 = fp_state
+	enable_irq r4
+	add	r20, r20, #TI_FPSTATE	@ r20 = workspace
+	cff	r1, s31			@ get fpu FPSCR
+	andn    r2, r1, #0x08000000
+	ctf     r2, s31			@ clear 27 bit
+	mov	r2, sp			@ nothing stacked - regdump is at TOS
+	mov	lr, r19			@ setup for a return to the user code
+
+	@ Now call the C code to package up the bounce to the support code
+	@   r0 holds the trigger instruction
+	@   r1 holds the FPSCR value
+	@   r2 pointer to register dump
+	b	ucf64_exchandler
+209:
+#endif
+	@
+	@ Call the processor-specific abort handler:
+	@
+	@  r2 - aborted context pc
+	@  r3 - aborted context asr
+	@
+	@ The abort handler must return the aborted address in r0, and
+	@ the fault status register in r1.
+	@
+	movc	r1, p0.c3, #0		@ get FSR
+	movc	r0, p0.c4, #0		@ get FAR
+
+	@
+	@ INTRs on, then call the main handler
+	@
+	enable_irq r2
+	mov	r2, sp
+	adr	lr, ret_from_exception
+	b	do_DataAbort
+ENDPROC(__dabt_user)
+
+	.align	5
+__intr_user:
+	user_entry
+
+	get_thread_info tsk
+
+	intr_handler
+
+	mov	why, #0
+	b	ret_to_user
+ENDPROC(__intr_user)
+
+	.ltorg
+
+	.align	5
+__extn_user:
+	user_entry
+
+	mov	r0, sp
+	mov	r1, asr
+	b	bad_mode
+ENDPROC(__extn_user)
+
+	.align	5
+__pabt_user:
+	user_entry
+
+	mov	r0, r2			@ pass address of aborted instruction.
+	mov	r1, #5
+	enable_irq r1			@ Enable interrupts
+	mov	r2, sp			@ regs
+	b.l	do_PrefetchAbort	@ call abort handler
+	/* fall through */
+/*
+ * This is the return code to user mode for abort handlers
+ */
+ENTRY(ret_from_exception)
+	get_thread_info tsk
+	mov	why, #0
+	b	ret_to_user
+ENDPROC(__pabt_user)
+ENDPROC(ret_from_exception)
+
+/*
+ * Register switch for UniCore V2 processors
+ * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info
+ * previous and next are guaranteed not to be the same.
+ */
+ENTRY(__switch_to)
+	add	ip, r1, #TI_CPU_SAVE
+	stm.w	(r4 - r15), [ip]+
+	stm.w	(r16 - r27, sp, lr), [ip]+
+
+#ifdef	CONFIG_UNICORE_FPU_F64
+	add	ip, r1, #TI_FPSTATE
+	sfm.w	(f0  - f7 ), [ip]+
+	sfm.w	(f8  - f15), [ip]+
+	sfm.w	(f16 - f23), [ip]+
+	sfm.w	(f24 - f31), [ip]+
+	cff	r4, s31
+	stw	r4, [ip]
+
+	add	ip, r2, #TI_FPSTATE
+	lfm.w	(f0  - f7 ), [ip]+
+	lfm.w	(f8  - f15), [ip]+
+	lfm.w	(f16 - f23), [ip]+
+	lfm.w	(f24 - f31), [ip]+
+	ldw	r4, [ip]
+	ctf	r4, s31
+#endif
+	add	ip, r2, #TI_CPU_SAVE
+	ldm.w	(r4 - r15), [ip]+
+	ldm	(r16 - r27, sp, pc), [ip]+	@ Load all regs saved previously
+ENDPROC(__switch_to)
+
+	.align	5
+/*
+ * This is the fast syscall return path.  We do as little as
+ * possible here, and this includes saving r0 back into the PRIV
+ * stack.
+ */
+ret_fast_syscall:
+	disable_irq r1				@ disable interrupts
+	ldw	r1, [tsk+], #TI_FLAGS
+	cand.a	r1, #_TIF_WORK_MASK
+	bne	fast_work_pending
+
+	@ fast_restore_user_regs
+	restore_user_regs fast = 1, offset = S_OFF
+
+/*
+ * Ok, we need to do extra processing, enter the slow path.
+ */
+fast_work_pending:
+	stw.w	r0, [sp+], #S_R0+S_OFF		@ returned r0
+work_pending:
+	cand.a	r1, #_TIF_NEED_RESCHED
+	bne	work_resched
+	cand.a	r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME
+	beq	no_work_pending
+	mov	r0, sp				@ 'regs'
+	mov	r2, why				@ 'syscall'
+	cand.a	r1, #_TIF_SIGPENDING		@ delivering a signal?
+	cmovne	why, #0				@ prevent further restarts
+	b.l	do_notify_resume
+	b	ret_slow_syscall		@ Check work again
+
+work_resched:
+	b.l	schedule
+/*
+ * "slow" syscall return path.  "why" tells us if this was a real syscall.
+ */
+ENTRY(ret_to_user)
+ret_slow_syscall:
+	disable_irq r1				@ disable interrupts
+	get_thread_info tsk			@ epip4d, one path error?!
+	ldw	r1, [tsk+], #TI_FLAGS
+	cand.a	r1, #_TIF_WORK_MASK
+	bne	work_pending
+no_work_pending:
+	@ slow_restore_user_regs
+	restore_user_regs fast = 0, offset = 0
+ENDPROC(ret_to_user)
+
+/*
+ * This is how we return from a fork.
+ */
+ENTRY(ret_from_fork)
+	b.l	schedule_tail
+	get_thread_info tsk
+	ldw	r1, [tsk+], #TI_FLAGS		@ check for syscall tracing
+	mov	why, #1
+	cand.a	r1, #_TIF_SYSCALL_TRACE		@ are we tracing syscalls?
+	beq	ret_slow_syscall
+	mov	r1, sp
+	mov	r0, #1				@ trace exit [IP = 1]
+	b.l	syscall_trace
+	b	ret_slow_syscall
+ENDPROC(ret_from_fork)
+
+/*=============================================================================
+ * SWI handler
+ *-----------------------------------------------------------------------------
+ */
+	.align	5
+ENTRY(vector_swi)
+	sub	sp, sp, #S_FRAME_SIZE
+	stm	(r0 - r15), [sp]+		@ Calling r0 - r15
+	add	r8, sp, #S_R16
+	stm	(r16 - r28), [r8]+		@ Calling r16 - r28
+	add	r8, sp, #S_PC
+	stur	(sp, lr), [r8-]			@ Calling sp, lr
+	mov	r8, bsr				@ called from non-REAL mode
+	stw	lr, [sp+], #S_PC		@ Save calling PC
+	stw	r8, [sp+], #S_PSR		@ Save ASR
+	stw	r0, [sp+], #S_OLD_R0		@ Save OLD_R0
+	zero_fp
+
+	/*
+	 * Get the system call number.
+	 */
+	sub	ip, lr, #4
+	ldw.u	scno, [ip]			@ get SWI instruction
+
+#ifdef CONFIG_ALIGNMENT_TRAP
+	ldw	ip, __cr_alignment
+	ldw	ip, [ip]
+	movc	p0.c1, ip, #0                   @ update control register
+#endif
+	enable_irq ip
+
+	get_thread_info tsk
+	ldw	tbl, =sys_call_table		@ load syscall table pointer
+
+	andn	scno, scno, #0xff000000		@ mask off SWI op-code
+	andn	scno, scno, #0x00ff0000		@ mask off SWI op-code
+
+	stm.w	(r4, r5), [sp-]			@ push fifth and sixth args
+	ldw	ip, [tsk+], #TI_FLAGS		@ check for syscall tracing
+	cand.a	ip, #_TIF_SYSCALL_TRACE		@ are we tracing syscalls?
+	bne	__sys_trace
+
+	csub.a	scno, #__NR_syscalls		@ check upper syscall limit
+	adr	lr, ret_fast_syscall		@ return address
+	bea	1f
+	ldw	pc, [tbl+], scno << #2		@ call sys_* routine
+1:
+	add	r1, sp, #S_OFF
+2:	mov	why, #0				@ no longer a real syscall
+	b	sys_ni_syscall			@ not private func
+
+	/*
+	 * This is the really slow path.  We're going to be doing
+	 * context switches, and waiting for our parent to respond.
+	 */
+__sys_trace:
+	mov	r2, scno
+	add	r1, sp, #S_OFF
+	mov	r0, #0				@ trace entry [IP = 0]
+	b.l	syscall_trace
+
+	adr	lr, __sys_trace_return		@ return address
+	mov	scno, r0			@ syscall number (possibly new)
+	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
+	csub.a	scno, #__NR_syscalls		@ check upper syscall limit
+	bea	2b
+	ldm	(r0 - r3), [r1]+		@ have to reload r0 - r3
+	ldw	pc, [tbl+], scno << #2		@ call sys_* routine
+
+__sys_trace_return:
+	stw.w	r0, [sp+], #S_R0 + S_OFF	@ save returned r0
+	mov	r2, scno
+	mov	r1, sp
+	mov	r0, #1				@ trace exit [IP = 1]
+	b.l	syscall_trace
+	b	ret_slow_syscall
+
+	.align	5
+#ifdef CONFIG_ALIGNMENT_TRAP
+	.type	__cr_alignment, #object
+__cr_alignment:
+	.word	cr_alignment
+#endif
+	.ltorg
+
+ENTRY(sys_execve)
+		add	r3, sp, #S_OFF
+		b	__sys_execve
+ENDPROC(sys_execve)
+
+ENTRY(sys_clone)
+		add	ip, sp, #S_OFF
+		stw	ip, [sp+], #4
+		b	__sys_clone
+ENDPROC(sys_clone)
+
+ENTRY(sys_rt_sigreturn)
+		add	r0, sp, #S_OFF
+		mov	why, #0		@ prevent syscall restart handling
+		b	__sys_rt_sigreturn
+ENDPROC(sys_rt_sigreturn)
+
+ENTRY(sys_sigaltstack)
+		ldw	r2, [sp+], #S_OFF + S_SP
+		b	do_sigaltstack
+ENDPROC(sys_sigaltstack)
+
+	__INIT
+
+/*
+ * Vector stubs.
+ *
+ * This code is copied to 0xffff0200 so we can use branches in the
+ * vectors, rather than ldr's.  Note that this code must not
+ * exceed 0x300 bytes.
+ *
+ * Common stub entry macro:
+ *   Enter in INTR mode, bsr = PRIV/USER ASR, lr = PRIV/USER PC
+ *
+ * SP points to a minimal amount of processor-private memory, the address
+ * of which is copied into r0 for the mode specific abort handler.
+ */
+	.macro	vector_stub, name, mode
+	.align	5
+
+vector_\name:
+	@
+	@ Save r0, lr_<exception> (parent PC) and bsr_<exception>
+	@ (parent ASR)
+	@
+	stw	r0, [sp]
+	stw	lr, [sp+], #4		@ save r0, lr
+	mov	lr, bsr
+	stw	lr, [sp+], #8		@ save bsr
+
+	@
+	@ Prepare for PRIV mode.  INTRs remain disabled.
+	@
+	mov	r0, asr
+	xor	r0, r0, #(\mode ^ PRIV_MODE)
+	mov.a	bsr, r0
+
+	@
+	@ the branch table must immediately follow this code
+	@
+	and	lr, lr, #0x03
+	add	lr, lr, #1
+	mov	r0, sp
+	ldw	lr, [pc+], lr << #2
+	mov.a	pc, lr			@ branch to handler in PRIV mode
+ENDPROC(vector_\name)
+	.align	2
+	@ handler addresses follow this label
+	.endm
+
+	.globl	__stubs_start
+__stubs_start:
+/*
+ * Interrupt dispatcher
+ */
+	vector_stub	intr, INTR_MODE
+
+	.long	__intr_user			@  0  (USER)
+	.long	__invalid			@  1
+	.long	__invalid			@  2
+	.long	__intr_priv			@  3  (PRIV)
+
+/*
+ * Data abort dispatcher
+ * Enter in ABT mode, bsr = USER ASR, lr = USER PC
+ */
+	vector_stub	dabt, ABRT_MODE
+
+	.long	__dabt_user			@  0  (USER)
+	.long	__invalid			@  1
+	.long	__invalid			@  2  (INTR)
+	.long	__dabt_priv			@  3  (PRIV)
+
+/*
+ * Prefetch abort dispatcher
+ * Enter in ABT mode, bsr = USER ASR, lr = USER PC
+ */
+	vector_stub	pabt, ABRT_MODE
+
+	.long	__pabt_user			@  0 (USER)
+	.long	__invalid			@  1
+	.long	__invalid			@  2 (INTR)
+	.long	__pabt_priv			@  3 (PRIV)
+
+/*
+ * Undef instr entry dispatcher
+ * Enter in EXTN mode, bsr = PRIV/USER ASR, lr = PRIV/USER PC
+ */
+	vector_stub	extn, EXTN_MODE
+
+	.long	__extn_user			@  0 (USER)
+	.long	__invalid			@  1
+	.long	__invalid			@  2 (INTR)
+	.long	__extn_priv			@  3 (PRIV)
+
+/*
+ * We group all the following data together to optimise
+ * for CPUs with separate I & D caches.
+ */
+	.align	5
+
+.LCvswi:
+	.word	vector_swi
+
+	.globl	__stubs_end
+__stubs_end:
+
+	.equ	stubs_offset, __vectors_start + 0x200 - __stubs_start
+
+	.globl	__vectors_start
+__vectors_start:
+	jepriv	SYS_ERROR0
+	b	vector_extn + stubs_offset
+	ldw	pc, .LCvswi + stubs_offset
+	b	vector_pabt + stubs_offset
+	b	vector_dabt + stubs_offset
+	jepriv	SYS_ERROR0
+	b	vector_intr + stubs_offset
+	jepriv	SYS_ERROR0
+
+	.globl	__vectors_end
+__vectors_end:
+
+	.data
+
+	.globl	cr_alignment
+	.globl	cr_no_alignment
+cr_alignment:
+	.space	4
+cr_no_alignment:
+	.space	4

+ 126 - 0
arch/unicore32/kernel/fpu-ucf64.c

@@ -0,0 +1,126 @@
+/*
+ * linux/arch/unicore32/kernel/fpu-ucf64.c
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/fpu-ucf64.h>
+
+/*
+ * A special flag to tell the normalisation code not to normalise.
+ */
+#define F64_NAN_FLAG	0x100
+
+/*
+ * A bit pattern used to indicate the initial (unset) value of the
+ * exception mask, in case nothing handles an instruction.  This
+ * doesn't include the NAN flag, which get masked out before
+ * we check for an error.
+ */
+#define F64_EXCEPTION_ERROR	((u32)-1 & ~F64_NAN_FLAG)
+
+/*
+ * Since we aren't building with -mfpu=f64, we need to code
+ * these instructions using their MRC/MCR equivalents.
+ */
+#define f64reg(_f64_) #_f64_
+
+#define cff(_f64_) ({			\
+	u32 __v;			\
+	asm("cff %0, " f64reg(_f64_) "@ fmrx	%0, " #_f64_	\
+	    : "=r" (__v) : : "cc");	\
+	__v;				\
+	})
+
+#define ctf(_f64_, _var_)		\
+	asm("ctf %0, " f64reg(_f64_) "@ fmxr	" #_f64_ ", %0"	\
+	   : : "r" (_var_) : "cc")
+
+/*
+ * Raise a SIGFPE for the current process.
+ * sicode describes the signal being raised.
+ */
+void ucf64_raise_sigfpe(unsigned int sicode, struct pt_regs *regs)
+{
+	siginfo_t info;
+
+	memset(&info, 0, sizeof(info));
+
+	info.si_signo = SIGFPE;
+	info.si_code = sicode;
+	info.si_addr = (void __user *)(instruction_pointer(regs) - 4);
+
+	/*
+	 * This is the same as NWFPE, because it's not clear what
+	 * this is used for
+	 */
+	current->thread.error_code = 0;
+	current->thread.trap_no = 6;
+
+	send_sig_info(SIGFPE, &info, current);
+}
+
+/*
+ * Handle exceptions of UniCore-F64.
+ */
+void ucf64_exchandler(u32 inst, u32 fpexc, struct pt_regs *regs)
+{
+	u32 tmp = fpexc;
+	u32 exc = F64_EXCEPTION_ERROR & fpexc;
+
+	pr_debug("UniCore-F64: instruction %08x fpscr %08x\n",
+			inst, fpexc);
+
+	if (exc & FPSCR_CMPINSTR_BIT) {
+		if (exc & FPSCR_CON)
+			tmp |= FPSCR_CON;
+		else
+			tmp &= ~(FPSCR_CON);
+		exc &= ~(FPSCR_CMPINSTR_BIT | FPSCR_CON);
+	} else {
+		pr_debug(KERN_ERR "UniCore-F64 Error: unhandled exceptions\n");
+		pr_debug(KERN_ERR "UniCore-F64 FPSCR 0x%08x INST 0x%08x\n",
+				cff(FPSCR), inst);
+
+		ucf64_raise_sigfpe(0, regs);
+		return;
+	}
+
+	/*
+	 * Update the FPSCR with the additional exception flags.
+	 * Comparison instructions always return at least one of
+	 * these flags set.
+	 */
+	tmp &= ~(FPSCR_TRAP | FPSCR_IOS | FPSCR_OFS | FPSCR_UFS |
+			FPSCR_IXS | FPSCR_HIS | FPSCR_IOC | FPSCR_OFC |
+			FPSCR_UFC | FPSCR_IXC | FPSCR_HIC);
+
+	tmp |= exc;
+	ctf(FPSCR, tmp);
+}
+
+/*
+ * F64 support code initialisation.
+ */
+static int __init ucf64_init(void)
+{
+	ctf(FPSCR, 0x0);     /* FPSCR_UFE | FPSCR_NDE perhaps better */
+
+	printk(KERN_INFO "Enable UniCore-F64 support.\n");
+
+	return 0;
+}
+
+late_initcall(ucf64_init);

+ 122 - 0
arch/unicore32/kernel/gpio.c

@@ -0,0 +1,122 @@
+/*
+ * linux/arch/unicore32/kernel/gpio.c
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
+ *	Copyright (C) 2001-2010 Guan Xuetao
+ *
+ * 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.
+ */
+/* in FPGA, no GPIO support */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <mach/hardware.h>
+
+#ifdef CONFIG_LEDS
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+
+static const struct gpio_led puv3_gpio_leds[] = {
+	{ .name = "cpuhealth", .gpio = GPO_CPU_HEALTH, .active_low = 0,
+		.default_trigger = "heartbeat",	},
+	{ .name = "hdd_led", .gpio = GPO_HDD_LED, .active_low = 1,
+		.default_trigger = "ide-disk", },
+};
+
+static const struct gpio_led_platform_data puv3_gpio_led_data = {
+	.num_leds =	ARRAY_SIZE(puv3_gpio_leds),
+	.leds =		(void *) puv3_gpio_leds,
+};
+
+static struct platform_device puv3_gpio_gpio_leds = {
+	.name =		"leds-gpio",
+	.id =		-1,
+	.dev = {
+		.platform_data = (void *) &puv3_gpio_led_data,
+	}
+};
+
+static int __init puv3_gpio_leds_init(void)
+{
+	platform_device_register(&puv3_gpio_gpio_leds);
+	return 0;
+}
+
+device_initcall(puv3_gpio_leds_init);
+#endif
+
+static int puv3_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	return readl(GPIO_GPLR) & GPIO_GPIO(offset);
+}
+
+static void puv3_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	if (value)
+		writel(GPIO_GPIO(offset), GPIO_GPSR);
+	else
+		writel(GPIO_GPIO(offset), GPIO_GPCR);
+}
+
+static int puv3_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	writel(readl(GPIO_GPDR) & ~GPIO_GPIO(offset), GPIO_GPDR);
+	local_irq_restore(flags);
+	return 0;
+}
+
+static int puv3_direction_output(struct gpio_chip *chip, unsigned offset,
+		int value)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	puv3_gpio_set(chip, offset, value);
+	writel(readl(GPIO_GPDR) | GPIO_GPIO(offset), GPIO_GPDR);
+	local_irq_restore(flags);
+	return 0;
+}
+
+static struct gpio_chip puv3_gpio_chip = {
+	.label			= "gpio",
+	.direction_input	= puv3_direction_input,
+	.direction_output	= puv3_direction_output,
+	.set			= puv3_gpio_set,
+	.get			= puv3_gpio_get,
+	.base			= 0,
+	.ngpio			= GPIO_MAX + 1,
+};
+
+void __init puv3_init_gpio(void)
+{
+	writel(GPIO_DIR, GPIO_GPDR);
+#if	defined(CONFIG_PUV3_NB0916) || defined(CONFIG_PUV3_SMW0919)	\
+	|| defined(CONFIG_PUV3_DB0913)
+	gpio_set_value(GPO_WIFI_EN, 1);
+	gpio_set_value(GPO_HDD_LED, 1);
+	gpio_set_value(GPO_VGA_EN, 1);
+	gpio_set_value(GPO_LCD_EN, 1);
+	gpio_set_value(GPO_CAM_PWR_EN, 0);
+	gpio_set_value(GPO_LCD_VCC_EN, 1);
+	gpio_set_value(GPO_SOFT_OFF, 1);
+	gpio_set_value(GPO_BT_EN, 1);
+	gpio_set_value(GPO_FAN_ON, 0);
+	gpio_set_value(GPO_SPKR, 0);
+	gpio_set_value(GPO_CPU_HEALTH, 1);
+	gpio_set_value(GPO_LAN_SEL, 1);
+/*
+ * DO NOT modify the GPO_SET_V1 and GPO_SET_V2 in kernel
+ *	gpio_set_value(GPO_SET_V1, 1);
+ *	gpio_set_value(GPO_SET_V2, 1);
+ */
+#endif
+	gpiochip_add(&puv3_gpio_chip);
+}

+ 252 - 0
arch/unicore32/kernel/head.S

@@ -0,0 +1,252 @@
+/*
+ * linux/arch/unicore32/kernel/head.S
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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/linkage.h>
+#include <linux/init.h>
+
+#include <asm/assembler.h>
+#include <asm/ptrace.h>
+#include <generated/asm-offsets.h>
+#include <asm/memory.h>
+#include <asm/thread_info.h>
+#include <asm/system.h>
+#include <asm/pgtable-hwdef.h>
+
+#if (PHYS_OFFSET & 0x003fffff)
+#error "PHYS_OFFSET must be at an even 4MiB boundary!"
+#endif
+
+#define KERNEL_RAM_VADDR	(PAGE_OFFSET + KERNEL_IMAGE_START)
+#define KERNEL_RAM_PADDR	(PHYS_OFFSET + KERNEL_IMAGE_START)
+
+#define KERNEL_PGD_PADDR	(KERNEL_RAM_PADDR - 0x1000)
+#define KERNEL_PGD_VADDR	(KERNEL_RAM_VADDR - 0x1000)
+
+#define KERNEL_START		KERNEL_RAM_VADDR
+#define KERNEL_END		_end
+
+/*
+ * swapper_pg_dir is the virtual address of the initial page table.
+ * We place the page tables 4K below KERNEL_RAM_VADDR.  Therefore, we must
+ * make sure that KERNEL_RAM_VADDR is correctly set.  Currently, we expect
+ * the least significant 16 bits to be 0x8000, but we could probably
+ * relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x1000.
+ */
+#if (KERNEL_RAM_VADDR & 0xffff) != 0x8000
+#error KERNEL_RAM_VADDR must start at 0xXXXX8000
+#endif
+
+	.globl	swapper_pg_dir
+	.equ	swapper_pg_dir, KERNEL_RAM_VADDR - 0x1000
+
+/*
+ * Kernel startup entry point.
+ * ---------------------------
+ *
+ * This is normally called from the decompressor code.  The requirements
+ * are: MMU = off, D-cache = off, I-cache = dont care
+ *
+ * This code is mostly position independent, so if you link the kernel at
+ * 0xc0008000, you call this at __pa(0xc0008000).
+ */
+	__HEAD
+ENTRY(stext)
+	@ set asr
+	mov	r0, #PRIV_MODE			@ ensure priv mode
+	or	r0, #PSR_R_BIT | PSR_I_BIT	@ disable irqs
+	mov.a	asr, r0
+
+	@ process identify
+	movc	r0, p0.c0, #0			@ cpuid
+	movl	r1, 0xff00ffff			@ mask
+	movl	r2, 0x4d000863			@ value
+	and	r0, r1, r0
+	cxor.a	r0, r2
+	bne	__error_p			@ invalid processor id
+
+	/*
+	 * Clear the 4K level 1 swapper page table
+	 */
+	movl	r0, #KERNEL_PGD_PADDR		@ page table address
+	mov	r1, #0
+	add	r2, r0, #0x1000
+101:	stw.w	r1, [r0]+, #4
+	stw.w	r1, [r0]+, #4
+	stw.w	r1, [r0]+, #4
+	stw.w	r1, [r0]+, #4
+	cxor.a	r0, r2
+	bne	101b
+
+	movl	r4, #KERNEL_PGD_PADDR		@ page table address
+	mov	r7, #PMD_TYPE_SECT | PMD_PRESENT	@ page size: section
+	or	r7, r7, #PMD_SECT_CACHEABLE		@ cacheable
+	or	r7, r7, #PMD_SECT_READ | PMD_SECT_WRITE | PMD_SECT_EXEC
+
+	/*
+	 * Create identity mapping for first 4MB of kernel to
+	 * cater for the MMU enable.  This identity mapping
+	 * will be removed by paging_init().  We use our current program
+	 * counter to determine corresponding section base address.
+	 */
+	mov	r6, pc
+	mov	r6, r6 >> #22			@ start of kernel section
+	or	r1, r7, r6 << #22		@ flags + kernel base
+	stw	r1, [r4+], r6 << #2		@ identity mapping
+
+	/*
+	 * Now setup the pagetables for our kernel direct
+	 * mapped region.
+	 */
+	add	r0, r4,  #(KERNEL_START & 0xff000000) >> 20
+	stw.w	r1, [r0+], #(KERNEL_START & 0x00c00000) >> 20
+	movl	r6, #(KERNEL_END - 1)
+	add	r0, r0, #4
+	add	r6, r4, r6 >> #20
+102:	csub.a	r0, r6
+	add	r1, r1, #1 << 22
+	bua	103f
+	stw.w	r1, [r0]+, #4
+	b	102b
+103:
+	/*
+	 * Then map first 4MB of ram in case it contains our boot params.
+	 */
+	add	r0, r4, #PAGE_OFFSET >> 20
+	or	r6, r7, #(PHYS_OFFSET & 0xffc00000)
+	stw	r6, [r0]
+
+	ldw	r15, __switch_data		@ address to jump to after
+
+	/*
+	 * Initialise TLB, Caches, and MMU state ready to switch the MMU
+	 * on.
+	 */
+	mov	r0, #0
+	movc	p0.c5, r0, #28			@ cache invalidate all
+	nop8
+	movc	p0.c6, r0, #6			@ TLB invalidate all
+	nop8
+
+	/*
+	 * ..V. .... ..TB IDAM
+	 * ..1. .... ..01 1111
+	 */
+	movl	r0, #0x201f			@ control register setting
+
+	/*
+	 * Setup common bits before finally enabling the MMU.  Essentially
+	 * this is just loading the page table pointer and domain access
+	 * registers.
+	 */
+	#ifndef CONFIG_ALIGNMENT_TRAP
+		andn	r0, r0, #CR_A
+	#endif
+	#ifdef CONFIG_CPU_DCACHE_DISABLE
+		andn	r0, r0, #CR_D
+	#endif
+	#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+		andn	r0, r0, #CR_B
+	#endif
+	#ifdef CONFIG_CPU_ICACHE_DISABLE
+		andn	r0, r0, #CR_I
+	#endif
+
+	movc	p0.c2, r4, #0			@ set pgd
+	b	__turn_mmu_on
+ENDPROC(stext)
+
+/*
+ * Enable the MMU.  This completely changes the stucture of the visible
+ * memory space.  You will not be able to trace execution through this.
+ *
+ *  r0  = cp#0 control register
+ *  r15 = *virtual* address to jump to upon completion
+ */
+	.align	5
+__turn_mmu_on:
+	mov	r0, r0
+	movc	p0.c1, r0, #0			@ write control reg
+	nop					@ fetch inst by phys addr
+	mov	pc, r15
+	nop8					@ fetch inst by phys addr
+ENDPROC(__turn_mmu_on)
+
+/*
+ * Setup the initial page tables.  We only setup the barest
+ * amount which are required to get the kernel running, which
+ * generally means mapping in the kernel code.
+ *
+ * r9  = cpuid
+ * r10 = procinfo
+ *
+ * Returns:
+ *  r0, r3, r6, r7 corrupted
+ *  r4 = physical page table address
+ */
+	.ltorg
+
+	.align	2
+	.type	__switch_data, %object
+__switch_data:
+	.long	__mmap_switched
+	.long	__bss_start			@ r6
+	.long	_end				@ r7
+	.long	cr_alignment			@ r8
+	.long	init_thread_union + THREAD_START_SP @ sp
+
+/*
+ * The following fragment of code is executed with the MMU on in MMU mode,
+ * and uses absolute addresses; this is not position independent.
+ *
+ *  r0  = cp#0 control register
+ */
+__mmap_switched:
+	adr	r3, __switch_data + 4
+
+	ldm.w	(r6, r7, r8), [r3]+
+	ldw	sp, [r3]
+
+	mov	fp, #0				@ Clear BSS (and zero fp)
+203:	csub.a	r6, r7
+	bea	204f
+	stw.w	fp, [r6]+,#4
+	b	203b
+204:
+	andn	r1, r0, #CR_A			@ Clear 'A' bit
+	stm	(r0, r1), [r8]+			@ Save control register values
+	b	start_kernel
+ENDPROC(__mmap_switched)
+
+/*
+ * Exception handling.  Something went wrong and we can't proceed.  We
+ * ought to tell the user, but since we don't have any guarantee that
+ * we're even running on the right architecture, we do virtually nothing.
+ *
+ * If CONFIG_DEBUG_LL is set we try to print out something about the error
+ * and hope for the best (useful if bootloader fails to pass a proper
+ * machine ID for example).
+ */
+__error_p:
+#ifdef CONFIG_DEBUG_LL
+	adr	r0, str_p1
+	b.l	printascii
+	mov	r0, r9
+	b.l	printhex8
+	adr	r0, str_p2
+	b.l	printascii
+901:	nop8
+	b	901b
+str_p1:	.asciz	"\nError: unrecognized processor variant (0x"
+str_p2:	.asciz	").\n"
+	.align
+#endif
+ENDPROC(__error_p)
+

+ 160 - 0
arch/unicore32/kernel/hibernate.c

@@ -0,0 +1,160 @@
+/*
+ *  linux/arch/unicore32/kernel/hibernate.c
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
+ *	Copyright (C) 2001-2010 Guan Xuetao
+ *
+ * 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/gfp.h>
+#include <linux/suspend.h>
+#include <linux/bootmem.h>
+
+#include <asm/system.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/suspend.h>
+
+#include "mach/pm.h"
+
+/* Pointer to the temporary resume page tables */
+pgd_t *resume_pg_dir;
+
+struct swsusp_arch_regs swsusp_arch_regs_cpu0;
+
+/*
+ * Create a middle page table on a resume-safe page and put a pointer to it in
+ * the given global directory entry.  This only returns the gd entry
+ * in non-PAE compilation mode, since the middle layer is folded.
+ */
+static pmd_t *resume_one_md_table_init(pgd_t *pgd)
+{
+	pud_t *pud;
+	pmd_t *pmd_table;
+
+	pud = pud_offset(pgd, 0);
+	pmd_table = pmd_offset(pud, 0);
+
+	return pmd_table;
+}
+
+/*
+ * Create a page table on a resume-safe page and place a pointer to it in
+ * a middle page directory entry.
+ */
+static pte_t *resume_one_page_table_init(pmd_t *pmd)
+{
+	if (pmd_none(*pmd)) {
+		pte_t *page_table = (pte_t *)get_safe_page(GFP_ATOMIC);
+		if (!page_table)
+			return NULL;
+
+		set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_KERNEL_TABLE));
+
+		BUG_ON(page_table != pte_offset_kernel(pmd, 0));
+
+		return page_table;
+	}
+
+	return pte_offset_kernel(pmd, 0);
+}
+
+/*
+ * This maps the physical memory to kernel virtual address space, a total
+ * of max_low_pfn pages, by creating page tables starting from address
+ * PAGE_OFFSET.  The page tables are allocated out of resume-safe pages.
+ */
+static int resume_physical_mapping_init(pgd_t *pgd_base)
+{
+	unsigned long pfn;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+	int pgd_idx, pmd_idx;
+
+	pgd_idx = pgd_index(PAGE_OFFSET);
+	pgd = pgd_base + pgd_idx;
+	pfn = 0;
+
+	for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
+		pmd = resume_one_md_table_init(pgd);
+		if (!pmd)
+			return -ENOMEM;
+
+		if (pfn >= max_low_pfn)
+			continue;
+
+		for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD; pmd++, pmd_idx++) {
+			pte_t *max_pte;
+
+			if (pfn >= max_low_pfn)
+				break;
+
+			/* Map with normal page tables.
+			 * NOTE: We can mark everything as executable here
+			 */
+			pte = resume_one_page_table_init(pmd);
+			if (!pte)
+				return -ENOMEM;
+
+			max_pte = pte + PTRS_PER_PTE;
+			for (; pte < max_pte; pte++, pfn++) {
+				if (pfn >= max_low_pfn)
+					break;
+
+				set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
+			}
+		}
+	}
+
+	return 0;
+}
+
+static inline void resume_init_first_level_page_table(pgd_t *pg_dir)
+{
+}
+
+int swsusp_arch_resume(void)
+{
+	int error;
+
+	resume_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC);
+	if (!resume_pg_dir)
+		return -ENOMEM;
+
+	resume_init_first_level_page_table(resume_pg_dir);
+	error = resume_physical_mapping_init(resume_pg_dir);
+	if (error)
+		return error;
+
+	/* We have got enough memory and from now on we cannot recover */
+	restore_image(resume_pg_dir, restore_pblist);
+	return 0;
+}
+
+/*
+ *	pfn_is_nosave - check if given pfn is in the 'nosave' section
+ */
+
+int pfn_is_nosave(unsigned long pfn)
+{
+	unsigned long begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
+	unsigned long end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
+
+	return (pfn >= begin_pfn) && (pfn < end_pfn);
+}
+
+void save_processor_state(void)
+{
+}
+
+void restore_processor_state(void)
+{
+	local_flush_tlb_all();
+}

+ 117 - 0
arch/unicore32/kernel/hibernate_asm.S

@@ -0,0 +1,117 @@
+/*
+ * linux/arch/unicore32/kernel/hibernate_asm.S
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
+ *	Copyright (C) 2001-2010 Guan Xuetao
+ *
+ * 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/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <generated/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/assembler.h>
+
+@ restore_image(pgd_t *resume_pg_dir, struct pbe *restore_pblist)
+@ r0: resume_pg_dir
+@ r1: restore_pblist
+@ copy restore_pblist pages
+@ restore registers from swsusp_arch_regs_cpu0
+@
+ENTRY(restore_image)
+	sub	r0, r0, #PAGE_OFFSET
+	mov	r5, #0
+	movc	p0.c6, r5, #6	@invalidate ITLB & DTLB
+	movc	p0.c2, r0, #0
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	.p2align 4,,7
+101:
+	csub.a	r1, #0
+	beq	109f
+
+	ldw	r6, [r1+], #PBE_ADDRESS
+	ldw	r7, [r1+], #PBE_ORIN_ADDRESS
+
+	movl	ip, #128
+102:	ldm.w	(r8 - r15), [r6]+
+	stm.w	(r8 - r15), [r7]+
+	sub.a	ip, ip, #1
+	bne	102b
+
+	ldw	r1, [r1+], #PBE_NEXT
+	b	101b
+
+	.p2align 4,,7
+109:
+	/* go back to the original page tables */
+	ldw	r0, =swapper_pg_dir
+	sub	r0, r0, #PAGE_OFFSET
+	mov	r5, #0
+	movc	p0.c6, r5, #6
+	movc	p0.c2, r0, #0
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+#ifdef	CONFIG_UNICORE_FPU_F64
+	ldw	ip, 1f
+	add	ip, ip, #SWSUSP_FPSTATE
+	lfm.w	(f0  - f7 ), [ip]+
+	lfm.w	(f8  - f15), [ip]+
+	lfm.w	(f16 - f23), [ip]+
+	lfm.w	(f24 - f31), [ip]+
+	ldw	r4, [ip]
+	ctf	r4, s31
+#endif
+	mov	r0, #0x0
+	ldw	ip, 1f
+	add	ip, ip, #SWSUSP_CPU
+	ldm.w	(r4 - r15), [ip]+
+	ldm	(r16 - r27, sp, pc), [ip]+	@ Load all regs saved previously
+
+	.align	2
+1:	.long	swsusp_arch_regs_cpu0
+
+
+@ swsusp_arch_suspend()
+@ - prepare pc for resume, return from function without swsusp_save on resume
+@ - save registers in swsusp_arch_regs_cpu0
+@ - call swsusp_save write suspend image
+
+ENTRY(swsusp_arch_suspend)
+	ldw	ip, 1f
+	add	ip, ip, #SWSUSP_CPU
+	stm.w	(r4 - r15), [ip]+
+	stm.w	(r16 - r27, sp, lr), [ip]+
+
+#ifdef	CONFIG_UNICORE_FPU_F64
+	ldw	ip, 1f
+	add	ip, ip, #SWSUSP_FPSTATE
+	sfm.w	(f0  - f7 ), [ip]+
+	sfm.w	(f8  - f15), [ip]+
+	sfm.w	(f16 - f23), [ip]+
+	sfm.w	(f24 - f31), [ip]+
+	cff	r4, s31
+	stw	r4, [ip]
+#endif
+	b	swsusp_save			@ no return
+
+1:	.long	swsusp_arch_regs_cpu0

+ 44 - 0
arch/unicore32/kernel/init_task.c

@@ -0,0 +1,44 @@
+/*
+ * linux/arch/unicore32/kernel/init_task.c
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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/mm.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/init_task.h>
+#include <linux/mqueue.h>
+#include <linux/uaccess.h>
+
+#include <asm/pgtable.h>
+
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by making sure
+ * the linker maps this in the .text segment right after head.S,
+ * and making head.S ensure the proper alignment.
+ *
+ * The things we do for performance..
+ */
+union thread_union init_thread_union __init_task_data = {
+	INIT_THREAD_INFO(init_task) };
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+EXPORT_SYMBOL(init_task);

Some files were not shown because too many files changed in this diff