diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/microblaze | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'arch/microblaze')
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 | |||
4 | mainmenu "Linux/Microblaze Kernel Configuration" | ||
5 | |||
6 | config MICROBLAZE | 1 | config 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 | ||
24 | config SWAP | 21 | config SWAP |
25 | def_bool n | 22 | def_bool n |
@@ -36,18 +33,9 @@ config ARCH_HAS_ILOG2_U32 | |||
36 | config ARCH_HAS_ILOG2_U64 | 33 | config ARCH_HAS_ILOG2_U64 |
37 | def_bool n | 34 | def_bool n |
38 | 35 | ||
39 | config GENERIC_FIND_NEXT_BIT | ||
40 | def_bool y | ||
41 | |||
42 | config GENERIC_HWEIGHT | 36 | config GENERIC_HWEIGHT |
43 | def_bool y | 37 | def_bool y |
44 | 38 | ||
45 | config GENERIC_HARDIRQS | ||
46 | def_bool y | ||
47 | |||
48 | config GENERIC_IRQ_PROBE | ||
49 | def_bool y | ||
50 | |||
51 | config GENERIC_CALIBRATE_DELAY | 39 | config GENERIC_CALIBRATE_DELAY |
52 | def_bool y | 40 | def_bool y |
53 | 41 | ||
@@ -57,9 +45,6 @@ config GENERIC_TIME_VSYSCALL | |||
57 | config GENERIC_CLOCKEVENTS | 45 | config GENERIC_CLOCKEVENTS |
58 | def_bool y | 46 | def_bool y |
59 | 47 | ||
60 | config GENERIC_HARDIRQS_NO__DO_IRQ | ||
61 | def_bool y | ||
62 | |||
63 | config GENERIC_GPIO | 48 | config 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 | ||
109 | config 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 | |||
124 | endmenu | 126 | endmenu |
125 | 127 | ||
126 | menu "Advanced setup" | 128 | menu "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 | ||
183 | config 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 | |||
181 | config KERNEL_START_BOOL | 194 | config 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 | ||
243 | source "mm/Kconfig" | 256 | source "mm/Kconfig" |
244 | 257 | ||
245 | menu "Exectuable file formats" | 258 | menu "Executable file formats" |
246 | 259 | ||
247 | source "fs/Kconfig.binfmt" | 260 | source "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 | ||
11 | config EARLY_PRINTK | 11 | config 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 | ||
26 | config DEBUG_BOOTMEM | ||
27 | depends on DEBUG_KERNEL | ||
28 | bool "Debug BOOTMEM initialization" | ||
29 | |||
30 | endmenu | 26 | endmenu |
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 |
24 | ifeq (,$(findstring spartan2,$(CONFIG_XILINX_MICROBLAZE0_FAMILY))) | 24 | ifeq (,$(findstring spartan2,$(CONFIG_XILINX_MICROBLAZE0_FAMILY))) |
@@ -42,11 +42,8 @@ KBUILD_CFLAGS += -ffixed-r31 $(CPUFLAGS-1) $(CPUFLAGS-2) | |||
42 | LDFLAGS := | 42 | LDFLAGS := |
43 | LDFLAGS_vmlinux := | 43 | LDFLAGS_vmlinux := |
44 | 44 | ||
45 | LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) | ||
46 | |||
47 | head-y := arch/microblaze/kernel/head.o | 45 | head-y := arch/microblaze/kernel/head.o |
48 | libs-y += arch/microblaze/lib/ | 46 | libs-y += arch/microblaze/lib/ |
49 | libs-y += $(LIBGCC) | ||
50 | core-y += arch/microblaze/kernel/ | 47 | core-y += arch/microblaze/kernel/ |
51 | core-y += arch/microblaze/mm/ | 48 | core-y += arch/microblaze/mm/ |
52 | core-y += arch/microblaze/platform/ | 49 | core-y += arch/microblaze/platform/ |
@@ -72,12 +69,16 @@ export MMU DTB | |||
72 | 69 | ||
73 | all: linux.bin | 70 | all: linux.bin |
74 | 71 | ||
75 | BOOT_TARGETS = linux.bin linux.bin.gz simpleImage.% | 72 | # With make 3.82 we cannot mix normal and wildcard targets |
73 | BOOT_TARGETS1 = linux.bin linux.bin.gz | ||
74 | BOOT_TARGETS2 = simpleImage.% | ||
76 | 75 | ||
77 | archclean: | 76 | archclean: |
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 | ||
83 | define archhelp | 84 | define 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 | ||
11 | OBJCOPYFLAGS := -O binary | 11 | OBJCOPYFLAGS := -O binary |
12 | 12 | ||
13 | # Where the DTS files live | ||
14 | dtstree := $(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 | ||
55 | DTC = $(objtree)/scripts/dtc/dtc | ||
56 | 51 | ||
57 | # Rule to build device tree blobs | 52 | # Rule to build device tree blobs |
58 | quiet_cmd_dtc = DTC $@ | 53 | DTC_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 | ||
64 | clean-files += *.dtb simpleImage.*.unstrip linux.bin.ub | 58 | clean-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 | |||
7 | CONFIG_INITRAMFS_SOURCE="rootfs.cpio" | 7 | CONFIG_INITRAMFS_SOURCE="rootfs.cpio" |
8 | CONFIG_INITRAMFS_COMPRESSION_GZIP=y | 8 | CONFIG_INITRAMFS_COMPRESSION_GZIP=y |
9 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 9 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
10 | CONFIG_EMBEDDED=y | 10 | CONFIG_EXPERT=y |
11 | CONFIG_KALLSYMS_ALL=y | 11 | CONFIG_KALLSYMS_ALL=y |
12 | CONFIG_KALLSYMS_EXTRA_PASS=y | 12 | CONFIG_KALLSYMS_EXTRA_PASS=y |
13 | # CONFIG_HOTPLUG is not set | 13 | # CONFIG_HOTPLUG is not set |
@@ -66,5 +66,4 @@ CONFIG_DEBUG_SPINLOCK=y | |||
66 | CONFIG_DEBUG_INFO=y | 66 | CONFIG_DEBUG_INFO=y |
67 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 67 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
68 | CONFIG_EARLY_PRINTK=y | 68 | CONFIG_EARLY_PRINTK=y |
69 | CONFIG_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 | |||
6 | CONFIG_IKCONFIG=y | 6 | CONFIG_IKCONFIG=y |
7 | CONFIG_IKCONFIG_PROC=y | 7 | CONFIG_IKCONFIG_PROC=y |
8 | CONFIG_SYSFS_DEPRECATED_V2=y | 8 | CONFIG_SYSFS_DEPRECATED_V2=y |
9 | CONFIG_EMBEDDED=y | 9 | CONFIG_EXPERT=y |
10 | CONFIG_KALLSYMS_ALL=y | 10 | CONFIG_KALLSYMS_ALL=y |
11 | CONFIG_KALLSYMS_EXTRA_PASS=y | 11 | CONFIG_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) \ |
105 | do { \ | 106 | do { \ |
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 | ||
97 | static inline unsigned int fcpu(struct device_node *cpu, char *n) | 97 | static 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 */ | |||
31 | DECLARE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */ | 31 | DECLARE_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 @@ | |||
66 | asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, | 66 | asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, |
67 | int fsr, int addr); | 67 | int fsr, int addr); |
68 | 68 | ||
69 | asmlinkage void sw_exception(struct pt_regs *regs); | ||
70 | void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig); | ||
71 | |||
69 | void die(const char *str, struct pt_regs *fp, long err); | 72 | void die(const char *str, struct pt_regs *fp, long err); |
70 | void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr); | 73 | void _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 | ||
31 | static inline int | 31 | static inline int |
32 | futex_atomic_op_inuser(int encoded_op, int __user *uaddr) | 32 | futex_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 | ||
96 | static inline int | 96 | static inline int |
97 | futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) | 97 | futex_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 | */ | ||
44 | static inline int gpio_to_irq(unsigned int gpio) | 41 | static inline int gpio_to_irq(unsigned int gpio) |
45 | { | 42 | { |
46 | return -ENOSYS; | 43 | return __gpio_to_irq(gpio); |
47 | } | 44 | } |
48 | 45 | ||
49 | static inline int irq_to_gpio(unsigned int irq) | 46 | static 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 | */ |
76 | static inline unsigned char readb(const volatile void __iomem *addr) | 76 | static 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) \ | 17 | static 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; \ | 28 | static 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;" \ | 38 | static 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; \ | 50 | static 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; \ | 64 | static 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; \ | 77 | static 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) \ | 92 | static inline unsigned long arch_local_save_flags(void) |
93 | : "memory"); \ | ||
94 | } while (0) | ||
95 | |||
96 | static 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()) | 103 | static 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 | |||
112 | static inline bool arch_irqs_disabled_flags(unsigned long flags) | ||
113 | { | ||
114 | return (flags & MSR_IE) == 0; | ||
115 | } | ||
116 | |||
117 | static 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 | ||
107 | static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) | 108 | static 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 | ||
113 | static 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 | |||
112 | static inline int isa_vaddr_is_ioport(void __iomem *address) | 123 | static 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, | |||
158 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); | 158 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); |
159 | extern void pcibios_setup_bus_self(struct pci_bus *bus); | 159 | extern 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 |
163 | extern void __init xilinx_pci_init(void); | 163 | extern void __init xilinx_pci_init(void); |
164 | #else | 164 | #else |
165 | static inline void __init xilinx_pci_init(void) { return; } | 165 | static 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) | |||
404 | static inline unsigned long pte_update(pte_t *p, unsigned long clr, | 411 | static 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 | ||
440 | static 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) | 447 | static 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 | ||
453 | static inline pte_t ptep_get_and_clear(struct mm_struct *mm, | 461 | static 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 | ||
568 | extern unsigned long ioremap_bot, ioremap_base; | 573 | extern unsigned long ioremap_bot, ioremap_base; |
569 | 574 | ||
570 | void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle); | 575 | void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle); |
571 | void consistent_free(size_t size, void *vaddr); | 576 | void consistent_free(size_t size, void *vaddr); |
572 | void consistent_sync(void *vaddr, size_t size, int direction); | 577 | void consistent_sync(void *vaddr, size_t size, int direction); |
573 | void consistent_sync_page(struct page *page, unsigned long offset, | 578 | void 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 */ |
29 | extern int early_uartlite_console(void); | 29 | extern int early_uartlite_console(void); |
30 | extern 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 */ |
64 | struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); | 65 | struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); |
65 | 66 | ||
66 | /* Get the MAC address */ | ||
67 | extern 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 | */ | ||
80 | struct pci_dev; | ||
81 | struct of_irq; | ||
82 | extern 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 | ||
212 | int cpu_has_pvr(void); | 223 | int cpu_has_pvr(void); |
213 | void get_pvr(struct pvr_s *pvr); | 224 | void 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, ...); | |||
25 | int setup_early_printk(char *opt); | 25 | int setup_early_printk(char *opt); |
26 | void disable_early_printk(void); | 26 | void 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 | |||
28 | void heartbeat(void); | 34 | void heartbeat(void); |
29 | void setup_heartbeat(void); | 35 | void 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 | ||
99 | asmlinkage long do_syscall_trace_enter(struct pt_regs *regs); | ||
100 | asmlinkage 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 | ||
3 | asmlinkage long microblaze_vfork(struct pt_regs *regs); | ||
4 | asmlinkage long microblaze_clone(int flags, unsigned long stack, | ||
5 | struct pt_regs *regs); | ||
6 | asmlinkage 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 | |||
3 | asmlinkage long sys_clone(int flags, unsigned long stack, struct pt_regs *regs); | 11 | asmlinkage 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 | |||
10 | CFLAGS_REMOVE_selfmod.o = -pg | 10 | CFLAGS_REMOVE_selfmod.o = -pg |
11 | CFLAGS_REMOVE_heartbeat.o = -pg | 11 | CFLAGS_REMOVE_heartbeat.o = -pg |
12 | CFLAGS_REMOVE_ftrace.o = -pg | 12 | CFLAGS_REMOVE_ftrace.o = -pg |
13 | CFLAGS_REMOVE_process.o = -pg | ||
13 | endif | 14 | endif |
14 | 15 | ||
15 | extra-y := head.o vmlinux.lds | 16 | extra-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 | |||
6 | CFLAGS_REMOVE_cache.o = -pg | 6 | CFLAGS_REMOVE_cache.o = -pg |
7 | endif | 7 | endif |
8 | 8 | ||
9 | EXTRA_CFLAGS += -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \ | 9 | ccflags-y := -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \ |
10 | -DCPU_REV=$(CPU_REV) | 10 | -DCPU_REV=$(CPU_REV) |
11 | 11 | ||
12 | obj-y += cache.o cpuinfo.o cpuinfo-pvr-full.o cpuinfo-static.o mb.o pvr.o | 12 | obj-y += cache.o cpuinfo.o cpuinfo-pvr-full.o cpuinfo-static.o mb.o pvr.o |
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c 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) | |||
519 | struct scache *mbc; | 519 | struct scache *mbc; |
520 | 520 | ||
521 | /* new wb cache model */ | 521 | /* new wb cache model */ |
522 | const struct scache wb_msr = { | 522 | static 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 */ |
538 | const struct scache wb_nomsr = { | 538 | static 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 */ |
554 | const struct scache wt_msr = { | 554 | static 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 | ||
569 | const struct scache wt_nomsr = { | 569 | static 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 */ |
585 | const struct scache wt_msr_noirq = { | 585 | static 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 | ||
600 | const struct scache wt_nomsr_noirq = { | 600 | static 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 @@ | |||
24 | static u32 early_console_initialized; | 24 | static u32 early_console_initialized; |
25 | static u32 base_addr; | 25 | static u32 base_addr; |
26 | 26 | ||
27 | static void early_printk_putc(char c) | 27 | #ifdef CONFIG_SERIAL_UARTLITE_CONSOLE |
28 | static 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 | ||
48 | static void early_printk_write(struct console *unused, | 49 | static 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 | ||
59 | static struct console early_serial_console = { | 60 | static 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 | ||
66 | static struct console *early_console = &early_serial_console; | 68 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
69 | static 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 | |||
93 | static 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 | |||
104 | static 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 | |||
112 | static struct console *early_console; | ||
67 | 113 | ||
68 | void early_printk(const char *fmt, ...) | 114 | void 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 | ||
103 | void __init disable_early_printk(void) | 172 | void __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 */ |
289 | 1: | 289 | 1: |
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 |
41 | syscall_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 @@ | |||
172 | 1: | 175 | 1: |
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; \ |
254 | 1: /* User-mode state save. */ \ | 261 | 1: /* 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; \ |
269 | 2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); | 276 | 2: 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 | */ |
285 | C_ENTRY(_user_exception): | 292 | C_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. */ | ||
313 | 1: | ||
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)); | 330 | 2: 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; |
335 | 4: | 363 | 4: |
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 */ |
368 | C_ENTRY(ret_from_trap): | 400 | C_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 |
382 | 1: | 417 | 1: |
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. */ | ||
452 | 2: 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); | ||
458 | 6: | ||
414 | TRAP_return: /* Make global symbol for debugging */ | 459 | TRAP_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 | ||
422 | C_ENTRY(sys_fork_wrapper): | 467 | C_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 | ||
443 | C_ENTRY(sys_vfork): | 488 | C_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 | ||
447 | C_ENTRY(sys_clone): | 492 | C_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 */ |
450 | 1: addik r7, r1, PTO; /* Arg 2: parent context */ | 495 | 1: 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 | ||
456 | C_ENTRY(sys_execve): | 501 | C_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 | ||
460 | C_ENTRY(sys_rt_sigreturn_wrapper): | 505 | C_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): | |||
542 | C_ENTRY(page_fault_data_trap): | 581 | C_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 | ||
554 | C_ENTRY(page_fault_instr_trap): | 593 | C_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. */ |
567 | C_ENTRY(ret_from_exc): | 606 | C_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); |
624 | 6: | 663 | 6: |
@@ -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 */ |
658 | 1: | 697 | 1: |
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; |
674 | 2: | 713 | 2: |
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; |
678 | irq_call:rtbd r0, do_IRQ; | 717 | irq_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 */ |
682 | ret_from_irq: | 721 | ret_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); |
742 | 6: | 781 | 6: |
743 | IRQ_return: /* MS: Make global symbol for debugging */ | 782 | IRQ_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; |
815 | dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */ | 850 | dbtrap_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 */ |
855 | DBTRAP_return_user: /* MS: Make global symbol for debugging */ | 888 | DBTRAP_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); |
869 | DBTRAP_return_kernel: /* MS: Make global symbol for debugging */ | 901 | DBTRAP_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 | ||
958 | ENTRY(_reset) | 990 | ENTRY(_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 */ |
52 | void sw_exception(struct pt_regs *regs) | 53 | asmlinkage 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 | ||
57 | void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) | 60 | void _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 |
45 | empty_zero_page: | 45 | empty_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 | ||
55 | endian_check: | ||
56 | .word 1 | ||
57 | |||
53 | __HEAD | 58 | __HEAD |
54 | ENTRY(_start) | 59 | ENTRY(_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 */ | ||
91 | big_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 | ||
234 | pt_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 | ||
242 | exception_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; |
901 | load1: lbui r5, r4, 0; /* Exception address in r4 - delay slot */ | 913 | load1: 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; |
905 | load2: lbui r5, r4, 1; | 917 | load2: lbui r5, r4, 1; |
906 | sbi r5, r6, 1; | 918 | sbi r5, r6, 1; |
@@ -914,7 +926,7 @@ load4: lbui r5, r4, 3; | |||
914 | ex_lhw_vm: | 926 | ex_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; |
919 | load5: lbui r5, r4, 1; | 931 | load5: 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; |
932 | ex_sw_tail_vm: | 944 | ex_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; | |||
945 | store4: sbi r3, r4, 3; /* Delay slot */ | 957 | store4: sbi r3, r4, 3; /* Delay slot */ |
946 | ex_shw_vm: | 958 | ex_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; | ||
962 | store5: sbi r3, r4, 0; | ||
963 | lbui r3, r5, 1; | ||
964 | brid ret_from_exc; | ||
965 | store6: sbi r3, r4, 1; /* Delay slot */ | ||
966 | #else | ||
948 | lbui r3, r5, 2; | 967 | lbui r3, r5, 2; |
949 | store5: sbi r3, r4, 0; | 968 | store5: sbi r3, r4, 0; |
950 | lbui r3, r5, 3; | 969 | lbui r3, r5, 3; |
951 | brid ret_from_exc; | 970 | brid ret_from_exc; |
952 | store6: sbi r3, r4, 1; /* Delay slot */ | 971 | store6: sbi r3, r4, 1; /* Delay slot */ |
972 | #endif | ||
973 | |||
953 | ex_sw_end_vm: /* Exception handling of store word, ends. */ | 974 | ex_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 | ||
43 | static void intc_enable_or_unmask(unsigned int irq) | 43 | static 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 | ||
57 | static void intc_disable_or_mask(unsigned int irq) | 57 | static 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 | ||
63 | static void intc_ack(unsigned int irq) | 63 | static 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 | ||
69 | static void intc_mask_ack(unsigned int irq) | 69 | static 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 | ||
77 | static 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 | |||
89 | static struct irq_chip intc_dev = { | 77 | static 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 | ||
98 | unsigned int get_irq(struct pt_regs *regs) | 85 | unsigned 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 | ||
50 | int 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'); | ||
84 | skip: | ||
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 */ |
92 | unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq) | 52 | unsigned 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) | |||
80 | void microblaze_kgdb_break(struct pt_regs *regs) | 80 | void 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 | */ |
145 | struct kgdb_arch arch_kgdb_ops = { | 144 | struct 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 | */ | ||
29 | extern void __ashldi3(void); | ||
30 | EXPORT_SYMBOL(__ashldi3); | ||
31 | extern void __ashrdi3(void); | ||
32 | EXPORT_SYMBOL(__ashrdi3); | ||
33 | extern void __divsi3(void); | ||
34 | EXPORT_SYMBOL(__divsi3); | ||
35 | extern void __lshrdi3(void); | ||
36 | EXPORT_SYMBOL(__lshrdi3); | ||
37 | extern void __modsi3(void); | ||
38 | EXPORT_SYMBOL(__modsi3); | ||
39 | extern void __mulsi3(void); | ||
40 | EXPORT_SYMBOL(__mulsi3); | ||
41 | extern void __muldi3(void); | ||
42 | EXPORT_SYMBOL(__muldi3); | ||
43 | extern void __ucmpdi2(void); | ||
44 | EXPORT_SYMBOL(__ucmpdi2); | ||
45 | extern void __udivsi3(void); | ||
46 | EXPORT_SYMBOL(__udivsi3); | ||
47 | extern void __umodsi3(void); | ||
48 | EXPORT_SYMBOL(__umodsi3); | ||
49 | extern char *_ebss; | 25 | extern char *_ebss; |
50 | EXPORT_SYMBOL_GPL(_ebss); | 26 | EXPORT_SYMBOL_GPL(_ebss); |
27 | |||
51 | #ifdef CONFIG_FUNCTION_TRACER | 28 | #ifdef CONFIG_FUNCTION_TRACER |
52 | extern void _mcount(void); | 29 | extern void _mcount(void); |
53 | EXPORT_SYMBOL(_mcount); | 30 | EXPORT_SYMBOL(_mcount); |
@@ -63,3 +40,20 @@ EXPORT_SYMBOL(__strncpy_user); | |||
63 | EXPORT_SYMBOL(memcpy); | 40 | EXPORT_SYMBOL(memcpy); |
64 | EXPORT_SYMBOL(memmove); | 41 | EXPORT_SYMBOL(memmove); |
65 | #endif | 42 | #endif |
43 | |||
44 | #ifdef CONFIG_MMU | ||
45 | EXPORT_SYMBOL(empty_zero_page); | ||
46 | #endif | ||
47 | |||
48 | EXPORT_SYMBOL(mbc); | ||
49 | |||
50 | extern void __divsi3(void); | ||
51 | EXPORT_SYMBOL(__divsi3); | ||
52 | extern void __modsi3(void); | ||
53 | EXPORT_SYMBOL(__modsi3); | ||
54 | extern void __mulsi3(void); | ||
55 | EXPORT_SYMBOL(__mulsi3); | ||
56 | extern void __udivsi3(void); | ||
57 | EXPORT_SYMBOL(__udivsi3); | ||
58 | extern void __umodsi3(void); | ||
59 | EXPORT_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 | ||
45 | void __init early_init_dt_scan_chosen_arch(unsigned long node) | ||
46 | { | ||
47 | /* No Microblaze specific code here */ | ||
48 | } | ||
49 | |||
50 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) | 45 | void __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 | ||
55 | u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | 50 | void * __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 */ | ||
88 | static 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 */ | ||
116 | int __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 | ||
94 | void __init early_init_devtree(void *params) | 122 | void __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 | ||
14 | int 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 | } | ||
85 | EXPORT_SYMBOL_GPL(of_irq_map_pci); | ||
86 | #endif /* CONFIG_PCI */ | ||
87 | 10 | ||
88 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | 11 | void 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 | */ | ||
132 | const 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 | } | ||
150 | EXPORT_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 | ||
76 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 77 | long 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 | |||
101 | void __init machine_early_init(const char *cmdline, unsigned int ram, | 95 | void __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, | |||
93 | asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) | 93 | asmlinkage 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 | ||
43 | asmlinkage long microblaze_clone(int flags, unsigned long stack, struct pt_regs *regs) | 43 | asmlinkage 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 | ||
41 | static unsigned int freq_div_hz; | ||
42 | static 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 = { | |||
168 | static __init void microblaze_clockevent_init(void) | 171 | static __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 | ||
202 | int __init init_microblaze_timecounter(void) | 205 | static 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(µblaze_tc, µblaze_cc, sched_clock()); | 210 | timecounter_init(µblaze_tc, µblaze_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 | ||
221 | static int __init microblaze_clocksource_init(void) | 223 | static 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 | */ |
186 | void microblaze_unwind_inner(struct task_struct *task, | 186 | static 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 | ||
11 | OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze") | ||
12 | OUTPUT_ARCH(microblaze) | 11 | OUTPUT_ARCH(microblaze) |
13 | ENTRY(microblaze_start) | 12 | ENTRY(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__ | ||
19 | jiffies = jiffies_64; | ||
20 | #else | ||
19 | jiffies = jiffies_64 + 4; | 21 | jiffies = jiffies_64 + 4; |
22 | #endif | ||
20 | 23 | ||
21 | SECTIONS { | 24 | SECTIONS { |
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 | ||
5 | ifdef CONFIG_FUNCTION_TRACER | ||
6 | CFLAGS_REMOVE_ashldi3.o = -pg | ||
7 | CFLAGS_REMOVE_ashrdi3.o = -pg | ||
8 | CFLAGS_REMOVE_lshrdi3.o = -pg | ||
9 | endif | ||
10 | |||
5 | lib-y := memset.o | 11 | lib-y := memset.o |
6 | 12 | ||
7 | ifeq ($(CONFIG_OPT_LIB_ASM),y) | 13 | ifeq ($(CONFIG_OPT_LIB_ASM),y) |
@@ -11,3 +17,13 @@ lib-y += memcpy.o memmove.o | |||
11 | endif | 17 | endif |
12 | 18 | ||
13 | lib-y += uaccess_old.o | 19 | lib-y += uaccess_old.o |
20 | |||
21 | lib-y += ashldi3.o | ||
22 | lib-y += ashrdi3.o | ||
23 | lib-y += divsi3.o | ||
24 | lib-y += lshrdi3.o | ||
25 | lib-y += modsi3.o | ||
26 | lib-y += muldi3.o | ||
27 | lib-y += mulsi3.o | ||
28 | lib-y += udivsi3.o | ||
29 | lib-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 | |||
5 | long 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 | |||
29 | EXPORT_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 | |||
5 | long 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 | |||
31 | EXPORT_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 */ | ||
27 | r5_pos: | ||
28 | bgei r6, r6_pos | ||
29 | rsubi r6, r6, 0 /* make r6 positive */ | ||
30 | r6_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 */ | ||
36 | div0: | ||
37 | blti r5, div2 /* this traps r5 == 0x80000000 */ | ||
38 | div1: | ||
39 | add r5, r5, r5 /* left shift logical r5 */ | ||
40 | bgtid r5, div1 | ||
41 | addik r29, r29, -1 | ||
42 | div2: | ||
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 | ||
51 | mod_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 */ | ||
56 | loop_end: | ||
57 | bgei r28, return_here | ||
58 | brid return_here | ||
59 | rsubi r3, r3, 0 /* negate the result */ | ||
60 | div_by_zero: | ||
61 | result_is_zero: | ||
62 | or r3, r0, r0 /* set result to 0 */ | ||
63 | return_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 | |||
6 | typedef int word_type __attribute__ ((mode (__word__))); | ||
7 | |||
8 | #ifdef __BIG_ENDIAN | ||
9 | struct DWstruct { | ||
10 | int high, low; | ||
11 | }; | ||
12 | #elif defined(__LITTLE_ENDIAN) | ||
13 | struct DWstruct { | ||
14 | int low, high; | ||
15 | }; | ||
16 | #else | ||
17 | #error I feel sick. | ||
18 | #endif | ||
19 | |||
20 | typedef 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 | |||
5 | long 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 | |||
29 | EXPORT_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 | ||
36 | void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c) | 37 | void *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 */ | ||
49 | void *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 */ | ||
155 | EXPORT_SYMBOL(memcpy); | 189 | EXPORT_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 | ||
34 | void *memmove(void *v_dst, const void *v_src, __kernel_size_t c) | 35 | void *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 */ | ||
58 | void *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 */ | ||
174 | EXPORT_SYMBOL(memmove); | 211 | EXPORT_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 | ||
35 | void *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 */ | ||
34 | void *memset(void *v_src, int c, __kernel_size_t n) | 49 | void *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 */ | ||
82 | EXPORT_SYMBOL(memset); | 96 | EXPORT_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 */ | ||
30 | r5_pos: | ||
31 | bgei r6, r6_pos | ||
32 | rsubi r6, r6, 0 /* make r6 positive */ | ||
33 | r6_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 */ | ||
38 | div1: | ||
39 | add r5, r5, r5 /* left shift logical r5 */ | ||
40 | bgeid r5, div1 | ||
41 | addik r29, r29, -1 | ||
42 | div2: | ||
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 | ||
51 | mod_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 */ | ||
56 | loop_end: | ||
57 | bgei r28, return_here | ||
58 | brid return_here | ||
59 | rsubi r3, r3, 0 /* negate the result */ | ||
60 | div_by_zero: | ||
61 | result_is_zero: | ||
62 | or r3, r0, r0 /* set result to 0 [both mod as well as div are 0] */ | ||
63 | return_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 | |||
50 | DWtype __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 | } | ||
61 | EXPORT_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 */ | ||
22 | r5_pos: | ||
23 | bgei r6, r6_pos | ||
24 | rsubi r6, r6, 0 /* make r6 positive */ | ||
25 | r6_pos: | ||
26 | bri l1 | ||
27 | l2: | ||
28 | add r5, r5, r5 | ||
29 | l1: | ||
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 | ||
38 | negateresult: | ||
39 | rtsd r15, 8 | ||
40 | rsub r3, r3, r0 | ||
41 | result_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 */ | ||
44 | checkr6: | ||
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 */ | ||
50 | div0: | ||
51 | blti r5, div2 | ||
52 | div1: | ||
53 | add r5, r5, r5 /* left shift logical r5 */ | ||
54 | bgtid r5, div1 | ||
55 | addik r29, r29, -1 | ||
56 | div2: | ||
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 | ||
65 | mod_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 */ | ||
70 | loop_end: | ||
71 | bri return_here | ||
72 | div_by_zero: | ||
73 | result_is_zero: | ||
74 | or r3, r0, r0 /* set result to 0 */ | ||
75 | return_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 */ | ||
52 | div0: | ||
53 | blti r5, div2 | ||
54 | div1: | ||
55 | add r5, r5, r5 /* left shift logical r5 */ | ||
56 | bgeid r5, div1 | ||
57 | addik r29, r29, -1 | ||
58 | div2: | ||
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 | ||
67 | mod_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 */ | ||
72 | loop_end: | ||
73 | bri return_here | ||
74 | div_by_zero: | ||
75 | result_is_zero: | ||
76 | or r3, r0, r0 /* set result to 0 */ | ||
77 | return_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 | */ |
62 | void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) | 62 | void *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; | |||
32 | EXPORT_SYMBOL(__page_offset); | 32 | EXPORT_SYMBOL(__page_offset); |
33 | 33 | ||
34 | #else | 34 | #else |
35 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | ||
36 | |||
37 | static int init_bootmem_done; | 35 | static 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 | ||
71 | void __init setup_memory(void) | 69 | void __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 | } |
61 | EXPORT_SYMBOL(get_pci_dma_ops); | 62 | EXPORT_SYMBOL(get_pci_dma_ops); |
62 | 63 | ||
63 | int pci_set_dma_mask(struct pci_dev *dev, u64 mask) | ||
64 | { | ||
65 | return dma_set_mask(&dev->dev, mask); | ||
66 | } | ||
67 | |||
68 | int 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 | |||
78 | struct pci_controller *pcibios_alloc_controller(struct device_node *dev) | 64 | struct 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 | ||
31 | config XILINX_MICROBLAZE0_FAMILY | 31 | config XILINX_MICROBLAZE0_FAMILY |
32 | string "Targetted FPGA family" | 32 | string "Targeted FPGA family" |
33 | default "virtex5" | 33 | default "virtex5" |
34 | 34 | ||
35 | config XILINX_MICROBLAZE0_USE_MSR_INSTR | 35 | config 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 | ||
18 | static struct of_device_id xilinx_of_bus_ids[] __initdata = { | 18 | static 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 | }; |