aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/microblaze
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'arch/microblaze')
-rw-r--r--arch/microblaze/Kconfig53
-rw-r--r--arch/microblaze/Kconfig.debug6
-rw-r--r--arch/microblaze/Makefile15
-rw-r--r--arch/microblaze/boot/Makefile12
-rw-r--r--arch/microblaze/configs/mmu_defconfig3
-rw-r--r--arch/microblaze/configs/nommu_defconfig2
-rw-r--r--arch/microblaze/include/asm/byteorder.h4
-rw-r--r--arch/microblaze/include/asm/cacheflush.h13
-rw-r--r--arch/microblaze/include/asm/checksum.h9
-rw-r--r--arch/microblaze/include/asm/cpuinfo.h7
-rw-r--r--arch/microblaze/include/asm/elf.h2
-rw-r--r--arch/microblaze/include/asm/entry.h36
-rw-r--r--arch/microblaze/include/asm/exceptions.h3
-rw-r--r--arch/microblaze/include/asm/futex.h31
-rw-r--r--arch/microblaze/include/asm/gpio.h5
-rw-r--r--arch/microblaze/include/asm/io.h4
-rw-r--r--arch/microblaze/include/asm/irq.h2
-rw-r--r--arch/microblaze/include/asm/irqflags.h193
-rw-r--r--arch/microblaze/include/asm/memblock.h3
-rw-r--r--arch/microblaze/include/asm/page.h3
-rw-r--r--arch/microblaze/include/asm/pci-bridge.h14
-rw-r--r--arch/microblaze/include/asm/pci.h4
-rw-r--r--arch/microblaze/include/asm/pgalloc.h3
-rw-r--r--arch/microblaze/include/asm/pgtable.h49
-rw-r--r--arch/microblaze/include/asm/processor.h2
-rw-r--r--arch/microblaze/include/asm/prom.h19
-rw-r--r--arch/microblaze/include/asm/ptrace.h14
-rw-r--r--arch/microblaze/include/asm/pvr.h199
-rw-r--r--arch/microblaze/include/asm/seccomp.h16
-rw-r--r--arch/microblaze/include/asm/setup.h6
-rw-r--r--arch/microblaze/include/asm/syscall.h3
-rw-r--r--arch/microblaze/include/asm/syscalls.h8
-rw-r--r--arch/microblaze/include/asm/thread_info.h20
-rw-r--r--arch/microblaze/include/asm/tlb.h1
-rw-r--r--arch/microblaze/include/asm/uaccess.h8
-rw-r--r--arch/microblaze/include/asm/unaligned.h17
-rw-r--r--arch/microblaze/include/asm/unistd.h10
-rw-r--r--arch/microblaze/kernel/Makefile1
-rw-r--r--arch/microblaze/kernel/cpu/Makefile2
-rw-r--r--arch/microblaze/kernel/cpu/cache.c18
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c1
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-static.c1
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo.c4
-rw-r--r--arch/microblaze/kernel/cpu/mb.c3
-rw-r--r--arch/microblaze/kernel/cpu/pvr.c4
-rw-r--r--arch/microblaze/kernel/dma.c1
-rw-r--r--arch/microblaze/kernel/early_printk.c87
-rw-r--r--arch/microblaze/kernel/entry-nommu.S4
-rw-r--r--arch/microblaze/kernel/entry.S368
-rw-r--r--arch/microblaze/kernel/exceptions.c30
-rw-r--r--arch/microblaze/kernel/ftrace.c10
-rw-r--r--arch/microblaze/kernel/head.S45
-rw-r--r--arch/microblaze/kernel/heartbeat.c11
-rw-r--r--arch/microblaze/kernel/hw_exception_handler.S61
-rw-r--r--arch/microblaze/kernel/intc.c73
-rw-r--r--arch/microblaze/kernel/irq.c40
-rw-r--r--arch/microblaze/kernel/kgdb.c7
-rw-r--r--arch/microblaze/kernel/microblaze_ksyms.c44
-rw-r--r--arch/microblaze/kernel/process.c2
-rw-r--r--arch/microblaze/kernel/prom.c56
-rw-r--r--arch/microblaze/kernel/prom_parse.c115
-rw-r--r--arch/microblaze/kernel/ptrace.c8
-rw-r--r--arch/microblaze/kernel/setup.c22
-rw-r--r--arch/microblaze/kernel/signal.c8
-rw-r--r--arch/microblaze/kernel/sys_microblaze.c3
-rw-r--r--arch/microblaze/kernel/syscall_table.S8
-rw-r--r--arch/microblaze/kernel/timer.c47
-rw-r--r--arch/microblaze/kernel/unwind.c2
-rw-r--r--arch/microblaze/kernel/vmlinux.lds.S26
-rw-r--r--arch/microblaze/lib/Makefile16
-rw-r--r--arch/microblaze/lib/ashldi3.c29
-rw-r--r--arch/microblaze/lib/ashrdi3.c31
-rw-r--r--arch/microblaze/lib/divsi3.S73
-rw-r--r--arch/microblaze/lib/fastcopy.S4
-rw-r--r--arch/microblaze/lib/libgcc.h25
-rw-r--r--arch/microblaze/lib/lshrdi3.c29
-rw-r--r--arch/microblaze/lib/memcpy.c54
-rw-r--r--arch/microblaze/lib/memmove.c65
-rw-r--r--arch/microblaze/lib/memset.c24
-rw-r--r--arch/microblaze/lib/modsi3.S73
-rw-r--r--arch/microblaze/lib/muldi3.c61
-rw-r--r--arch/microblaze/lib/mulsi3.S46
-rw-r--r--arch/microblaze/lib/udivsi3.S84
-rw-r--r--arch/microblaze/lib/umodsi3.S86
-rw-r--r--arch/microblaze/mm/consistent.c2
-rw-r--r--arch/microblaze/mm/fault.c2
-rw-r--r--arch/microblaze/mm/init.c32
-rw-r--r--arch/microblaze/pci/indirect_pci.c2
-rw-r--r--arch/microblaze/pci/pci-common.c24
-rw-r--r--arch/microblaze/pci/pci_32.c1
-rw-r--r--arch/microblaze/platform/generic/Kconfig.auto2
-rw-r--r--arch/microblaze/platform/generic/system.dts3
-rw-r--r--arch/microblaze/platform/platform.c3
93 files changed, 1677 insertions, 1005 deletions
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 692fdfce2a23..e446bab2427b 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -1,8 +1,3 @@
1# For a description of the syntax of this configuration file,
2# see Documentation/kbuild/kconfig-language.txt.
3
4mainmenu "Linux/Microblaze Kernel Configuration"
5
6config MICROBLAZE 1config MICROBLAZE
7 def_bool y 2 def_bool y
8 select HAVE_MEMBLOCK 3 select HAVE_MEMBLOCK
@@ -11,7 +6,6 @@ config MICROBLAZE
11 select HAVE_FUNCTION_GRAPH_TRACER 6 select HAVE_FUNCTION_GRAPH_TRACER
12 select HAVE_DYNAMIC_FTRACE 7 select HAVE_DYNAMIC_FTRACE
13 select HAVE_FTRACE_MCOUNT_RECORD 8 select HAVE_FTRACE_MCOUNT_RECORD
14 select USB_ARCH_HAS_EHCI
15 select ARCH_WANT_OPTIONAL_GPIOLIB 9 select ARCH_WANT_OPTIONAL_GPIOLIB
16 select HAVE_OPROFILE 10 select HAVE_OPROFILE
17 select HAVE_ARCH_KGDB 11 select HAVE_ARCH_KGDB
@@ -19,7 +13,10 @@ config MICROBLAZE
19 select HAVE_DMA_API_DEBUG 13 select HAVE_DMA_API_DEBUG
20 select TRACING_SUPPORT 14 select TRACING_SUPPORT
21 select OF 15 select OF
22 select OF_FLATTREE 16 select OF_EARLY_FLATTREE
17 select HAVE_GENERIC_HARDIRQS
18 select GENERIC_IRQ_PROBE
19 select GENERIC_IRQ_SHOW
23 20
24config SWAP 21config SWAP
25 def_bool n 22 def_bool n
@@ -36,18 +33,9 @@ config ARCH_HAS_ILOG2_U32
36config ARCH_HAS_ILOG2_U64 33config ARCH_HAS_ILOG2_U64
37 def_bool n 34 def_bool n
38 35
39config GENERIC_FIND_NEXT_BIT
40 def_bool y
41
42config GENERIC_HWEIGHT 36config GENERIC_HWEIGHT
43 def_bool y 37 def_bool y
44 38
45config GENERIC_HARDIRQS
46 def_bool y
47
48config GENERIC_IRQ_PROBE
49 def_bool y
50
51config GENERIC_CALIBRATE_DELAY 39config GENERIC_CALIBRATE_DELAY
52 def_bool y 40 def_bool y
53 41
@@ -57,9 +45,6 @@ config GENERIC_TIME_VSYSCALL
57config GENERIC_CLOCKEVENTS 45config GENERIC_CLOCKEVENTS
58 def_bool y 46 def_bool y
59 47
60config GENERIC_HARDIRQS_NO__DO_IRQ
61 def_bool y
62
63config GENERIC_GPIO 48config GENERIC_GPIO
64 def_bool y 49 def_bool y
65 50
@@ -121,6 +106,23 @@ config CMDLINE_FORCE
121 Set this to have arguments from the default kernel command string 106 Set this to have arguments from the default kernel command string
122 override those passed by the boot loader. 107 override those passed by the boot loader.
123 108
109config SECCOMP
110 bool "Enable seccomp to safely compute untrusted bytecode"
111 depends on PROC_FS
112 default y
113 help
114 This kernel feature is useful for number crunching applications
115 that may need to compute untrusted bytecode during their
116 execution. By using pipes or other transports made available to
117 the process as file descriptors supporting the read/write
118 syscalls, it's possible to isolate those applications in
119 their own address space using seccomp. Once seccomp is
120 enabled via /proc/<pid>/seccomp, it cannot be disabled
121 and the task is only allowed to execute a few safe syscalls
122 defined by each seccomp mode.
123
124 If unsure, say Y. Only embedded should say N here.
125
124endmenu 126endmenu
125 127
126menu "Advanced setup" 128menu "Advanced setup"
@@ -178,6 +180,17 @@ config LOWMEM_SIZE
178 hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL 180 hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL
179 default "0x30000000" 181 default "0x30000000"
180 182
183config MANUAL_RESET_VECTOR
184 hex "Microblaze reset vector address setup"
185 default "0x0"
186 help
187 Set this option to have the kernel override the CPU Reset vector.
188 If zero, no change will be made to the MicroBlaze reset vector at
189 address 0x0.
190 If non-zero, a jump instruction to this address, will be written
191 to the reset vector at address 0x0.
192 If you are unsure, set it to default value 0x0.
193
181config KERNEL_START_BOOL 194config KERNEL_START_BOOL
182 bool "Set custom kernel base address" 195 bool "Set custom kernel base address"
183 depends on ADVANCED_OPTIONS 196 depends on ADVANCED_OPTIONS
@@ -242,7 +255,7 @@ endmenu
242 255
243source "mm/Kconfig" 256source "mm/Kconfig"
244 257
245menu "Exectuable file formats" 258menu "Executable file formats"
246 259
247source "fs/Kconfig.binfmt" 260source "fs/Kconfig.binfmt"
248 261
diff --git a/arch/microblaze/Kconfig.debug b/arch/microblaze/Kconfig.debug
index e6e5e0da28c3..012e377330cd 100644
--- a/arch/microblaze/Kconfig.debug
+++ b/arch/microblaze/Kconfig.debug
@@ -10,7 +10,7 @@ source "lib/Kconfig.debug"
10 10
11config EARLY_PRINTK 11config EARLY_PRINTK
12 bool "Early printk function for kernel" 12 bool "Early printk function for kernel"
13 depends on SERIAL_UARTLITE_CONSOLE 13 depends on SERIAL_UARTLITE_CONSOLE || SERIAL_8250_CONSOLE
14 default n 14 default n
15 help 15 help
16 This option turns on/off early printk messages to console. 16 This option turns on/off early printk messages to console.
@@ -23,8 +23,4 @@ config HEART_BEAT
23 This option turns on/off heart beat kernel functionality. 23 This option turns on/off heart beat kernel functionality.
24 First GPIO node is taken. 24 First GPIO node is taken.
25 25
26config DEBUG_BOOTMEM
27 depends on DEBUG_KERNEL
28 bool "Debug BOOTMEM initialization"
29
30endmenu 26endmenu
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile
index 592c7079de88..b23c40eb7a52 100644
--- a/arch/microblaze/Makefile
+++ b/arch/microblaze/Makefile
@@ -17,8 +17,8 @@ export CPU_VER CPU_MAJOR CPU_MINOR CPU_REV
17# The various CONFIG_XILINX cpu features options are integers 0/1/2... 17# The various CONFIG_XILINX cpu features options are integers 0/1/2...
18# rather than bools y/n 18# rather than bools y/n
19 19
20# Work out HW multipler support. This is icky. 20# Work out HW multipler support. This is tricky.
21# 1. Spartan2 has no HW multiplers. 21# 1. Spartan2 has no HW multipliers.
22# 2. MicroBlaze v3.x always uses them, except in Spartan 2 22# 2. MicroBlaze v3.x always uses them, except in Spartan 2
23# 3. All other FPGa/CPU ver combos, we can trust the CONFIG_ settings 23# 3. All other FPGa/CPU ver combos, we can trust the CONFIG_ settings
24ifeq (,$(findstring spartan2,$(CONFIG_XILINX_MICROBLAZE0_FAMILY))) 24ifeq (,$(findstring spartan2,$(CONFIG_XILINX_MICROBLAZE0_FAMILY)))
@@ -42,11 +42,8 @@ KBUILD_CFLAGS += -ffixed-r31 $(CPUFLAGS-1) $(CPUFLAGS-2)
42LDFLAGS := 42LDFLAGS :=
43LDFLAGS_vmlinux := 43LDFLAGS_vmlinux :=
44 44
45LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
46
47head-y := arch/microblaze/kernel/head.o 45head-y := arch/microblaze/kernel/head.o
48libs-y += arch/microblaze/lib/ 46libs-y += arch/microblaze/lib/
49libs-y += $(LIBGCC)
50core-y += arch/microblaze/kernel/ 47core-y += arch/microblaze/kernel/
51core-y += arch/microblaze/mm/ 48core-y += arch/microblaze/mm/
52core-y += arch/microblaze/platform/ 49core-y += arch/microblaze/platform/
@@ -72,12 +69,16 @@ export MMU DTB
72 69
73all: linux.bin 70all: linux.bin
74 71
75BOOT_TARGETS = linux.bin linux.bin.gz simpleImage.% 72# With make 3.82 we cannot mix normal and wildcard targets
73BOOT_TARGETS1 = linux.bin linux.bin.gz
74BOOT_TARGETS2 = simpleImage.%
76 75
77archclean: 76archclean:
78 $(Q)$(MAKE) $(clean)=$(boot) 77 $(Q)$(MAKE) $(clean)=$(boot)
79 78
80$(BOOT_TARGETS): vmlinux 79$(BOOT_TARGETS1): vmlinux
80 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
81$(BOOT_TARGETS2): vmlinux
81 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ 82 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
82 83
83define archhelp 84define archhelp
diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile
index be01d78750d9..4c4e58ef0cb6 100644
--- a/arch/microblaze/boot/Makefile
+++ b/arch/microblaze/boot/Makefile
@@ -10,9 +10,6 @@ targets := linux.bin linux.bin.gz simpleImage.%
10 10
11OBJCOPYFLAGS := -O binary 11OBJCOPYFLAGS := -O binary
12 12
13# Where the DTS files live
14dtstree := $(srctree)/$(src)/dts
15
16# Ensure system.dtb exists 13# Ensure system.dtb exists
17$(obj)/linked_dtb.o: $(obj)/system.dtb 14$(obj)/linked_dtb.o: $(obj)/system.dtb
18 15
@@ -51,14 +48,11 @@ $(obj)/simpleImage.%: vmlinux FORCE
51 $(call if_changed,strip) 48 $(call if_changed,strip)
52 @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' 49 @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
53 50
54# Rule to build device tree blobs
55DTC = $(objtree)/scripts/dtc/dtc
56 51
57# Rule to build device tree blobs 52# Rule to build device tree blobs
58quiet_cmd_dtc = DTC $@ 53DTC_FLAGS := -p 1024
59 cmd_dtc = $(DTC) -O dtb -o $(obj)/$*.dtb -b 0 -p 1024 $(dtstree)/$*.dts
60 54
61$(obj)/%.dtb: $(dtstree)/%.dts FORCE 55$(obj)/%.dtb: $(src)/dts/%.dts FORCE
62 $(call if_changed,dtc) 56 $(call cmd,dtc)
63 57
64clean-files += *.dtb simpleImage.*.unstrip linux.bin.ub 58clean-files += *.dtb simpleImage.*.unstrip linux.bin.ub
diff --git a/arch/microblaze/configs/mmu_defconfig b/arch/microblaze/configs/mmu_defconfig
index 8b422b12ef78..b3f5eecff2a7 100644
--- a/arch/microblaze/configs/mmu_defconfig
+++ b/arch/microblaze/configs/mmu_defconfig
@@ -7,7 +7,7 @@ CONFIG_BLK_DEV_INITRD=y
7CONFIG_INITRAMFS_SOURCE="rootfs.cpio" 7CONFIG_INITRAMFS_SOURCE="rootfs.cpio"
8CONFIG_INITRAMFS_COMPRESSION_GZIP=y 8CONFIG_INITRAMFS_COMPRESSION_GZIP=y
9# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 9# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
10CONFIG_EMBEDDED=y 10CONFIG_EXPERT=y
11CONFIG_KALLSYMS_ALL=y 11CONFIG_KALLSYMS_ALL=y
12CONFIG_KALLSYMS_EXTRA_PASS=y 12CONFIG_KALLSYMS_EXTRA_PASS=y
13# CONFIG_HOTPLUG is not set 13# CONFIG_HOTPLUG is not set
@@ -66,5 +66,4 @@ CONFIG_DEBUG_SPINLOCK=y
66CONFIG_DEBUG_INFO=y 66CONFIG_DEBUG_INFO=y
67# CONFIG_RCU_CPU_STALL_DETECTOR is not set 67# CONFIG_RCU_CPU_STALL_DETECTOR is not set
68CONFIG_EARLY_PRINTK=y 68CONFIG_EARLY_PRINTK=y
69CONFIG_DEBUG_BOOTMEM=y
70# CONFIG_CRYPTO_ANSI_CPRNG is not set 69# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/microblaze/configs/nommu_defconfig b/arch/microblaze/configs/nommu_defconfig
index ebc143c5368e..0249e4b7e1d3 100644
--- a/arch/microblaze/configs/nommu_defconfig
+++ b/arch/microblaze/configs/nommu_defconfig
@@ -6,7 +6,7 @@ CONFIG_BSD_PROCESS_ACCT_V3=y
6CONFIG_IKCONFIG=y 6CONFIG_IKCONFIG=y
7CONFIG_IKCONFIG_PROC=y 7CONFIG_IKCONFIG_PROC=y
8CONFIG_SYSFS_DEPRECATED_V2=y 8CONFIG_SYSFS_DEPRECATED_V2=y
9CONFIG_EMBEDDED=y 9CONFIG_EXPERT=y
10CONFIG_KALLSYMS_ALL=y 10CONFIG_KALLSYMS_ALL=y
11CONFIG_KALLSYMS_EXTRA_PASS=y 11CONFIG_KALLSYMS_EXTRA_PASS=y
12# CONFIG_HOTPLUG is not set 12# CONFIG_HOTPLUG is not set
diff --git a/arch/microblaze/include/asm/byteorder.h b/arch/microblaze/include/asm/byteorder.h
index ce9c58732ffc..31902762a426 100644
--- a/arch/microblaze/include/asm/byteorder.h
+++ b/arch/microblaze/include/asm/byteorder.h
@@ -1,6 +1,10 @@
1#ifndef _ASM_MICROBLAZE_BYTEORDER_H 1#ifndef _ASM_MICROBLAZE_BYTEORDER_H
2#define _ASM_MICROBLAZE_BYTEORDER_H 2#define _ASM_MICROBLAZE_BYTEORDER_H
3 3
4#ifdef __MICROBLAZEEL__
5#include <linux/byteorder/little_endian.h>
6#else
4#include <linux/byteorder/big_endian.h> 7#include <linux/byteorder/big_endian.h>
8#endif
5 9
6#endif /* _ASM_MICROBLAZE_BYTEORDER_H */ 10#endif /* _ASM_MICROBLAZE_BYTEORDER_H */
diff --git a/arch/microblaze/include/asm/cacheflush.h b/arch/microblaze/include/asm/cacheflush.h
index 7ebd955460d9..0f553bc009a0 100644
--- a/arch/microblaze/include/asm/cacheflush.h
+++ b/arch/microblaze/include/asm/cacheflush.h
@@ -84,12 +84,13 @@ do { \
84#define flush_dcache_mmap_lock(mapping) do { } while (0) 84#define flush_dcache_mmap_lock(mapping) do { } while (0)
85#define flush_dcache_mmap_unlock(mapping) do { } while (0) 85#define flush_dcache_mmap_unlock(mapping) do { } while (0)
86 86
87
88#define flush_cache_dup_mm(mm) do { } while (0) 87#define flush_cache_dup_mm(mm) do { } while (0)
89#define flush_cache_vmap(start, end) do { } while (0) 88#define flush_cache_vmap(start, end) do { } while (0)
90#define flush_cache_vunmap(start, end) do { } while (0) 89#define flush_cache_vunmap(start, end) do { } while (0)
91#define flush_cache_mm(mm) do { } while (0) 90#define flush_cache_mm(mm) do { } while (0)
92#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) 91
92#define flush_cache_page(vma, vmaddr, pfn) \
93 flush_dcache_range(pfn << PAGE_SHIFT, (pfn << PAGE_SHIFT) + PAGE_SIZE);
93 94
94/* MS: kgdb code use this macro, wrong len with FLASH */ 95/* MS: kgdb code use this macro, wrong len with FLASH */
95#if 0 96#if 0
@@ -104,9 +105,13 @@ do { \
104#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ 105#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
105do { \ 106do { \
106 u32 addr = virt_to_phys(dst); \ 107 u32 addr = virt_to_phys(dst); \
107 invalidate_icache_range((unsigned) (addr), (unsigned) (addr) + (len));\
108 memcpy((dst), (src), (len)); \ 108 memcpy((dst), (src), (len)); \
109 flush_dcache_range((unsigned) (addr), (unsigned) (addr) + (len));\ 109 if (vma->vm_flags & VM_EXEC) { \
110 invalidate_icache_range((unsigned) (addr), \
111 (unsigned) (addr) + PAGE_SIZE); \
112 flush_dcache_range((unsigned) (addr), \
113 (unsigned) (addr) + PAGE_SIZE); \
114 } \
110} while (0) 115} while (0)
111 116
112#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ 117#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
diff --git a/arch/microblaze/include/asm/checksum.h b/arch/microblaze/include/asm/checksum.h
index 128bf03b54b7..0185cbefdda4 100644
--- a/arch/microblaze/include/asm/checksum.h
+++ b/arch/microblaze/include/asm/checksum.h
@@ -24,8 +24,13 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
24 "addc %0, %0, %3\n\t" 24 "addc %0, %0, %3\n\t"
25 "addc %0, %0, r0\n\t" 25 "addc %0, %0, r0\n\t"
26 : "+&d" (sum) 26 : "+&d" (sum)
27 : "d" (saddr), "d" (daddr), "d" (len + proto)); 27 : "d" (saddr), "d" (daddr),
28 28#ifdef __MICROBLAZEEL__
29 "d" ((len + proto) << 8)
30#else
31 "d" (len + proto)
32#endif
33);
29 return sum; 34 return sum;
30} 35}
31 36
diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h
index b4f5ca33aebf..d8f013347a9e 100644
--- a/arch/microblaze/include/asm/cpuinfo.h
+++ b/arch/microblaze/include/asm/cpuinfo.h
@@ -38,6 +38,7 @@ struct cpuinfo {
38 u32 use_exc; 38 u32 use_exc;
39 u32 ver_code; 39 u32 ver_code;
40 u32 mmu; 40 u32 mmu;
41 u32 endian;
41 42
42 /* CPU caches */ 43 /* CPU caches */
43 u32 use_icache; 44 u32 use_icache;
@@ -76,7 +77,6 @@ struct cpuinfo {
76 u32 num_rd_brk; 77 u32 num_rd_brk;
77 u32 num_wr_brk; 78 u32 num_wr_brk;
78 u32 cpu_clock_freq; /* store real freq of cpu */ 79 u32 cpu_clock_freq; /* store real freq of cpu */
79 u32 freq_div_hz; /* store freq/HZ */
80 80
81 /* FPGA family */ 81 /* FPGA family */
82 u32 fpga_family_code; 82 u32 fpga_family_code;
@@ -96,8 +96,9 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu);
96 96
97static inline unsigned int fcpu(struct device_node *cpu, char *n) 97static inline unsigned int fcpu(struct device_node *cpu, char *n)
98{ 98{
99 int *val; 99 const __be32 *val;
100 return (val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0; 100 return (val = of_get_property(cpu, n, NULL)) ?
101 be32_to_cpup(val) : 0;
101} 102}
102 103
103#endif /* _ASM_MICROBLAZE_CPUINFO_H */ 104#endif /* _ASM_MICROBLAZE_CPUINFO_H */
diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h
index 732caf1be741..098dfdde4b06 100644
--- a/arch/microblaze/include/asm/elf.h
+++ b/arch/microblaze/include/asm/elf.h
@@ -71,7 +71,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
71 71
72#define ELF_ET_DYN_BASE (0x08000000) 72#define ELF_ET_DYN_BASE (0x08000000)
73 73
74#ifdef __LITTLE_ENDIAN__ 74#ifdef __MICROBLAZEEL__
75#define ELF_DATA ELFDATA2LSB 75#define ELF_DATA ELFDATA2LSB
76#else 76#else
77#define ELF_DATA ELFDATA2MSB 77#define ELF_DATA ELFDATA2MSB
diff --git a/arch/microblaze/include/asm/entry.h b/arch/microblaze/include/asm/entry.h
index ec89f2ad0fe1..af0144b91b79 100644
--- a/arch/microblaze/include/asm/entry.h
+++ b/arch/microblaze/include/asm/entry.h
@@ -31,40 +31,4 @@ DECLARE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */
31DECLARE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */ 31DECLARE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */
32# endif /* __ASSEMBLY__ */ 32# endif /* __ASSEMBLY__ */
33 33
34#ifndef CONFIG_MMU
35
36/* noMMU hasn't any space for args */
37# define STATE_SAVE_ARG_SPACE (0)
38
39#else /* CONFIG_MMU */
40
41/* If true, system calls save and restore all registers (except result
42 * registers, of course). If false, then `call clobbered' registers
43 * will not be preserved, on the theory that system calls are basically
44 * function calls anyway, and the caller should be able to deal with it.
45 * This is a security risk, of course, as `internal' values may leak out
46 * after a system call, but that certainly doesn't matter very much for
47 * a processor with no MMU protection! For a protected-mode kernel, it
48 * would be faster to just zero those registers before returning.
49 *
50 * I can not rely on the glibc implementation. If you turn it off make
51 * sure that r11/r12 is saved in user-space. --KAA
52 *
53 * These are special variables using by the kernel trap/interrupt code
54 * to save registers in, at a time when there are no spare registers we
55 * can use to do so, and we can't depend on the value of the stack
56 * pointer. This means that they must be within a signed 16-bit
57 * displacement of 0x00000000.
58 */
59
60/* A `state save frame' is a struct pt_regs preceded by some extra space
61 * suitable for a function call stack frame. */
62
63/* Amount of room on the stack reserved for arguments and to satisfy the
64 * C calling conventions, in addition to the space used by the struct
65 * pt_regs that actually holds saved values. */
66#define STATE_SAVE_ARG_SPACE (6*4) /* Up to six arguments */
67
68#endif /* CONFIG_MMU */
69
70#endif /* _ASM_MICROBLAZE_ENTRY_H */ 34#endif /* _ASM_MICROBLAZE_ENTRY_H */
diff --git a/arch/microblaze/include/asm/exceptions.h b/arch/microblaze/include/asm/exceptions.h
index 6479097b802b..e6a8ddea1dca 100644
--- a/arch/microblaze/include/asm/exceptions.h
+++ b/arch/microblaze/include/asm/exceptions.h
@@ -66,6 +66,9 @@
66asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, 66asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
67 int fsr, int addr); 67 int fsr, int addr);
68 68
69asmlinkage void sw_exception(struct pt_regs *regs);
70void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig);
71
69void die(const char *str, struct pt_regs *fp, long err); 72void die(const char *str, struct pt_regs *fp, long err);
70void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr); 73void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr);
71 74
diff --git a/arch/microblaze/include/asm/futex.h b/arch/microblaze/include/asm/futex.h
index ad3fd61b2fe7..b0526d2716fa 100644
--- a/arch/microblaze/include/asm/futex.h
+++ b/arch/microblaze/include/asm/futex.h
@@ -29,7 +29,7 @@
29}) 29})
30 30
31static inline int 31static inline int
32futex_atomic_op_inuser(int encoded_op, int __user *uaddr) 32futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
33{ 33{
34 int op = (encoded_op >> 28) & 7; 34 int op = (encoded_op >> 28) & 7;
35 int cmp = (encoded_op >> 24) & 15; 35 int cmp = (encoded_op >> 24) & 15;
@@ -39,7 +39,7 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
39 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) 39 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
40 oparg = 1 << oparg; 40 oparg = 1 << oparg;
41 41
42 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) 42 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
43 return -EFAULT; 43 return -EFAULT;
44 44
45 pagefault_disable(); 45 pagefault_disable();
@@ -94,31 +94,34 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
94} 94}
95 95
96static inline int 96static inline int
97futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) 97futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
98 u32 oldval, u32 newval)
98{ 99{
99 int prev, cmp; 100 int ret = 0, cmp;
101 u32 prev;
100 102
101 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) 103 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
102 return -EFAULT; 104 return -EFAULT;
103 105
104 __asm__ __volatile__ ("1: lwx %0, %2, r0; \ 106 __asm__ __volatile__ ("1: lwx %1, %3, r0; \
105 cmp %1, %0, %3; \ 107 cmp %2, %1, %4; \
106 beqi %1, 3f; \ 108 beqi %2, 3f; \
107 2: swx %4, %2, r0; \ 109 2: swx %5, %3, r0; \
108 addic %1, r0, 0; \ 110 addic %2, r0, 0; \
109 bnei %1, 1b; \ 111 bnei %2, 1b; \
110 3: \ 112 3: \
111 .section .fixup,\"ax\"; \ 113 .section .fixup,\"ax\"; \
112 4: brid 3b; \ 114 4: brid 3b; \
113 addik %0, r0, %5; \ 115 addik %0, r0, %6; \
114 .previous; \ 116 .previous; \
115 .section __ex_table,\"a\"; \ 117 .section __ex_table,\"a\"; \
116 .word 1b,4b,2b,4b; \ 118 .word 1b,4b,2b,4b; \
117 .previous;" \ 119 .previous;" \
118 : "=&r" (prev), "=&r"(cmp) \ 120 : "+r" (ret), "=&r" (prev), "=&r"(cmp) \
119 : "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT)); 121 : "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT));
120 122
121 return prev; 123 *uval = prev;
124 return ret;
122} 125}
123 126
124#endif /* __KERNEL__ */ 127#endif /* __KERNEL__ */
diff --git a/arch/microblaze/include/asm/gpio.h b/arch/microblaze/include/asm/gpio.h
index 2345ac354d9b..2b2c18be71c6 100644
--- a/arch/microblaze/include/asm/gpio.h
+++ b/arch/microblaze/include/asm/gpio.h
@@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio)
38 return __gpio_cansleep(gpio); 38 return __gpio_cansleep(gpio);
39} 39}
40 40
41/*
42 * Not implemented, yet.
43 */
44static inline int gpio_to_irq(unsigned int gpio) 41static inline int gpio_to_irq(unsigned int gpio)
45{ 42{
46 return -ENOSYS; 43 return __gpio_to_irq(gpio);
47} 44}
48 45
49static inline int irq_to_gpio(unsigned int irq) 46static inline int irq_to_gpio(unsigned int irq)
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h
index 00b5398d08c7..8cdac14b55b0 100644
--- a/arch/microblaze/include/asm/io.h
+++ b/arch/microblaze/include/asm/io.h
@@ -70,7 +70,7 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
70 70
71/* 71/*
72 * read (readb, readw, readl, readq) and write (writeb, writew, 72 * read (readb, readw, readl, readq) and write (writeb, writew,
73 * writel, writeq) accessors are for PCI and thus littel endian. 73 * writel, writeq) accessors are for PCI and thus little endian.
74 * Linux 2.4 for Microblaze had this wrong. 74 * Linux 2.4 for Microblaze had this wrong.
75 */ 75 */
76static inline unsigned char readb(const volatile void __iomem *addr) 76static inline unsigned char readb(const volatile void __iomem *addr)
@@ -243,6 +243,8 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size,
243#define out_8(a, v) __raw_writeb((v), (a)) 243#define out_8(a, v) __raw_writeb((v), (a))
244#define in_8(a) __raw_readb(a) 244#define in_8(a) __raw_readb(a)
245 245
246#define mmiowb()
247
246#define ioport_map(port, nr) ((void __iomem *)(port)) 248#define ioport_map(port, nr) ((void __iomem *)(port))
247#define ioport_unmap(addr) 249#define ioport_unmap(addr)
248 250
diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h
index ec5583d6111c..cc54187f3d38 100644
--- a/arch/microblaze/include/asm/irq.h
+++ b/arch/microblaze/include/asm/irq.h
@@ -12,8 +12,6 @@
12#define NR_IRQS 32 12#define NR_IRQS 32
13#include <asm-generic/irq.h> 13#include <asm-generic/irq.h>
14 14
15#include <linux/interrupt.h>
16
17/* This type is the placeholder for a hardware interrupt number. It has to 15/* This type is the placeholder for a hardware interrupt number. It has to
18 * be big enough to enclose whatever representation is used by a given 16 * be big enough to enclose whatever representation is used by a given
19 * platform. 17 * platform.
diff --git a/arch/microblaze/include/asm/irqflags.h b/arch/microblaze/include/asm/irqflags.h
index 2c38c6d80176..c4532f032b3b 100644
--- a/arch/microblaze/include/asm/irqflags.h
+++ b/arch/microblaze/include/asm/irqflags.h
@@ -9,103 +9,114 @@
9#ifndef _ASM_MICROBLAZE_IRQFLAGS_H 9#ifndef _ASM_MICROBLAZE_IRQFLAGS_H
10#define _ASM_MICROBLAZE_IRQFLAGS_H 10#define _ASM_MICROBLAZE_IRQFLAGS_H
11 11
12#include <linux/irqflags.h> 12#include <linux/types.h>
13#include <asm/registers.h> 13#include <asm/registers.h>
14 14
15# if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR 15#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
16 16
17# define raw_local_irq_save(flags) \ 17static inline unsigned long arch_local_irq_save(void)
18 do { \ 18{
19 asm volatile (" msrclr %0, %1; \ 19 unsigned long flags;
20 nop;" \ 20 asm volatile(" msrclr %0, %1 \n"
21 : "=r"(flags) \ 21 " nop \n"
22 : "i"(MSR_IE) \ 22 : "=r"(flags)
23 : "memory"); \ 23 : "i"(MSR_IE)
24 } while (0) 24 : "memory");
25 25 return flags;
26# define raw_local_irq_disable() \ 26}
27 do { \ 27
28 asm volatile (" msrclr r0, %0; \ 28static inline void arch_local_irq_disable(void)
29 nop;" \ 29{
30 : \ 30 /* this uses r0 without declaring it - is that correct? */
31 : "i"(MSR_IE) \ 31 asm volatile(" msrclr r0, %0 \n"
32 : "memory"); \ 32 " nop \n"
33 } while (0) 33 :
34 34 : "i"(MSR_IE)
35# define raw_local_irq_enable() \ 35 : "memory");
36 do { \ 36}
37 asm volatile (" msrset r0, %0; \ 37
38 nop;" \ 38static inline void arch_local_irq_enable(void)
39 : \ 39{
40 : "i"(MSR_IE) \ 40 /* this uses r0 without declaring it - is that correct? */
41 : "memory"); \ 41 asm volatile(" msrset r0, %0 \n"
42 } while (0) 42 " nop \n"
43 43 :
44# else /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR == 0 */ 44 : "i"(MSR_IE)
45 45 : "memory");
46# define raw_local_irq_save(flags) \ 46}
47 do { \ 47
48 register unsigned tmp; \ 48#else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
49 asm volatile (" mfs %0, rmsr; \ 49
50 nop; \ 50static inline unsigned long arch_local_irq_save(void)
51 andi %1, %0, %2; \ 51{
52 mts rmsr, %1; \ 52 unsigned long flags, tmp;
53 nop;" \ 53 asm volatile (" mfs %0, rmsr \n"
54 : "=r"(flags), "=r" (tmp) \ 54 " nop \n"
55 : "i"(~MSR_IE) \ 55 " andi %1, %0, %2 \n"
56 : "memory"); \ 56 " mts rmsr, %1 \n"
57 } while (0) 57 " nop \n"
58 58 : "=r"(flags), "=r"(tmp)
59# define raw_local_irq_disable() \ 59 : "i"(~MSR_IE)
60 do { \ 60 : "memory");
61 register unsigned tmp; \ 61 return flags;
62 asm volatile (" mfs %0, rmsr; \ 62}
63 nop; \ 63
64 andi %0, %0, %1; \ 64static inline void arch_local_irq_disable(void)
65 mts rmsr, %0; \ 65{
66 nop;" \ 66 unsigned long tmp;
67 : "=r"(tmp) \ 67 asm volatile(" mfs %0, rmsr \n"
68 : "i"(~MSR_IE) \ 68 " nop \n"
69 : "memory"); \ 69 " andi %0, %0, %1 \n"
70 } while (0) 70 " mts rmsr, %0 \n"
71 71 " nop \n"
72# define raw_local_irq_enable() \ 72 : "=r"(tmp)
73 do { \ 73 : "i"(~MSR_IE)
74 register unsigned tmp; \ 74 : "memory");
75 asm volatile (" mfs %0, rmsr; \ 75}
76 nop; \ 76
77 ori %0, %0, %1; \ 77static inline void arch_local_irq_enable(void)
78 mts rmsr, %0; \ 78{
79 nop;" \ 79 unsigned long tmp;
80 : "=r"(tmp) \ 80 asm volatile(" mfs %0, rmsr \n"
81 : "i"(MSR_IE) \ 81 " nop \n"
82 : "memory"); \ 82 " ori %0, %0, %1 \n"
83 } while (0) 83 " mts rmsr, %0 \n"
84 84 " nop \n"
85# endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */ 85 : "=r"(tmp)
86 86 : "i"(MSR_IE)
87#define raw_local_irq_restore(flags) \ 87 : "memory");
88 do { \ 88}
89 asm volatile (" mts rmsr, %0; \ 89
90 nop;" \ 90#endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
91 : \ 91
92 : "r"(flags) \ 92static inline unsigned long arch_local_save_flags(void)
93 : "memory"); \
94 } while (0)
95
96static inline unsigned long get_msr(void)
97{ 93{
98 unsigned long flags; 94 unsigned long flags;
99 asm volatile (" mfs %0, rmsr; \ 95 asm volatile(" mfs %0, rmsr \n"
100 nop;" \ 96 " nop \n"
101 : "=r"(flags) \ 97 : "=r"(flags)
102 : \ 98 :
103 : "memory"); \ 99 : "memory");
104 return flags; 100 return flags;
105} 101}
106 102
107#define raw_local_save_flags(flags) ((flags) = get_msr()) 103static inline void arch_local_irq_restore(unsigned long flags)
108#define raw_irqs_disabled() ((get_msr() & MSR_IE) == 0) 104{
109#define raw_irqs_disabled_flags(flags) ((flags & MSR_IE) == 0) 105 asm volatile(" mts rmsr, %0 \n"
106 " nop \n"
107 :
108 : "r"(flags)
109 : "memory");
110}
111
112static inline bool arch_irqs_disabled_flags(unsigned long flags)
113{
114 return (flags & MSR_IE) == 0;
115}
116
117static inline bool arch_irqs_disabled(void)
118{
119 return arch_irqs_disabled_flags(arch_local_save_flags());
120}
110 121
111#endif /* _ASM_MICROBLAZE_IRQFLAGS_H */ 122#endif /* _ASM_MICROBLAZE_IRQFLAGS_H */
diff --git a/arch/microblaze/include/asm/memblock.h b/arch/microblaze/include/asm/memblock.h
index f9c2fa331d2a..20a8e257c77f 100644
--- a/arch/microblaze/include/asm/memblock.h
+++ b/arch/microblaze/include/asm/memblock.h
@@ -9,9 +9,6 @@
9#ifndef _ASM_MICROBLAZE_MEMBLOCK_H 9#ifndef _ASM_MICROBLAZE_MEMBLOCK_H
10#define _ASM_MICROBLAZE_MEMBLOCK_H 10#define _ASM_MICROBLAZE_MEMBLOCK_H
11 11
12/* MEMBLOCK limit is OFF */
13#define MEMBLOCK_REAL_LIMIT 0xFFFFFFFF
14
15#endif /* _ASM_MICROBLAZE_MEMBLOCK_H */ 12#endif /* _ASM_MICROBLAZE_MEMBLOCK_H */
16 13
17 14
diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h
index cf377d91da71..ed9d0f6e2cdb 100644
--- a/arch/microblaze/include/asm/page.h
+++ b/arch/microblaze/include/asm/page.h
@@ -205,9 +205,6 @@ extern int page_is_ram(unsigned long pfn);
205#define TOPHYS(addr) __virt_to_phys(addr) 205#define TOPHYS(addr) __virt_to_phys(addr)
206 206
207#ifdef CONFIG_MMU 207#ifdef CONFIG_MMU
208#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
209#define WANT_PAGE_VIRTUAL 1 /* page alloc 2 relies on this */
210#endif
211 208
212#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ 209#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
213 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 210 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
index 0c68764ab547..746df91e5796 100644
--- a/arch/microblaze/include/asm/pci-bridge.h
+++ b/arch/microblaze/include/asm/pci-bridge.h
@@ -76,7 +76,7 @@ struct pci_controller {
76 * Used for variants of PCI indirect handling and possible quirks: 76 * Used for variants of PCI indirect handling and possible quirks:
77 * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1 77 * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
78 * EXT_REG - provides access to PCI-e extended registers 78 * EXT_REG - provides access to PCI-e extended registers
79 * SURPRESS_PRIMARY_BUS - we surpress the setting of PCI_PRIMARY_BUS 79 * SURPRESS_PRIMARY_BUS - we suppress the setting of PCI_PRIMARY_BUS
80 * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS 80 * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
81 * to determine which bus number to match on when generating type0 81 * to determine which bus number to match on when generating type0
82 * config cycles 82 * config cycles
@@ -104,11 +104,22 @@ struct pci_controller {
104 int global_number; /* PCI domain number */ 104 int global_number; /* PCI domain number */
105}; 105};
106 106
107#ifdef CONFIG_PCI
107static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) 108static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
108{ 109{
109 return bus->sysdata; 110 return bus->sysdata;
110} 111}
111 112
113static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
114{
115 struct pci_controller *host;
116
117 if (bus->self)
118 return pci_device_to_OF_node(bus->self);
119 host = pci_bus_to_host(bus);
120 return host ? host->dn : NULL;
121}
122
112static inline int isa_vaddr_is_ioport(void __iomem *address) 123static inline int isa_vaddr_is_ioport(void __iomem *address)
113{ 124{
114 /* No specific ISA handling on ppc32 at this stage, it 125 /* No specific ISA handling on ppc32 at this stage, it
@@ -116,6 +127,7 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
116 */ 127 */
117 return 0; 128 return 0;
118} 129}
130#endif /* CONFIG_PCI */
119 131
120/* These are used for config access before all the PCI probing 132/* These are used for config access before all the PCI probing
121 has been done. */ 133 has been done. */
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h
index 5a388eeeb28f..ba65cf472544 100644
--- a/arch/microblaze/include/asm/pci.h
+++ b/arch/microblaze/include/asm/pci.h
@@ -158,12 +158,14 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
158extern void pcibios_setup_bus_devices(struct pci_bus *bus); 158extern void pcibios_setup_bus_devices(struct pci_bus *bus);
159extern void pcibios_setup_bus_self(struct pci_bus *bus); 159extern void pcibios_setup_bus_self(struct pci_bus *bus);
160 160
161/* This part of code was originaly in xilinx-pci.h */ 161/* This part of code was originally in xilinx-pci.h */
162#ifdef CONFIG_PCI_XILINX 162#ifdef CONFIG_PCI_XILINX
163extern void __init xilinx_pci_init(void); 163extern void __init xilinx_pci_init(void);
164#else 164#else
165static inline void __init xilinx_pci_init(void) { return; } 165static inline void __init xilinx_pci_init(void) { return; }
166#endif 166#endif
167 167
168#include <asm-generic/pci-dma-compat.h>
169
168#endif /* __KERNEL__ */ 170#endif /* __KERNEL__ */
169#endif /* __ASM_MICROBLAZE_PCI_H */ 171#endif /* __ASM_MICROBLAZE_PCI_H */
diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h
index c614a893f8a3..ebd35792482c 100644
--- a/arch/microblaze/include/asm/pgalloc.h
+++ b/arch/microblaze/include/asm/pgalloc.h
@@ -165,7 +165,8 @@ extern inline void pte_free(struct mm_struct *mm, struct page *ptepage)
165 165
166#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, (pte)) 166#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, (pte))
167 167
168#define pmd_populate(mm, pmd, pte) (pmd_val(*(pmd)) = page_address(pte)) 168#define pmd_populate(mm, pmd, pte) \
169 (pmd_val(*(pmd)) = (unsigned long)page_address(pte))
169 170
170#define pmd_populate_kernel(mm, pmd, pte) \ 171#define pmd_populate_kernel(mm, pmd, pte) \
171 (pmd_val(*(pmd)) = (unsigned long) (pte)) 172 (pmd_val(*(pmd)) = (unsigned long) (pte))
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h
index ca2d92871545..b2af42311a12 100644
--- a/arch/microblaze/include/asm/pgtable.h
+++ b/arch/microblaze/include/asm/pgtable.h
@@ -57,6 +57,13 @@ static inline int pte_file(pte_t pte) { return 0; }
57 57
58#define pgprot_noncached_wc(prot) prot 58#define pgprot_noncached_wc(prot) prot
59 59
60/*
61 * All 32bit addresses are effectively valid for vmalloc...
62 * Sort of meaningless for non-VM targets.
63 */
64#define VMALLOC_START 0
65#define VMALLOC_END 0xffffffff
66
60#else /* CONFIG_MMU */ 67#else /* CONFIG_MMU */
61 68
62#include <asm-generic/4level-fixup.h> 69#include <asm-generic/4level-fixup.h>
@@ -404,20 +411,19 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
404static inline unsigned long pte_update(pte_t *p, unsigned long clr, 411static inline unsigned long pte_update(pte_t *p, unsigned long clr,
405 unsigned long set) 412 unsigned long set)
406{ 413{
407 unsigned long old, tmp, msr; 414 unsigned long flags, old, tmp;
408 415
409 __asm__ __volatile__("\ 416 raw_local_irq_save(flags);
410 msrclr %2, 0x2\n\ 417
411 nop\n\ 418 __asm__ __volatile__( "lw %0, %2, r0 \n"
412 lw %0, %4, r0\n\ 419 "andn %1, %0, %3 \n"
413 andn %1, %0, %5\n\ 420 "or %1, %1, %4 \n"
414 or %1, %1, %6\n\ 421 "sw %1, %2, r0 \n"
415 sw %1, %4, r0\n\ 422 : "=&r" (old), "=&r" (tmp)
416 mts rmsr, %2\n\ 423 : "r" ((unsigned long)(p + 1) - 4), "r" (clr), "r" (set)
417 nop" 424 : "cc");
418 : "=&r" (old), "=&r" (tmp), "=&r" (msr), "=m" (*p) 425
419 : "r" ((unsigned long)(p + 1) - 4), "r" (clr), "r" (set), "m" (*p) 426 raw_local_irq_restore(flags);
420 : "cc");
421 427
422 return old; 428 return old;
423} 429}
@@ -437,8 +443,9 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
437 *ptep = pte; 443 *ptep = pte;
438} 444}
439 445
440static inline int ptep_test_and_clear_young(struct mm_struct *mm, 446#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
441 unsigned long addr, pte_t *ptep) 447static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
448 unsigned long address, pte_t *ptep)
442{ 449{
443 return (pte_update(ptep, _PAGE_ACCESSED, 0) & _PAGE_ACCESSED) != 0; 450 return (pte_update(ptep, _PAGE_ACCESSED, 0) & _PAGE_ACCESSED) != 0;
444} 451}
@@ -450,6 +457,7 @@ static inline int ptep_test_and_clear_dirty(struct mm_struct *mm,
450 (_PAGE_DIRTY | _PAGE_HWWRITE), 0) & _PAGE_DIRTY) != 0; 457 (_PAGE_DIRTY | _PAGE_HWWRITE), 0) & _PAGE_DIRTY) != 0;
451} 458}
452 459
460#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
453static inline pte_t ptep_get_and_clear(struct mm_struct *mm, 461static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
454 unsigned long addr, pte_t *ptep) 462 unsigned long addr, pte_t *ptep)
455{ 463{
@@ -497,12 +505,9 @@ static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
497#define pte_offset_kernel(dir, addr) \ 505#define pte_offset_kernel(dir, addr) \
498 ((pte_t *) pmd_page_kernel(*(dir)) + pte_index(addr)) 506 ((pte_t *) pmd_page_kernel(*(dir)) + pte_index(addr))
499#define pte_offset_map(dir, addr) \ 507#define pte_offset_map(dir, addr) \
500 ((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE0) + pte_index(addr)) 508 ((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr))
501#define pte_offset_map_nested(dir, addr) \
502 ((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE1) + pte_index(addr))
503 509
504#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) 510#define pte_unmap(pte) kunmap_atomic(pte)
505#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
506 511
507/* Encode and decode a nonlinear file mapping entry */ 512/* Encode and decode a nonlinear file mapping entry */
508#define PTE_FILE_MAX_BITS 29 513#define PTE_FILE_MAX_BITS 29
@@ -567,7 +572,7 @@ void __init *early_get_page(void);
567 572
568extern unsigned long ioremap_bot, ioremap_base; 573extern unsigned long ioremap_bot, ioremap_base;
569 574
570void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle); 575void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle);
571void consistent_free(size_t size, void *vaddr); 576void consistent_free(size_t size, void *vaddr);
572void consistent_sync(void *vaddr, size_t size, int direction); 577void consistent_sync(void *vaddr, size_t size, int direction);
573void consistent_sync_page(struct page *page, unsigned long offset, 578void consistent_sync_page(struct page *page, unsigned long offset,
diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h
index 8eeb09211ece..aed2a6be8e27 100644
--- a/arch/microblaze/include/asm/processor.h
+++ b/arch/microblaze/include/asm/processor.h
@@ -155,7 +155,7 @@ unsigned long get_wchan(struct task_struct *p);
155# define task_regs(task) ((struct pt_regs *)task_tos(task) - 1) 155# define task_regs(task) ((struct pt_regs *)task_tos(task) - 1)
156 156
157# define task_pt_regs_plus_args(tsk) \ 157# define task_pt_regs_plus_args(tsk) \
158 (((void *)task_pt_regs(tsk)) - STATE_SAVE_ARG_SPACE) 158 ((void *)task_pt_regs(tsk))
159 159
160# define task_sp(task) (task_regs(task)->r1) 160# define task_sp(task) (task_regs(task)->r1)
161# define task_pc(task) (task_regs(task)->pc) 161# define task_pc(task) (task_regs(task)->pc)
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index 101fa098f62a..d0890d36ef61 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -27,6 +27,7 @@
27 27
28/* Other Prototypes */ 28/* Other Prototypes */
29extern int early_uartlite_console(void); 29extern int early_uartlite_console(void);
30extern int early_uart16550_console(void);
30 31
31#ifdef CONFIG_PCI 32#ifdef CONFIG_PCI
32/* 33/*
@@ -63,24 +64,6 @@ extern void kdump_move_device_tree(void);
63/* CPU OF node matching */ 64/* CPU OF node matching */
64struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); 65struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
65 66
66/* Get the MAC address */
67extern const void *of_get_mac_address(struct device_node *np);
68
69/**
70 * of_irq_map_pci - Resolve the interrupt for a PCI device
71 * @pdev: the device whose interrupt is to be resolved
72 * @out_irq: structure of_irq filled by this function
73 *
74 * This function resolves the PCI interrupt for a given PCI device. If a
75 * device-node exists for a given pci_dev, it will use normal OF tree
76 * walking. If not, it will implement standard swizzling and walk up the
77 * PCI tree until an device-node is found, at which point it will finish
78 * resolving using the OF tree walking.
79 */
80struct pci_dev;
81struct of_irq;
82extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
83
84#endif /* __ASSEMBLY__ */ 67#endif /* __ASSEMBLY__ */
85#endif /* __KERNEL__ */ 68#endif /* __KERNEL__ */
86 69
diff --git a/arch/microblaze/include/asm/ptrace.h b/arch/microblaze/include/asm/ptrace.h
index d74dbfb92c04..d9b66304d5dd 100644
--- a/arch/microblaze/include/asm/ptrace.h
+++ b/arch/microblaze/include/asm/ptrace.h
@@ -66,13 +66,13 @@ void show_regs(struct pt_regs *);
66#else /* __KERNEL__ */ 66#else /* __KERNEL__ */
67 67
68/* pt_regs offsets used by gdbserver etc in ptrace syscalls */ 68/* pt_regs offsets used by gdbserver etc in ptrace syscalls */
69#define PT_GPR(n) ((n) * sizeof(microblaze_reg_t)) 69#define PT_GPR(n) ((n) * sizeof(microblaze_reg_t))
70#define PT_PC (32 * sizeof(microblaze_reg_t)) 70#define PT_PC (32 * sizeof(microblaze_reg_t))
71#define PT_MSR (33 * sizeof(microblaze_reg_t)) 71#define PT_MSR (33 * sizeof(microblaze_reg_t))
72#define PT_EAR (34 * sizeof(microblaze_reg_t)) 72#define PT_EAR (34 * sizeof(microblaze_reg_t))
73#define PT_ESR (35 * sizeof(microblaze_reg_t)) 73#define PT_ESR (35 * sizeof(microblaze_reg_t))
74#define PT_FSR (36 * sizeof(microblaze_reg_t)) 74#define PT_FSR (36 * sizeof(microblaze_reg_t))
75#define PT_KERNEL_MODE (37 * sizeof(microblaze_reg_t)) 75#define PT_KERNEL_MODE (37 * sizeof(microblaze_reg_t))
76 76
77#endif /* __KERNEL */ 77#endif /* __KERNEL */
78 78
diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h
index 9578666e98ba..a10bec62e857 100644
--- a/arch/microblaze/include/asm/pvr.h
+++ b/arch/microblaze/include/asm/pvr.h
@@ -1,9 +1,9 @@
1/* 1/*
2 * Support for the MicroBlaze PVR (Processor Version Register) 2 * Support for the MicroBlaze PVR (Processor Version Register)
3 * 3 *
4 * Copyright (C) 2009 Michal Simek <monstr@monstr.eu> 4 * Copyright (C) 2009 - 2011 Michal Simek <monstr@monstr.eu>
5 * Copyright (C) 2007 John Williams <john.williams@petalogix.com> 5 * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
6 * Copyright (C) 2007 - 2009 PetaLogix 6 * Copyright (C) 2007 - 2011 PetaLogix
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General 8 * This file is subject to the terms and conditions of the GNU General
9 * Public License. See the file COPYING in the main directory of this 9 * Public License. See the file COPYING in the main directory of this
@@ -30,7 +30,9 @@ struct pvr_s {
30#define PVR0_USE_EXC_MASK 0x04000000 30#define PVR0_USE_EXC_MASK 0x04000000
31#define PVR0_USE_ICACHE_MASK 0x02000000 31#define PVR0_USE_ICACHE_MASK 0x02000000
32#define PVR0_USE_DCACHE_MASK 0x01000000 32#define PVR0_USE_DCACHE_MASK 0x01000000
33#define PVR0_USE_MMU 0x00800000 /* new */ 33#define PVR0_USE_MMU 0x00800000
34#define PVR0_USE_BTC 0x00400000
35#define PVR0_ENDI 0x00200000
34#define PVR0_VERSION_MASK 0x0000FF00 36#define PVR0_VERSION_MASK 0x0000FF00
35#define PVR0_USER1_MASK 0x000000FF 37#define PVR0_USER1_MASK 0x000000FF
36 38
@@ -38,17 +40,17 @@ struct pvr_s {
38#define PVR1_USER2_MASK 0xFFFFFFFF 40#define PVR1_USER2_MASK 0xFFFFFFFF
39 41
40/* Configuration PVR masks */ 42/* Configuration PVR masks */
41#define PVR2_D_OPB_MASK 0x80000000 43#define PVR2_D_OPB_MASK 0x80000000 /* or AXI */
42#define PVR2_D_LMB_MASK 0x40000000 44#define PVR2_D_LMB_MASK 0x40000000
43#define PVR2_I_OPB_MASK 0x20000000 45#define PVR2_I_OPB_MASK 0x20000000 /* or AXI */
44#define PVR2_I_LMB_MASK 0x10000000 46#define PVR2_I_LMB_MASK 0x10000000
45#define PVR2_INTERRUPT_IS_EDGE_MASK 0x08000000 47#define PVR2_INTERRUPT_IS_EDGE_MASK 0x08000000
46#define PVR2_EDGE_IS_POSITIVE_MASK 0x04000000 48#define PVR2_EDGE_IS_POSITIVE_MASK 0x04000000
47#define PVR2_D_PLB_MASK 0x02000000 /* new */ 49#define PVR2_D_PLB_MASK 0x02000000 /* new */
48#define PVR2_I_PLB_MASK 0x01000000 /* new */ 50#define PVR2_I_PLB_MASK 0x01000000 /* new */
49#define PVR2_INTERCONNECT 0x00800000 /* new */ 51#define PVR2_INTERCONNECT 0x00800000 /* new */
50#define PVR2_USE_EXTEND_FSL 0x00080000 /* new */ 52#define PVR2_USE_EXTEND_FSL 0x00080000 /* new */
51#define PVR2_USE_FSL_EXC 0x00040000 /* new */ 53#define PVR2_USE_FSL_EXC 0x00040000 /* new */
52#define PVR2_USE_MSR_INSTR 0x00020000 54#define PVR2_USE_MSR_INSTR 0x00020000
53#define PVR2_USE_PCMP_INSTR 0x00010000 55#define PVR2_USE_PCMP_INSTR 0x00010000
54#define PVR2_AREA_OPTIMISED 0x00008000 56#define PVR2_AREA_OPTIMISED 0x00008000
@@ -57,14 +59,14 @@ struct pvr_s {
57#define PVR2_USE_HW_MUL_MASK 0x00001000 59#define PVR2_USE_HW_MUL_MASK 0x00001000
58#define PVR2_USE_FPU_MASK 0x00000800 60#define PVR2_USE_FPU_MASK 0x00000800
59#define PVR2_USE_MUL64_MASK 0x00000400 61#define PVR2_USE_MUL64_MASK 0x00000400
60#define PVR2_USE_FPU2_MASK 0x00000200 /* new */ 62#define PVR2_USE_FPU2_MASK 0x00000200 /* new */
61#define PVR2_USE_IPLBEXC 0x00000100 63#define PVR2_USE_IPLBEXC 0x00000100
62#define PVR2_USE_DPLBEXC 0x00000080 64#define PVR2_USE_DPLBEXC 0x00000080
63#define PVR2_OPCODE_0x0_ILL_MASK 0x00000040 65#define PVR2_OPCODE_0x0_ILL_MASK 0x00000040
64#define PVR2_UNALIGNED_EXC_MASK 0x00000020 66#define PVR2_UNALIGNED_EXC_MASK 0x00000020
65#define PVR2_ILL_OPCODE_EXC_MASK 0x00000010 67#define PVR2_ILL_OPCODE_EXC_MASK 0x00000010
66#define PVR2_IOPB_BUS_EXC_MASK 0x00000008 68#define PVR2_IOPB_BUS_EXC_MASK 0x00000008 /* or AXI */
67#define PVR2_DOPB_BUS_EXC_MASK 0x00000004 69#define PVR2_DOPB_BUS_EXC_MASK 0x00000004 /* or AXI */
68#define PVR2_DIV_ZERO_EXC_MASK 0x00000002 70#define PVR2_DIV_ZERO_EXC_MASK 0x00000002
69#define PVR2_FPU_EXC_MASK 0x00000001 71#define PVR2_FPU_EXC_MASK 0x00000001
70 72
@@ -120,94 +122,103 @@ struct pvr_s {
120 122
121 123
122/* PVR access macros */ 124/* PVR access macros */
123#define PVR_IS_FULL(pvr) (pvr.pvr[0] & PVR0_PVR_FULL_MASK) 125#define PVR_IS_FULL(_pvr) (_pvr.pvr[0] & PVR0_PVR_FULL_MASK)
124#define PVR_USE_BARREL(pvr) (pvr.pvr[0] & PVR0_USE_BARREL_MASK) 126#define PVR_USE_BARREL(_pvr) (_pvr.pvr[0] & PVR0_USE_BARREL_MASK)
125#define PVR_USE_DIV(pvr) (pvr.pvr[0] & PVR0_USE_DIV_MASK) 127#define PVR_USE_DIV(_pvr) (_pvr.pvr[0] & PVR0_USE_DIV_MASK)
126#define PVR_USE_HW_MUL(pvr) (pvr.pvr[0] & PVR0_USE_HW_MUL_MASK) 128#define PVR_USE_HW_MUL(_pvr) (_pvr.pvr[0] & PVR0_USE_HW_MUL_MASK)
127#define PVR_USE_FPU(pvr) (pvr.pvr[0] & PVR0_USE_FPU_MASK) 129#define PVR_USE_FPU(_pvr) (_pvr.pvr[0] & PVR0_USE_FPU_MASK)
128#define PVR_USE_FPU2(pvr) (pvr.pvr[2] & PVR2_USE_FPU2_MASK) 130#define PVR_USE_FPU2(_pvr) (_pvr.pvr[2] & PVR2_USE_FPU2_MASK)
129#define PVR_USE_ICACHE(pvr) (pvr.pvr[0] & PVR0_USE_ICACHE_MASK) 131#define PVR_USE_ICACHE(_pvr) (_pvr.pvr[0] & PVR0_USE_ICACHE_MASK)
130#define PVR_USE_DCACHE(pvr) (pvr.pvr[0] & PVR0_USE_DCACHE_MASK) 132#define PVR_USE_DCACHE(_pvr) (_pvr.pvr[0] & PVR0_USE_DCACHE_MASK)
131#define PVR_VERSION(pvr) ((pvr.pvr[0] & PVR0_VERSION_MASK) >> 8) 133#define PVR_VERSION(_pvr) ((_pvr.pvr[0] & PVR0_VERSION_MASK) >> 8)
132#define PVR_USER1(pvr) (pvr.pvr[0] & PVR0_USER1_MASK) 134#define PVR_USER1(_pvr) (_pvr.pvr[0] & PVR0_USER1_MASK)
133#define PVR_USER2(pvr) (pvr.pvr[1] & PVR1_USER2_MASK) 135#define PVR_USER2(_pvr) (_pvr.pvr[1] & PVR1_USER2_MASK)
134 136
135#define PVR_D_OPB(pvr) (pvr.pvr[2] & PVR2_D_OPB_MASK) 137#define PVR_D_OPB(_pvr) (_pvr.pvr[2] & PVR2_D_OPB_MASK)
136#define PVR_D_LMB(pvr) (pvr.pvr[2] & PVR2_D_LMB_MASK) 138#define PVR_D_LMB(_pvr) (_pvr.pvr[2] & PVR2_D_LMB_MASK)
137#define PVR_I_OPB(pvr) (pvr.pvr[2] & PVR2_I_OPB_MASK) 139#define PVR_I_OPB(_pvr) (_pvr.pvr[2] & PVR2_I_OPB_MASK)
138#define PVR_I_LMB(pvr) (pvr.pvr[2] & PVR2_I_LMB_MASK) 140#define PVR_I_LMB(_pvr) (_pvr.pvr[2] & PVR2_I_LMB_MASK)
139#define PVR_INTERRUPT_IS_EDGE(pvr) \ 141#define PVR_INTERRUPT_IS_EDGE(_pvr) \
140 (pvr.pvr[2] & PVR2_INTERRUPT_IS_EDGE_MASK) 142 (_pvr.pvr[2] & PVR2_INTERRUPT_IS_EDGE_MASK)
141#define PVR_EDGE_IS_POSITIVE(pvr) \ 143#define PVR_EDGE_IS_POSITIVE(_pvr) \
142 (pvr.pvr[2] & PVR2_EDGE_IS_POSITIVE_MASK) 144 (_pvr.pvr[2] & PVR2_EDGE_IS_POSITIVE_MASK)
143#define PVR_USE_MSR_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_MSR_INSTR) 145#define PVR_USE_MSR_INSTR(_pvr) (_pvr.pvr[2] & PVR2_USE_MSR_INSTR)
144#define PVR_USE_PCMP_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_PCMP_INSTR) 146#define PVR_USE_PCMP_INSTR(_pvr) (_pvr.pvr[2] & PVR2_USE_PCMP_INSTR)
145#define PVR_AREA_OPTIMISED(pvr) (pvr.pvr[2] & PVR2_AREA_OPTIMISED) 147#define PVR_AREA_OPTIMISED(_pvr) (_pvr.pvr[2] & PVR2_AREA_OPTIMISED)
146#define PVR_USE_MUL64(pvr) (pvr.pvr[2] & PVR2_USE_MUL64_MASK) 148#define PVR_USE_MUL64(_pvr) (_pvr.pvr[2] & PVR2_USE_MUL64_MASK)
147#define PVR_OPCODE_0x0_ILLEGAL(pvr) \ 149#define PVR_OPCODE_0x0_ILLEGAL(_pvr) \
148 (pvr.pvr[2] & PVR2_OPCODE_0x0_ILL_MASK) 150 (_pvr.pvr[2] & PVR2_OPCODE_0x0_ILL_MASK)
149#define PVR_UNALIGNED_EXCEPTION(pvr) \ 151#define PVR_UNALIGNED_EXCEPTION(_pvr) \
150 (pvr.pvr[2] & PVR2_UNALIGNED_EXC_MASK) 152 (_pvr.pvr[2] & PVR2_UNALIGNED_EXC_MASK)
151#define PVR_ILL_OPCODE_EXCEPTION(pvr) \ 153#define PVR_ILL_OPCODE_EXCEPTION(_pvr) \
152 (pvr.pvr[2] & PVR2_ILL_OPCODE_EXC_MASK) 154 (_pvr.pvr[2] & PVR2_ILL_OPCODE_EXC_MASK)
153#define PVR_IOPB_BUS_EXCEPTION(pvr) \ 155#define PVR_IOPB_BUS_EXCEPTION(_pvr) \
154 (pvr.pvr[2] & PVR2_IOPB_BUS_EXC_MASK) 156 (_pvr.pvr[2] & PVR2_IOPB_BUS_EXC_MASK)
155#define PVR_DOPB_BUS_EXCEPTION(pvr) \ 157#define PVR_DOPB_BUS_EXCEPTION(_pvr) \
156 (pvr.pvr[2] & PVR2_DOPB_BUS_EXC_MASK) 158 (_pvr.pvr[2] & PVR2_DOPB_BUS_EXC_MASK)
157#define PVR_DIV_ZERO_EXCEPTION(pvr) \ 159#define PVR_DIV_ZERO_EXCEPTION(_pvr) \
158 (pvr.pvr[2] & PVR2_DIV_ZERO_EXC_MASK) 160 (_pvr.pvr[2] & PVR2_DIV_ZERO_EXC_MASK)
159#define PVR_FPU_EXCEPTION(pvr) (pvr.pvr[2] & PVR2_FPU_EXC_MASK) 161#define PVR_FPU_EXCEPTION(_pvr) (_pvr.pvr[2] & PVR2_FPU_EXC_MASK)
160#define PVR_FSL_EXCEPTION(pvr) (pvr.pvr[2] & PVR2_USE_EXTEND_FSL) 162#define PVR_FSL_EXCEPTION(_pvr) (_pvr.pvr[2] & PVR2_USE_EXTEND_FSL)
161 163
162#define PVR_DEBUG_ENABLED(pvr) (pvr.pvr[3] & PVR3_DEBUG_ENABLED_MASK) 164#define PVR_DEBUG_ENABLED(_pvr) (_pvr.pvr[3] & PVR3_DEBUG_ENABLED_MASK)
163#define PVR_NUMBER_OF_PC_BRK(pvr) \ 165#define PVR_NUMBER_OF_PC_BRK(_pvr) \
164 ((pvr.pvr[3] & PVR3_NUMBER_OF_PC_BRK_MASK) >> 25) 166 ((_pvr.pvr[3] & PVR3_NUMBER_OF_PC_BRK_MASK) >> 25)
165#define PVR_NUMBER_OF_RD_ADDR_BRK(pvr) \ 167#define PVR_NUMBER_OF_RD_ADDR_BRK(_pvr) \
166 ((pvr.pvr[3] & PVR3_NUMBER_OF_RD_ADDR_BRK_MASK) >> 19) 168 ((_pvr.pvr[3] & PVR3_NUMBER_OF_RD_ADDR_BRK_MASK) >> 19)
167#define PVR_NUMBER_OF_WR_ADDR_BRK(pvr) \ 169#define PVR_NUMBER_OF_WR_ADDR_BRK(_pvr) \
168 ((pvr.pvr[3] & PVR3_NUMBER_OF_WR_ADDR_BRK_MASK) >> 13) 170 ((_pvr.pvr[3] & PVR3_NUMBER_OF_WR_ADDR_BRK_MASK) >> 13)
169#define PVR_FSL_LINKS(pvr) ((pvr.pvr[3] & PVR3_FSL_LINKS_MASK) >> 7) 171#define PVR_FSL_LINKS(_pvr) ((_pvr.pvr[3] & PVR3_FSL_LINKS_MASK) >> 7)
170 172
171#define PVR_ICACHE_ADDR_TAG_BITS(pvr) \ 173#define PVR_ICACHE_ADDR_TAG_BITS(_pvr) \
172 ((pvr.pvr[4] & PVR4_ICACHE_ADDR_TAG_BITS_MASK) >> 26) 174 ((_pvr.pvr[4] & PVR4_ICACHE_ADDR_TAG_BITS_MASK) >> 26)
173#define PVR_ICACHE_USE_FSL(pvr) (pvr.pvr[4] & PVR4_ICACHE_USE_FSL_MASK) 175#define PVR_ICACHE_USE_FSL(_pvr) \
174#define PVR_ICACHE_ALLOW_WR(pvr) (pvr.pvr[4] & PVR4_ICACHE_ALLOW_WR_MASK) 176 (_pvr.pvr[4] & PVR4_ICACHE_USE_FSL_MASK)
175#define PVR_ICACHE_LINE_LEN(pvr) \ 177#define PVR_ICACHE_ALLOW_WR(_pvr) \
176 (1 << ((pvr.pvr[4] & PVR4_ICACHE_LINE_LEN_MASK) >> 21)) 178 (_pvr.pvr[4] & PVR4_ICACHE_ALLOW_WR_MASK)
177#define PVR_ICACHE_BYTE_SIZE(pvr) \ 179#define PVR_ICACHE_LINE_LEN(_pvr) \
178 (1 << ((pvr.pvr[4] & PVR4_ICACHE_BYTE_SIZE_MASK) >> 16)) 180 (1 << ((_pvr.pvr[4] & PVR4_ICACHE_LINE_LEN_MASK) >> 21))
179 181#define PVR_ICACHE_BYTE_SIZE(_pvr) \
180#define PVR_DCACHE_ADDR_TAG_BITS(pvr) \ 182 (1 << ((_pvr.pvr[4] & PVR4_ICACHE_BYTE_SIZE_MASK) >> 16))
181 ((pvr.pvr[5] & PVR5_DCACHE_ADDR_TAG_BITS_MASK) >> 26) 183
182#define PVR_DCACHE_USE_FSL(pvr) (pvr.pvr[5] & PVR5_DCACHE_USE_FSL_MASK) 184#define PVR_DCACHE_ADDR_TAG_BITS(_pvr) \
183#define PVR_DCACHE_ALLOW_WR(pvr) (pvr.pvr[5] & PVR5_DCACHE_ALLOW_WR_MASK) 185 ((_pvr.pvr[5] & PVR5_DCACHE_ADDR_TAG_BITS_MASK) >> 26)
186#define PVR_DCACHE_USE_FSL(_pvr) (_pvr.pvr[5] & PVR5_DCACHE_USE_FSL_MASK)
187#define PVR_DCACHE_ALLOW_WR(_pvr) \
188 (_pvr.pvr[5] & PVR5_DCACHE_ALLOW_WR_MASK)
184/* FIXME two shifts on one line needs any comment */ 189/* FIXME two shifts on one line needs any comment */
185#define PVR_DCACHE_LINE_LEN(pvr) \ 190#define PVR_DCACHE_LINE_LEN(_pvr) \
186 (1 << ((pvr.pvr[5] & PVR5_DCACHE_LINE_LEN_MASK) >> 21)) 191 (1 << ((_pvr.pvr[5] & PVR5_DCACHE_LINE_LEN_MASK) >> 21))
187#define PVR_DCACHE_BYTE_SIZE(pvr) \ 192#define PVR_DCACHE_BYTE_SIZE(_pvr) \
188 (1 << ((pvr.pvr[5] & PVR5_DCACHE_BYTE_SIZE_MASK) >> 16)) 193 (1 << ((_pvr.pvr[5] & PVR5_DCACHE_BYTE_SIZE_MASK) >> 16))
189 194
190#define PVR_DCACHE_USE_WRITEBACK(pvr) \ 195#define PVR_DCACHE_USE_WRITEBACK(_pvr) \
191 ((pvr.pvr[5] & PVR5_DCACHE_USE_WRITEBACK) >> 14) 196 ((_pvr.pvr[5] & PVR5_DCACHE_USE_WRITEBACK) >> 14)
192 197
193#define PVR_ICACHE_BASEADDR(pvr) (pvr.pvr[6] & PVR6_ICACHE_BASEADDR_MASK) 198#define PVR_ICACHE_BASEADDR(_pvr) \
194#define PVR_ICACHE_HIGHADDR(pvr) (pvr.pvr[7] & PVR7_ICACHE_HIGHADDR_MASK) 199 (_pvr.pvr[6] & PVR6_ICACHE_BASEADDR_MASK)
200#define PVR_ICACHE_HIGHADDR(_pvr) \
201 (_pvr.pvr[7] & PVR7_ICACHE_HIGHADDR_MASK)
202#define PVR_DCACHE_BASEADDR(_pvr) \
203 (_pvr.pvr[8] & PVR8_DCACHE_BASEADDR_MASK)
204#define PVR_DCACHE_HIGHADDR(_pvr) \
205 (_pvr.pvr[9] & PVR9_DCACHE_HIGHADDR_MASK)
195 206
196#define PVR_DCACHE_BASEADDR(pvr) (pvr.pvr[8] & PVR8_DCACHE_BASEADDR_MASK) 207#define PVR_TARGET_FAMILY(_pvr) \
197#define PVR_DCACHE_HIGHADDR(pvr) (pvr.pvr[9] & PVR9_DCACHE_HIGHADDR_MASK) 208 ((_pvr.pvr[10] & PVR10_TARGET_FAMILY_MASK) >> 24)
198 209
199#define PVR_TARGET_FAMILY(pvr) ((pvr.pvr[10] & PVR10_TARGET_FAMILY_MASK) >> 24) 210#define PVR_MSR_RESET_VALUE(_pvr) \
200 211 (_pvr.pvr[11] & PVR11_MSR_RESET_VALUE_MASK)
201#define PVR_MSR_RESET_VALUE(pvr) \
202 (pvr.pvr[11] & PVR11_MSR_RESET_VALUE_MASK)
203 212
204/* mmu */ 213/* mmu */
205#define PVR_USE_MMU(pvr) ((pvr.pvr[11] & PVR11_USE_MMU) >> 30) 214#define PVR_USE_MMU(_pvr) ((_pvr.pvr[11] & PVR11_USE_MMU) >> 30)
206#define PVR_MMU_ITLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_ITLB_SIZE) 215#define PVR_MMU_ITLB_SIZE(_pvr) (_pvr.pvr[11] & PVR11_MMU_ITLB_SIZE)
207#define PVR_MMU_DTLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_DTLB_SIZE) 216#define PVR_MMU_DTLB_SIZE(_pvr) (_pvr.pvr[11] & PVR11_MMU_DTLB_SIZE)
208#define PVR_MMU_TLB_ACCESS(pvr) (pvr.pvr[11] & PVR11_MMU_TLB_ACCESS) 217#define PVR_MMU_TLB_ACCESS(_pvr) (_pvr.pvr[11] & PVR11_MMU_TLB_ACCESS)
209#define PVR_MMU_ZONES(pvr) (pvr.pvr[11] & PVR11_MMU_ZONES) 218#define PVR_MMU_ZONES(_pvr) (_pvr.pvr[11] & PVR11_MMU_ZONES)
210 219
220/* endian */
221#define PVR_ENDIAN(_pvr) (_pvr.pvr[0] & PVR0_ENDI)
211 222
212int cpu_has_pvr(void); 223int cpu_has_pvr(void);
213void get_pvr(struct pvr_s *pvr); 224void get_pvr(struct pvr_s *pvr);
diff --git a/arch/microblaze/include/asm/seccomp.h b/arch/microblaze/include/asm/seccomp.h
new file mode 100644
index 000000000000..0d912758a0d7
--- /dev/null
+++ b/arch/microblaze/include/asm/seccomp.h
@@ -0,0 +1,16 @@
1#ifndef _ASM_MICROBLAZE_SECCOMP_H
2#define _ASM_MICROBLAZE_SECCOMP_H
3
4#include <linux/unistd.h>
5
6#define __NR_seccomp_read __NR_read
7#define __NR_seccomp_write __NR_write
8#define __NR_seccomp_exit __NR_exit
9#define __NR_seccomp_sigreturn __NR_sigreturn
10
11#define __NR_seccomp_read_32 __NR_read
12#define __NR_seccomp_write_32 __NR_write
13#define __NR_seccomp_exit_32 __NR_exit
14#define __NR_seccomp_sigreturn_32 __NR_sigreturn
15
16#endif /* _ASM_MICROBLAZE_SECCOMP_H */
diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h
index 782b5c89248e..8f3968971e4e 100644
--- a/arch/microblaze/include/asm/setup.h
+++ b/arch/microblaze/include/asm/setup.h
@@ -25,6 +25,12 @@ void early_printk(const char *fmt, ...);
25int setup_early_printk(char *opt); 25int setup_early_printk(char *opt);
26void disable_early_printk(void); 26void disable_early_printk(void);
27 27
28#if defined(CONFIG_EARLY_PRINTK)
29#define eprintk early_printk
30#else
31#define eprintk printk
32#endif
33
28void heartbeat(void); 34void heartbeat(void);
29void setup_heartbeat(void); 35void setup_heartbeat(void);
30 36
diff --git a/arch/microblaze/include/asm/syscall.h b/arch/microblaze/include/asm/syscall.h
index 048dfcd8d89d..9bc431783105 100644
--- a/arch/microblaze/include/asm/syscall.h
+++ b/arch/microblaze/include/asm/syscall.h
@@ -96,4 +96,7 @@ static inline void syscall_set_arguments(struct task_struct *task,
96 microblaze_set_syscall_arg(regs, i++, *args++); 96 microblaze_set_syscall_arg(regs, i++, *args++);
97} 97}
98 98
99asmlinkage long do_syscall_trace_enter(struct pt_regs *regs);
100asmlinkage void do_syscall_trace_leave(struct pt_regs *regs);
101
99#endif /* __ASM_MICROBLAZE_SYSCALL_H */ 102#endif /* __ASM_MICROBLAZE_SYSCALL_H */
diff --git a/arch/microblaze/include/asm/syscalls.h b/arch/microblaze/include/asm/syscalls.h
index 720761cc741f..27f2f4c0f39f 100644
--- a/arch/microblaze/include/asm/syscalls.h
+++ b/arch/microblaze/include/asm/syscalls.h
@@ -1,5 +1,13 @@
1#ifndef __ASM_MICROBLAZE_SYSCALLS_H 1#ifndef __ASM_MICROBLAZE_SYSCALLS_H
2 2
3asmlinkage long microblaze_vfork(struct pt_regs *regs);
4asmlinkage long microblaze_clone(int flags, unsigned long stack,
5 struct pt_regs *regs);
6asmlinkage long microblaze_execve(const char __user *filenamei,
7 const char __user *const __user *argv,
8 const char __user *const __user *envp,
9 struct pt_regs *regs);
10
3asmlinkage long sys_clone(int flags, unsigned long stack, struct pt_regs *regs); 11asmlinkage long sys_clone(int flags, unsigned long stack, struct pt_regs *regs);
4#define sys_clone sys_clone 12#define sys_clone sys_clone
5 13
diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h
index 8a8e9fc6e0c0..b73da2ac21b3 100644
--- a/arch/microblaze/include/asm/thread_info.h
+++ b/arch/microblaze/include/asm/thread_info.h
@@ -127,23 +127,19 @@ static inline struct thread_info *current_thread_info(void)
127#define TIF_SECCOMP 10 /* secure computing */ 127#define TIF_SECCOMP 10 /* secure computing */
128#define TIF_FREEZE 14 /* Freezing for suspend */ 128#define TIF_FREEZE 14 /* Freezing for suspend */
129 129
130/* FIXME change in entry.S */
131#define TIF_KERNEL_TRACE 8 /* kernel trace active */
132
133/* true if poll_idle() is polling TIF_NEED_RESCHED */ 130/* true if poll_idle() is polling TIF_NEED_RESCHED */
134#define TIF_POLLING_NRFLAG 16 131#define TIF_POLLING_NRFLAG 16
135 132
136#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 133#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
137#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) 134#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
138#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) 135#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
139#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) 136#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
140#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) 137#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
141#define _TIF_IRET (1<<TIF_IRET) 138#define _TIF_IRET (1 << TIF_IRET)
142#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 139#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
143#define _TIF_FREEZE (1<<TIF_FREEZE) 140#define _TIF_FREEZE (1 << TIF_FREEZE)
144#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) 141#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
145#define _TIF_SECCOMP (1 << TIF_SECCOMP) 142#define _TIF_SECCOMP (1 << TIF_SECCOMP)
146#define _TIF_KERNEL_TRACE (1 << TIF_KERNEL_TRACE)
147 143
148/* work to do in syscall trace */ 144/* work to do in syscall trace */
149#define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \ 145#define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
diff --git a/arch/microblaze/include/asm/tlb.h b/arch/microblaze/include/asm/tlb.h
index e8abd4a0349c..8aa97817cc8c 100644
--- a/arch/microblaze/include/asm/tlb.h
+++ b/arch/microblaze/include/asm/tlb.h
@@ -13,6 +13,7 @@
13 13
14#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) 14#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
15 15
16#include <linux/pagemap.h>
16#include <asm-generic/tlb.h> 17#include <asm-generic/tlb.h>
17 18
18#ifdef CONFIG_MMU 19#ifdef CONFIG_MMU
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h
index d840f4a2d3c9..5bb95a11880d 100644
--- a/arch/microblaze/include/asm/uaccess.h
+++ b/arch/microblaze/include/asm/uaccess.h
@@ -120,16 +120,16 @@ static inline unsigned long __must_check __clear_user(void __user *to,
120{ 120{
121 /* normal memset with two words to __ex_table */ 121 /* normal memset with two words to __ex_table */
122 __asm__ __volatile__ ( \ 122 __asm__ __volatile__ ( \
123 "1: sb r0, %2, r0;" \ 123 "1: sb r0, %1, r0;" \
124 " addik %0, %0, -1;" \ 124 " addik %0, %0, -1;" \
125 " bneid %0, 1b;" \ 125 " bneid %0, 1b;" \
126 " addik %2, %2, 1;" \ 126 " addik %1, %1, 1;" \
127 "2: " \ 127 "2: " \
128 __EX_TABLE_SECTION \ 128 __EX_TABLE_SECTION \
129 ".word 1b,2b;" \ 129 ".word 1b,2b;" \
130 ".previous;" \ 130 ".previous;" \
131 : "=r"(n) \ 131 : "=r"(n), "=r"(to) \
132 : "0"(n), "r"(to) 132 : "0"(n), "1"(to)
133 ); 133 );
134 return n; 134 return n;
135} 135}
diff --git a/arch/microblaze/include/asm/unaligned.h b/arch/microblaze/include/asm/unaligned.h
index 3658d91ac0fb..b162ed880495 100644
--- a/arch/microblaze/include/asm/unaligned.h
+++ b/arch/microblaze/include/asm/unaligned.h
@@ -12,12 +12,19 @@
12 12
13# ifdef __KERNEL__ 13# ifdef __KERNEL__
14 14
15# include <linux/unaligned/be_struct.h> 15# ifdef __MICROBLAZEEL__
16# include <linux/unaligned/le_byteshift.h> 16# include <linux/unaligned/le_struct.h>
17# include <linux/unaligned/generic.h> 17# include <linux/unaligned/be_byteshift.h>
18# define get_unaligned __get_unaligned_le
19# define put_unaligned __put_unaligned_le
20# else
21# include <linux/unaligned/be_struct.h>
22# include <linux/unaligned/le_byteshift.h>
23# define get_unaligned __get_unaligned_be
24# define put_unaligned __put_unaligned_be
25# endif
18 26
19# define get_unaligned __get_unaligned_be 27# include <linux/unaligned/generic.h>
20# define put_unaligned __put_unaligned_be
21 28
22# endif /* __KERNEL__ */ 29# endif /* __KERNEL__ */
23#endif /* _ASM_MICROBLAZE_UNALIGNED_H */ 30#endif /* _ASM_MICROBLAZE_UNALIGNED_H */
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h
index 2b67e92a773c..7d7092b917ac 100644
--- a/arch/microblaze/include/asm/unistd.h
+++ b/arch/microblaze/include/asm/unistd.h
@@ -383,8 +383,16 @@
383#define __NR_rt_tgsigqueueinfo 365 /* new */ 383#define __NR_rt_tgsigqueueinfo 365 /* new */
384#define __NR_perf_event_open 366 /* new */ 384#define __NR_perf_event_open 366 /* new */
385#define __NR_recvmmsg 367 /* new */ 385#define __NR_recvmmsg 367 /* new */
386#define __NR_fanotify_init 368
387#define __NR_fanotify_mark 369
388#define __NR_prlimit64 370
389#define __NR_name_to_handle_at 371
390#define __NR_open_by_handle_at 372
391#define __NR_clock_adjtime 373
392#define __NR_syncfs 374
393#define __NR_setns 375
386 394
387#define __NR_syscalls 368 395#define __NR_syscalls 376
388 396
389#ifdef __KERNEL__ 397#ifdef __KERNEL__
390#ifndef __ASSEMBLY__ 398#ifndef __ASSEMBLY__
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
index f0cb5c26c81c..494b63b72dd7 100644
--- a/arch/microblaze/kernel/Makefile
+++ b/arch/microblaze/kernel/Makefile
@@ -10,6 +10,7 @@ CFLAGS_REMOVE_early_printk.o = -pg
10CFLAGS_REMOVE_selfmod.o = -pg 10CFLAGS_REMOVE_selfmod.o = -pg
11CFLAGS_REMOVE_heartbeat.o = -pg 11CFLAGS_REMOVE_heartbeat.o = -pg
12CFLAGS_REMOVE_ftrace.o = -pg 12CFLAGS_REMOVE_ftrace.o = -pg
13CFLAGS_REMOVE_process.o = -pg
13endif 14endif
14 15
15extra-y := head.o vmlinux.lds 16extra-y := head.o vmlinux.lds
diff --git a/arch/microblaze/kernel/cpu/Makefile b/arch/microblaze/kernel/cpu/Makefile
index 59cc7bceaf8c..fceed4edea41 100644
--- a/arch/microblaze/kernel/cpu/Makefile
+++ b/arch/microblaze/kernel/cpu/Makefile
@@ -6,7 +6,7 @@ ifdef CONFIG_FUNCTION_TRACER
6CFLAGS_REMOVE_cache.o = -pg 6CFLAGS_REMOVE_cache.o = -pg
7endif 7endif
8 8
9EXTRA_CFLAGS += -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \ 9ccflags-y := -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \
10 -DCPU_REV=$(CPU_REV) 10 -DCPU_REV=$(CPU_REV)
11 11
12obj-y += cache.o cpuinfo.o cpuinfo-pvr-full.o cpuinfo-static.o mb.o pvr.o 12obj-y += cache.o cpuinfo.o cpuinfo-pvr-full.o cpuinfo-static.o mb.o pvr.o
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c
index 109876e8d643..4b7d8a3f4aef 100644
--- a/arch/microblaze/kernel/cpu/cache.c
+++ b/arch/microblaze/kernel/cpu/cache.c
@@ -129,7 +129,7 @@ do { \
129 * to use for simple wdc or wic. 129 * to use for simple wdc or wic.
130 * 130 *
131 * start address is cache aligned 131 * start address is cache aligned
132 * end address is not aligned, if end is aligned then I have to substract 132 * end address is not aligned, if end is aligned then I have to subtract
133 * cacheline length because I can't flush/invalidate the next cacheline. 133 * cacheline length because I can't flush/invalidate the next cacheline.
134 * If is not, I align it because I will flush/invalidate whole line. 134 * If is not, I align it because I will flush/invalidate whole line.
135 */ 135 */
@@ -519,7 +519,7 @@ static void __flush_dcache_range_wb(unsigned long start, unsigned long end)
519struct scache *mbc; 519struct scache *mbc;
520 520
521/* new wb cache model */ 521/* new wb cache model */
522const struct scache wb_msr = { 522static const struct scache wb_msr = {
523 .ie = __enable_icache_msr, 523 .ie = __enable_icache_msr,
524 .id = __disable_icache_msr, 524 .id = __disable_icache_msr,
525 .ifl = __flush_icache_all_noirq, 525 .ifl = __flush_icache_all_noirq,
@@ -535,7 +535,7 @@ const struct scache wb_msr = {
535}; 535};
536 536
537/* There is only difference in ie, id, de, dd functions */ 537/* There is only difference in ie, id, de, dd functions */
538const struct scache wb_nomsr = { 538static const struct scache wb_nomsr = {
539 .ie = __enable_icache_nomsr, 539 .ie = __enable_icache_nomsr,
540 .id = __disable_icache_nomsr, 540 .id = __disable_icache_nomsr,
541 .ifl = __flush_icache_all_noirq, 541 .ifl = __flush_icache_all_noirq,
@@ -551,7 +551,7 @@ const struct scache wb_nomsr = {
551}; 551};
552 552
553/* Old wt cache model with disabling irq and turn off cache */ 553/* Old wt cache model with disabling irq and turn off cache */
554const struct scache wt_msr = { 554static const struct scache wt_msr = {
555 .ie = __enable_icache_msr, 555 .ie = __enable_icache_msr,
556 .id = __disable_icache_msr, 556 .id = __disable_icache_msr,
557 .ifl = __flush_icache_all_msr_irq, 557 .ifl = __flush_icache_all_msr_irq,
@@ -566,7 +566,7 @@ const struct scache wt_msr = {
566 .dinr = __invalidate_dcache_range_msr_irq_wt, 566 .dinr = __invalidate_dcache_range_msr_irq_wt,
567}; 567};
568 568
569const struct scache wt_nomsr = { 569static const struct scache wt_nomsr = {
570 .ie = __enable_icache_nomsr, 570 .ie = __enable_icache_nomsr,
571 .id = __disable_icache_nomsr, 571 .id = __disable_icache_nomsr,
572 .ifl = __flush_icache_all_nomsr_irq, 572 .ifl = __flush_icache_all_nomsr_irq,
@@ -582,7 +582,7 @@ const struct scache wt_nomsr = {
582}; 582};
583 583
584/* New wt cache model for newer Microblaze versions */ 584/* New wt cache model for newer Microblaze versions */
585const struct scache wt_msr_noirq = { 585static const struct scache wt_msr_noirq = {
586 .ie = __enable_icache_msr, 586 .ie = __enable_icache_msr,
587 .id = __disable_icache_msr, 587 .id = __disable_icache_msr,
588 .ifl = __flush_icache_all_noirq, 588 .ifl = __flush_icache_all_noirq,
@@ -597,7 +597,7 @@ const struct scache wt_msr_noirq = {
597 .dinr = __invalidate_dcache_range_nomsr_wt, 597 .dinr = __invalidate_dcache_range_nomsr_wt,
598}; 598};
599 599
600const struct scache wt_nomsr_noirq = { 600static const struct scache wt_nomsr_noirq = {
601 .ie = __enable_icache_nomsr, 601 .ie = __enable_icache_nomsr,
602 .id = __disable_icache_nomsr, 602 .id = __disable_icache_nomsr,
603 .ifl = __flush_icache_all_noirq, 603 .ifl = __flush_icache_all_noirq,
@@ -624,7 +624,7 @@ void microblaze_cache_init(void)
624 if (cpuinfo.dcache_wb) { 624 if (cpuinfo.dcache_wb) {
625 INFO("wb_msr"); 625 INFO("wb_msr");
626 mbc = (struct scache *)&wb_msr; 626 mbc = (struct scache *)&wb_msr;
627 if (cpuinfo.ver_code < CPUVER_7_20_D) { 627 if (cpuinfo.ver_code <= CPUVER_7_20_D) {
628 /* MS: problem with signal handling - hw bug */ 628 /* MS: problem with signal handling - hw bug */
629 INFO("WB won't work properly"); 629 INFO("WB won't work properly");
630 } 630 }
@@ -641,7 +641,7 @@ void microblaze_cache_init(void)
641 if (cpuinfo.dcache_wb) { 641 if (cpuinfo.dcache_wb) {
642 INFO("wb_nomsr"); 642 INFO("wb_nomsr");
643 mbc = (struct scache *)&wb_nomsr; 643 mbc = (struct scache *)&wb_nomsr;
644 if (cpuinfo.ver_code < CPUVER_7_20_D) { 644 if (cpuinfo.ver_code <= CPUVER_7_20_D) {
645 /* MS: problem with signal handling - hw bug */ 645 /* MS: problem with signal handling - hw bug */
646 INFO("WB won't work properly"); 646 INFO("WB won't work properly");
647 } 647 }
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
index f72dbd66c844..f70a6047f08e 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
@@ -72,6 +72,7 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
72 CI(pvr_user2, USER2); 72 CI(pvr_user2, USER2);
73 73
74 CI(mmu, USE_MMU); 74 CI(mmu, USE_MMU);
75 CI(endian, ENDIAN);
75 76
76 CI(use_icache, USE_ICACHE); 77 CI(use_icache, USE_ICACHE);
77 CI(icache_tagbits, ICACHE_ADDR_TAG_BITS); 78 CI(icache_tagbits, ICACHE_ADDR_TAG_BITS);
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c
index 6095aa6b5c88..b16b994ca3d2 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo-static.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c
@@ -119,6 +119,7 @@ void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
119 ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2"); 119 ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2");
120 120
121 ci->mmu = fcpu(cpu, "xlnx,use-mmu"); 121 ci->mmu = fcpu(cpu, "xlnx,use-mmu");
122 ci->endian = fcpu(cpu, "xlnx,endianness");
122 123
123 ci->ver_code = 0; 124 ci->ver_code = 0;
124 ci->fpga_family_code = 0; 125 ci->fpga_family_code = 0;
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
index 255ef880351e..c1640c52711f 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -30,6 +30,10 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
30 {"7.20.c", 0x0e}, 30 {"7.20.c", 0x0e},
31 {"7.20.d", 0x0f}, 31 {"7.20.d", 0x0f},
32 {"7.30.a", 0x10}, 32 {"7.30.a", 0x10},
33 {"7.30.b", 0x11},
34 {"8.00.a", 0x12},
35 {"8.00.b", 0x13},
36 {"8.10.a", 0x14},
33 {NULL, 0}, 37 {NULL, 0},
34}; 38};
35 39
diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c
index 7086e3564281..b4048af02615 100644
--- a/arch/microblaze/kernel/cpu/mb.c
+++ b/arch/microblaze/kernel/cpu/mb.c
@@ -51,11 +51,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
51 count = seq_printf(m, 51 count = seq_printf(m,
52 "CPU-Family: MicroBlaze\n" 52 "CPU-Family: MicroBlaze\n"
53 "FPGA-Arch: %s\n" 53 "FPGA-Arch: %s\n"
54 "CPU-Ver: %s\n" 54 "CPU-Ver: %s, %s endian\n"
55 "CPU-MHz: %d.%02d\n" 55 "CPU-MHz: %d.%02d\n"
56 "BogoMips: %lu.%02lu\n", 56 "BogoMips: %lu.%02lu\n",
57 fpga_family, 57 fpga_family,
58 cpu_ver, 58 cpu_ver,
59 cpuinfo.endian ? "little" : "big",
59 cpuinfo.cpu_clock_freq / 60 cpuinfo.cpu_clock_freq /
60 1000000, 61 1000000,
61 cpuinfo.cpu_clock_freq % 62 cpuinfo.cpu_clock_freq %
diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c
index 9bee9382bf74..488c1ed24e38 100644
--- a/arch/microblaze/kernel/cpu/pvr.c
+++ b/arch/microblaze/kernel/cpu/pvr.c
@@ -27,7 +27,7 @@
27 register unsigned tmp __asm__("r3"); \ 27 register unsigned tmp __asm__("r3"); \
28 tmp = 0x0; /* Prevent warning about unused */ \ 28 tmp = 0x0; /* Prevent warning about unused */ \
29 __asm__ __volatile__ ( \ 29 __asm__ __volatile__ ( \
30 ".byte 0x94,0x60,0xa0, " #pvrid "\n\t" \ 30 "mfs %0, rpvr" #pvrid ";" \
31 : "=r" (tmp) : : "memory"); \ 31 : "=r" (tmp) : : "memory"); \
32 val = tmp; \ 32 val = tmp; \
33} 33}
@@ -54,7 +54,7 @@ int cpu_has_pvr(void)
54 if (!(flags & PVR_MSR_BIT)) 54 if (!(flags & PVR_MSR_BIT))
55 return 0; 55 return 0;
56 56
57 get_single_pvr(0x00, pvr0); 57 get_single_pvr(0, pvr0);
58 pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0); 58 pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0);
59 59
60 if (pvr0 & PVR0_PVR_FULL_MASK) 60 if (pvr0 & PVR0_PVR_FULL_MASK)
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
index 79c74659f204..393e6b2db688 100644
--- a/arch/microblaze/kernel/dma.c
+++ b/arch/microblaze/kernel/dma.c
@@ -26,6 +26,7 @@ static inline void __dma_sync_page(unsigned long paddr, unsigned long offset,
26{ 26{
27 switch (direction) { 27 switch (direction) {
28 case DMA_TO_DEVICE: 28 case DMA_TO_DEVICE:
29 case DMA_BIDIRECTIONAL:
29 flush_dcache_range(paddr + offset, paddr + offset + size); 30 flush_dcache_range(paddr + offset, paddr + offset + size);
30 break; 31 break;
31 case DMA_FROM_DEVICE: 32 case DMA_FROM_DEVICE:
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c
index 7de84923ba07..c3616a080ebf 100644
--- a/arch/microblaze/kernel/early_printk.c
+++ b/arch/microblaze/kernel/early_printk.c
@@ -24,7 +24,8 @@
24static u32 early_console_initialized; 24static u32 early_console_initialized;
25static u32 base_addr; 25static u32 base_addr;
26 26
27static void early_printk_putc(char c) 27#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
28static void early_printk_uartlite_putc(char c)
28{ 29{
29 /* 30 /*
30 * Limit how many times we'll spin waiting for TX FIFO status. 31 * Limit how many times we'll spin waiting for TX FIFO status.
@@ -45,25 +46,70 @@ static void early_printk_putc(char c)
45 out_be32(base_addr + 4, c & 0xff); 46 out_be32(base_addr + 4, c & 0xff);
46} 47}
47 48
48static void early_printk_write(struct console *unused, 49static void early_printk_uartlite_write(struct console *unused,
49 const char *s, unsigned n) 50 const char *s, unsigned n)
50{ 51{
51 while (*s && n-- > 0) { 52 while (*s && n-- > 0) {
52 early_printk_putc(*s); 53 early_printk_uartlite_putc(*s);
53 if (*s == '\n') 54 if (*s == '\n')
54 early_printk_putc('\r'); 55 early_printk_uartlite_putc('\r');
55 s++; 56 s++;
56 } 57 }
57} 58}
58 59
59static struct console early_serial_console = { 60static struct console early_serial_uartlite_console = {
60 .name = "earlyser", 61 .name = "earlyser",
61 .write = early_printk_write, 62 .write = early_printk_uartlite_write,
62 .flags = CON_PRINTBUFFER, 63 .flags = CON_PRINTBUFFER,
63 .index = -1, 64 .index = -1,
64}; 65};
66#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
65 67
66static struct console *early_console = &early_serial_console; 68#ifdef CONFIG_SERIAL_8250_CONSOLE
69static void early_printk_uart16550_putc(char c)
70{
71 /*
72 * Limit how many times we'll spin waiting for TX FIFO status.
73 * This will prevent lockups if the base address is incorrectly
74 * set, or any other issue on the UARTLITE.
75 * This limit is pretty arbitrary, unless we are at about 10 baud
76 * we'll never timeout on a working UART.
77 */
78
79 #define UART_LSR_TEMT 0x40 /* Transmitter empty */
80 #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
81 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
82
83 unsigned retries = 10000;
84
85 while (--retries &&
86 !((in_be32(base_addr + 0x14) & BOTH_EMPTY) == BOTH_EMPTY))
87 ;
88
89 if (retries)
90 out_be32(base_addr, c & 0xff);
91}
92
93static void early_printk_uart16550_write(struct console *unused,
94 const char *s, unsigned n)
95{
96 while (*s && n-- > 0) {
97 early_printk_uart16550_putc(*s);
98 if (*s == '\n')
99 early_printk_uart16550_putc('\r');
100 s++;
101 }
102}
103
104static struct console early_serial_uart16550_console = {
105 .name = "earlyser",
106 .write = early_printk_uart16550_write,
107 .flags = CON_PRINTBUFFER,
108 .index = -1,
109};
110#endif /* CONFIG_SERIAL_8250_CONSOLE */
111
112static struct console *early_console;
67 113
68void early_printk(const char *fmt, ...) 114void early_printk(const char *fmt, ...)
69{ 115{
@@ -84,20 +130,43 @@ int __init setup_early_printk(char *opt)
84 if (early_console_initialized) 130 if (early_console_initialized)
85 return 1; 131 return 1;
86 132
133#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
87 base_addr = early_uartlite_console(); 134 base_addr = early_uartlite_console();
88 if (base_addr) { 135 if (base_addr) {
89 early_console_initialized = 1; 136 early_console_initialized = 1;
90#ifdef CONFIG_MMU 137#ifdef CONFIG_MMU
91 early_console_reg_tlb_alloc(base_addr); 138 early_console_reg_tlb_alloc(base_addr);
92#endif 139#endif
140 early_console = &early_serial_uartlite_console;
93 early_printk("early_printk_console is enabled at 0x%08x\n", 141 early_printk("early_printk_console is enabled at 0x%08x\n",
94 base_addr); 142 base_addr);
95 143
96 /* register_console(early_console); */ 144 /* register_console(early_console); */
97 145
98 return 0; 146 return 0;
99 } else 147 }
100 return 1; 148#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
149
150#ifdef CONFIG_SERIAL_8250_CONSOLE
151 base_addr = early_uart16550_console();
152 base_addr &= ~3; /* clear register offset */
153 if (base_addr) {
154 early_console_initialized = 1;
155#ifdef CONFIG_MMU
156 early_console_reg_tlb_alloc(base_addr);
157#endif
158 early_console = &early_serial_uart16550_console;
159
160 early_printk("early_printk_console is enabled at 0x%08x\n",
161 base_addr);
162
163 /* register_console(early_console); */
164
165 return 0;
166 }
167#endif /* CONFIG_SERIAL_8250_CONSOLE */
168
169 return 1;
101} 170}
102 171
103void __init disable_early_printk(void) 172void __init disable_early_printk(void)
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
index ca84368570b6..34b526f59b43 100644
--- a/arch/microblaze/kernel/entry-nommu.S
+++ b/arch/microblaze/kernel/entry-nommu.S
@@ -115,7 +115,7 @@ ENTRY(_interrupt)
115 /* restore r31 */ 115 /* restore r31 */
116 lwi r31, r0, PER_CPU(CURRENT_SAVE) 116 lwi r31, r0, PER_CPU(CURRENT_SAVE)
117 /* prepare the link register, the argument and jump */ 117 /* prepare the link register, the argument and jump */
118 la r15, r0, ret_from_intr - 8 118 addik r15, r0, ret_from_intr - 8
119 addk r6, r0, r15 119 addk r6, r0, r15
120 braid do_IRQ 120 braid do_IRQ
121 add r5, r0, r1 121 add r5, r0, r1
@@ -283,7 +283,7 @@ ENTRY(_user_exception)
283 add r12, r12, r12 /* convert num -> ptr */ 283 add r12, r12, r12 /* convert num -> ptr */
284 add r12, r12, r12 284 add r12, r12, r12
285 lwi r12, r12, sys_call_table /* Get function pointer */ 285 lwi r12, r12, sys_call_table /* Get function pointer */
286 la r15, r0, ret_to_user-8 /* set return address */ 286 addik r15, r0, ret_to_user-8 /* set return address */
287 bra r12 /* Make the system call. */ 287 bra r12 /* Make the system call. */
288 bri 0 /* won't reach here */ 288 bri 0 /* won't reach here */
2891: 2891:
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 304882e56459..ca15bc5c7449 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -33,11 +33,14 @@
33 33
34#undef DEBUG 34#undef DEBUG
35 35
36/* The size of a state save frame. */ 36#ifdef DEBUG
37#define STATE_SAVE_SIZE (PT_SIZE + STATE_SAVE_ARG_SPACE) 37/* Create space for syscalls counting. */
38 38.section .data
39/* The offset of the struct pt_regs in a `state save frame' on the stack. */ 39.global syscall_debug_table
40#define PTO STATE_SAVE_ARG_SPACE /* 24 the space for args */ 40.align 4
41syscall_debug_table:
42 .space (__NR_syscalls * 4)
43#endif /* DEBUG */
41 44
42#define C_ENTRY(name) .globl name; .align 4; name 45#define C_ENTRY(name) .globl name; .align 4; name
43 46
@@ -172,68 +175,72 @@
1721: 1751:
173 176
174#define SAVE_REGS \ 177#define SAVE_REGS \
175 swi r2, r1, PTO+PT_R2; /* Save SDA */ \ 178 swi r2, r1, PT_R2; /* Save SDA */ \
176 swi r3, r1, PTO+PT_R3; \ 179 swi r3, r1, PT_R3; \
177 swi r4, r1, PTO+PT_R4; \ 180 swi r4, r1, PT_R4; \
178 swi r5, r1, PTO+PT_R5; \ 181 swi r5, r1, PT_R5; \
179 swi r6, r1, PTO+PT_R6; \ 182 swi r6, r1, PT_R6; \
180 swi r7, r1, PTO+PT_R7; \ 183 swi r7, r1, PT_R7; \
181 swi r8, r1, PTO+PT_R8; \ 184 swi r8, r1, PT_R8; \
182 swi r9, r1, PTO+PT_R9; \ 185 swi r9, r1, PT_R9; \
183 swi r10, r1, PTO+PT_R10; \ 186 swi r10, r1, PT_R10; \
184 swi r11, r1, PTO+PT_R11; /* save clobbered regs after rval */\ 187 swi r11, r1, PT_R11; /* save clobbered regs after rval */\
185 swi r12, r1, PTO+PT_R12; \ 188 swi r12, r1, PT_R12; \
186 swi r13, r1, PTO+PT_R13; /* Save SDA2 */ \ 189 swi r13, r1, PT_R13; /* Save SDA2 */ \
187 swi r14, r1, PTO+PT_PC; /* PC, before IRQ/trap */ \ 190 swi r14, r1, PT_PC; /* PC, before IRQ/trap */ \
188 swi r15, r1, PTO+PT_R15; /* Save LP */ \ 191 swi r15, r1, PT_R15; /* Save LP */ \
189 swi r18, r1, PTO+PT_R18; /* Save asm scratch reg */ \ 192 swi r16, r1, PT_R16; \
190 swi r19, r1, PTO+PT_R19; \ 193 swi r17, r1, PT_R17; \
191 swi r20, r1, PTO+PT_R20; \ 194 swi r18, r1, PT_R18; /* Save asm scratch reg */ \
192 swi r21, r1, PTO+PT_R21; \ 195 swi r19, r1, PT_R19; \
193 swi r22, r1, PTO+PT_R22; \ 196 swi r20, r1, PT_R20; \
194 swi r23, r1, PTO+PT_R23; \ 197 swi r21, r1, PT_R21; \
195 swi r24, r1, PTO+PT_R24; \ 198 swi r22, r1, PT_R22; \
196 swi r25, r1, PTO+PT_R25; \ 199 swi r23, r1, PT_R23; \
197 swi r26, r1, PTO+PT_R26; \ 200 swi r24, r1, PT_R24; \
198 swi r27, r1, PTO+PT_R27; \ 201 swi r25, r1, PT_R25; \
199 swi r28, r1, PTO+PT_R28; \ 202 swi r26, r1, PT_R26; \
200 swi r29, r1, PTO+PT_R29; \ 203 swi r27, r1, PT_R27; \
201 swi r30, r1, PTO+PT_R30; \ 204 swi r28, r1, PT_R28; \
202 swi r31, r1, PTO+PT_R31; /* Save current task reg */ \ 205 swi r29, r1, PT_R29; \
206 swi r30, r1, PT_R30; \
207 swi r31, r1, PT_R31; /* Save current task reg */ \
203 mfs r11, rmsr; /* save MSR */ \ 208 mfs r11, rmsr; /* save MSR */ \
204 swi r11, r1, PTO+PT_MSR; 209 swi r11, r1, PT_MSR;
205 210
206#define RESTORE_REGS \ 211#define RESTORE_REGS \
207 lwi r11, r1, PTO+PT_MSR; \ 212 lwi r11, r1, PT_MSR; \
208 mts rmsr , r11; \ 213 mts rmsr , r11; \
209 lwi r2, r1, PTO+PT_R2; /* restore SDA */ \ 214 lwi r2, r1, PT_R2; /* restore SDA */ \
210 lwi r3, r1, PTO+PT_R3; \ 215 lwi r3, r1, PT_R3; \
211 lwi r4, r1, PTO+PT_R4; \ 216 lwi r4, r1, PT_R4; \
212 lwi r5, r1, PTO+PT_R5; \ 217 lwi r5, r1, PT_R5; \
213 lwi r6, r1, PTO+PT_R6; \ 218 lwi r6, r1, PT_R6; \
214 lwi r7, r1, PTO+PT_R7; \ 219 lwi r7, r1, PT_R7; \
215 lwi r8, r1, PTO+PT_R8; \ 220 lwi r8, r1, PT_R8; \
216 lwi r9, r1, PTO+PT_R9; \ 221 lwi r9, r1, PT_R9; \
217 lwi r10, r1, PTO+PT_R10; \ 222 lwi r10, r1, PT_R10; \
218 lwi r11, r1, PTO+PT_R11; /* restore clobbered regs after rval */\ 223 lwi r11, r1, PT_R11; /* restore clobbered regs after rval */\
219 lwi r12, r1, PTO+PT_R12; \ 224 lwi r12, r1, PT_R12; \
220 lwi r13, r1, PTO+PT_R13; /* restore SDA2 */ \ 225 lwi r13, r1, PT_R13; /* restore SDA2 */ \
221 lwi r14, r1, PTO+PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\ 226 lwi r14, r1, PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\
222 lwi r15, r1, PTO+PT_R15; /* restore LP */ \ 227 lwi r15, r1, PT_R15; /* restore LP */ \
223 lwi r18, r1, PTO+PT_R18; /* restore asm scratch reg */ \ 228 lwi r16, r1, PT_R16; \
224 lwi r19, r1, PTO+PT_R19; \ 229 lwi r17, r1, PT_R17; \
225 lwi r20, r1, PTO+PT_R20; \ 230 lwi r18, r1, PT_R18; /* restore asm scratch reg */ \
226 lwi r21, r1, PTO+PT_R21; \ 231 lwi r19, r1, PT_R19; \
227 lwi r22, r1, PTO+PT_R22; \ 232 lwi r20, r1, PT_R20; \
228 lwi r23, r1, PTO+PT_R23; \ 233 lwi r21, r1, PT_R21; \
229 lwi r24, r1, PTO+PT_R24; \ 234 lwi r22, r1, PT_R22; \
230 lwi r25, r1, PTO+PT_R25; \ 235 lwi r23, r1, PT_R23; \
231 lwi r26, r1, PTO+PT_R26; \ 236 lwi r24, r1, PT_R24; \
232 lwi r27, r1, PTO+PT_R27; \ 237 lwi r25, r1, PT_R25; \
233 lwi r28, r1, PTO+PT_R28; \ 238 lwi r26, r1, PT_R26; \
234 lwi r29, r1, PTO+PT_R29; \ 239 lwi r27, r1, PT_R27; \
235 lwi r30, r1, PTO+PT_R30; \ 240 lwi r28, r1, PT_R28; \
236 lwi r31, r1, PTO+PT_R31; /* Restore cur task reg */ 241 lwi r29, r1, PT_R29; \
242 lwi r30, r1, PT_R30; \
243 lwi r31, r1, PT_R31; /* Restore cur task reg */
237 244
238#define SAVE_STATE \ 245#define SAVE_STATE \
239 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* save stack */ \ 246 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* save stack */ \
@@ -246,11 +253,11 @@
246 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); \ 253 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); \
247 /* FIXME: I can add these two lines to one */ \ 254 /* FIXME: I can add these two lines to one */ \
248 /* tophys(r1,r1); */ \ 255 /* tophys(r1,r1); */ \
249 /* addik r1, r1, -STATE_SAVE_SIZE; */ \ 256 /* addik r1, r1, -PT_SIZE; */ \
250 addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; \ 257 addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - PT_SIZE; \
251 SAVE_REGS \ 258 SAVE_REGS \
252 brid 2f; \ 259 brid 2f; \
253 swi r1, r1, PTO+PT_MODE; \ 260 swi r1, r1, PT_MODE; \
2541: /* User-mode state save. */ \ 2611: /* User-mode state save. */ \
255 lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\ 262 lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\
256 tophys(r1,r1); \ 263 tophys(r1,r1); \
@@ -258,12 +265,12 @@
258 /* MS these three instructions can be added to one */ \ 265 /* MS these three instructions can be added to one */ \
259 /* addik r1, r1, THREAD_SIZE; */ \ 266 /* addik r1, r1, THREAD_SIZE; */ \
260 /* tophys(r1,r1); */ \ 267 /* tophys(r1,r1); */ \
261 /* addik r1, r1, -STATE_SAVE_SIZE; */ \ 268 /* addik r1, r1, -PT_SIZE; */ \
262 addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; \ 269 addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - PT_SIZE; \
263 SAVE_REGS \ 270 SAVE_REGS \
264 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); \ 271 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); \
265 swi r11, r1, PTO+PT_R1; /* Store user SP. */ \ 272 swi r11, r1, PT_R1; /* Store user SP. */ \
266 swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */ \ 273 swi r0, r1, PT_MODE; /* Was in user-mode. */ \
267 /* MS: I am clearing UMS even in case when I come from kernel space */ \ 274 /* MS: I am clearing UMS even in case when I come from kernel space */ \
268 clear_ums; \ 275 clear_ums; \
2692: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 2762: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
@@ -283,25 +290,46 @@
283 * are masked. This is nice, means we don't have to CLI before state save 290 * are masked. This is nice, means we don't have to CLI before state save
284 */ 291 */
285C_ENTRY(_user_exception): 292C_ENTRY(_user_exception):
286 addi r14, r14, 4 /* return address is 4 byte after call */
287 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */ 293 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */
294 addi r14, r14, 4 /* return address is 4 byte after call */
295
296 mfs r1, rmsr
297 nop
298 andi r1, r1, MSR_UMS
299 bnei r1, 1f
288 300
301/* Kernel-mode state save - kernel execve */
302 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
303 tophys(r1,r1);
304
305 addik r1, r1, -PT_SIZE; /* Make room on the stack. */
306 SAVE_REGS
307
308 swi r1, r1, PT_MODE; /* pt_regs -> kernel mode */
309 brid 2f;
310 nop; /* Fill delay slot */
311
312/* User-mode state save. */
3131:
289 lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */ 314 lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
290 tophys(r1,r1); 315 tophys(r1,r1);
291 lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */ 316 lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */
292 /* MS these three instructions can be added to one */ 317/* calculate kernel stack pointer from task struct 8k */
293 /* addik r1, r1, THREAD_SIZE; */ 318 addik r1, r1, THREAD_SIZE;
294 /* tophys(r1,r1); */ 319 tophys(r1,r1);
295 /* addik r1, r1, -STATE_SAVE_SIZE; */ 320
296 addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; 321 addik r1, r1, -PT_SIZE; /* Make room on the stack. */
297 SAVE_REGS 322 SAVE_REGS
323 swi r0, r1, PT_R3
324 swi r0, r1, PT_R4
298 325
326 swi r0, r1, PT_MODE; /* Was in user-mode. */
299 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 327 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
300 swi r11, r1, PTO+PT_R1; /* Store user SP. */ 328 swi r11, r1, PT_R1; /* Store user SP. */
301 clear_ums; 329 clear_ums;
302 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 3302: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
303 /* Save away the syscall number. */ 331 /* Save away the syscall number. */
304 swi r12, r1, PTO+PT_R0; 332 swi r12, r1, PT_R0;
305 tovirt(r1,r1) 333 tovirt(r1,r1)
306 334
307/* where the trap should return need -8 to adjust for rtsd r15, 8*/ 335/* where the trap should return need -8 to adjust for rtsd r15, 8*/
@@ -320,18 +348,18 @@ C_ENTRY(_user_exception):
320 beqi r11, 4f 348 beqi r11, 4f
321 349
322 addik r3, r0, -ENOSYS 350 addik r3, r0, -ENOSYS
323 swi r3, r1, PTO + PT_R3 351 swi r3, r1, PT_R3
324 brlid r15, do_syscall_trace_enter 352 brlid r15, do_syscall_trace_enter
325 addik r5, r1, PTO + PT_R0 353 addik r5, r1, PT_R0
326 354
327 # do_syscall_trace_enter returns the new syscall nr. 355 # do_syscall_trace_enter returns the new syscall nr.
328 addk r12, r0, r3 356 addk r12, r0, r3
329 lwi r5, r1, PTO+PT_R5; 357 lwi r5, r1, PT_R5;
330 lwi r6, r1, PTO+PT_R6; 358 lwi r6, r1, PT_R6;
331 lwi r7, r1, PTO+PT_R7; 359 lwi r7, r1, PT_R7;
332 lwi r8, r1, PTO+PT_R8; 360 lwi r8, r1, PT_R8;
333 lwi r9, r1, PTO+PT_R9; 361 lwi r9, r1, PT_R9;
334 lwi r10, r1, PTO+PT_R10; 362 lwi r10, r1, PT_R10;
3354: 3634:
336/* Jump to the appropriate function for the system call number in r12 364/* Jump to the appropriate function for the system call number in r12
337 * (r12 is not preserved), or return an error if r12 is not valid. 365 * (r12 is not preserved), or return an error if r12 is not valid.
@@ -346,10 +374,14 @@ C_ENTRY(_user_exception):
346 add r12, r12, r12; 374 add r12, r12, r12;
347 375
348#ifdef DEBUG 376#ifdef DEBUG
349 /* Trac syscalls and stored them to r0_ram */ 377 /* Trac syscalls and stored them to syscall_debug_table */
350 lwi r3, r12, 0x400 + r0_ram 378 /* The first syscall location stores total syscall number */
379 lwi r3, r0, syscall_debug_table
380 addi r3, r3, 1
381 swi r3, r0, syscall_debug_table
382 lwi r3, r12, syscall_debug_table
351 addi r3, r3, 1 383 addi r3, r3, 1
352 swi r3, r12, 0x400 + r0_ram 384 swi r3, r12, syscall_debug_table
353#endif 385#endif
354 386
355 # Find and jump into the syscall handler. 387 # Find and jump into the syscall handler.
@@ -366,9 +398,12 @@ C_ENTRY(_user_exception):
366/* Entry point used to return from a syscall/trap */ 398/* Entry point used to return from a syscall/trap */
367/* We re-enable BIP bit before state restore */ 399/* We re-enable BIP bit before state restore */
368C_ENTRY(ret_from_trap): 400C_ENTRY(ret_from_trap):
369 swi r3, r1, PTO + PT_R3 401 swi r3, r1, PT_R3
370 swi r4, r1, PTO + PT_R4 402 swi r4, r1, PT_R4
371 403
404 lwi r11, r1, PT_MODE;
405/* See if returning to kernel mode, if so, skip resched &c. */
406 bnei r11, 2f;
372 /* We're returning to user mode, so check for various conditions that 407 /* We're returning to user mode, so check for various conditions that
373 * trigger rescheduling. */ 408 * trigger rescheduling. */
374 /* FIXME: Restructure all these flag checks. */ 409 /* FIXME: Restructure all these flag checks. */
@@ -378,7 +413,7 @@ C_ENTRY(ret_from_trap):
378 beqi r11, 1f 413 beqi r11, 1f
379 414
380 brlid r15, do_syscall_trace_leave 415 brlid r15, do_syscall_trace_leave
381 addik r5, r1, PTO + PT_R0 416 addik r5, r1, PT_R0
3821: 4171:
383 /* We're returning to user mode, so check for various conditions that 418 /* We're returning to user mode, so check for various conditions that
384 * trigger rescheduling. */ 419 * trigger rescheduling. */
@@ -398,7 +433,7 @@ C_ENTRY(ret_from_trap):
398 andi r11, r11, _TIF_SIGPENDING; 433 andi r11, r11, _TIF_SIGPENDING;
399 beqi r11, 1f; /* Signals to handle, handle them */ 434 beqi r11, 1f; /* Signals to handle, handle them */
400 435
401 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ 436 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
402 addi r7, r0, 1; /* Arg 3: int in_syscall */ 437 addi r7, r0, 1; /* Arg 3: int in_syscall */
403 bralid r15, do_signal; /* Handle any signals */ 438 bralid r15, do_signal; /* Handle any signals */
404 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 439 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
@@ -409,8 +444,18 @@ C_ENTRY(ret_from_trap):
409 VM_OFF; 444 VM_OFF;
410 tophys(r1,r1); 445 tophys(r1,r1);
411 RESTORE_REGS; 446 RESTORE_REGS;
412 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ 447 addik r1, r1, PT_SIZE /* Clean up stack space. */
413 lwi r1, r1, PT_R1 - PT_SIZE;/* Restore user stack pointer. */ 448 lwi r1, r1, PT_R1 - PT_SIZE;/* Restore user stack pointer. */
449 bri 6f;
450
451/* Return to kernel state. */
4522: set_bip; /* Ints masked for state restore */
453 VM_OFF;
454 tophys(r1,r1);
455 RESTORE_REGS;
456 addik r1, r1, PT_SIZE /* Clean up stack space. */
457 tovirt(r1,r1);
4586:
414TRAP_return: /* Make global symbol for debugging */ 459TRAP_return: /* Make global symbol for debugging */
415 rtbd r14, 0; /* Instructions to return from an IRQ */ 460 rtbd r14, 0; /* Instructions to return from an IRQ */
416 nop; 461 nop;
@@ -421,8 +466,8 @@ TRAP_return: /* Make global symbol for debugging */
421 466
422C_ENTRY(sys_fork_wrapper): 467C_ENTRY(sys_fork_wrapper):
423 addi r5, r0, SIGCHLD /* Arg 0: flags */ 468 addi r5, r0, SIGCHLD /* Arg 0: flags */
424 lwi r6, r1, PTO+PT_R1 /* Arg 1: child SP (use parent's) */ 469 lwi r6, r1, PT_R1 /* Arg 1: child SP (use parent's) */
425 addik r7, r1, PTO /* Arg 2: parent context */ 470 addik r7, r1, 0 /* Arg 2: parent context */
426 add r8. r0, r0 /* Arg 3: (unused) */ 471 add r8. r0, r0 /* Arg 3: (unused) */
427 add r9, r0, r0; /* Arg 4: (unused) */ 472 add r9, r0, r0; /* Arg 4: (unused) */
428 brid do_fork /* Do real work (tail-call) */ 473 brid do_fork /* Do real work (tail-call) */
@@ -442,12 +487,12 @@ C_ENTRY(ret_from_fork):
442 487
443C_ENTRY(sys_vfork): 488C_ENTRY(sys_vfork):
444 brid microblaze_vfork /* Do real work (tail-call) */ 489 brid microblaze_vfork /* Do real work (tail-call) */
445 addik r5, r1, PTO 490 addik r5, r1, 0
446 491
447C_ENTRY(sys_clone): 492C_ENTRY(sys_clone):
448 bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */ 493 bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */
449 lwi r6, r1, PTO + PT_R1; /* If so, use paret's stack ptr */ 494 lwi r6, r1, PT_R1; /* If so, use paret's stack ptr */
4501: addik r7, r1, PTO; /* Arg 2: parent context */ 4951: addik r7, r1, 0; /* Arg 2: parent context */
451 add r8, r0, r0; /* Arg 3: (unused) */ 496 add r8, r0, r0; /* Arg 3: (unused) */
452 add r9, r0, r0; /* Arg 4: (unused) */ 497 add r9, r0, r0; /* Arg 4: (unused) */
453 brid do_fork /* Do real work (tail-call) */ 498 brid do_fork /* Do real work (tail-call) */
@@ -455,17 +500,11 @@ C_ENTRY(sys_clone):
455 500
456C_ENTRY(sys_execve): 501C_ENTRY(sys_execve):
457 brid microblaze_execve; /* Do real work (tail-call).*/ 502 brid microblaze_execve; /* Do real work (tail-call).*/
458 addik r8, r1, PTO; /* add user context as 4th arg */ 503 addik r8, r1, 0; /* add user context as 4th arg */
459 504
460C_ENTRY(sys_rt_sigreturn_wrapper): 505C_ENTRY(sys_rt_sigreturn_wrapper):
461 swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ 506 brid sys_rt_sigreturn /* Do real work */
462 swi r4, r1, PTO+PT_R4; 507 addik r5, r1, 0; /* add user context as 1st arg */
463 brlid r15, sys_rt_sigreturn /* Do real work */
464 addik r5, r1, PTO; /* add user context as 1st arg */
465 lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
466 lwi r4, r1, PTO+PT_R4;
467 bri ret_from_trap /* fall through will not work here due to align */
468 nop;
469 508
470/* 509/*
471 * HW EXCEPTION rutine start 510 * HW EXCEPTION rutine start
@@ -476,7 +515,7 @@ C_ENTRY(full_exception_trap):
476 addik r17, r17, -4 515 addik r17, r17, -4
477 SAVE_STATE /* Save registers */ 516 SAVE_STATE /* Save registers */
478 /* PC, before IRQ/trap - this is one instruction above */ 517 /* PC, before IRQ/trap - this is one instruction above */
479 swi r17, r1, PTO+PT_PC; 518 swi r17, r1, PT_PC;
480 tovirt(r1,r1) 519 tovirt(r1,r1)
481 /* FIXME this can be store directly in PT_ESR reg. 520 /* FIXME this can be store directly in PT_ESR reg.
482 * I tested it but there is a fault */ 521 * I tested it but there is a fault */
@@ -486,7 +525,7 @@ C_ENTRY(full_exception_trap):
486 mfs r7, rfsr; /* save FSR */ 525 mfs r7, rfsr; /* save FSR */
487 mts rfsr, r0; /* Clear sticky fsr */ 526 mts rfsr, r0; /* Clear sticky fsr */
488 rted r0, full_exception 527 rted r0, full_exception
489 addik r5, r1, PTO /* parameter struct pt_regs * regs */ 528 addik r5, r1, 0 /* parameter struct pt_regs * regs */
490 529
491/* 530/*
492 * Unaligned data trap. 531 * Unaligned data trap.
@@ -512,14 +551,14 @@ C_ENTRY(unaligned_data_trap):
512 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 551 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
513 SAVE_STATE /* Save registers.*/ 552 SAVE_STATE /* Save registers.*/
514 /* PC, before IRQ/trap - this is one instruction above */ 553 /* PC, before IRQ/trap - this is one instruction above */
515 swi r17, r1, PTO+PT_PC; 554 swi r17, r1, PT_PC;
516 tovirt(r1,r1) 555 tovirt(r1,r1)
517 /* where the trap should return need -8 to adjust for rtsd r15, 8 */ 556 /* where the trap should return need -8 to adjust for rtsd r15, 8 */
518 addik r15, r0, ret_from_exc-8 557 addik r15, r0, ret_from_exc-8
519 mfs r3, resr /* ESR */ 558 mfs r3, resr /* ESR */
520 mfs r4, rear /* EAR */ 559 mfs r4, rear /* EAR */
521 rtbd r0, _unaligned_data_exception 560 rtbd r0, _unaligned_data_exception
522 addik r7, r1, PTO /* parameter struct pt_regs * regs */ 561 addik r7, r1, 0 /* parameter struct pt_regs * regs */
523 562
524/* 563/*
525 * Page fault traps. 564 * Page fault traps.
@@ -542,30 +581,30 @@ C_ENTRY(unaligned_data_trap):
542C_ENTRY(page_fault_data_trap): 581C_ENTRY(page_fault_data_trap):
543 SAVE_STATE /* Save registers.*/ 582 SAVE_STATE /* Save registers.*/
544 /* PC, before IRQ/trap - this is one instruction above */ 583 /* PC, before IRQ/trap - this is one instruction above */
545 swi r17, r1, PTO+PT_PC; 584 swi r17, r1, PT_PC;
546 tovirt(r1,r1) 585 tovirt(r1,r1)
547 /* where the trap should return need -8 to adjust for rtsd r15, 8 */ 586 /* where the trap should return need -8 to adjust for rtsd r15, 8 */
548 addik r15, r0, ret_from_exc-8 587 addik r15, r0, ret_from_exc-8
549 mfs r6, rear /* parameter unsigned long address */ 588 mfs r6, rear /* parameter unsigned long address */
550 mfs r7, resr /* parameter unsigned long error_code */ 589 mfs r7, resr /* parameter unsigned long error_code */
551 rted r0, do_page_fault 590 rted r0, do_page_fault
552 addik r5, r1, PTO /* parameter struct pt_regs * regs */ 591 addik r5, r1, 0 /* parameter struct pt_regs * regs */
553 592
554C_ENTRY(page_fault_instr_trap): 593C_ENTRY(page_fault_instr_trap):
555 SAVE_STATE /* Save registers.*/ 594 SAVE_STATE /* Save registers.*/
556 /* PC, before IRQ/trap - this is one instruction above */ 595 /* PC, before IRQ/trap - this is one instruction above */
557 swi r17, r1, PTO+PT_PC; 596 swi r17, r1, PT_PC;
558 tovirt(r1,r1) 597 tovirt(r1,r1)
559 /* where the trap should return need -8 to adjust for rtsd r15, 8 */ 598 /* where the trap should return need -8 to adjust for rtsd r15, 8 */
560 addik r15, r0, ret_from_exc-8 599 addik r15, r0, ret_from_exc-8
561 mfs r6, rear /* parameter unsigned long address */ 600 mfs r6, rear /* parameter unsigned long address */
562 ori r7, r0, 0 /* parameter unsigned long error_code */ 601 ori r7, r0, 0 /* parameter unsigned long error_code */
563 rted r0, do_page_fault 602 rted r0, do_page_fault
564 addik r5, r1, PTO /* parameter struct pt_regs * regs */ 603 addik r5, r1, 0 /* parameter struct pt_regs * regs */
565 604
566/* Entry point used to return from an exception. */ 605/* Entry point used to return from an exception. */
567C_ENTRY(ret_from_exc): 606C_ENTRY(ret_from_exc):
568 lwi r11, r1, PTO + PT_MODE; 607 lwi r11, r1, PT_MODE;
569 bnei r11, 2f; /* See if returning to kernel mode, */ 608 bnei r11, 2f; /* See if returning to kernel mode, */
570 /* ... if so, skip resched &c. */ 609 /* ... if so, skip resched &c. */
571 610
@@ -597,7 +636,7 @@ C_ENTRY(ret_from_exc):
597 * complete register state. Here we save anything not saved by 636 * complete register state. Here we save anything not saved by
598 * the normal entry sequence, so that it may be safely restored 637 * the normal entry sequence, so that it may be safely restored
599 * (in a possibly modified form) after do_signal returns. */ 638 * (in a possibly modified form) after do_signal returns. */
600 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ 639 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
601 addi r7, r0, 0; /* Arg 3: int in_syscall */ 640 addi r7, r0, 0; /* Arg 3: int in_syscall */
602 bralid r15, do_signal; /* Handle any signals */ 641 bralid r15, do_signal; /* Handle any signals */
603 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 642 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
@@ -609,7 +648,7 @@ C_ENTRY(ret_from_exc):
609 tophys(r1,r1); 648 tophys(r1,r1);
610 649
611 RESTORE_REGS; 650 RESTORE_REGS;
612 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ 651 addik r1, r1, PT_SIZE /* Clean up stack space. */
613 652
614 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer. */ 653 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer. */
615 bri 6f; 654 bri 6f;
@@ -618,7 +657,7 @@ C_ENTRY(ret_from_exc):
618 VM_OFF; 657 VM_OFF;
619 tophys(r1,r1); 658 tophys(r1,r1);
620 RESTORE_REGS; 659 RESTORE_REGS;
621 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ 660 addik r1, r1, PT_SIZE /* Clean up stack space. */
622 661
623 tovirt(r1,r1); 662 tovirt(r1,r1);
6246: 6636:
@@ -651,10 +690,10 @@ C_ENTRY(_interrupt):
651 tophys(r1,r1); /* MS: I have in r1 physical address where stack is */ 690 tophys(r1,r1); /* MS: I have in r1 physical address where stack is */
652 /* save registers */ 691 /* save registers */
653/* MS: Make room on the stack -> activation record */ 692/* MS: Make room on the stack -> activation record */
654 addik r1, r1, -STATE_SAVE_SIZE; 693 addik r1, r1, -PT_SIZE;
655 SAVE_REGS 694 SAVE_REGS
656 brid 2f; 695 brid 2f;
657 swi r1, r1, PTO + PT_MODE; /* 0 - user mode, 1 - kernel mode */ 696 swi r1, r1, PT_MODE; /* 0 - user mode, 1 - kernel mode */
6581: 6971:
659/* User-mode state save. */ 698/* User-mode state save. */
660 /* MS: get the saved current */ 699 /* MS: get the saved current */
@@ -664,23 +703,23 @@ C_ENTRY(_interrupt):
664 addik r1, r1, THREAD_SIZE; 703 addik r1, r1, THREAD_SIZE;
665 tophys(r1,r1); 704 tophys(r1,r1);
666 /* save registers */ 705 /* save registers */
667 addik r1, r1, -STATE_SAVE_SIZE; 706 addik r1, r1, -PT_SIZE;
668 SAVE_REGS 707 SAVE_REGS
669 /* calculate mode */ 708 /* calculate mode */
670 swi r0, r1, PTO + PT_MODE; 709 swi r0, r1, PT_MODE;
671 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 710 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
672 swi r11, r1, PTO+PT_R1; 711 swi r11, r1, PT_R1;
673 clear_ums; 712 clear_ums;
6742: 7132:
675 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 714 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
676 tovirt(r1,r1) 715 tovirt(r1,r1)
677 addik r15, r0, irq_call; 716 addik r15, r0, irq_call;
678irq_call:rtbd r0, do_IRQ; 717irq_call:rtbd r0, do_IRQ;
679 addik r5, r1, PTO; 718 addik r5, r1, 0;
680 719
681/* MS: we are in virtual mode */ 720/* MS: we are in virtual mode */
682ret_from_irq: 721ret_from_irq:
683 lwi r11, r1, PTO + PT_MODE; 722 lwi r11, r1, PT_MODE;
684 bnei r11, 2f; 723 bnei r11, 2f;
685 724
686 lwi r11, CURRENT_TASK, TS_THREAD_INFO; 725 lwi r11, CURRENT_TASK, TS_THREAD_INFO;
@@ -697,7 +736,7 @@ ret_from_irq:
697 beqid r11, no_intr_resched 736 beqid r11, no_intr_resched
698/* Handle a signal return; Pending signals should be in r18. */ 737/* Handle a signal return; Pending signals should be in r18. */
699 addi r7, r0, 0; /* Arg 3: int in_syscall */ 738 addi r7, r0, 0; /* Arg 3: int in_syscall */
700 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ 739 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
701 bralid r15, do_signal; /* Handle any signals */ 740 bralid r15, do_signal; /* Handle any signals */
702 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 741 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
703 742
@@ -709,7 +748,7 @@ no_intr_resched:
709 VM_OFF; 748 VM_OFF;
710 tophys(r1,r1); 749 tophys(r1,r1);
711 RESTORE_REGS 750 RESTORE_REGS
712 addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */ 751 addik r1, r1, PT_SIZE /* MS: Clean up stack space. */
713 lwi r1, r1, PT_R1 - PT_SIZE; 752 lwi r1, r1, PT_R1 - PT_SIZE;
714 bri 6f; 753 bri 6f;
715/* MS: Return to kernel state. */ 754/* MS: Return to kernel state. */
@@ -737,7 +776,7 @@ restore:
737 VM_OFF /* MS: turn off MMU */ 776 VM_OFF /* MS: turn off MMU */
738 tophys(r1,r1) 777 tophys(r1,r1)
739 RESTORE_REGS 778 RESTORE_REGS
740 addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */ 779 addik r1, r1, PT_SIZE /* MS: Clean up stack space. */
741 tovirt(r1,r1); 780 tovirt(r1,r1);
7426: 7816:
743IRQ_return: /* MS: Make global symbol for debugging */ 782IRQ_return: /* MS: Make global symbol for debugging */
@@ -760,31 +799,29 @@ C_ENTRY(_debug_exception):
760 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/ 799 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
761 800
762 /* BIP bit is set on entry, no interrupts can occur */ 801 /* BIP bit is set on entry, no interrupts can occur */
763 addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; 802 addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - PT_SIZE;
764 SAVE_REGS; 803 SAVE_REGS;
765 /* save all regs to pt_reg structure */ 804 /* save all regs to pt_reg structure */
766 swi r0, r1, PTO+PT_R0; /* R0 must be saved too */ 805 swi r0, r1, PT_R0; /* R0 must be saved too */
767 swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */ 806 swi r14, r1, PT_R14 /* rewrite saved R14 value */
768 swi r16, r1, PTO+PT_R16 807 swi r16, r1, PT_PC; /* PC and r16 are the same */
769 swi r16, r1, PTO+PT_PC; /* PC and r16 are the same */
770 swi r17, r1, PTO+PT_R17
771 /* save special purpose registers to pt_regs */ 808 /* save special purpose registers to pt_regs */
772 mfs r11, rear; 809 mfs r11, rear;
773 swi r11, r1, PTO+PT_EAR; 810 swi r11, r1, PT_EAR;
774 mfs r11, resr; 811 mfs r11, resr;
775 swi r11, r1, PTO+PT_ESR; 812 swi r11, r1, PT_ESR;
776 mfs r11, rfsr; 813 mfs r11, rfsr;
777 swi r11, r1, PTO+PT_FSR; 814 swi r11, r1, PT_FSR;
778 815
779 /* stack pointer is in physical address at it is decrease 816 /* stack pointer is in physical address at it is decrease
780 * by STATE_SAVE_SIZE but we need to get correct R1 value */ 817 * by PT_SIZE but we need to get correct R1 value */
781 addik r11, r1, CONFIG_KERNEL_START - CONFIG_KERNEL_BASE_ADDR + STATE_SAVE_SIZE; 818 addik r11, r1, CONFIG_KERNEL_START - CONFIG_KERNEL_BASE_ADDR + PT_SIZE;
782 swi r11, r1, PTO+PT_R1 819 swi r11, r1, PT_R1
783 /* MS: r31 - current pointer isn't changed */ 820 /* MS: r31 - current pointer isn't changed */
784 tovirt(r1,r1) 821 tovirt(r1,r1)
785#ifdef CONFIG_KGDB 822#ifdef CONFIG_KGDB
786 addi r5, r1, PTO /* pass pt_reg address as the first arg */ 823 addi r5, r1, 0 /* pass pt_reg address as the first arg */
787 la r15, r0, dbtrap_call; /* return address */ 824 addik r15, r0, dbtrap_call; /* return address */
788 rtbd r0, microblaze_kgdb_break 825 rtbd r0, microblaze_kgdb_break
789 nop; 826 nop;
790#endif 827#endif
@@ -799,18 +836,16 @@ C_ENTRY(_debug_exception):
799 addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */ 836 addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */
800 tophys(r1,r1); 837 tophys(r1,r1);
801 838
802 addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ 839 addik r1, r1, -PT_SIZE; /* Make room on the stack. */
803 SAVE_REGS; 840 SAVE_REGS;
804 swi r17, r1, PTO+PT_R17; 841 swi r16, r1, PT_PC; /* Save LP */
805 swi r16, r1, PTO+PT_R16; 842 swi r0, r1, PT_MODE; /* Was in user-mode. */
806 swi r16, r1, PTO+PT_PC; /* Save LP */
807 swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */
808 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 843 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
809 swi r11, r1, PTO+PT_R1; /* Store user SP. */ 844 swi r11, r1, PT_R1; /* Store user SP. */
810 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 845 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
811 tovirt(r1,r1) 846 tovirt(r1,r1)
812 set_vms; 847 set_vms;
813 addik r5, r1, PTO; 848 addik r5, r1, 0;
814 addik r15, r0, dbtrap_call; 849 addik r15, r0, dbtrap_call;
815dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */ 850dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
816 rtbd r0, sw_exception 851 rtbd r0, sw_exception
@@ -818,7 +853,7 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
818 853
819 /* MS: The first instruction for the second part of the gdb/kgdb */ 854 /* MS: The first instruction for the second part of the gdb/kgdb */
820 set_bip; /* Ints masked for state restore */ 855 set_bip; /* Ints masked for state restore */
821 lwi r11, r1, PTO + PT_MODE; 856 lwi r11, r1, PT_MODE;
822 bnei r11, 2f; 857 bnei r11, 2f;
823/* MS: Return to user space - gdb */ 858/* MS: Return to user space - gdb */
824 /* Get current task ptr into r11 */ 859 /* Get current task ptr into r11 */
@@ -837,7 +872,7 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
837 andi r11, r11, _TIF_SIGPENDING; 872 andi r11, r11, _TIF_SIGPENDING;
838 beqi r11, 1f; /* Signals to handle, handle them */ 873 beqi r11, 1f; /* Signals to handle, handle them */
839 874
840 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ 875 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
841 addi r7, r0, 0; /* Arg 3: int in_syscall */ 876 addi r7, r0, 0; /* Arg 3: int in_syscall */
842 bralid r15, do_signal; /* Handle any signals */ 877 bralid r15, do_signal; /* Handle any signals */
843 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 878 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
@@ -848,9 +883,7 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
848 tophys(r1,r1); 883 tophys(r1,r1);
849 /* MS: Restore all regs */ 884 /* MS: Restore all regs */
850 RESTORE_REGS 885 RESTORE_REGS
851 lwi r17, r1, PTO+PT_R17; 886 addik r1, r1, PT_SIZE /* Clean up stack space */
852 lwi r16, r1, PTO+PT_R16;
853 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */
854 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */ 887 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
855DBTRAP_return_user: /* MS: Make global symbol for debugging */ 888DBTRAP_return_user: /* MS: Make global symbol for debugging */
856 rtbd r16, 0; /* MS: Instructions to return from a debug trap */ 889 rtbd r16, 0; /* MS: Instructions to return from a debug trap */
@@ -861,10 +894,9 @@ DBTRAP_return_user: /* MS: Make global symbol for debugging */
861 tophys(r1,r1); 894 tophys(r1,r1);
862 /* MS: Restore all regs */ 895 /* MS: Restore all regs */
863 RESTORE_REGS 896 RESTORE_REGS
864 lwi r14, r1, PTO+PT_R14; 897 lwi r14, r1, PT_R14;
865 lwi r16, r1, PTO+PT_PC; 898 lwi r16, r1, PT_PC;
866 lwi r17, r1, PTO+PT_R17; 899 addik r1, r1, PT_SIZE; /* MS: Clean up stack space */
867 addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */
868 tovirt(r1,r1); 900 tovirt(r1,r1);
869DBTRAP_return_kernel: /* MS: Make global symbol for debugging */ 901DBTRAP_return_kernel: /* MS: Make global symbol for debugging */
870 rtbd r16, 0; /* MS: Instructions to return from a debug trap */ 902 rtbd r16, 0; /* MS: Instructions to return from a debug trap */
@@ -956,20 +988,22 @@ ENTRY(_switch_to)
956 nop 988 nop
957 989
958ENTRY(_reset) 990ENTRY(_reset)
959 brai 0x70; /* Jump back to FS-boot */ 991 brai 0; /* Jump to reset vector */
960 992
961 /* These are compiled and loaded into high memory, then 993 /* These are compiled and loaded into high memory, then
962 * copied into place in mach_early_setup */ 994 * copied into place in mach_early_setup */
963 .section .init.ivt, "ax" 995 .section .init.ivt, "ax"
996#if CONFIG_MANUAL_RESET_VECTOR
964 .org 0x0 997 .org 0x0
965 /* this is very important - here is the reset vector */ 998 brai CONFIG_MANUAL_RESET_VECTOR
966 /* in current MMU branch you don't care what is here - it is 999#endif
967 * used from bootloader site - but this is correct for FS-BOOT */ 1000 .org 0x8
968 brai 0x70
969 nop
970 brai TOPHYS(_user_exception); /* syscall handler */ 1001 brai TOPHYS(_user_exception); /* syscall handler */
1002 .org 0x10
971 brai TOPHYS(_interrupt); /* Interrupt handler */ 1003 brai TOPHYS(_interrupt); /* Interrupt handler */
1004 .org 0x18
972 brai TOPHYS(_debug_exception); /* debug trap handler */ 1005 brai TOPHYS(_debug_exception); /* debug trap handler */
1006 .org 0x20
973 brai TOPHYS(_hw_exception_handler); /* HW exception handler */ 1007 brai TOPHYS(_hw_exception_handler); /* HW exception handler */
974 1008
975.section .rodata,"a" 1009.section .rodata,"a"
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
index b98ee8d0c1cd..66fad2301221 100644
--- a/arch/microblaze/kernel/exceptions.c
+++ b/arch/microblaze/kernel/exceptions.c
@@ -25,6 +25,7 @@
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/ptrace.h> 26#include <linux/ptrace.h>
27#include <asm/current.h> 27#include <asm/current.h>
28#include <asm/cacheflush.h>
28 29
29#define MICROBLAZE_ILL_OPCODE_EXCEPTION 0x02 30#define MICROBLAZE_ILL_OPCODE_EXCEPTION 0x02
30#define MICROBLAZE_IBUS_EXCEPTION 0x03 31#define MICROBLAZE_IBUS_EXCEPTION 0x03
@@ -49,9 +50,11 @@ void die(const char *str, struct pt_regs *fp, long err)
49} 50}
50 51
51/* for user application debugging */ 52/* for user application debugging */
52void sw_exception(struct pt_regs *regs) 53asmlinkage void sw_exception(struct pt_regs *regs)
53{ 54{
54 _exception(SIGTRAP, regs, TRAP_BRKPT, regs->r16); 55 _exception(SIGTRAP, regs, TRAP_BRKPT, regs->r16);
56 flush_dcache_range(regs->r16, regs->r16 + 0x4);
57 flush_icache_range(regs->r16, regs->r16 + 0x4);
55} 58}
56 59
57void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) 60void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
@@ -72,7 +75,6 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
72 int fsr, int addr) 75 int fsr, int addr)
73{ 76{
74#ifdef CONFIG_MMU 77#ifdef CONFIG_MMU
75 int code;
76 addr = regs->pc; 78 addr = regs->pc;
77#endif 79#endif
78 80
@@ -86,8 +88,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
86 switch (type & 0x1F) { 88 switch (type & 0x1F) {
87 case MICROBLAZE_ILL_OPCODE_EXCEPTION: 89 case MICROBLAZE_ILL_OPCODE_EXCEPTION:
88 if (user_mode(regs)) { 90 if (user_mode(regs)) {
89 pr_debug(KERN_WARNING "Illegal opcode exception " \ 91 pr_debug("Illegal opcode exception in user mode\n");
90 "in user mode.\n");
91 _exception(SIGILL, regs, ILL_ILLOPC, addr); 92 _exception(SIGILL, regs, ILL_ILLOPC, addr);
92 return; 93 return;
93 } 94 }
@@ -97,8 +98,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
97 break; 98 break;
98 case MICROBLAZE_IBUS_EXCEPTION: 99 case MICROBLAZE_IBUS_EXCEPTION:
99 if (user_mode(regs)) { 100 if (user_mode(regs)) {
100 pr_debug(KERN_WARNING "Instruction bus error " \ 101 pr_debug("Instruction bus error exception in user mode\n");
101 "exception in user mode.\n");
102 _exception(SIGBUS, regs, BUS_ADRERR, addr); 102 _exception(SIGBUS, regs, BUS_ADRERR, addr);
103 return; 103 return;
104 } 104 }
@@ -108,8 +108,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
108 break; 108 break;
109 case MICROBLAZE_DBUS_EXCEPTION: 109 case MICROBLAZE_DBUS_EXCEPTION:
110 if (user_mode(regs)) { 110 if (user_mode(regs)) {
111 pr_debug(KERN_WARNING "Data bus error exception " \ 111 pr_debug("Data bus error exception in user mode\n");
112 "in user mode.\n");
113 _exception(SIGBUS, regs, BUS_ADRERR, addr); 112 _exception(SIGBUS, regs, BUS_ADRERR, addr);
114 return; 113 return;
115 } 114 }
@@ -119,8 +118,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
119 break; 118 break;
120 case MICROBLAZE_DIV_ZERO_EXCEPTION: 119 case MICROBLAZE_DIV_ZERO_EXCEPTION:
121 if (user_mode(regs)) { 120 if (user_mode(regs)) {
122 pr_debug(KERN_WARNING "Divide by zero exception " \ 121 pr_debug("Divide by zero exception in user mode\n");
123 "in user mode\n");
124 _exception(SIGILL, regs, FPE_INTDIV, addr); 122 _exception(SIGILL, regs, FPE_INTDIV, addr);
125 return; 123 return;
126 } 124 }
@@ -129,7 +127,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
129 die("Divide by zero exception", regs, SIGBUS); 127 die("Divide by zero exception", regs, SIGBUS);
130 break; 128 break;
131 case MICROBLAZE_FPU_EXCEPTION: 129 case MICROBLAZE_FPU_EXCEPTION:
132 pr_debug(KERN_WARNING "FPU exception\n"); 130 pr_debug("FPU exception\n");
133 /* IEEE FP exception */ 131 /* IEEE FP exception */
134 /* I removed fsr variable and use code var for storing fsr */ 132 /* I removed fsr variable and use code var for storing fsr */
135 if (fsr & FSR_IO) 133 if (fsr & FSR_IO)
@@ -147,14 +145,8 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
147 145
148#ifdef CONFIG_MMU 146#ifdef CONFIG_MMU
149 case MICROBLAZE_PRIVILEGED_EXCEPTION: 147 case MICROBLAZE_PRIVILEGED_EXCEPTION:
150 pr_debug(KERN_WARNING "Privileged exception\n"); 148 pr_debug("Privileged exception\n");
151 /* "brk r0,r0" - used as debug breakpoint - old toolchain */ 149 _exception(SIGILL, regs, ILL_PRVOPC, addr);
152 if (get_user(code, (unsigned long *)regs->pc) == 0
153 && code == 0x980c0000) {
154 _exception(SIGTRAP, regs, TRAP_BRKPT, addr);
155 } else {
156 _exception(SIGILL, regs, ILL_PRVOPC, addr);
157 }
158 break; 150 break;
159#endif 151#endif
160 default: 152 default:
diff --git a/arch/microblaze/kernel/ftrace.c b/arch/microblaze/kernel/ftrace.c
index 515feb404555..357d56abe24a 100644
--- a/arch/microblaze/kernel/ftrace.c
+++ b/arch/microblaze/kernel/ftrace.c
@@ -51,6 +51,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
51 : "r" (parent), "r" (return_hooker) 51 : "r" (parent), "r" (return_hooker)
52 ); 52 );
53 53
54 flush_dcache_range((u32)parent, (u32)parent + 4);
55 flush_icache_range((u32)parent, (u32)parent + 4);
56
54 if (unlikely(faulted)) { 57 if (unlikely(faulted)) {
55 ftrace_graph_stop(); 58 ftrace_graph_stop();
56 WARN_ON(1); 59 WARN_ON(1);
@@ -95,6 +98,9 @@ static int ftrace_modify_code(unsigned long addr, unsigned int value)
95 if (unlikely(faulted)) 98 if (unlikely(faulted))
96 return -EFAULT; 99 return -EFAULT;
97 100
101 flush_dcache_range(addr, addr + 4);
102 flush_icache_range(addr, addr + 4);
103
98 return 0; 104 return 0;
99} 105}
100 106
@@ -195,8 +201,6 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
195 ret += ftrace_modify_code((unsigned long)&ftrace_caller, 201 ret += ftrace_modify_code((unsigned long)&ftrace_caller,
196 MICROBLAZE_NOP); 202 MICROBLAZE_NOP);
197 203
198 /* All changes are done - lets do caches consistent */
199 flush_icache();
200 return ret; 204 return ret;
201} 205}
202 206
@@ -210,7 +214,6 @@ int ftrace_enable_ftrace_graph_caller(void)
210 214
211 old_jump = *(unsigned int *)ip; /* save jump over instruction */ 215 old_jump = *(unsigned int *)ip; /* save jump over instruction */
212 ret = ftrace_modify_code(ip, MICROBLAZE_NOP); 216 ret = ftrace_modify_code(ip, MICROBLAZE_NOP);
213 flush_icache();
214 217
215 pr_debug("%s: Replace instruction: 0x%x\n", __func__, old_jump); 218 pr_debug("%s: Replace instruction: 0x%x\n", __func__, old_jump);
216 return ret; 219 return ret;
@@ -222,7 +225,6 @@ int ftrace_disable_ftrace_graph_caller(void)
222 unsigned long ip = (unsigned long)(&ftrace_call_graph); 225 unsigned long ip = (unsigned long)(&ftrace_call_graph);
223 226
224 ret = ftrace_modify_code(ip, old_jump); 227 ret = ftrace_modify_code(ip, old_jump);
225 flush_icache();
226 228
227 pr_debug("%s\n", __func__); 229 pr_debug("%s\n", __func__);
228 return ret; 230 return ret;
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S
index 42434008209e..77320b8fc16a 100644
--- a/arch/microblaze/kernel/head.S
+++ b/arch/microblaze/kernel/head.S
@@ -39,7 +39,7 @@
39#include <asm/mmu.h> 39#include <asm/mmu.h>
40#include <asm/processor.h> 40#include <asm/processor.h>
41 41
42.data 42.section .data
43.global empty_zero_page 43.global empty_zero_page
44.align 12 44.align 12
45empty_zero_page: 45empty_zero_page:
@@ -50,6 +50,11 @@ swapper_pg_dir:
50 50
51#endif /* CONFIG_MMU */ 51#endif /* CONFIG_MMU */
52 52
53.section .rodata
54.align 4
55endian_check:
56 .word 1
57
53 __HEAD 58 __HEAD
54ENTRY(_start) 59ENTRY(_start)
55#if CONFIG_KERNEL_BASE_ADDR == 0 60#if CONFIG_KERNEL_BASE_ADDR == 0
@@ -62,23 +67,29 @@ real_start:
62 andi r1, r1, ~2 67 andi r1, r1, ~2
63 mts rmsr, r1 68 mts rmsr, r1
64/* 69/*
65 * Here is checking mechanism which check if Microblaze has msr instructions 70 * According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc'
66 * We load msr and compare it with previous r1 value - if is the same, 71 * if the msrclr instruction is not enabled. We use this to detect
67 * msr instructions works if not - cpu don't have them. 72 * if the opcode is available, by issuing msrclr and then testing the result.
73 * r8 == 0 - msr instructions are implemented
74 * r8 != 0 - msr instructions are not implemented
68 */ 75 */
69 /* r8=0 - I have msr instr, 1 - I don't have them */ 76 msrclr r8, 0 /* clear nothing - just read msr for test */
70 rsubi r0, r0, 1 /* set the carry bit */ 77 cmpu r8, r8, r1 /* r1 must contain msr reg content */
71 msrclr r0, 0x4 /* try to clear it */
72 /* read the carry bit, r8 will be '0' if msrclr exists */
73 addik r8, r0, 0
74 78
75/* r7 may point to an FDT, or there may be one linked in. 79/* r7 may point to an FDT, or there may be one linked in.
76 if it's in r7, we've got to save it away ASAP. 80 if it's in r7, we've got to save it away ASAP.
77 We ensure r7 points to a valid FDT, just in case the bootloader 81 We ensure r7 points to a valid FDT, just in case the bootloader
78 is broken or non-existent */ 82 is broken or non-existent */
79 beqi r7, no_fdt_arg /* NULL pointer? don't copy */ 83 beqi r7, no_fdt_arg /* NULL pointer? don't copy */
80 lw r11, r0, r7 /* Does r7 point to a */ 84/* Does r7 point to a valid FDT? Load HEADER magic number */
81 rsubi r11, r11, OF_DT_HEADER /* valid FDT? */ 85 /* Run time Big/Little endian platform */
86 /* Save 1 as word and load byte - 0 - BIG, 1 - LITTLE */
87 lbui r11, r0, TOPHYS(endian_check)
88 beqid r11, big_endian /* DO NOT break delay stop dependency */
89 lw r11, r0, r7 /* Big endian load in delay slot */
90 lwr r11, r0, r7 /* Little endian load */
91big_endian:
92 rsubi r11, r11, OF_DT_HEADER /* Check FDT header */
82 beqi r11, _prepare_copy_fdt 93 beqi r11, _prepare_copy_fdt
83 or r7, r0, r0 /* clear R7 when not valid DTB */ 94 or r7, r0, r0 /* clear R7 when not valid DTB */
84 bnei r11, no_fdt_arg /* No - get out of here */ 95 bnei r11, no_fdt_arg /* No - get out of here */
@@ -213,26 +224,26 @@ start_here:
213#endif /* CONFIG_MMU */ 224#endif /* CONFIG_MMU */
214 225
215 /* Initialize small data anchors */ 226 /* Initialize small data anchors */
216 la r13, r0, _KERNEL_SDA_BASE_ 227 addik r13, r0, _KERNEL_SDA_BASE_
217 la r2, r0, _KERNEL_SDA2_BASE_ 228 addik r2, r0, _KERNEL_SDA2_BASE_
218 229
219 /* Initialize stack pointer */ 230 /* Initialize stack pointer */
220 la r1, r0, init_thread_union + THREAD_SIZE - 4 231 addik r1, r0, init_thread_union + THREAD_SIZE - 4
221 232
222 /* Initialize r31 with current task address */ 233 /* Initialize r31 with current task address */
223 la r31, r0, init_task 234 addik r31, r0, init_task
224 235
225 /* 236 /*
226 * Call platform dependent initialize function. 237 * Call platform dependent initialize function.
227 * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for 238 * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for
228 * the function. 239 * the function.
229 */ 240 */
230 la r9, r0, machine_early_init 241 addik r9, r0, machine_early_init
231 brald r15, r9 242 brald r15, r9
232 nop 243 nop
233 244
234#ifndef CONFIG_MMU 245#ifndef CONFIG_MMU
235 la r15, r0, machine_halt 246 addik r15, r0, machine_halt
236 braid start_kernel 247 braid start_kernel
237 nop 248 nop
238#else 249#else
diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c
index 522751737cfa..154756f3c694 100644
--- a/arch/microblaze/kernel/heartbeat.c
+++ b/arch/microblaze/kernel/heartbeat.c
@@ -47,11 +47,10 @@ void setup_heartbeat(void)
47 struct device_node *gpio = NULL; 47 struct device_node *gpio = NULL;
48 int *prop; 48 int *prop;
49 int j; 49 int j;
50 char *gpio_list[] = { 50 const char * const gpio_list[] = {
51 "xlnx,xps-gpio-1.00.a", 51 "xlnx,xps-gpio-1.00.a",
52 "xlnx,opb-gpio-1.00.a", 52 NULL
53 NULL 53 };
54 };
55 54
56 for (j = 0; gpio_list[j] != NULL; j++) { 55 for (j = 0; gpio_list[j] != NULL; j++) {
57 gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]); 56 gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]);
@@ -60,7 +59,7 @@ void setup_heartbeat(void)
60 } 59 }
61 60
62 if (gpio) { 61 if (gpio) {
63 base_addr = *(int *) of_get_property(gpio, "reg", NULL); 62 base_addr = be32_to_cpup(of_get_property(gpio, "reg", NULL));
64 base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE); 63 base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
65 printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr); 64 printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
66 65
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
index 781195438ee6..56572e923a83 100644
--- a/arch/microblaze/kernel/hw_exception_handler.S
+++ b/arch/microblaze/kernel/hw_exception_handler.S
@@ -77,6 +77,8 @@
77#include <asm/signal.h> 77#include <asm/signal.h>
78#include <asm/asm-offsets.h> 78#include <asm/asm-offsets.h>
79 79
80#undef DEBUG
81
80/* Helpful Macros */ 82/* Helpful Macros */
81#define NUM_TO_REG(num) r ## num 83#define NUM_TO_REG(num) r ## num
82 84
@@ -91,7 +93,7 @@
91 lwi r6, r1, PT_R6; \ 93 lwi r6, r1, PT_R6; \
92 lwi r11, r1, PT_R11; \ 94 lwi r11, r1, PT_R11; \
93 lwi r31, r1, PT_R31; \ 95 lwi r31, r1, PT_R31; \
94 lwi r1, r0, TOPHYS(r0_ram + 0); 96 lwi r1, r1, PT_R1;
95#endif /* CONFIG_MMU */ 97#endif /* CONFIG_MMU */
96 98
97#define LWREG_NOP \ 99#define LWREG_NOP \
@@ -147,10 +149,6 @@
147 #if CONFIG_XILINX_MICROBLAZE0_USE_BARREL > 0 149 #if CONFIG_XILINX_MICROBLAZE0_USE_BARREL > 0
148 #define BSRLI(rD, rA, imm) \ 150 #define BSRLI(rD, rA, imm) \
149 bsrli rD, rA, imm 151 bsrli rD, rA, imm
150 #elif CONFIG_XILINX_MICROBLAZE0_USE_DIV > 0
151 #define BSRLI(rD, rA, imm) \
152 ori rD, r0, (1 << imm); \
153 idivu rD, rD, rA
154 #else 152 #else
155 #define BSRLI(rD, rA, imm) BSRLI ## imm (rD, rA) 153 #define BSRLI(rD, rA, imm) BSRLI ## imm (rD, rA)
156 /* Only the used shift constants defined here - add more if needed */ 154 /* Only the used shift constants defined here - add more if needed */
@@ -210,8 +208,8 @@
210 * | . | 208 * | . |
211 * | . | 209 * | . |
212 * 210 *
213 * NO_MMU kernel use the same r0_ram pointed space - look to vmlinux.lds.S 211 * MMU kernel uses the same 'pt_pool_space' pointed space
214 * which is used for storing register values - old style was, that value were 212 * which is used for storing register values - noMMu style was, that values were
215 * stored in stack but in case of failure you lost information about register. 213 * stored in stack but in case of failure you lost information about register.
216 * Currently you can see register value in memory in specific place. 214 * Currently you can see register value in memory in specific place.
217 * In compare to with previous solution the speed should be the same. 215 * In compare to with previous solution the speed should be the same.
@@ -230,8 +228,22 @@
230 */ 228 */
231 229
232/* wrappers to restore state before coming to entry.S */ 230/* wrappers to restore state before coming to entry.S */
233
234#ifdef CONFIG_MMU 231#ifdef CONFIG_MMU
232.section .data
233.align 4
234pt_pool_space:
235 .space PT_SIZE
236
237#ifdef DEBUG
238/* Create space for exception counting. */
239.section .data
240.global exception_debug_table
241.align 4
242exception_debug_table:
243 /* Look at exception vector table. There is 32 exceptions * word size */
244 .space (32 * 4)
245#endif /* DEBUG */
246
235.section .rodata 247.section .rodata
236.align 4 248.align 4
237_MB_HW_ExceptionVectorTable: 249_MB_HW_ExceptionVectorTable:
@@ -291,10 +303,10 @@ _hw_exception_handler:
291#ifndef CONFIG_MMU 303#ifndef CONFIG_MMU
292 addik r1, r1, -(EX_HANDLER_STACK_SIZ); /* Create stack frame */ 304 addik r1, r1, -(EX_HANDLER_STACK_SIZ); /* Create stack frame */
293#else 305#else
294 swi r1, r0, TOPHYS(r0_ram + 0); /* GET_SP */ 306 swi r1, r0, TOPHYS(pt_pool_space + PT_R1); /* GET_SP */
295 /* Save date to kernel memory. Here is the problem 307 /* Save date to kernel memory. Here is the problem
296 * when you came from user space */ 308 * when you came from user space */
297 ori r1, r0, TOPHYS(r0_ram + 28); 309 ori r1, r0, TOPHYS(pt_pool_space);
298#endif 310#endif
299 swi r3, r1, PT_R3 311 swi r3, r1, PT_R3
300 swi r4, r1, PT_R4 312 swi r4, r1, PT_R4
@@ -333,12 +345,12 @@ not_in_delay_slot:
333 345
334#ifdef DEBUG 346#ifdef DEBUG
335/* counting which exception happen */ 347/* counting which exception happen */
336 lwi r5, r0, 0x200 + TOPHYS(r0_ram) 348 lwi r5, r0, TOPHYS(exception_debug_table)
337 addi r5, r5, 1 349 addi r5, r5, 1
338 swi r5, r0, 0x200 + TOPHYS(r0_ram) 350 swi r5, r0, TOPHYS(exception_debug_table)
339 lwi r5, r6, 0x200 + TOPHYS(r0_ram) 351 lwi r5, r6, TOPHYS(exception_debug_table)
340 addi r5, r5, 1 352 addi r5, r5, 1
341 swi r5, r6, 0x200 + TOPHYS(r0_ram) 353 swi r5, r6, TOPHYS(exception_debug_table)
342#endif 354#endif
343/* end */ 355/* end */
344 /* Load the HW Exception vector */ 356 /* Load the HW Exception vector */
@@ -478,7 +490,7 @@ ex_lw_tail:
478 /* Get the destination register number into r5 */ 490 /* Get the destination register number into r5 */
479 lbui r5, r0, TOPHYS(ex_reg_op); 491 lbui r5, r0, TOPHYS(ex_reg_op);
480 /* Form load_word jump table offset (lw_table + (8 * regnum)) */ 492 /* Form load_word jump table offset (lw_table + (8 * regnum)) */
481 la r6, r0, TOPHYS(lw_table); 493 addik r6, r0, TOPHYS(lw_table);
482 addk r5, r5, r5; 494 addk r5, r5, r5;
483 addk r5, r5, r5; 495 addk r5, r5, r5;
484 addk r5, r5, r5; 496 addk r5, r5, r5;
@@ -489,7 +501,7 @@ ex_sw:
489 /* Get the destination register number into r5 */ 501 /* Get the destination register number into r5 */
490 lbui r5, r0, TOPHYS(ex_reg_op); 502 lbui r5, r0, TOPHYS(ex_reg_op);
491 /* Form store_word jump table offset (sw_table + (8 * regnum)) */ 503 /* Form store_word jump table offset (sw_table + (8 * regnum)) */
492 la r6, r0, TOPHYS(sw_table); 504 addik r6, r0, TOPHYS(sw_table);
493 add r5, r5, r5; 505 add r5, r5, r5;
494 add r5, r5, r5; 506 add r5, r5, r5;
495 add r5, r5, r5; 507 add r5, r5, r5;
@@ -900,7 +912,7 @@ ex_lw_vm:
900 beqid r6, ex_lhw_vm; 912 beqid r6, ex_lhw_vm;
901load1: lbui r5, r4, 0; /* Exception address in r4 - delay slot */ 913load1: lbui r5, r4, 0; /* Exception address in r4 - delay slot */
902/* Load a word, byte-by-byte from destination address and save it in tmp space*/ 914/* Load a word, byte-by-byte from destination address and save it in tmp space*/
903 la r6, r0, ex_tmp_data_loc_0; 915 addik r6, r0, ex_tmp_data_loc_0;
904 sbi r5, r6, 0; 916 sbi r5, r6, 0;
905load2: lbui r5, r4, 1; 917load2: lbui r5, r4, 1;
906 sbi r5, r6, 1; 918 sbi r5, r6, 1;
@@ -914,7 +926,7 @@ load4: lbui r5, r4, 3;
914ex_lhw_vm: 926ex_lhw_vm:
915 /* Load a half-word, byte-by-byte from destination address and 927 /* Load a half-word, byte-by-byte from destination address and
916 * save it in tmp space */ 928 * save it in tmp space */
917 la r6, r0, ex_tmp_data_loc_0; 929 addik r6, r0, ex_tmp_data_loc_0;
918 sbi r5, r6, 0; 930 sbi r5, r6, 0;
919load5: lbui r5, r4, 1; 931load5: lbui r5, r4, 1;
920 sbi r5, r6, 1; 932 sbi r5, r6, 1;
@@ -930,7 +942,7 @@ ex_sw_vm:
930 addik r5, r8, sw_table_vm; 942 addik r5, r8, sw_table_vm;
931 bra r5; 943 bra r5;
932ex_sw_tail_vm: 944ex_sw_tail_vm:
933 la r5, r0, ex_tmp_data_loc_0; 945 addik r5, r0, ex_tmp_data_loc_0;
934 beqid r6, ex_shw_vm; 946 beqid r6, ex_shw_vm;
935 swi r3, r5, 0; /* Get the word - delay slot */ 947 swi r3, r5, 0; /* Get the word - delay slot */
936 /* Store the word, byte-by-byte into destination address */ 948 /* Store the word, byte-by-byte into destination address */
@@ -945,11 +957,20 @@ store3: sbi r3, r4, 2;
945store4: sbi r3, r4, 3; /* Delay slot */ 957store4: sbi r3, r4, 3; /* Delay slot */
946ex_shw_vm: 958ex_shw_vm:
947 /* Store the lower half-word, byte-by-byte into destination address */ 959 /* Store the lower half-word, byte-by-byte into destination address */
960#ifdef __MICROBLAZEEL__
961 lbui r3, r5, 0;
962store5: sbi r3, r4, 0;
963 lbui r3, r5, 1;
964 brid ret_from_exc;
965store6: sbi r3, r4, 1; /* Delay slot */
966#else
948 lbui r3, r5, 2; 967 lbui r3, r5, 2;
949store5: sbi r3, r4, 0; 968store5: sbi r3, r4, 0;
950 lbui r3, r5, 3; 969 lbui r3, r5, 3;
951 brid ret_from_exc; 970 brid ret_from_exc;
952store6: sbi r3, r4, 1; /* Delay slot */ 971store6: sbi r3, r4, 1; /* Delay slot */
972#endif
973
953ex_sw_end_vm: /* Exception handling of store word, ends. */ 974ex_sw_end_vm: /* Exception handling of store word, ends. */
954 975
955/* We have to prevent cases that get/put_user macros get unaligned pointer 976/* We have to prevent cases that get/put_user macros get unaligned pointer
@@ -964,7 +985,7 @@ ex_unaligned_fixup:
964 addik r7, r0, SIGSEGV 985 addik r7, r0, SIGSEGV
965 /* call bad_page_fault for finding aligned fixup, fixup address is saved 986 /* call bad_page_fault for finding aligned fixup, fixup address is saved
966 * in PT_PC which is used as return address from exception */ 987 * in PT_PC which is used as return address from exception */
967 la r15, r0, ret_from_exc-8 /* setup return address */ 988 addik r15, r0, ret_from_exc-8 /* setup return address */
968 brid bad_page_fault 989 brid bad_page_fault
969 nop 990 nop
970 991
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index 03172c1da770..c88f066f41bd 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -40,59 +40,46 @@ unsigned int nr_irq;
40#define MER_ME (1<<0) 40#define MER_ME (1<<0)
41#define MER_HIE (1<<1) 41#define MER_HIE (1<<1)
42 42
43static void intc_enable_or_unmask(unsigned int irq) 43static void intc_enable_or_unmask(struct irq_data *d)
44{ 44{
45 unsigned long mask = 1 << irq; 45 unsigned long mask = 1 << d->irq;
46 pr_debug("enable_or_unmask: %d\n", irq); 46 pr_debug("enable_or_unmask: %d\n", d->irq);
47 out_be32(INTC_BASE + SIE, mask); 47 out_be32(INTC_BASE + SIE, mask);
48 48
49 /* ack level irqs because they can't be acked during 49 /* ack level irqs because they can't be acked during
50 * ack function since the handle_level_irq function 50 * ack function since the handle_level_irq function
51 * acks the irq before calling the interrupt handler 51 * acks the irq before calling the interrupt handler
52 */ 52 */
53 if (irq_desc[irq].status & IRQ_LEVEL) 53 if (irqd_is_level_type(d))
54 out_be32(INTC_BASE + IAR, mask); 54 out_be32(INTC_BASE + IAR, mask);
55} 55}
56 56
57static void intc_disable_or_mask(unsigned int irq) 57static void intc_disable_or_mask(struct irq_data *d)
58{ 58{
59 pr_debug("disable: %d\n", irq); 59 pr_debug("disable: %d\n", d->irq);
60 out_be32(INTC_BASE + CIE, 1 << irq); 60 out_be32(INTC_BASE + CIE, 1 << d->irq);
61} 61}
62 62
63static void intc_ack(unsigned int irq) 63static void intc_ack(struct irq_data *d)
64{ 64{
65 pr_debug("ack: %d\n", irq); 65 pr_debug("ack: %d\n", d->irq);
66 out_be32(INTC_BASE + IAR, 1 << irq); 66 out_be32(INTC_BASE + IAR, 1 << d->irq);
67} 67}
68 68
69static void intc_mask_ack(unsigned int irq) 69static void intc_mask_ack(struct irq_data *d)
70{ 70{
71 unsigned long mask = 1 << irq; 71 unsigned long mask = 1 << d->irq;
72 pr_debug("disable_and_ack: %d\n", irq); 72 pr_debug("disable_and_ack: %d\n", d->irq);
73 out_be32(INTC_BASE + CIE, mask); 73 out_be32(INTC_BASE + CIE, mask);
74 out_be32(INTC_BASE + IAR, mask); 74 out_be32(INTC_BASE + IAR, mask);
75} 75}
76 76
77static void intc_end(unsigned int irq)
78{
79 unsigned long mask = 1 << irq;
80 pr_debug("end: %d\n", irq);
81 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
82 out_be32(INTC_BASE + SIE, mask);
83 /* ack level sensitive intr */
84 if (irq_desc[irq].status & IRQ_LEVEL)
85 out_be32(INTC_BASE + IAR, mask);
86 }
87}
88
89static struct irq_chip intc_dev = { 77static struct irq_chip intc_dev = {
90 .name = "Xilinx INTC", 78 .name = "Xilinx INTC",
91 .unmask = intc_enable_or_unmask, 79 .irq_unmask = intc_enable_or_unmask,
92 .mask = intc_disable_or_mask, 80 .irq_mask = intc_disable_or_mask,
93 .ack = intc_ack, 81 .irq_ack = intc_ack,
94 .mask_ack = intc_mask_ack, 82 .irq_mask_ack = intc_mask_ack,
95 .end = intc_end,
96}; 83};
97 84
98unsigned int get_irq(struct pt_regs *regs) 85unsigned int get_irq(struct pt_regs *regs)
@@ -126,11 +113,8 @@ void __init init_IRQ(void)
126 0 113 0
127 }; 114 };
128#endif 115#endif
129 static char *intc_list[] = { 116 const char * const intc_list[] = {
130 "xlnx,xps-intc-1.00.a", 117 "xlnx,xps-intc-1.00.a",
131 "xlnx,opb-intc-1.00.c",
132 "xlnx,opb-intc-1.00.b",
133 "xlnx,opb-intc-1.00.a",
134 NULL 118 NULL
135 }; 119 };
136 120
@@ -141,12 +125,15 @@ void __init init_IRQ(void)
141 } 125 }
142 BUG_ON(!intc); 126 BUG_ON(!intc);
143 127
144 intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL); 128 intc_baseaddr = be32_to_cpup(of_get_property(intc,
129 "reg", NULL));
145 intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE); 130 intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
146 nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL); 131 nr_irq = be32_to_cpup(of_get_property(intc,
132 "xlnx,num-intr-inputs", NULL));
147 133
148 intr_type = 134 intr_type =
149 *(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL); 135 be32_to_cpup(of_get_property(intc,
136 "xlnx,kind-of-intr", NULL));
150 if (intr_type >= (1 << (nr_irq + 1))) 137 if (intr_type >= (1 << (nr_irq + 1)))
151 printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n"); 138 printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");
152 139
@@ -170,13 +157,13 @@ void __init init_IRQ(void)
170 157
171 for (i = 0; i < nr_irq; ++i) { 158 for (i = 0; i < nr_irq; ++i) {
172 if (intr_type & (0x00000001 << i)) { 159 if (intr_type & (0x00000001 << i)) {
173 set_irq_chip_and_handler_name(i, &intc_dev, 160 irq_set_chip_and_handler_name(i, &intc_dev,
174 handle_edge_irq, intc_dev.name); 161 handle_edge_irq, "edge");
175 irq_desc[i].status &= ~IRQ_LEVEL; 162 irq_clear_status_flags(i, IRQ_LEVEL);
176 } else { 163 } else {
177 set_irq_chip_and_handler_name(i, &intc_dev, 164 irq_set_chip_and_handler_name(i, &intc_dev,
178 handle_level_irq, intc_dev.name); 165 handle_level_irq, "level");
179 irq_desc[i].status |= IRQ_LEVEL; 166 irq_set_status_flags(i, IRQ_LEVEL);
180 } 167 }
181 } 168 }
182} 169}
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
index a9345fb4906a..ce7ac8435d5c 100644
--- a/arch/microblaze/kernel/irq.c
+++ b/arch/microblaze/kernel/irq.c
@@ -47,46 +47,6 @@ next_irq:
47 trace_hardirqs_on(); 47 trace_hardirqs_on();
48} 48}
49 49
50int show_interrupts(struct seq_file *p, void *v)
51{
52 int i = *(loff_t *) v, j;
53 struct irqaction *action;
54 unsigned long flags;
55
56 if (i == 0) {
57 seq_printf(p, " ");
58 for_each_online_cpu(j)
59 seq_printf(p, "CPU%-8d", j);
60 seq_putc(p, '\n');
61 }
62
63 if (i < nr_irq) {
64 raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
65 action = irq_desc[i].action;
66 if (!action)
67 goto skip;
68 seq_printf(p, "%3d: ", i);
69#ifndef CONFIG_SMP
70 seq_printf(p, "%10u ", kstat_irqs(i));
71#else
72 for_each_online_cpu(j)
73 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
74#endif
75 seq_printf(p, " %8s", irq_desc[i].status &
76 IRQ_LEVEL ? "level" : "edge");
77 seq_printf(p, " %8s", irq_desc[i].chip->name);
78 seq_printf(p, " %s", action->name);
79
80 for (action = action->next; action; action = action->next)
81 seq_printf(p, ", %s", action->name);
82
83 seq_putc(p, '\n');
84skip:
85 raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
86 }
87 return 0;
88}
89
90/* MS: There is no any advance mapping mechanism. We are using simple 32bit 50/* MS: There is no any advance mapping mechanism. We are using simple 32bit
91 intc without any cascades or any connection that's why mapping is 1:1 */ 51 intc without any cascades or any connection that's why mapping is 1:1 */
92unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq) 52unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
diff --git a/arch/microblaze/kernel/kgdb.c b/arch/microblaze/kernel/kgdb.c
index bfc006b7f2d8..09a5e8286137 100644
--- a/arch/microblaze/kernel/kgdb.c
+++ b/arch/microblaze/kernel/kgdb.c
@@ -80,7 +80,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
80void microblaze_kgdb_break(struct pt_regs *regs) 80void microblaze_kgdb_break(struct pt_regs *regs)
81{ 81{
82 if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0) 82 if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0)
83 return 0; 83 return;
84 84
85 /* Jump over the first arch_kgdb_breakpoint which is barrier to 85 /* Jump over the first arch_kgdb_breakpoint which is barrier to
86 * get kgdb work. The same solution is used for powerpc */ 86 * get kgdb work. The same solution is used for powerpc */
@@ -114,7 +114,6 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
114{ 114{
115 char *ptr; 115 char *ptr;
116 unsigned long address; 116 unsigned long address;
117 int cpu = smp_processor_id();
118 117
119 switch (remcom_in_buffer[0]) { 118 switch (remcom_in_buffer[0]) {
120 case 'c': 119 case 'c':
@@ -143,5 +142,9 @@ void kgdb_arch_exit(void)
143 * Global data 142 * Global data
144 */ 143 */
145struct kgdb_arch arch_kgdb_ops = { 144struct kgdb_arch arch_kgdb_ops = {
145#ifdef __MICROBLAZEEL__
146 .gdb_bpt_instr = {0x18, 0x00, 0x0c, 0xba}, /* brki r16, 0x18 */
147#else
146 .gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */ 148 .gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */
149#endif
147}; 150};
diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c
index ff85f7718035..49faeb429599 100644
--- a/arch/microblaze/kernel/microblaze_ksyms.c
+++ b/arch/microblaze/kernel/microblaze_ksyms.c
@@ -15,39 +15,16 @@
15#include <linux/syscalls.h> 15#include <linux/syscalls.h>
16 16
17#include <asm/checksum.h> 17#include <asm/checksum.h>
18#include <asm/cacheflush.h>
18#include <linux/io.h> 19#include <linux/io.h>
19#include <asm/page.h> 20#include <asm/page.h>
20#include <asm/system.h> 21#include <asm/system.h>
21#include <linux/ftrace.h> 22#include <linux/ftrace.h>
22#include <linux/uaccess.h> 23#include <linux/uaccess.h>
23 24
24/*
25 * libgcc functions - functions that are used internally by the
26 * compiler... (prototypes are not correct though, but that
27 * doesn't really matter since they're not versioned).
28 */
29extern void __ashldi3(void);
30EXPORT_SYMBOL(__ashldi3);
31extern void __ashrdi3(void);
32EXPORT_SYMBOL(__ashrdi3);
33extern void __divsi3(void);
34EXPORT_SYMBOL(__divsi3);
35extern void __lshrdi3(void);
36EXPORT_SYMBOL(__lshrdi3);
37extern void __modsi3(void);
38EXPORT_SYMBOL(__modsi3);
39extern void __mulsi3(void);
40EXPORT_SYMBOL(__mulsi3);
41extern void __muldi3(void);
42EXPORT_SYMBOL(__muldi3);
43extern void __ucmpdi2(void);
44EXPORT_SYMBOL(__ucmpdi2);
45extern void __udivsi3(void);
46EXPORT_SYMBOL(__udivsi3);
47extern void __umodsi3(void);
48EXPORT_SYMBOL(__umodsi3);
49extern char *_ebss; 25extern char *_ebss;
50EXPORT_SYMBOL_GPL(_ebss); 26EXPORT_SYMBOL_GPL(_ebss);
27
51#ifdef CONFIG_FUNCTION_TRACER 28#ifdef CONFIG_FUNCTION_TRACER
52extern void _mcount(void); 29extern void _mcount(void);
53EXPORT_SYMBOL(_mcount); 30EXPORT_SYMBOL(_mcount);
@@ -63,3 +40,20 @@ EXPORT_SYMBOL(__strncpy_user);
63EXPORT_SYMBOL(memcpy); 40EXPORT_SYMBOL(memcpy);
64EXPORT_SYMBOL(memmove); 41EXPORT_SYMBOL(memmove);
65#endif 42#endif
43
44#ifdef CONFIG_MMU
45EXPORT_SYMBOL(empty_zero_page);
46#endif
47
48EXPORT_SYMBOL(mbc);
49
50extern void __divsi3(void);
51EXPORT_SYMBOL(__divsi3);
52extern void __modsi3(void);
53EXPORT_SYMBOL(__modsi3);
54extern void __mulsi3(void);
55EXPORT_SYMBOL(__mulsi3);
56extern void __udivsi3(void);
57EXPORT_SYMBOL(__udivsi3);
58extern void __umodsi3(void);
59EXPORT_SYMBOL(__umodsi3);
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index ba7c4b16ed35..968648a81c1e 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -159,7 +159,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
159 } 159 }
160 160
161 /* FIXME STATE_SAVE_PT_OFFSET; */ 161 /* FIXME STATE_SAVE_PT_OFFSET; */
162 ti->cpu_context.r1 = (unsigned long)childregs - STATE_SAVE_ARG_SPACE; 162 ti->cpu_context.r1 = (unsigned long)childregs;
163 /* we should consider the fact that childregs is a copy of the parent 163 /* we should consider the fact that childregs is a copy of the parent
164 * regs which were saved immediately after entering the kernel state 164 * regs which were saved immediately after entering the kernel state
165 * before enabling VM. This MSR will be restored in switch_to and 165 * before enabling VM. This MSR will be restored in switch_to and
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 427b13b4740f..b15cc219b1d9 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -42,19 +42,14 @@
42#include <asm/sections.h> 42#include <asm/sections.h>
43#include <asm/pci-bridge.h> 43#include <asm/pci-bridge.h>
44 44
45void __init early_init_dt_scan_chosen_arch(unsigned long node)
46{
47 /* No Microblaze specific code here */
48}
49
50void __init early_init_dt_add_memory_arch(u64 base, u64 size) 45void __init early_init_dt_add_memory_arch(u64 base, u64 size)
51{ 46{
52 memblock_add(base, size); 47 memblock_add(base, size);
53} 48}
54 49
55u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align) 50void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
56{ 51{
57 return memblock_alloc(size, align); 52 return __va(memblock_alloc(size, align));
58} 53}
59 54
60#ifdef CONFIG_EARLY_PRINTK 55#ifdef CONFIG_EARLY_PRINTK
@@ -64,24 +59,23 @@ static int __init early_init_dt_scan_serial(unsigned long node,
64{ 59{
65 unsigned long l; 60 unsigned long l;
66 char *p; 61 char *p;
67 int *addr; 62 const __be32 *addr;
68 63
69 pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); 64 pr_debug("search \"serial\", depth: %d, uname: %s\n", depth, uname);
70 65
71/* find all serial nodes */ 66/* find all serial nodes */
72 if (strncmp(uname, "serial", 6) != 0) 67 if (strncmp(uname, "serial", 6) != 0)
73 return 0; 68 return 0;
74 69
75 early_init_dt_check_for_initrd(node);
76
77/* find compatible node with uartlite */ 70/* find compatible node with uartlite */
78 p = of_get_flat_dt_prop(node, "compatible", &l); 71 p = of_get_flat_dt_prop(node, "compatible", &l);
79 if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) && 72 if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
80 (strncmp(p, "xlnx,opb-uartlite", 17) != 0)) 73 (strncmp(p, "xlnx,opb-uartlite", 17) != 0) &&
74 (strncmp(p, "xlnx,axi-uartlite", 17) != 0))
81 return 0; 75 return 0;
82 76
83 addr = of_get_flat_dt_prop(node, "reg", &l); 77 addr = of_get_flat_dt_prop(node, "reg", &l);
84 return *addr; /* return address */ 78 return be32_to_cpup(addr); /* return address */
85} 79}
86 80
87/* this function is looking for early uartlite console - Microblaze specific */ 81/* this function is looking for early uartlite console - Microblaze specific */
@@ -89,6 +83,40 @@ int __init early_uartlite_console(void)
89{ 83{
90 return of_scan_flat_dt(early_init_dt_scan_serial, NULL); 84 return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
91} 85}
86
87/* MS this is Microblaze specifig function */
88static int __init early_init_dt_scan_serial_full(unsigned long node,
89 const char *uname, int depth, void *data)
90{
91 unsigned long l;
92 char *p;
93 unsigned int addr;
94
95 pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
96
97/* find all serial nodes */
98 if (strncmp(uname, "serial", 6) != 0)
99 return 0;
100
101 early_init_dt_check_for_initrd(node);
102
103/* find compatible node with uartlite */
104 p = of_get_flat_dt_prop(node, "compatible", &l);
105
106 if ((strncmp(p, "xlnx,xps-uart16550", 18) != 0) &&
107 (strncmp(p, "xlnx,axi-uart16550", 18) != 0))
108 return 0;
109
110 addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l);
111 addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l);
112 return be32_to_cpu(addr); /* return address */
113}
114
115/* this function is looking for early uartlite console - Microblaze specific */
116int __init early_uart16550_console(void)
117{
118 return of_scan_flat_dt(early_init_dt_scan_serial_full, NULL);
119}
92#endif 120#endif
93 121
94void __init early_init_devtree(void *params) 122void __init early_init_devtree(void *params)
@@ -102,7 +130,7 @@ void __init early_init_devtree(void *params)
102 * device-tree, including the platform type, initrd location and 130 * device-tree, including the platform type, initrd location and
103 * size, TCE reserve, and more ... 131 * size, TCE reserve, and more ...
104 */ 132 */
105 of_scan_flat_dt(early_init_dt_scan_chosen, NULL); 133 of_scan_flat_dt(early_init_dt_scan_chosen, cmd_line);
106 134
107 /* Scan memory nodes and rebuild MEMBLOCKs */ 135 /* Scan memory nodes and rebuild MEMBLOCKs */
108 memblock_init(); 136 memblock_init();
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
index 99d9b61cccb5..47187cc2cf00 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -2,88 +2,11 @@
2 2
3#include <linux/kernel.h> 3#include <linux/kernel.h>
4#include <linux/string.h> 4#include <linux/string.h>
5#include <linux/pci_regs.h>
6#include <linux/module.h> 5#include <linux/module.h>
7#include <linux/ioport.h> 6#include <linux/ioport.h>
8#include <linux/etherdevice.h> 7#include <linux/etherdevice.h>
9#include <linux/of_address.h> 8#include <linux/of_address.h>
10#include <asm/prom.h> 9#include <asm/prom.h>
11#include <asm/pci-bridge.h>
12
13#ifdef CONFIG_PCI
14int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
15{
16 struct device_node *dn, *ppnode;
17 struct pci_dev *ppdev;
18 u32 lspec;
19 u32 laddr[3];
20 u8 pin;
21 int rc;
22
23 /* Check if we have a device node, if yes, fallback to standard OF
24 * parsing
25 */
26 dn = pci_device_to_OF_node(pdev);
27 if (dn)
28 return of_irq_map_one(dn, 0, out_irq);
29
30 /* Ok, we don't, time to have fun. Let's start by building up an
31 * interrupt spec. we assume #interrupt-cells is 1, which is standard
32 * for PCI. If you do different, then don't use that routine.
33 */
34 rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
35 if (rc != 0)
36 return rc;
37 /* No pin, exit */
38 if (pin == 0)
39 return -ENODEV;
40
41 /* Now we walk up the PCI tree */
42 lspec = pin;
43 for (;;) {
44 /* Get the pci_dev of our parent */
45 ppdev = pdev->bus->self;
46
47 /* Ouch, it's a host bridge... */
48 if (ppdev == NULL) {
49 struct pci_controller *host;
50 host = pci_bus_to_host(pdev->bus);
51 ppnode = host ? host->dn : NULL;
52 /* No node for host bridge ? give up */
53 if (ppnode == NULL)
54 return -EINVAL;
55 } else
56 /* We found a P2P bridge, check if it has a node */
57 ppnode = pci_device_to_OF_node(ppdev);
58
59 /* Ok, we have found a parent with a device-node, hand over to
60 * the OF parsing code.
61 * We build a unit address from the linux device to be used for
62 * resolution. Note that we use the linux bus number which may
63 * not match your firmware bus numbering.
64 * Fortunately, in most cases, interrupt-map-mask doesn't
65 * include the bus number as part of the matching.
66 * You should still be careful about that though if you intend
67 * to rely on this function (you ship a firmware that doesn't
68 * create device nodes for all PCI devices).
69 */
70 if (ppnode)
71 break;
72
73 /* We can only get here if we hit a P2P bridge with no node,
74 * let's do standard swizzling and try again
75 */
76 lspec = pci_swizzle_interrupt_pin(pdev, lspec);
77 pdev = ppdev;
78 }
79
80 laddr[0] = (pdev->bus->number << 16)
81 | (pdev->devfn << 8);
82 laddr[1] = laddr[2] = 0;
83 return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
84}
85EXPORT_SYMBOL_GPL(of_irq_map_pci);
86#endif /* CONFIG_PCI */
87 10
88void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, 11void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
89 unsigned long *busno, unsigned long *phys, unsigned long *size) 12 unsigned long *busno, unsigned long *phys, unsigned long *size)
@@ -110,41 +33,3 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
110 cells = prop ? *(u32 *)prop : of_n_size_cells(dn); 33 cells = prop ? *(u32 *)prop : of_n_size_cells(dn);
111 *size = of_read_number(dma_window, cells); 34 *size = of_read_number(dma_window, cells);
112} 35}
113
114/**
115 * Search the device tree for the best MAC address to use. 'mac-address' is
116 * checked first, because that is supposed to contain to "most recent" MAC
117 * address. If that isn't set, then 'local-mac-address' is checked next,
118 * because that is the default address. If that isn't set, then the obsolete
119 * 'address' is checked, just in case we're using an old device tree.
120 *
121 * Note that the 'address' property is supposed to contain a virtual address of
122 * the register set, but some DTS files have redefined that property to be the
123 * MAC address.
124 *
125 * All-zero MAC addresses are rejected, because those could be properties that
126 * exist in the device tree, but were not set by U-Boot. For example, the
127 * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
128 * addresses. Some older U-Boots only initialized 'local-mac-address'. In
129 * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
130 * but is all zeros.
131*/
132const void *of_get_mac_address(struct device_node *np)
133{
134 struct property *pp;
135
136 pp = of_find_property(np, "mac-address", NULL);
137 if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
138 return pp->value;
139
140 pp = of_find_property(np, "local-mac-address", NULL);
141 if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
142 return pp->value;
143
144 pp = of_find_property(np, "address", NULL);
145 if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
146 return pp->value;
147
148 return NULL;
149}
150EXPORT_SYMBOL(of_get_mac_address);
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c
index dc03ffc8174a..6a8e0cc5c57d 100644
--- a/arch/microblaze/kernel/ptrace.c
+++ b/arch/microblaze/kernel/ptrace.c
@@ -39,6 +39,7 @@
39#include <linux/uaccess.h> 39#include <linux/uaccess.h>
40#include <asm/asm-offsets.h> 40#include <asm/asm-offsets.h>
41#include <asm/cacheflush.h> 41#include <asm/cacheflush.h>
42#include <asm/syscall.h>
42#include <asm/io.h> 43#include <asm/io.h>
43 44
44/* Returns the address where the register at REG_OFFS in P is stashed away. */ 45/* Returns the address where the register at REG_OFFS in P is stashed away. */
@@ -73,7 +74,8 @@ static microblaze_reg_t *reg_save_addr(unsigned reg_offs,
73 return (microblaze_reg_t *)((char *)regs + reg_offs); 74 return (microblaze_reg_t *)((char *)regs + reg_offs);
74} 75}
75 76
76long arch_ptrace(struct task_struct *child, long request, long addr, long data) 77long arch_ptrace(struct task_struct *child, long request,
78 unsigned long addr, unsigned long data)
77{ 79{
78 int rval; 80 int rval;
79 unsigned long val = 0; 81 unsigned long val = 0;
@@ -99,7 +101,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
99 } else { 101 } else {
100 rval = -EIO; 102 rval = -EIO;
101 } 103 }
102 } else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) { 104 } else if (addr < PT_SIZE && (addr & 0x3) == 0) {
103 microblaze_reg_t *reg_addr = reg_save_addr(addr, child); 105 microblaze_reg_t *reg_addr = reg_save_addr(addr, child);
104 if (request == PTRACE_PEEKUSR) 106 if (request == PTRACE_PEEKUSR)
105 val = *reg_addr; 107 val = *reg_addr;
@@ -122,7 +124,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
122 rval = -EIO; 124 rval = -EIO;
123 125
124 if (rval == 0 && request == PTRACE_PEEKUSR) 126 if (rval == 0 && request == PTRACE_PEEKUSR)
125 rval = put_user(val, (unsigned long *)data); 127 rval = put_user(val, (unsigned long __user *)data);
126 break; 128 break;
127 default: 129 default:
128 rval = ptrace_request(child, request, addr, data); 130 rval = ptrace_request(child, request, addr, data);
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index f5f768842354..8e2c09b7ff26 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -92,16 +92,11 @@ inline unsigned get_romfs_len(unsigned *addr)
92} 92}
93#endif /* CONFIG_MTD_UCLINUX_EBSS */ 93#endif /* CONFIG_MTD_UCLINUX_EBSS */
94 94
95#if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE)
96#define eprintk early_printk
97#else
98#define eprintk printk
99#endif
100
101void __init machine_early_init(const char *cmdline, unsigned int ram, 95void __init machine_early_init(const char *cmdline, unsigned int ram,
102 unsigned int fdt, unsigned int msr) 96 unsigned int fdt, unsigned int msr)
103{ 97{
104 unsigned long *src, *dst = (unsigned long *)0x0; 98 unsigned long *src, *dst;
99 unsigned int offset = 0;
105 100
106 /* If CONFIG_MTD_UCLINUX is defined, assume ROMFS is at the 101 /* If CONFIG_MTD_UCLINUX is defined, assume ROMFS is at the
107 * end of kernel. There are two position which we want to check. 102 * end of kernel. There are two position which we want to check.
@@ -167,14 +162,21 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
167#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR 162#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
168 if (msr) 163 if (msr)
169 eprintk("!!!Your kernel has setup MSR instruction but " 164 eprintk("!!!Your kernel has setup MSR instruction but "
170 "CPU don't have it %d\n", msr); 165 "CPU don't have it %x\n", msr);
171#else 166#else
172 if (!msr) 167 if (!msr)
173 eprintk("!!!Your kernel not setup MSR instruction but " 168 eprintk("!!!Your kernel not setup MSR instruction but "
174 "CPU have it %d\n", msr); 169 "CPU have it %x\n", msr);
175#endif 170#endif
176 171
177 for (src = __ivt_start; src < __ivt_end; src++, dst++) 172 /* Do not copy reset vectors. offset = 0x2 means skip the first
173 * two instructions. dst is pointer to MB vectors which are placed
174 * in block ram. If you want to copy reset vector setup offset to 0x0 */
175#if !CONFIG_MANUAL_RESET_VECTOR
176 offset = 0x2;
177#endif
178 dst = (unsigned long *) (offset * sizeof(u32));
179 for (src = __ivt_start + offset; src < __ivt_end; src++, dst++)
178 *dst = *src; 180 *dst = *src;
179 181
180 /* Initialize global data */ 182 /* Initialize global data */
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index d8d3bb396cd6..599671168980 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -93,7 +93,7 @@ static int restore_sigcontext(struct pt_regs *regs,
93asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) 93asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
94{ 94{
95 struct rt_sigframe __user *frame = 95 struct rt_sigframe __user *frame =
96 (struct rt_sigframe __user *)(regs->r1 + STATE_SAVE_ARG_SPACE); 96 (struct rt_sigframe __user *)(regs->r1);
97 97
98 sigset_t set; 98 sigset_t set;
99 int rval; 99 int rval;
@@ -197,8 +197,8 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
197 197
198 /* Create the ucontext. */ 198 /* Create the ucontext. */
199 err |= __put_user(0, &frame->uc.uc_flags); 199 err |= __put_user(0, &frame->uc.uc_flags);
200 err |= __put_user(0, &frame->uc.uc_link); 200 err |= __put_user(NULL, &frame->uc.uc_link);
201 err |= __put_user((void *)current->sas_ss_sp, 201 err |= __put_user((void __user *)current->sas_ss_sp,
202 &frame->uc.uc_stack.ss_sp); 202 &frame->uc.uc_stack.ss_sp);
203 err |= __put_user(sas_ss_flags(regs->r1), 203 err |= __put_user(sas_ss_flags(regs->r1),
204 &frame->uc.uc_stack.ss_flags); 204 &frame->uc.uc_stack.ss_flags);
@@ -247,7 +247,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
247 goto give_sigsegv; 247 goto give_sigsegv;
248 248
249 /* Set up registers for signal handler */ 249 /* Set up registers for signal handler */
250 regs->r1 = (unsigned long) frame - STATE_SAVE_ARG_SPACE; 250 regs->r1 = (unsigned long) frame;
251 251
252 /* Signal handler args: */ 252 /* Signal handler args: */
253 regs->r5 = signal; /* arg 0: signum */ 253 regs->r5 = signal; /* arg 0: signum */
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
index 2250fe9d269b..e5b154f24f85 100644
--- a/arch/microblaze/kernel/sys_microblaze.c
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -40,7 +40,8 @@ asmlinkage long microblaze_vfork(struct pt_regs *regs)
40 regs, 0, NULL, NULL); 40 regs, 0, NULL, NULL);
41} 41}
42 42
43asmlinkage long microblaze_clone(int flags, unsigned long stack, struct pt_regs *regs) 43asmlinkage long microblaze_clone(int flags, unsigned long stack,
44 struct pt_regs *regs)
44{ 45{
45 if (!stack) 46 if (!stack)
46 stack = regs->r1; 47 stack = regs->r1;
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index 03376dc814c9..d915a122c865 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -372,3 +372,11 @@ ENTRY(sys_call_table)
372 .long sys_rt_tgsigqueueinfo /* 365 */ 372 .long sys_rt_tgsigqueueinfo /* 365 */
373 .long sys_perf_event_open 373 .long sys_perf_event_open
374 .long sys_recvmmsg 374 .long sys_recvmmsg
375 .long sys_fanotify_init
376 .long sys_fanotify_mark
377 .long sys_prlimit64 /* 370 */
378 .long sys_name_to_handle_at
379 .long sys_open_by_handle_at
380 .long sys_clock_adjtime
381 .long sys_syncfs
382 .long sys_setns /* 375 */
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index b1380ae93ae1..e5550ce4e0eb 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -38,6 +38,9 @@ static unsigned int timer_baseaddr;
38#define TIMER_BASE timer_baseaddr 38#define TIMER_BASE timer_baseaddr
39#endif 39#endif
40 40
41static unsigned int freq_div_hz;
42static unsigned int timer_clock_freq;
43
41#define TCSR0 (0x00) 44#define TCSR0 (0x00)
42#define TLR0 (0x04) 45#define TLR0 (0x04)
43#define TCR0 (0x08) 46#define TCR0 (0x08)
@@ -115,7 +118,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode,
115 switch (mode) { 118 switch (mode) {
116 case CLOCK_EVT_MODE_PERIODIC: 119 case CLOCK_EVT_MODE_PERIODIC:
117 printk(KERN_INFO "%s: periodic\n", __func__); 120 printk(KERN_INFO "%s: periodic\n", __func__);
118 microblaze_timer0_start_periodic(cpuinfo.freq_div_hz); 121 microblaze_timer0_start_periodic(freq_div_hz);
119 break; 122 break;
120 case CLOCK_EVT_MODE_ONESHOT: 123 case CLOCK_EVT_MODE_ONESHOT:
121 printk(KERN_INFO "%s: oneshot\n", __func__); 124 printk(KERN_INFO "%s: oneshot\n", __func__);
@@ -168,7 +171,7 @@ static struct irqaction timer_irqaction = {
168static __init void microblaze_clockevent_init(void) 171static __init void microblaze_clockevent_init(void)
169{ 172{
170 clockevent_microblaze_timer.mult = 173 clockevent_microblaze_timer.mult =
171 div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, 174 div_sc(timer_clock_freq, NSEC_PER_SEC,
172 clockevent_microblaze_timer.shift); 175 clockevent_microblaze_timer.shift);
173 clockevent_microblaze_timer.max_delta_ns = 176 clockevent_microblaze_timer.max_delta_ns =
174 clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer); 177 clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
@@ -199,9 +202,9 @@ static struct cyclecounter microblaze_cc = {
199 .shift = 8, 202 .shift = 8,
200}; 203};
201 204
202int __init init_microblaze_timecounter(void) 205static int __init init_microblaze_timecounter(void)
203{ 206{
204 microblaze_cc.mult = div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, 207 microblaze_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
205 microblaze_cc.shift); 208 microblaze_cc.shift);
206 209
207 timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock()); 210 timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock());
@@ -214,16 +217,12 @@ static struct clocksource clocksource_microblaze = {
214 .rating = 300, 217 .rating = 300,
215 .read = microblaze_read, 218 .read = microblaze_read,
216 .mask = CLOCKSOURCE_MASK(32), 219 .mask = CLOCKSOURCE_MASK(32),
217 .shift = 8, /* I can shift it */
218 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 220 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
219}; 221};
220 222
221static int __init microblaze_clocksource_init(void) 223static int __init microblaze_clocksource_init(void)
222{ 224{
223 clocksource_microblaze.mult = 225 if (clocksource_register_hz(&clocksource_microblaze, timer_clock_freq))
224 clocksource_hz2mult(cpuinfo.cpu_clock_freq,
225 clocksource_microblaze.shift);
226 if (clocksource_register(&clocksource_microblaze))
227 panic("failed to register clocksource"); 226 panic("failed to register clocksource");
228 227
229 /* stop timer1 */ 228 /* stop timer1 */
@@ -247,6 +246,7 @@ void __init time_init(void)
247 u32 irq, i = 0; 246 u32 irq, i = 0;
248 u32 timer_num = 1; 247 u32 timer_num = 1;
249 struct device_node *timer = NULL; 248 struct device_node *timer = NULL;
249 const void *prop;
250#ifdef CONFIG_SELFMOD_TIMER 250#ifdef CONFIG_SELFMOD_TIMER
251 unsigned int timer_baseaddr = 0; 251 unsigned int timer_baseaddr = 0;
252 int arr_func[] = { 252 int arr_func[] = {
@@ -258,12 +258,10 @@ void __init time_init(void)
258 0 258 0
259 }; 259 };
260#endif 260#endif
261 char *timer_list[] = { 261 const char * const timer_list[] = {
262 "xlnx,xps-timer-1.00.a", 262 "xlnx,xps-timer-1.00.a",
263 "xlnx,opb-timer-1.00.b", 263 NULL
264 "xlnx,opb-timer-1.00.a", 264 };
265 NULL
266 };
267 265
268 for (i = 0; timer_list[i] != NULL; i++) { 266 for (i = 0; timer_list[i] != NULL; i++) {
269 timer = of_find_compatible_node(NULL, NULL, timer_list[i]); 267 timer = of_find_compatible_node(NULL, NULL, timer_list[i]);
@@ -272,13 +270,13 @@ void __init time_init(void)
272 } 270 }
273 BUG_ON(!timer); 271 BUG_ON(!timer);
274 272
275 timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL); 273 timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL));
276 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); 274 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
277 irq = *(int *) of_get_property(timer, "interrupts", NULL); 275 irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL));
278 timer_num = 276 timer_num = be32_to_cpup(of_get_property(timer,
279 *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL); 277 "xlnx,one-timer-only", NULL));
280 if (timer_num) { 278 if (timer_num) {
281 printk(KERN_EMERG "Please enable two timers in HW\n"); 279 eprintk(KERN_EMERG "Please enable two timers in HW\n");
282 BUG(); 280 BUG();
283 } 281 }
284 282
@@ -288,7 +286,14 @@ void __init time_init(void)
288 printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", 286 printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
289 timer_list[i], timer_baseaddr, irq); 287 timer_list[i], timer_baseaddr, irq);
290 288
291 cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ; 289 /* If there is clock-frequency property than use it */
290 prop = of_get_property(timer, "clock-frequency", NULL);
291 if (prop)
292 timer_clock_freq = be32_to_cpup(prop);
293 else
294 timer_clock_freq = cpuinfo.cpu_clock_freq;
295
296 freq_div_hz = timer_clock_freq / HZ;
292 297
293 setup_irq(irq, &timer_irqaction); 298 setup_irq(irq, &timer_irqaction);
294#ifdef CONFIG_HEART_BEAT 299#ifdef CONFIG_HEART_BEAT
diff --git a/arch/microblaze/kernel/unwind.c b/arch/microblaze/kernel/unwind.c
index fefac5c33586..9781a528cfc9 100644
--- a/arch/microblaze/kernel/unwind.c
+++ b/arch/microblaze/kernel/unwind.c
@@ -183,7 +183,7 @@ static inline void unwind_trap(struct task_struct *task, unsigned long pc,
183 * @trace : Where to store stack backtrace (PC values). 183 * @trace : Where to store stack backtrace (PC values).
184 * NULL == print backtrace to kernel log 184 * NULL == print backtrace to kernel log
185 */ 185 */
186void microblaze_unwind_inner(struct task_struct *task, 186static void microblaze_unwind_inner(struct task_struct *task,
187 unsigned long pc, unsigned long fp, 187 unsigned long pc, unsigned long fp,
188 unsigned long leaf_return, 188 unsigned long leaf_return,
189 struct stack_trace *trace) 189 struct stack_trace *trace)
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
index a09f2962fbec..ac0e1a5d4782 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -8,7 +8,6 @@
8 * for more details. 8 * for more details.
9 */ 9 */
10 10
11OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
12OUTPUT_ARCH(microblaze) 11OUTPUT_ARCH(microblaze)
13ENTRY(microblaze_start) 12ENTRY(microblaze_start)
14 13
@@ -16,7 +15,11 @@ ENTRY(microblaze_start)
16#include <asm-generic/vmlinux.lds.h> 15#include <asm-generic/vmlinux.lds.h>
17#include <asm/thread_info.h> 16#include <asm/thread_info.h>
18 17
18#ifdef __MICROBLAZEEL__
19jiffies = jiffies_64;
20#else
19jiffies = jiffies_64 + 4; 21jiffies = jiffies_64 + 4;
22#endif
20 23
21SECTIONS { 24SECTIONS {
22 . = CONFIG_KERNEL_START; 25 . = CONFIG_KERNEL_START;
@@ -67,11 +70,6 @@ SECTIONS {
67 RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE) 70 RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
68 _edata = . ; 71 _edata = . ;
69 72
70 /* Reserve some low RAM for r0 based memory references */
71 . = ALIGN(0x4) ;
72 r0_ram = . ;
73 . = . + PAGE_SIZE; /* a page should be enough */
74
75 /* Under the microblaze ABI, .sdata and .sbss must be contiguous */ 73 /* Under the microblaze ABI, .sdata and .sbss must be contiguous */
76 . = ALIGN(8); 74 . = ALIGN(8);
77 .sdata : AT(ADDR(.sdata) - LOAD_OFFSET) { 75 .sdata : AT(ADDR(.sdata) - LOAD_OFFSET) {
@@ -120,20 +118,10 @@ SECTIONS {
120 118
121 __init_end_before_initramfs = .; 119 __init_end_before_initramfs = .;
122 120
123 .init.ramfs ALIGN(PAGE_SIZE) : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { 121 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
124 __initramfs_start = .; 122 INIT_RAM_FS
125 *(.init.ramfs)
126 __initramfs_end = .;
127 . = ALIGN(4);
128 LONG(0);
129/*
130 * FIXME this can break initramfs for MMU.
131 * Pad init.ramfs up to page boundary,
132 * so that __init_end == __bss_start. This will make image.elf
133 * consistent with the image.bin
134 */
135 /* . = ALIGN(PAGE_SIZE); */
136 } 123 }
124
137 __init_end = .; 125 __init_end = .;
138 126
139 .bss ALIGN (PAGE_SIZE) : AT(ADDR(.bss) - LOAD_OFFSET) { 127 .bss ALIGN (PAGE_SIZE) : AT(ADDR(.bss) - LOAD_OFFSET) {
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile
index 4dfe47d3cd91..10c320aa908b 100644
--- a/arch/microblaze/lib/Makefile
+++ b/arch/microblaze/lib/Makefile
@@ -2,6 +2,12 @@
2# Makefile 2# Makefile
3# 3#
4 4
5ifdef CONFIG_FUNCTION_TRACER
6CFLAGS_REMOVE_ashldi3.o = -pg
7CFLAGS_REMOVE_ashrdi3.o = -pg
8CFLAGS_REMOVE_lshrdi3.o = -pg
9endif
10
5lib-y := memset.o 11lib-y := memset.o
6 12
7ifeq ($(CONFIG_OPT_LIB_ASM),y) 13ifeq ($(CONFIG_OPT_LIB_ASM),y)
@@ -11,3 +17,13 @@ lib-y += memcpy.o memmove.o
11endif 17endif
12 18
13lib-y += uaccess_old.o 19lib-y += uaccess_old.o
20
21lib-y += ashldi3.o
22lib-y += ashrdi3.o
23lib-y += divsi3.o
24lib-y += lshrdi3.o
25lib-y += modsi3.o
26lib-y += muldi3.o
27lib-y += mulsi3.o
28lib-y += udivsi3.o
29lib-y += umodsi3.o
diff --git a/arch/microblaze/lib/ashldi3.c b/arch/microblaze/lib/ashldi3.c
new file mode 100644
index 000000000000..beb80f316095
--- /dev/null
+++ b/arch/microblaze/lib/ashldi3.c
@@ -0,0 +1,29 @@
1#include <linux/module.h>
2
3#include "libgcc.h"
4
5long long __ashldi3(long long u, word_type b)
6{
7 DWunion uu, w;
8 word_type bm;
9
10 if (b == 0)
11 return u;
12
13 uu.ll = u;
14 bm = 32 - b;
15
16 if (bm <= 0) {
17 w.s.low = 0;
18 w.s.high = (unsigned int) uu.s.low << -bm;
19 } else {
20 const unsigned int carries = (unsigned int) uu.s.low >> bm;
21
22 w.s.low = (unsigned int) uu.s.low << b;
23 w.s.high = ((unsigned int) uu.s.high << b) | carries;
24 }
25
26 return w.ll;
27}
28
29EXPORT_SYMBOL(__ashldi3);
diff --git a/arch/microblaze/lib/ashrdi3.c b/arch/microblaze/lib/ashrdi3.c
new file mode 100644
index 000000000000..c884a912b660
--- /dev/null
+++ b/arch/microblaze/lib/ashrdi3.c
@@ -0,0 +1,31 @@
1#include <linux/module.h>
2
3#include "libgcc.h"
4
5long long __ashrdi3(long long u, word_type b)
6{
7 DWunion uu, w;
8 word_type bm;
9
10 if (b == 0)
11 return u;
12
13 uu.ll = u;
14 bm = 32 - b;
15
16 if (bm <= 0) {
17 /* w.s.high = 1..1 or 0..0 */
18 w.s.high =
19 uu.s.high >> 31;
20 w.s.low = uu.s.high >> -bm;
21 } else {
22 const unsigned int carries = (unsigned int) uu.s.high << bm;
23
24 w.s.high = uu.s.high >> b;
25 w.s.low = ((unsigned int) uu.s.low >> b) | carries;
26 }
27
28 return w.ll;
29}
30
31EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/microblaze/lib/divsi3.S b/arch/microblaze/lib/divsi3.S
new file mode 100644
index 000000000000..595b02d6e86b
--- /dev/null
+++ b/arch/microblaze/lib/divsi3.S
@@ -0,0 +1,73 @@
1#include <linux/linkage.h>
2
3/*
4* Divide operation for 32 bit integers.
5* Input : Dividend in Reg r5
6* Divisor in Reg r6
7* Output: Result in Reg r3
8*/
9 .text
10 .globl __divsi3
11 .type __divsi3, @function
12 .ent __divsi3
13__divsi3:
14 .frame r1, 0, r15
15
16 addik r1, r1, -16
17 swi r28, r1, 0
18 swi r29, r1, 4
19 swi r30, r1, 8
20 swi r31, r1, 12
21
22 beqi r6, div_by_zero /* div_by_zero - division error */
23 beqi r5, result_is_zero /* result is zero */
24 bgeid r5, r5_pos
25 xor r28, r5, r6 /* get the sign of the result */
26 rsubi r5, r5, 0 /* make r5 positive */
27r5_pos:
28 bgei r6, r6_pos
29 rsubi r6, r6, 0 /* make r6 positive */
30r6_pos:
31 addik r30, r0, 0 /* clear mod */
32 addik r3, r0, 0 /* clear div */
33 addik r29, r0, 32 /* initialize the loop count */
34
35 /* first part try to find the first '1' in the r5 */
36div0:
37 blti r5, div2 /* this traps r5 == 0x80000000 */
38div1:
39 add r5, r5, r5 /* left shift logical r5 */
40 bgtid r5, div1
41 addik r29, r29, -1
42div2:
43 /* left shift logical r5 get the '1' into the carry */
44 add r5, r5, r5
45 addc r30, r30, r30 /* move that bit into the mod register */
46 rsub r31, r6, r30 /* try to subtract (r30 a r6) */
47 blti r31, mod_too_small
48 /* move the r31 to mod since the result was positive */
49 or r30, r0, r31
50 addik r3, r3, 1
51mod_too_small:
52 addik r29, r29, -1
53 beqi r29, loop_end
54 add r3, r3, r3 /* shift in the '1' into div */
55 bri div2 /* div2 */
56loop_end:
57 bgei r28, return_here
58 brid return_here
59 rsubi r3, r3, 0 /* negate the result */
60div_by_zero:
61result_is_zero:
62 or r3, r0, r0 /* set result to 0 */
63return_here:
64/* restore values of csrs and that of r3 and the divisor and the dividend */
65 lwi r28, r1, 0
66 lwi r29, r1, 4
67 lwi r30, r1, 8
68 lwi r31, r1, 12
69 rtsd r15, 8
70 addik r1, r1, 16
71
72.size __divsi3, . - __divsi3
73.end __divsi3
diff --git a/arch/microblaze/lib/fastcopy.S b/arch/microblaze/lib/fastcopy.S
index fdc48bb065d8..62021d7e249e 100644
--- a/arch/microblaze/lib/fastcopy.S
+++ b/arch/microblaze/lib/fastcopy.S
@@ -29,6 +29,10 @@
29 * between mem locations with size of xfer spec'd in bytes 29 * between mem locations with size of xfer spec'd in bytes
30 */ 30 */
31 31
32#ifdef __MICROBLAZEEL__
33#error Microblaze LE not support ASM optimized lib func. Disable OPT_LIB_ASM.
34#endif
35
32#include <linux/linkage.h> 36#include <linux/linkage.h>
33 .text 37 .text
34 .globl memcpy 38 .globl memcpy
diff --git a/arch/microblaze/lib/libgcc.h b/arch/microblaze/lib/libgcc.h
new file mode 100644
index 000000000000..05909d58e2fe
--- /dev/null
+++ b/arch/microblaze/lib/libgcc.h
@@ -0,0 +1,25 @@
1#ifndef __ASM_LIBGCC_H
2#define __ASM_LIBGCC_H
3
4#include <asm/byteorder.h>
5
6typedef int word_type __attribute__ ((mode (__word__)));
7
8#ifdef __BIG_ENDIAN
9struct DWstruct {
10 int high, low;
11};
12#elif defined(__LITTLE_ENDIAN)
13struct DWstruct {
14 int low, high;
15};
16#else
17#error I feel sick.
18#endif
19
20typedef union {
21 struct DWstruct s;
22 long long ll;
23} DWunion;
24
25#endif /* __ASM_LIBGCC_H */
diff --git a/arch/microblaze/lib/lshrdi3.c b/arch/microblaze/lib/lshrdi3.c
new file mode 100644
index 000000000000..dcf8d6810b7c
--- /dev/null
+++ b/arch/microblaze/lib/lshrdi3.c
@@ -0,0 +1,29 @@
1#include <linux/module.h>
2
3#include "libgcc.h"
4
5long long __lshrdi3(long long u, word_type b)
6{
7 DWunion uu, w;
8 word_type bm;
9
10 if (b == 0)
11 return u;
12
13 uu.ll = u;
14 bm = 32 - b;
15
16 if (bm <= 0) {
17 w.s.high = 0;
18 w.s.low = (unsigned int) uu.s.high >> -bm;
19 } else {
20 const unsigned int carries = (unsigned int) uu.s.high << bm;
21
22 w.s.high = (unsigned int) uu.s.high >> b;
23 w.s.low = ((unsigned int) uu.s.low >> b) | carries;
24 }
25
26 return w.ll;
27}
28
29EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c
index 014bac92bdff..52746e718dfa 100644
--- a/arch/microblaze/lib/memcpy.c
+++ b/arch/microblaze/lib/memcpy.c
@@ -33,17 +33,24 @@
33#include <asm/system.h> 33#include <asm/system.h>
34 34
35#ifdef __HAVE_ARCH_MEMCPY 35#ifdef __HAVE_ARCH_MEMCPY
36#ifndef CONFIG_OPT_LIB_FUNCTION
36void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c) 37void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
37{ 38{
38 const char *src = v_src; 39 const char *src = v_src;
39 char *dst = v_dst; 40 char *dst = v_dst;
40#ifndef CONFIG_OPT_LIB_FUNCTION 41
41 /* Simple, byte oriented memcpy. */ 42 /* Simple, byte oriented memcpy. */
42 while (c--) 43 while (c--)
43 *dst++ = *src++; 44 *dst++ = *src++;
44 45
45 return v_dst; 46 return v_dst;
46#else 47}
48#else /* CONFIG_OPT_LIB_FUNCTION */
49void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
50{
51 const char *src = v_src;
52 char *dst = v_dst;
53
47 /* The following code tries to optimize the copy by using unsigned 54 /* The following code tries to optimize the copy by using unsigned
48 * alignment. This will work fine if both source and destination are 55 * alignment. This will work fine if both source and destination are
49 * aligned on the same boundary. However, if they are aligned on 56 * aligned on the same boundary. However, if they are aligned on
@@ -56,8 +63,8 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
56 if (likely(c >= 4)) { 63 if (likely(c >= 4)) {
57 unsigned value, buf_hold; 64 unsigned value, buf_hold;
58 65
59 /* Align the dstination to a word boundry. */ 66 /* Align the destination to a word boundary. */
60 /* This is done in an endian independant manner. */ 67 /* This is done in an endian independent manner. */
61 switch ((unsigned long)dst & 3) { 68 switch ((unsigned long)dst & 3) {
62 case 1: 69 case 1:
63 *dst++ = *src++; 70 *dst++ = *src++;
@@ -73,7 +80,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
73 i_dst = (void *)dst; 80 i_dst = (void *)dst;
74 81
75 /* Choose a copy scheme based on the source */ 82 /* Choose a copy scheme based on the source */
76 /* alignment relative to dstination. */ 83 /* alignment relative to destination. */
77 switch ((unsigned long)src & 3) { 84 switch ((unsigned long)src & 3) {
78 case 0x0: /* Both byte offsets are aligned */ 85 case 0x0: /* Both byte offsets are aligned */
79 i_src = (const void *)src; 86 i_src = (const void *)src;
@@ -86,7 +93,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
86 case 0x1: /* Unaligned - Off by 1 */ 93 case 0x1: /* Unaligned - Off by 1 */
87 /* Word align the source */ 94 /* Word align the source */
88 i_src = (const void *) ((unsigned)src & ~3); 95 i_src = (const void *) ((unsigned)src & ~3);
89 96#ifndef __MICROBLAZEEL__
90 /* Load the holding buffer */ 97 /* Load the holding buffer */
91 buf_hold = *i_src++ << 8; 98 buf_hold = *i_src++ << 8;
92 99
@@ -95,7 +102,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
95 *i_dst++ = buf_hold | value >> 24; 102 *i_dst++ = buf_hold | value >> 24;
96 buf_hold = value << 8; 103 buf_hold = value << 8;
97 } 104 }
105#else
106 /* Load the holding buffer */
107 buf_hold = (*i_src++ & 0xFFFFFF00) >>8;
98 108
109 for (; c >= 4; c -= 4) {
110 value = *i_src++;
111 *i_dst++ = buf_hold | ((value & 0xFF) << 24);
112 buf_hold = (value & 0xFFFFFF00) >>8;
113 }
114#endif
99 /* Realign the source */ 115 /* Realign the source */
100 src = (const void *)i_src; 116 src = (const void *)i_src;
101 src -= 3; 117 src -= 3;
@@ -103,7 +119,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
103 case 0x2: /* Unaligned - Off by 2 */ 119 case 0x2: /* Unaligned - Off by 2 */
104 /* Word align the source */ 120 /* Word align the source */
105 i_src = (const void *) ((unsigned)src & ~3); 121 i_src = (const void *) ((unsigned)src & ~3);
106 122#ifndef __MICROBLAZEEL__
107 /* Load the holding buffer */ 123 /* Load the holding buffer */
108 buf_hold = *i_src++ << 16; 124 buf_hold = *i_src++ << 16;
109 125
@@ -112,7 +128,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
112 *i_dst++ = buf_hold | value >> 16; 128 *i_dst++ = buf_hold | value >> 16;
113 buf_hold = value << 16; 129 buf_hold = value << 16;
114 } 130 }
131#else
132 /* Load the holding buffer */
133 buf_hold = (*i_src++ & 0xFFFF0000 )>>16;
115 134
135 for (; c >= 4; c -= 4) {
136 value = *i_src++;
137 *i_dst++ = buf_hold | ((value & 0xFFFF)<<16);
138 buf_hold = (value & 0xFFFF0000) >>16;
139 }
140#endif
116 /* Realign the source */ 141 /* Realign the source */
117 src = (const void *)i_src; 142 src = (const void *)i_src;
118 src -= 2; 143 src -= 2;
@@ -120,7 +145,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
120 case 0x3: /* Unaligned - Off by 3 */ 145 case 0x3: /* Unaligned - Off by 3 */
121 /* Word align the source */ 146 /* Word align the source */
122 i_src = (const void *) ((unsigned)src & ~3); 147 i_src = (const void *) ((unsigned)src & ~3);
123 148#ifndef __MICROBLAZEEL__
124 /* Load the holding buffer */ 149 /* Load the holding buffer */
125 buf_hold = *i_src++ << 24; 150 buf_hold = *i_src++ << 24;
126 151
@@ -129,7 +154,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
129 *i_dst++ = buf_hold | value >> 8; 154 *i_dst++ = buf_hold | value >> 8;
130 buf_hold = value << 24; 155 buf_hold = value << 24;
131 } 156 }
157#else
158 /* Load the holding buffer */
159 buf_hold = (*i_src++ & 0xFF000000) >> 24;
132 160
161 for (; c >= 4; c -= 4) {
162 value = *i_src++;
163 *i_dst++ = buf_hold | ((value & 0xFFFFFF) << 8);
164 buf_hold = (value & 0xFF000000) >> 24;
165 }
166#endif
133 /* Realign the source */ 167 /* Realign the source */
134 src = (const void *)i_src; 168 src = (const void *)i_src;
135 src -= 1; 169 src -= 1;
@@ -139,7 +173,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
139 } 173 }
140 174
141 /* Finish off any remaining bytes */ 175 /* Finish off any remaining bytes */
142 /* simple fast copy, ... unless a cache boundry is crossed */ 176 /* simple fast copy, ... unless a cache boundary is crossed */
143 switch (c) { 177 switch (c) {
144 case 3: 178 case 3:
145 *dst++ = *src++; 179 *dst++ = *src++;
@@ -150,7 +184,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
150 } 184 }
151 185
152 return v_dst; 186 return v_dst;
153#endif
154} 187}
188#endif /* CONFIG_OPT_LIB_FUNCTION */
155EXPORT_SYMBOL(memcpy); 189EXPORT_SYMBOL(memcpy);
156#endif /* __HAVE_ARCH_MEMCPY */ 190#endif /* __HAVE_ARCH_MEMCPY */
diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c
index 0929198c5e68..2146c3752a80 100644
--- a/arch/microblaze/lib/memmove.c
+++ b/arch/microblaze/lib/memmove.c
@@ -31,16 +31,12 @@
31#include <linux/string.h> 31#include <linux/string.h>
32 32
33#ifdef __HAVE_ARCH_MEMMOVE 33#ifdef __HAVE_ARCH_MEMMOVE
34#ifndef CONFIG_OPT_LIB_FUNCTION
34void *memmove(void *v_dst, const void *v_src, __kernel_size_t c) 35void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
35{ 36{
36 const char *src = v_src; 37 const char *src = v_src;
37 char *dst = v_dst; 38 char *dst = v_dst;
38 39
39#ifdef CONFIG_OPT_LIB_FUNCTION
40 const uint32_t *i_src;
41 uint32_t *i_dst;
42#endif
43
44 if (!c) 40 if (!c)
45 return v_dst; 41 return v_dst;
46 42
@@ -48,7 +44,6 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
48 if (v_dst <= v_src) 44 if (v_dst <= v_src)
49 return memcpy(v_dst, v_src, c); 45 return memcpy(v_dst, v_src, c);
50 46
51#ifndef CONFIG_OPT_LIB_FUNCTION
52 /* copy backwards, from end to beginning */ 47 /* copy backwards, from end to beginning */
53 src += c; 48 src += c;
54 dst += c; 49 dst += c;
@@ -58,7 +53,22 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
58 *--dst = *--src; 53 *--dst = *--src;
59 54
60 return v_dst; 55 return v_dst;
61#else 56}
57#else /* CONFIG_OPT_LIB_FUNCTION */
58void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
59{
60 const char *src = v_src;
61 char *dst = v_dst;
62 const uint32_t *i_src;
63 uint32_t *i_dst;
64
65 if (!c)
66 return v_dst;
67
68 /* Use memcpy when source is higher than dest */
69 if (v_dst <= v_src)
70 return memcpy(v_dst, v_src, c);
71
62 /* The following code tries to optimize the copy by using unsigned 72 /* The following code tries to optimize the copy by using unsigned
63 * alignment. This will work fine if both source and destination are 73 * alignment. This will work fine if both source and destination are
64 * aligned on the same boundary. However, if they are aligned on 74 * aligned on the same boundary. However, if they are aligned on
@@ -73,8 +83,8 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
73 if (c >= 4) { 83 if (c >= 4) {
74 unsigned value, buf_hold; 84 unsigned value, buf_hold;
75 85
76 /* Align the destination to a word boundry. */ 86 /* Align the destination to a word boundary. */
77 /* This is done in an endian independant manner. */ 87 /* This is done in an endian independent manner. */
78 88
79 switch ((unsigned long)dst & 3) { 89 switch ((unsigned long)dst & 3) {
80 case 3: 90 case 3:
@@ -104,7 +114,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
104 case 0x1: /* Unaligned - Off by 1 */ 114 case 0x1: /* Unaligned - Off by 1 */
105 /* Word align the source */ 115 /* Word align the source */
106 i_src = (const void *) (((unsigned)src + 4) & ~3); 116 i_src = (const void *) (((unsigned)src + 4) & ~3);
107 117#ifndef __MICROBLAZEEL__
108 /* Load the holding buffer */ 118 /* Load the holding buffer */
109 buf_hold = *--i_src >> 24; 119 buf_hold = *--i_src >> 24;
110 120
@@ -113,7 +123,16 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
113 *--i_dst = buf_hold << 8 | value; 123 *--i_dst = buf_hold << 8 | value;
114 buf_hold = value >> 24; 124 buf_hold = value >> 24;
115 } 125 }
126#else
127 /* Load the holding buffer */
128 buf_hold = (*--i_src & 0xFF) << 24;
116 129
130 for (; c >= 4; c -= 4) {
131 value = *--i_src;
132 *--i_dst = buf_hold | ((value & 0xFFFFFF00)>>8);
133 buf_hold = (value & 0xFF) << 24;
134 }
135#endif
117 /* Realign the source */ 136 /* Realign the source */
118 src = (const void *)i_src; 137 src = (const void *)i_src;
119 src += 1; 138 src += 1;
@@ -121,7 +140,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
121 case 0x2: /* Unaligned - Off by 2 */ 140 case 0x2: /* Unaligned - Off by 2 */
122 /* Word align the source */ 141 /* Word align the source */
123 i_src = (const void *) (((unsigned)src + 4) & ~3); 142 i_src = (const void *) (((unsigned)src + 4) & ~3);
124 143#ifndef __MICROBLAZEEL__
125 /* Load the holding buffer */ 144 /* Load the holding buffer */
126 buf_hold = *--i_src >> 16; 145 buf_hold = *--i_src >> 16;
127 146
@@ -130,7 +149,16 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
130 *--i_dst = buf_hold << 16 | value; 149 *--i_dst = buf_hold << 16 | value;
131 buf_hold = value >> 16; 150 buf_hold = value >> 16;
132 } 151 }
152#else
153 /* Load the holding buffer */
154 buf_hold = (*--i_src & 0xFFFF) << 16;
133 155
156 for (; c >= 4; c -= 4) {
157 value = *--i_src;
158 *--i_dst = buf_hold | ((value & 0xFFFF0000)>>16);
159 buf_hold = (value & 0xFFFF) << 16;
160 }
161#endif
134 /* Realign the source */ 162 /* Realign the source */
135 src = (const void *)i_src; 163 src = (const void *)i_src;
136 src += 2; 164 src += 2;
@@ -138,7 +166,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
138 case 0x3: /* Unaligned - Off by 3 */ 166 case 0x3: /* Unaligned - Off by 3 */
139 /* Word align the source */ 167 /* Word align the source */
140 i_src = (const void *) (((unsigned)src + 4) & ~3); 168 i_src = (const void *) (((unsigned)src + 4) & ~3);
141 169#ifndef __MICROBLAZEEL__
142 /* Load the holding buffer */ 170 /* Load the holding buffer */
143 buf_hold = *--i_src >> 8; 171 buf_hold = *--i_src >> 8;
144 172
@@ -147,7 +175,16 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
147 *--i_dst = buf_hold << 24 | value; 175 *--i_dst = buf_hold << 24 | value;
148 buf_hold = value >> 8; 176 buf_hold = value >> 8;
149 } 177 }
178#else
179 /* Load the holding buffer */
180 buf_hold = (*--i_src & 0xFFFFFF) << 8;
150 181
182 for (; c >= 4; c -= 4) {
183 value = *--i_src;
184 *--i_dst = buf_hold | ((value & 0xFF000000)>> 24);
185 buf_hold = (value & 0xFFFFFF) << 8;
186 }
187#endif
151 /* Realign the source */ 188 /* Realign the source */
152 src = (const void *)i_src; 189 src = (const void *)i_src;
153 src += 3; 190 src += 3;
@@ -156,7 +193,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
156 dst = (void *)i_dst; 193 dst = (void *)i_dst;
157 } 194 }
158 195
159 /* simple fast copy, ... unless a cache boundry is crossed */ 196 /* simple fast copy, ... unless a cache boundary is crossed */
160 /* Finish off any remaining bytes */ 197 /* Finish off any remaining bytes */
161 switch (c) { 198 switch (c) {
162 case 4: 199 case 4:
@@ -169,7 +206,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
169 *--dst = *--src; 206 *--dst = *--src;
170 } 207 }
171 return v_dst; 208 return v_dst;
172#endif
173} 209}
210#endif /* CONFIG_OPT_LIB_FUNCTION */
174EXPORT_SYMBOL(memmove); 211EXPORT_SYMBOL(memmove);
175#endif /* __HAVE_ARCH_MEMMOVE */ 212#endif /* __HAVE_ARCH_MEMMOVE */
diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c
index ecfb663e1fc1..ddf67939576d 100644
--- a/arch/microblaze/lib/memset.c
+++ b/arch/microblaze/lib/memset.c
@@ -31,17 +31,30 @@
31#include <linux/string.h> 31#include <linux/string.h>
32 32
33#ifdef __HAVE_ARCH_MEMSET 33#ifdef __HAVE_ARCH_MEMSET
34#ifndef CONFIG_OPT_LIB_FUNCTION
35void *memset(void *v_src, int c, __kernel_size_t n)
36{
37 char *src = v_src;
38
39 /* Truncate c to 8 bits */
40 c = (c & 0xFF);
41
42 /* Simple, byte oriented memset or the rest of count. */
43 while (n--)
44 *src++ = c;
45
46 return v_src;
47}
48#else /* CONFIG_OPT_LIB_FUNCTION */
34void *memset(void *v_src, int c, __kernel_size_t n) 49void *memset(void *v_src, int c, __kernel_size_t n)
35{ 50{
36 char *src = v_src; 51 char *src = v_src;
37#ifdef CONFIG_OPT_LIB_FUNCTION
38 uint32_t *i_src; 52 uint32_t *i_src;
39 uint32_t w32 = 0; 53 uint32_t w32 = 0;
40#endif 54
41 /* Truncate c to 8 bits */ 55 /* Truncate c to 8 bits */
42 c = (c & 0xFF); 56 c = (c & 0xFF);
43 57
44#ifdef CONFIG_OPT_LIB_FUNCTION
45 if (unlikely(c)) { 58 if (unlikely(c)) {
46 /* Make a repeating word out of it */ 59 /* Make a repeating word out of it */
47 w32 = c; 60 w32 = c;
@@ -51,7 +64,7 @@ void *memset(void *v_src, int c, __kernel_size_t n)
51 64
52 if (likely(n >= 4)) { 65 if (likely(n >= 4)) {
53 /* Align the destination to a word boundary */ 66 /* Align the destination to a word boundary */
54 /* This is done in an endian independant manner */ 67 /* This is done in an endian independent manner */
55 switch ((unsigned) src & 3) { 68 switch ((unsigned) src & 3) {
56 case 1: 69 case 1:
57 *src++ = c; 70 *src++ = c;
@@ -72,12 +85,13 @@ void *memset(void *v_src, int c, __kernel_size_t n)
72 85
73 src = (void *)i_src; 86 src = (void *)i_src;
74 } 87 }
75#endif 88
76 /* Simple, byte oriented memset or the rest of count. */ 89 /* Simple, byte oriented memset or the rest of count. */
77 while (n--) 90 while (n--)
78 *src++ = c; 91 *src++ = c;
79 92
80 return v_src; 93 return v_src;
81} 94}
95#endif /* CONFIG_OPT_LIB_FUNCTION */
82EXPORT_SYMBOL(memset); 96EXPORT_SYMBOL(memset);
83#endif /* __HAVE_ARCH_MEMSET */ 97#endif /* __HAVE_ARCH_MEMSET */
diff --git a/arch/microblaze/lib/modsi3.S b/arch/microblaze/lib/modsi3.S
new file mode 100644
index 000000000000..84e0bee6e8c7
--- /dev/null
+++ b/arch/microblaze/lib/modsi3.S
@@ -0,0 +1,73 @@
1#include <linux/linkage.h>
2
3/*
4* modulo operation for 32 bit integers.
5* Input : op1 in Reg r5
6* op2 in Reg r6
7* Output: op1 mod op2 in Reg r3
8*/
9
10 .text
11 .globl __modsi3
12 .type __modsi3, @function
13 .ent __modsi3
14
15__modsi3:
16 .frame r1, 0, r15
17
18 addik r1, r1, -16
19 swi r28, r1, 0
20 swi r29, r1, 4
21 swi r30, r1, 8
22 swi r31, r1, 12
23
24 beqi r6, div_by_zero /* div_by_zero division error */
25 beqi r5, result_is_zero /* result is zero */
26 bgeid r5, r5_pos
27 /* get the sign of the result [ depends only on the first arg] */
28 add r28, r5, r0
29 rsubi r5, r5, 0 /* make r5 positive */
30r5_pos:
31 bgei r6, r6_pos
32 rsubi r6, r6, 0 /* make r6 positive */
33r6_pos:
34 addik r3, r0, 0 /* clear mod */
35 addik r30, r0, 0 /* clear div */
36 addik r29, r0, 32 /* initialize the loop count */
37/* first part try to find the first '1' in the r5 */
38div1:
39 add r5, r5, r5 /* left shift logical r5 */
40 bgeid r5, div1
41 addik r29, r29, -1
42div2:
43 /* left shift logical r5 get the '1' into the carry */
44 add r5, r5, r5
45 addc r3, r3, r3 /* move that bit into the mod register */
46 rsub r31, r6, r3 /* try to subtract (r30 a r6) */
47 blti r31, mod_too_small
48 /* move the r31 to mod since the result was positive */
49 or r3, r0, r31
50 addik r30, r30, 1
51mod_too_small:
52 addik r29, r29, -1
53 beqi r29, loop_end
54 add r30, r30, r30 /* shift in the '1' into div */
55 bri div2 /* div2 */
56loop_end:
57 bgei r28, return_here
58 brid return_here
59 rsubi r3, r3, 0 /* negate the result */
60div_by_zero:
61result_is_zero:
62 or r3, r0, r0 /* set result to 0 [both mod as well as div are 0] */
63return_here:
64/* restore values of csrs and that of r3 and the divisor and the dividend */
65 lwi r28, r1, 0
66 lwi r29, r1, 4
67 lwi r30, r1, 8
68 lwi r31, r1, 12
69 rtsd r15, 8
70 addik r1, r1, 16
71
72.size __modsi3, . - __modsi3
73.end __modsi3
diff --git a/arch/microblaze/lib/muldi3.c b/arch/microblaze/lib/muldi3.c
new file mode 100644
index 000000000000..0585bccb7fad
--- /dev/null
+++ b/arch/microblaze/lib/muldi3.c
@@ -0,0 +1,61 @@
1#include <linux/module.h>
2
3#include "libgcc.h"
4
5#define DWtype long long
6#define UWtype unsigned long
7#define UHWtype unsigned short
8
9#define W_TYPE_SIZE 32
10
11#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
12#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
13#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
14
15/* If we still don't have umul_ppmm, define it using plain C. */
16#if !defined(umul_ppmm)
17#define umul_ppmm(w1, w0, u, v) \
18 do { \
19 UWtype __x0, __x1, __x2, __x3; \
20 UHWtype __ul, __vl, __uh, __vh; \
21 \
22 __ul = __ll_lowpart(u); \
23 __uh = __ll_highpart(u); \
24 __vl = __ll_lowpart(v); \
25 __vh = __ll_highpart(v); \
26 \
27 __x0 = (UWtype) __ul * __vl; \
28 __x1 = (UWtype) __ul * __vh; \
29 __x2 = (UWtype) __uh * __vl; \
30 __x3 = (UWtype) __uh * __vh; \
31 \
32 __x1 += __ll_highpart(__x0); /* this can't give carry */\
33 __x1 += __x2; /* but this indeed can */ \
34 if (__x1 < __x2) /* did we get it? */ \
35 __x3 += __ll_B; /* yes, add it in the proper pos */ \
36 \
37 (w1) = __x3 + __ll_highpart(__x1); \
38 (w0) = __ll_lowpart(__x1) * __ll_B + __ll_lowpart(__x0);\
39 } while (0)
40#endif
41
42#if !defined(__umulsidi3)
43#define __umulsidi3(u, v) ({ \
44 DWunion __w; \
45 umul_ppmm(__w.s.high, __w.s.low, u, v); \
46 __w.ll; \
47 })
48#endif
49
50DWtype __muldi3(DWtype u, DWtype v)
51{
52 const DWunion uu = {.ll = u};
53 const DWunion vv = {.ll = v};
54 DWunion w = {.ll = __umulsidi3(uu.s.low, vv.s.low)};
55
56 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
57 + (UWtype) uu.s.high * (UWtype) vv.s.low);
58
59 return w.ll;
60}
61EXPORT_SYMBOL(__muldi3);
diff --git a/arch/microblaze/lib/mulsi3.S b/arch/microblaze/lib/mulsi3.S
new file mode 100644
index 000000000000..90bd7b93afe6
--- /dev/null
+++ b/arch/microblaze/lib/mulsi3.S
@@ -0,0 +1,46 @@
1#include <linux/linkage.h>
2
3/*
4 * Multiply operation for 32 bit integers.
5 * Input : Operand1 in Reg r5
6 * Operand2 in Reg r6
7 * Output: Result [op1 * op2] in Reg r3
8 */
9 .text
10 .globl __mulsi3
11 .type __mulsi3, @function
12 .ent __mulsi3
13
14__mulsi3:
15 .frame r1, 0, r15
16 add r3, r0, r0
17 beqi r5, result_is_zero /* multiply by zero */
18 beqi r6, result_is_zero /* multiply by zero */
19 bgeid r5, r5_pos
20 xor r4, r5, r6 /* get the sign of the result */
21 rsubi r5, r5, 0 /* make r5 positive */
22r5_pos:
23 bgei r6, r6_pos
24 rsubi r6, r6, 0 /* make r6 positive */
25r6_pos:
26 bri l1
27l2:
28 add r5, r5, r5
29l1:
30 srl r6, r6
31 addc r7, r0, r0
32 beqi r7, l2
33 bneid r6, l2
34 add r3, r3, r5
35 blti r4, negateresult
36 rtsd r15, 8
37 nop
38negateresult:
39 rtsd r15, 8
40 rsub r3, r3, r0
41result_is_zero:
42 rtsd r15, 8
43 addi r3, r0, 0
44
45.size __mulsi3, . - __mulsi3
46.end __mulsi3
diff --git a/arch/microblaze/lib/udivsi3.S b/arch/microblaze/lib/udivsi3.S
new file mode 100644
index 000000000000..64cf57e4bb85
--- /dev/null
+++ b/arch/microblaze/lib/udivsi3.S
@@ -0,0 +1,84 @@
1#include <linux/linkage.h>
2
3/*
4* Unsigned divide operation.
5* Input : Divisor in Reg r5
6* Dividend in Reg r6
7* Output: Result in Reg r3
8*/
9
10 .text
11 .globl __udivsi3
12 .type __udivsi3, @function
13 .ent __udivsi3
14
15__udivsi3:
16
17 .frame r1, 0, r15
18
19 addik r1, r1, -12
20 swi r29, r1, 0
21 swi r30, r1, 4
22 swi r31, r1, 8
23
24 beqi r6, div_by_zero /* div_by_zero /* division error */
25 beqid r5, result_is_zero /* result is zero */
26 addik r30, r0, 0 /* clear mod */
27 addik r29, r0, 32 /* initialize the loop count */
28
29/* check if r6 and r5 are equal - if yes, return 1 */
30 rsub r18, r5, r6
31 beqid r18, return_here
32 addik r3, r0, 1
33
34/* check if (uns)r6 is greater than (uns)r5. in that case, just return 0 */
35 xor r18, r5, r6
36 bgeid r18, 16
37 add r3, r0, r0 /* we would anyways clear r3 */
38 blti r6, return_here /* r6[bit 31 = 1] hence is greater */
39 bri checkr6
40 rsub r18, r6, r5 /* microblazecmp */
41 blti r18, return_here
42
43/* if r6 [bit 31] is set, then return result as 1 */
44checkr6:
45 bgti r6, div0
46 brid return_here
47 addik r3, r0, 1
48
49/* first part try to find the first '1' in the r5 */
50div0:
51 blti r5, div2
52div1:
53 add r5, r5, r5 /* left shift logical r5 */
54 bgtid r5, div1
55 addik r29, r29, -1
56div2:
57/* left shift logical r5 get the '1' into the carry */
58 add r5, r5, r5
59 addc r30, r30, r30 /* move that bit into the mod register */
60 rsub r31, r6, r30 /* try to subtract (r30 a r6) */
61 blti r31, mod_too_small
62/* move the r31 to mod since the result was positive */
63 or r30, r0, r31
64 addik r3, r3, 1
65mod_too_small:
66 addik r29, r29, -1
67 beqi r29, loop_end
68 add r3, r3, r3 /* shift in the '1' into div */
69 bri div2 /* div2 */
70loop_end:
71 bri return_here
72div_by_zero:
73result_is_zero:
74 or r3, r0, r0 /* set result to 0 */
75return_here:
76/* restore values of csrs and that of r3 and the divisor and the dividend */
77 lwi r29, r1, 0
78 lwi r30, r1, 4
79 lwi r31, r1, 8
80 rtsd r15, 8
81 addik r1, r1, 12
82
83.size __udivsi3, . - __udivsi3
84.end __udivsi3
diff --git a/arch/microblaze/lib/umodsi3.S b/arch/microblaze/lib/umodsi3.S
new file mode 100644
index 000000000000..17d16bafae58
--- /dev/null
+++ b/arch/microblaze/lib/umodsi3.S
@@ -0,0 +1,86 @@
1#include <linux/linkage.h>
2
3/*
4 * Unsigned modulo operation for 32 bit integers.
5 * Input : op1 in Reg r5
6 * op2 in Reg r6
7 * Output: op1 mod op2 in Reg r3
8 */
9
10 .text
11 .globl __umodsi3
12 .type __umodsi3, @function
13 .ent __umodsi3
14
15__umodsi3:
16 .frame r1, 0, r15
17
18 addik r1, r1, -12
19 swi r29, r1, 0
20 swi r30, r1, 4
21 swi r31, r1, 8
22
23 beqi r6, div_by_zero /* div_by_zero - division error */
24 beqid r5, result_is_zero /* result is zero */
25 addik r3, r0, 0 /* clear div */
26 addik r30, r0, 0 /* clear mod */
27 addik r29, r0, 32 /* initialize the loop count */
28
29/* check if r6 and r5 are equal /* if yes, return 0 */
30 rsub r18, r5, r6
31 beqi r18, return_here
32
33/* check if (uns)r6 is greater than (uns)r5. in that case, just return r5 */
34 xor r18, r5, r6
35 bgeid r18, 16
36 addik r3, r5, 0
37 blti r6, return_here
38 bri $lcheckr6
39 rsub r18, r5, r6 /* microblazecmp */
40 bgti r18, return_here
41
42/* if r6 [bit 31] is set, then return result as r5-r6 */
43$lcheckr6:
44 bgtid r6, div0
45 addik r3, r0, 0
46 addik r18, r0, 0x7fffffff
47 and r5, r5, r18
48 and r6, r6, r18
49 brid return_here
50 rsub r3, r6, r5
51/* first part: try to find the first '1' in the r5 */
52div0:
53 blti r5, div2
54div1:
55 add r5, r5, r5 /* left shift logical r5 */
56 bgeid r5, div1
57 addik r29, r29, -1
58div2:
59 /* left shift logical r5 get the '1' into the carry */
60 add r5, r5, r5
61 addc r3, r3, r3 /* move that bit into the mod register */
62 rsub r31, r6, r3 /* try to subtract (r3 a r6) */
63 blti r31, mod_too_small
64 /* move the r31 to mod since the result was positive */
65 or r3, r0, r31
66 addik r30, r30, 1
67mod_too_small:
68 addik r29, r29, -1
69 beqi r29, loop_end
70 add r30, r30, r30 /* shift in the '1' into div */
71 bri div2 /* div2 */
72loop_end:
73 bri return_here
74div_by_zero:
75result_is_zero:
76 or r3, r0, r0 /* set result to 0 */
77return_here:
78/* restore values of csrs and that of r3 and the divisor and the dividend */
79 lwi r29, r1, 0
80 lwi r30, r1, 4
81 lwi r31, r1, 8
82 rtsd r15, 8
83 addik r1, r1, 12
84
85.size __umodsi3, . - __umodsi3
86.end __umodsi3
diff --git a/arch/microblaze/mm/consistent.c b/arch/microblaze/mm/consistent.c
index 5a59dad62bd2..a1e2e18e0961 100644
--- a/arch/microblaze/mm/consistent.c
+++ b/arch/microblaze/mm/consistent.c
@@ -59,7 +59,7 @@
59 * uncached region. This will no doubt cause big problems if memory allocated 59 * uncached region. This will no doubt cause big problems if memory allocated
60 * here is not also freed properly. -- JW 60 * here is not also freed properly. -- JW
61 */ 61 */
62void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) 62void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle)
63{ 63{
64 unsigned long order, vaddr; 64 unsigned long order, vaddr;
65 void *ret; 65 void *ret;
diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c
index 57bd2a09610c..ae97d2ccdc22 100644
--- a/arch/microblaze/mm/fault.c
+++ b/arch/microblaze/mm/fault.c
@@ -48,7 +48,7 @@ static int store_updates_sp(struct pt_regs *regs)
48{ 48{
49 unsigned int inst; 49 unsigned int inst;
50 50
51 if (get_user(inst, (unsigned int *)regs->pc)) 51 if (get_user(inst, (unsigned int __user *)regs->pc))
52 return 0; 52 return 0;
53 /* check for 1 in the rD field */ 53 /* check for 1 in the rD field */
54 if (((inst >> 21) & 0x1f) != 1) 54 if (((inst >> 21) & 0x1f) != 1)
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index 65eb00419d19..213f2d671669 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -32,8 +32,6 @@ unsigned int __page_offset;
32EXPORT_SYMBOL(__page_offset); 32EXPORT_SYMBOL(__page_offset);
33 33
34#else 34#else
35DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
36
37static int init_bootmem_done; 35static int init_bootmem_done;
38#endif /* CONFIG_MMU */ 36#endif /* CONFIG_MMU */
39 37
@@ -70,16 +68,16 @@ static void __init paging_init(void)
70 68
71void __init setup_memory(void) 69void __init setup_memory(void)
72{ 70{
73 int i;
74 unsigned long map_size; 71 unsigned long map_size;
72 struct memblock_region *reg;
73
75#ifndef CONFIG_MMU 74#ifndef CONFIG_MMU
76 u32 kernel_align_start, kernel_align_size; 75 u32 kernel_align_start, kernel_align_size;
77 76
78 /* Find main memory where is the kernel */ 77 /* Find main memory where is the kernel */
79 for (i = 0; i < memblock.memory.cnt; i++) { 78 for_each_memblock(memory, reg) {
80 memory_start = (u32) memblock.memory.region[i].base; 79 memory_start = (u32)reg->base;
81 memory_end = (u32) memblock.memory.region[i].base 80 memory_end = (u32) reg->base + reg->size;
82 + (u32) memblock.memory.region[i].size;
83 if ((memory_start <= (u32)_text) && 81 if ((memory_start <= (u32)_text) &&
84 ((u32)_text <= memory_end)) { 82 ((u32)_text <= memory_end)) {
85 memory_size = memory_end - memory_start; 83 memory_size = memory_end - memory_start;
@@ -142,12 +140,10 @@ void __init setup_memory(void)
142 free_bootmem(memory_start, memory_size); 140 free_bootmem(memory_start, memory_size);
143 141
144 /* reserve allocate blocks */ 142 /* reserve allocate blocks */
145 for (i = 0; i < memblock.reserved.cnt; i++) { 143 for_each_memblock(reserved, reg) {
146 pr_debug("reserved %d - 0x%08x-0x%08x\n", i, 144 pr_debug("reserved - 0x%08x-0x%08x\n",
147 (u32) memblock.reserved.region[i].base, 145 (u32) reg->base, (u32) reg->size);
148 (u32) memblock_size_bytes(&memblock.reserved, i)); 146 reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
149 reserve_bootmem(memblock.reserved.region[i].base,
150 memblock_size_bytes(&memblock.reserved, i) - 1, BOOTMEM_DEFAULT);
151 } 147 }
152#ifdef CONFIG_MMU 148#ifdef CONFIG_MMU
153 init_bootmem_done = 1; 149 init_bootmem_done = 1;
@@ -230,7 +226,7 @@ static void mm_cmdline_setup(void)
230 if (maxmem && memory_size > maxmem) { 226 if (maxmem && memory_size > maxmem) {
231 memory_size = maxmem; 227 memory_size = maxmem;
232 memory_end = memory_start + memory_size; 228 memory_end = memory_start + memory_size;
233 memblock.memory.region[0].size = memory_size; 229 memblock.memory.regions[0].size = memory_size;
234 } 230 }
235 } 231 }
236} 232}
@@ -273,14 +269,14 @@ asmlinkage void __init mmu_init(void)
273 machine_restart(NULL); 269 machine_restart(NULL);
274 } 270 }
275 271
276 if ((u32) memblock.memory.region[0].size < 0x1000000) { 272 if ((u32) memblock.memory.regions[0].size < 0x1000000) {
277 printk(KERN_EMERG "Memory must be greater than 16MB\n"); 273 printk(KERN_EMERG "Memory must be greater than 16MB\n");
278 machine_restart(NULL); 274 machine_restart(NULL);
279 } 275 }
280 /* Find main memory where the kernel is */ 276 /* Find main memory where the kernel is */
281 memory_start = (u32) memblock.memory.region[0].base; 277 memory_start = (u32) memblock.memory.regions[0].base;
282 memory_end = (u32) memblock.memory.region[0].base + 278 memory_end = (u32) memblock.memory.regions[0].base +
283 (u32) memblock.memory.region[0].size; 279 (u32) memblock.memory.regions[0].size;
284 memory_size = memory_end - memory_start; 280 memory_size = memory_end - memory_start;
285 281
286 mm_cmdline_setup(); /* FIXME parse args from command line - not used */ 282 mm_cmdline_setup(); /* FIXME parse args from command line - not used */
diff --git a/arch/microblaze/pci/indirect_pci.c b/arch/microblaze/pci/indirect_pci.c
index 25f18f017f21..4196eb6bd764 100644
--- a/arch/microblaze/pci/indirect_pci.c
+++ b/arch/microblaze/pci/indirect_pci.c
@@ -108,7 +108,7 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
108 out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) | 108 out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
109 (devfn << 8) | reg | cfg_type)); 109 (devfn << 8) | reg | cfg_type));
110 110
111 /* surpress setting of PCI_PRIMARY_BUS */ 111 /* suppress setting of PCI_PRIMARY_BUS */
112 if (hose->indirect_type & INDIRECT_TYPE_SURPRESS_PRIMARY_BUS) 112 if (hose->indirect_type & INDIRECT_TYPE_SURPRESS_PRIMARY_BUS)
113 if ((offset == PCI_PRIMARY_BUS) && 113 if ((offset == PCI_PRIMARY_BUS) &&
114 (bus->number == hose->first_busno)) 114 (bus->number == hose->first_busno))
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 55ef532f32be..53599067d2f9 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -29,6 +29,7 @@
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/of.h> 30#include <linux/of.h>
31#include <linux/of_address.h> 31#include <linux/of_address.h>
32#include <linux/of_pci.h>
32 33
33#include <asm/processor.h> 34#include <asm/processor.h>
34#include <asm/io.h> 35#include <asm/io.h>
@@ -60,21 +61,6 @@ struct dma_map_ops *get_pci_dma_ops(void)
60} 61}
61EXPORT_SYMBOL(get_pci_dma_ops); 62EXPORT_SYMBOL(get_pci_dma_ops);
62 63
63int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
64{
65 return dma_set_mask(&dev->dev, mask);
66}
67
68int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
69{
70 int rc;
71
72 rc = dma_set_mask(&dev->dev, mask);
73 dev->dev.coherent_dma_mask = dev->dma_mask;
74
75 return rc;
76}
77
78struct pci_controller *pcibios_alloc_controller(struct device_node *dev) 64struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
79{ 65{
80 struct pci_controller *phb; 66 struct pci_controller *phb;
@@ -251,7 +237,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
251 237
252 virq = irq_create_mapping(NULL, line); 238 virq = irq_create_mapping(NULL, line);
253 if (virq != NO_IRQ) 239 if (virq != NO_IRQ)
254 set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); 240 irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
255 } else { 241 } else {
256 pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", 242 pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
257 oirq.size, oirq.specifier[0], oirq.specifier[1], 243 oirq.size, oirq.specifier[0], oirq.specifier[1],
@@ -1075,8 +1061,6 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
1075 bus->number, bus->self ? pci_name(bus->self) : "PHB"); 1061 bus->number, bus->self ? pci_name(bus->self) : "PHB");
1076 1062
1077 list_for_each_entry(dev, &bus->devices, bus_list) { 1063 list_for_each_entry(dev, &bus->devices, bus_list) {
1078 struct dev_archdata *sd = &dev->dev.archdata;
1079
1080 /* Setup OF node pointer in archdata */ 1064 /* Setup OF node pointer in archdata */
1081 dev->dev.of_node = pci_device_to_OF_node(dev); 1065 dev->dev.of_node = pci_device_to_OF_node(dev);
1082 1066
@@ -1086,8 +1070,8 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
1086 set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); 1070 set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
1087 1071
1088 /* Hook up default DMA ops */ 1072 /* Hook up default DMA ops */
1089 sd->dma_ops = pci_dma_ops; 1073 set_dma_ops(&dev->dev, pci_dma_ops);
1090 sd->dma_data = (void *)PCI_DRAM_OFFSET; 1074 dev->dev.archdata.dma_data = (void *)PCI_DRAM_OFFSET;
1091 1075
1092 /* Read default IRQs and fixup if necessary */ 1076 /* Read default IRQs and fixup if necessary */
1093 pci_read_irq_line(dev); 1077 pci_read_irq_line(dev);
diff --git a/arch/microblaze/pci/pci_32.c b/arch/microblaze/pci/pci_32.c
index 3c3d808d7ce0..92728a6cfd80 100644
--- a/arch/microblaze/pci/pci_32.c
+++ b/arch/microblaze/pci/pci_32.c
@@ -332,6 +332,7 @@ static void __devinit pcibios_scan_phb(struct pci_controller *hose)
332 hose->global_number); 332 hose->global_number);
333 return; 333 return;
334 } 334 }
335 bus.dev->of_node = of_node_get(node);
335 bus->secondary = hose->first_busno; 336 bus->secondary = hose->first_busno;
336 hose->bus = bus; 337 hose->bus = bus;
337 338
diff --git a/arch/microblaze/platform/generic/Kconfig.auto b/arch/microblaze/platform/generic/Kconfig.auto
index 5d86fc19029d..25a6f019e94d 100644
--- a/arch/microblaze/platform/generic/Kconfig.auto
+++ b/arch/microblaze/platform/generic/Kconfig.auto
@@ -29,7 +29,7 @@ config KERNEL_BASE_ADDR
29 BASE Address for kernel 29 BASE Address for kernel
30 30
31config XILINX_MICROBLAZE0_FAMILY 31config XILINX_MICROBLAZE0_FAMILY
32 string "Targetted FPGA family" 32 string "Targeted FPGA family"
33 default "virtex5" 33 default "virtex5"
34 34
35config XILINX_MICROBLAZE0_USE_MSR_INSTR 35config XILINX_MICROBLAZE0_USE_MSR_INSTR
diff --git a/arch/microblaze/platform/generic/system.dts b/arch/microblaze/platform/generic/system.dts
index 2d5c41767cd0..3f85df2b73b3 100644
--- a/arch/microblaze/platform/generic/system.dts
+++ b/arch/microblaze/platform/generic/system.dts
@@ -85,6 +85,7 @@
85 xlnx,dynamic-bus-sizing = <0x1>; 85 xlnx,dynamic-bus-sizing = <0x1>;
86 xlnx,edge-is-positive = <0x1>; 86 xlnx,edge-is-positive = <0x1>;
87 xlnx,family = "virtex5"; 87 xlnx,family = "virtex5";
88 xlnx,endianness = <0x1>;
88 xlnx,fpu-exception = <0x1>; 89 xlnx,fpu-exception = <0x1>;
89 xlnx,fsl-data-size = <0x20>; 90 xlnx,fsl-data-size = <0x20>;
90 xlnx,fsl-exception = <0x0>; 91 xlnx,fsl-exception = <0x0>;
@@ -218,6 +219,7 @@
218 #address-cells = <1>; 219 #address-cells = <1>;
219 #size-cells = <1>; 220 #size-cells = <1>;
220 compatible = "xlnx,compound"; 221 compatible = "xlnx,compound";
222 ranges ;
221 ethernet@81c00000 { 223 ethernet@81c00000 {
222 compatible = "xlnx,xps-ll-temac-1.01.b", "xlnx,xps-ll-temac-1.00.a"; 224 compatible = "xlnx,xps-ll-temac-1.01.b", "xlnx,xps-ll-temac-1.00.a";
223 device_type = "network"; 225 device_type = "network";
@@ -332,6 +334,7 @@
332 #address-cells = <1>; 334 #address-cells = <1>;
333 #size-cells = <1>; 335 #size-cells = <1>;
334 compatible = "xlnx,mpmc-4.02.a"; 336 compatible = "xlnx,mpmc-4.02.a";
337 ranges ;
335 PIM3: sdma@84600180 { 338 PIM3: sdma@84600180 {
336 compatible = "xlnx,ll-dma-1.00.a"; 339 compatible = "xlnx,ll-dma-1.00.a";
337 interrupt-parent = <&xps_intc_0>; 340 interrupt-parent = <&xps_intc_0>;
diff --git a/arch/microblaze/platform/platform.c b/arch/microblaze/platform/platform.c
index 5b89b58c5aed..b9529caa507a 100644
--- a/arch/microblaze/platform/platform.c
+++ b/arch/microblaze/platform/platform.c
@@ -17,9 +17,6 @@
17 17
18static struct of_device_id xilinx_of_bus_ids[] __initdata = { 18static struct of_device_id xilinx_of_bus_ids[] __initdata = {
19 { .compatible = "simple-bus", }, 19 { .compatible = "simple-bus", },
20 { .compatible = "xlnx,plb-v46-1.00.a", },
21 { .compatible = "xlnx,opb-v20-1.10.c", },
22 { .compatible = "xlnx,opb-v20-1.10.b", },
23 { .compatible = "xlnx,compound", }, 20 { .compatible = "xlnx,compound", },
24 {} 21 {}
25}; 22};