aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze')
-rw-r--r--arch/microblaze/Kconfig17
-rw-r--r--arch/microblaze/Kconfig.debug2
-rw-r--r--arch/microblaze/Makefile11
-rw-r--r--arch/microblaze/include/asm/byteorder.h4
-rw-r--r--arch/microblaze/include/asm/checksum.h9
-rw-r--r--arch/microblaze/include/asm/cpuinfo.h5
-rw-r--r--arch/microblaze/include/asm/elf.h2
-rw-r--r--arch/microblaze/include/asm/gpio.h5
-rw-r--r--arch/microblaze/include/asm/io.h2
-rw-r--r--arch/microblaze/include/asm/page.h3
-rw-r--r--arch/microblaze/include/asm/pci.h2
-rw-r--r--arch/microblaze/include/asm/pgalloc.h3
-rw-r--r--arch/microblaze/include/asm/pgtable.h7
-rw-r--r--arch/microblaze/include/asm/prom.h1
-rw-r--r--arch/microblaze/include/asm/pvr.h14
-rw-r--r--arch/microblaze/include/asm/seccomp.h16
-rw-r--r--arch/microblaze/include/asm/setup.h6
-rw-r--r--arch/microblaze/include/asm/thread_info.h20
-rw-r--r--arch/microblaze/include/asm/unaligned.h12
-rw-r--r--arch/microblaze/include/asm/unistd.h5
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c1
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-static.c1
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo.c2
-rw-r--r--arch/microblaze/kernel/cpu/mb.c3
-rw-r--r--arch/microblaze/kernel/cpu/pvr.c2
-rw-r--r--arch/microblaze/kernel/early_printk.c87
-rw-r--r--arch/microblaze/kernel/entry.S21
-rw-r--r--arch/microblaze/kernel/exceptions.c25
-rw-r--r--arch/microblaze/kernel/heartbeat.c11
-rw-r--r--arch/microblaze/kernel/intc.c14
-rw-r--r--arch/microblaze/kernel/kgdb.c7
-rw-r--r--arch/microblaze/kernel/microblaze_ksyms.c32
-rw-r--r--arch/microblaze/kernel/prom.c39
-rw-r--r--arch/microblaze/kernel/setup.c6
-rw-r--r--arch/microblaze/kernel/syscall_table.S3
-rw-r--r--arch/microblaze/kernel/timer.c41
-rw-r--r--arch/microblaze/kernel/vmlinux.lds.S5
-rw-r--r--arch/microblaze/lib/Makefile10
-rw-r--r--arch/microblaze/lib/ashldi3.c29
-rw-r--r--arch/microblaze/lib/ashrdi3.c31
-rw-r--r--arch/microblaze/lib/divsi3.S73
-rw-r--r--arch/microblaze/lib/libgcc.h25
-rw-r--r--arch/microblaze/lib/lshrdi3.c29
-rw-r--r--arch/microblaze/lib/memcpy.c46
-rw-r--r--arch/microblaze/lib/memmove.c59
-rw-r--r--arch/microblaze/lib/memset.c22
-rw-r--r--arch/microblaze/lib/modsi3.S73
-rw-r--r--arch/microblaze/lib/muldi3.S121
-rw-r--r--arch/microblaze/lib/mulsi3.S46
-rw-r--r--arch/microblaze/lib/udivsi3.S84
-rw-r--r--arch/microblaze/lib/umodsi3.S86
-rw-r--r--arch/microblaze/pci/pci-common.c21
-rw-r--r--arch/microblaze/platform/generic/system.dts3
-rw-r--r--arch/microblaze/platform/platform.c3
54 files changed, 1016 insertions, 191 deletions
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 692fdfce2a23..dad40fc2bef8 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -121,6 +121,23 @@ config CMDLINE_FORCE
121 Set this to have arguments from the default kernel command string 121 Set this to have arguments from the default kernel command string
122 override those passed by the boot loader. 122 override those passed by the boot loader.
123 123
124config SECCOMP
125 bool "Enable seccomp to safely compute untrusted bytecode"
126 depends on PROC_FS
127 default y
128 help
129 This kernel feature is useful for number crunching applications
130 that may need to compute untrusted bytecode during their
131 execution. By using pipes or other transports made available to
132 the process as file descriptors supporting the read/write
133 syscalls, it's possible to isolate those applications in
134 their own address space using seccomp. Once seccomp is
135 enabled via /proc/<pid>/seccomp, it cannot be disabled
136 and the task is only allowed to execute a few safe syscalls
137 defined by each seccomp mode.
138
139 If unsure, say Y. Only embedded should say N here.
140
124endmenu 141endmenu
125 142
126menu "Advanced setup" 143menu "Advanced setup"
diff --git a/arch/microblaze/Kconfig.debug b/arch/microblaze/Kconfig.debug
index e6e5e0da28c3..e66e25c4b0b2 100644
--- a/arch/microblaze/Kconfig.debug
+++ b/arch/microblaze/Kconfig.debug
@@ -10,7 +10,7 @@ source "lib/Kconfig.debug"
10 10
11config EARLY_PRINTK 11config EARLY_PRINTK
12 bool "Early printk function for kernel" 12 bool "Early printk function for kernel"
13 depends on SERIAL_UARTLITE_CONSOLE 13 depends on SERIAL_UARTLITE_CONSOLE || SERIAL_8250_CONSOLE
14 default n 14 default n
15 help 15 help
16 This option turns on/off early printk messages to console. 16 This option turns on/off early printk messages to console.
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile
index 592c7079de88..15f1f1d1840d 100644
--- a/arch/microblaze/Makefile
+++ b/arch/microblaze/Makefile
@@ -42,11 +42,8 @@ KBUILD_CFLAGS += -ffixed-r31 $(CPUFLAGS-1) $(CPUFLAGS-2)
42LDFLAGS := 42LDFLAGS :=
43LDFLAGS_vmlinux := 43LDFLAGS_vmlinux :=
44 44
45LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
46
47head-y := arch/microblaze/kernel/head.o 45head-y := arch/microblaze/kernel/head.o
48libs-y += arch/microblaze/lib/ 46libs-y += arch/microblaze/lib/
49libs-y += $(LIBGCC)
50core-y += arch/microblaze/kernel/ 47core-y += arch/microblaze/kernel/
51core-y += arch/microblaze/mm/ 48core-y += arch/microblaze/mm/
52core-y += arch/microblaze/platform/ 49core-y += arch/microblaze/platform/
@@ -72,12 +69,16 @@ export MMU DTB
72 69
73all: linux.bin 70all: linux.bin
74 71
75BOOT_TARGETS = linux.bin linux.bin.gz simpleImage.% 72# With make 3.82 we cannot mix normal and wildcard targets
73BOOT_TARGETS1 = linux.bin linux.bin.gz
74BOOT_TARGETS2 = simpleImage.%
76 75
77archclean: 76archclean:
78 $(Q)$(MAKE) $(clean)=$(boot) 77 $(Q)$(MAKE) $(clean)=$(boot)
79 78
80$(BOOT_TARGETS): vmlinux 79$(BOOT_TARGETS1): vmlinux
80 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
81$(BOOT_TARGETS2): vmlinux
81 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ 82 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
82 83
83define archhelp 84define archhelp
diff --git a/arch/microblaze/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/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..cd257537ae54 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;
@@ -97,7 +97,8 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu);
97static inline unsigned int fcpu(struct device_node *cpu, char *n) 97static inline unsigned int fcpu(struct device_node *cpu, char *n)
98{ 98{
99 int *val; 99 int *val;
100 return (val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0; 100 return (val = (int *) 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/gpio.h b/arch/microblaze/include/asm/gpio.h
index 2345ac354d9b..2b2c18be71c6 100644
--- a/arch/microblaze/include/asm/gpio.h
+++ b/arch/microblaze/include/asm/gpio.h
@@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio)
38 return __gpio_cansleep(gpio); 38 return __gpio_cansleep(gpio);
39} 39}
40 40
41/*
42 * Not implemented, yet.
43 */
44static inline int gpio_to_irq(unsigned int gpio) 41static inline int gpio_to_irq(unsigned int gpio)
45{ 42{
46 return -ENOSYS; 43 return __gpio_to_irq(gpio);
47} 44}
48 45
49static inline int irq_to_gpio(unsigned int irq) 46static inline int irq_to_gpio(unsigned int irq)
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h
index 00b5398d08c7..eae32220f447 100644
--- a/arch/microblaze/include/asm/io.h
+++ b/arch/microblaze/include/asm/io.h
@@ -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/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.h b/arch/microblaze/include/asm/pci.h
index 5a388eeeb28f..2232ff942ba9 100644
--- a/arch/microblaze/include/asm/pci.h
+++ b/arch/microblaze/include/asm/pci.h
@@ -165,5 +165,7 @@ extern void __init xilinx_pci_init(void);
165static inline void __init xilinx_pci_init(void) { return; } 165static inline void __init xilinx_pci_init(void) { return; }
166#endif 166#endif
167 167
168#include <asm-generic/pci-dma-compat.h>
169
168#endif /* __KERNEL__ */ 170#endif /* __KERNEL__ */
169#endif /* __ASM_MICROBLAZE_PCI_H */ 171#endif /* __ASM_MICROBLAZE_PCI_H */
diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h
index c614a893f8a3..ebd35792482c 100644
--- a/arch/microblaze/include/asm/pgalloc.h
+++ b/arch/microblaze/include/asm/pgalloc.h
@@ -165,7 +165,8 @@ extern inline void pte_free(struct mm_struct *mm, struct page *ptepage)
165 165
166#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, (pte)) 166#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, (pte))
167 167
168#define pmd_populate(mm, pmd, pte) (pmd_val(*(pmd)) = page_address(pte)) 168#define pmd_populate(mm, pmd, pte) \
169 (pmd_val(*(pmd)) = (unsigned long)page_address(pte))
169 170
170#define pmd_populate_kernel(mm, pmd, pte) \ 171#define pmd_populate_kernel(mm, pmd, pte) \
171 (pmd_val(*(pmd)) = (unsigned long) (pte)) 172 (pmd_val(*(pmd)) = (unsigned long) (pte))
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h
index ca2d92871545..d4f421672d3b 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>
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index 101fa098f62a..bdc38312ae4a 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -27,6 +27,7 @@
27 27
28/* Other Prototypes */ 28/* Other Prototypes */
29extern int early_uartlite_console(void); 29extern int early_uartlite_console(void);
30extern int early_uart16550_console(void);
30 31
31#ifdef CONFIG_PCI 32#ifdef CONFIG_PCI
32/* 33/*
diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h
index 9578666e98ba..37db96a15b45 100644
--- a/arch/microblaze/include/asm/pvr.h
+++ b/arch/microblaze/include/asm/pvr.h
@@ -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,9 +40,9 @@ 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
@@ -63,8 +65,8 @@ struct pvr_s {
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
@@ -208,6 +210,8 @@ struct pvr_s {
208#define PVR_MMU_TLB_ACCESS(pvr) (pvr.pvr[11] & PVR11_MMU_TLB_ACCESS) 210#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) 211#define PVR_MMU_ZONES(pvr) (pvr.pvr[11] & PVR11_MMU_ZONES)
210 212
213/* endian */
214#define PVR_ENDIAN(pvr) (pvr.pvr[0] & PVR0_ENDI)
211 215
212int cpu_has_pvr(void); 216int cpu_has_pvr(void);
213void get_pvr(struct pvr_s *pvr); 217void get_pvr(struct pvr_s *pvr);
diff --git a/arch/microblaze/include/asm/seccomp.h b/arch/microblaze/include/asm/seccomp.h
new file mode 100644
index 000000000000..0d912758a0d7
--- /dev/null
+++ b/arch/microblaze/include/asm/seccomp.h
@@ -0,0 +1,16 @@
1#ifndef _ASM_MICROBLAZE_SECCOMP_H
2#define _ASM_MICROBLAZE_SECCOMP_H
3
4#include <linux/unistd.h>
5
6#define __NR_seccomp_read __NR_read
7#define __NR_seccomp_write __NR_write
8#define __NR_seccomp_exit __NR_exit
9#define __NR_seccomp_sigreturn __NR_sigreturn
10
11#define __NR_seccomp_read_32 __NR_read
12#define __NR_seccomp_write_32 __NR_write
13#define __NR_seccomp_exit_32 __NR_exit
14#define __NR_seccomp_sigreturn_32 __NR_sigreturn
15
16#endif /* _ASM_MICROBLAZE_SECCOMP_H */
diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h
index 782b5c89248e..8f3968971e4e 100644
--- a/arch/microblaze/include/asm/setup.h
+++ b/arch/microblaze/include/asm/setup.h
@@ -25,6 +25,12 @@ void early_printk(const char *fmt, ...);
25int setup_early_printk(char *opt); 25int setup_early_printk(char *opt);
26void disable_early_printk(void); 26void disable_early_printk(void);
27 27
28#if defined(CONFIG_EARLY_PRINTK)
29#define eprintk early_printk
30#else
31#define eprintk printk
32#endif
33
28void heartbeat(void); 34void heartbeat(void);
29void setup_heartbeat(void); 35void setup_heartbeat(void);
30 36
diff --git a/arch/microblaze/include/asm/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/unaligned.h b/arch/microblaze/include/asm/unaligned.h
index 3658d91ac0fb..2b97cbe500e9 100644
--- a/arch/microblaze/include/asm/unaligned.h
+++ b/arch/microblaze/include/asm/unaligned.h
@@ -12,12 +12,18 @@
12 12
13# ifdef __KERNEL__ 13# ifdef __KERNEL__
14 14
15# include <linux/unaligned/be_struct.h> 15# include <linux/unaligned/be_byteshift.h>
16# include <linux/unaligned/le_byteshift.h> 16# include <linux/unaligned/le_byteshift.h>
17# include <linux/unaligned/generic.h> 17# include <linux/unaligned/generic.h>
18 18
19# define get_unaligned __get_unaligned_be 19
20# define put_unaligned __put_unaligned_be 20# ifdef __MICROBLAZEEL__
21# define get_unaligned __get_unaligned_le
22# define put_unaligned __put_unaligned_le
23# else
24# define get_unaligned __get_unaligned_be
25# define put_unaligned __put_unaligned_be
26# endif
21 27
22# endif /* __KERNEL__ */ 28# endif /* __KERNEL__ */
23#endif /* _ASM_MICROBLAZE_UNALIGNED_H */ 29#endif /* _ASM_MICROBLAZE_UNALIGNED_H */
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h
index 2b67e92a773c..d770b00ec6b1 100644
--- a/arch/microblaze/include/asm/unistd.h
+++ b/arch/microblaze/include/asm/unistd.h
@@ -383,8 +383,11 @@
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
386 389
387#define __NR_syscalls 368 390#define __NR_syscalls 371
388 391
389#ifdef __KERNEL__ 392#ifdef __KERNEL__
390#ifndef __ASSEMBLY__ 393#ifndef __ASSEMBLY__
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..87c79fa275c3 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -30,6 +30,8 @@ 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},
33 {NULL, 0}, 35 {NULL, 0},
34}; 36};
35 37
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..e01afa68273e 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}
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c
index 7de84923ba07..c3616a080ebf 100644
--- a/arch/microblaze/kernel/early_printk.c
+++ b/arch/microblaze/kernel/early_printk.c
@@ -24,7 +24,8 @@
24static u32 early_console_initialized; 24static u32 early_console_initialized;
25static u32 base_addr; 25static u32 base_addr;
26 26
27static void early_printk_putc(char c) 27#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
28static void early_printk_uartlite_putc(char c)
28{ 29{
29 /* 30 /*
30 * Limit how many times we'll spin waiting for TX FIFO status. 31 * Limit how many times we'll spin waiting for TX FIFO status.
@@ -45,25 +46,70 @@ static void early_printk_putc(char c)
45 out_be32(base_addr + 4, c & 0xff); 46 out_be32(base_addr + 4, c & 0xff);
46} 47}
47 48
48static void early_printk_write(struct console *unused, 49static void early_printk_uartlite_write(struct console *unused,
49 const char *s, unsigned n) 50 const char *s, unsigned n)
50{ 51{
51 while (*s && n-- > 0) { 52 while (*s && n-- > 0) {
52 early_printk_putc(*s); 53 early_printk_uartlite_putc(*s);
53 if (*s == '\n') 54 if (*s == '\n')
54 early_printk_putc('\r'); 55 early_printk_uartlite_putc('\r');
55 s++; 56 s++;
56 } 57 }
57} 58}
58 59
59static struct console early_serial_console = { 60static struct console early_serial_uartlite_console = {
60 .name = "earlyser", 61 .name = "earlyser",
61 .write = early_printk_write, 62 .write = early_printk_uartlite_write,
62 .flags = CON_PRINTBUFFER, 63 .flags = CON_PRINTBUFFER,
63 .index = -1, 64 .index = -1,
64}; 65};
66#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
65 67
66static struct console *early_console = &early_serial_console; 68#ifdef CONFIG_SERIAL_8250_CONSOLE
69static void early_printk_uart16550_putc(char c)
70{
71 /*
72 * Limit how many times we'll spin waiting for TX FIFO status.
73 * This will prevent lockups if the base address is incorrectly
74 * set, or any other issue on the UARTLITE.
75 * This limit is pretty arbitrary, unless we are at about 10 baud
76 * we'll never timeout on a working UART.
77 */
78
79 #define UART_LSR_TEMT 0x40 /* Transmitter empty */
80 #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
81 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
82
83 unsigned retries = 10000;
84
85 while (--retries &&
86 !((in_be32(base_addr + 0x14) & BOTH_EMPTY) == BOTH_EMPTY))
87 ;
88
89 if (retries)
90 out_be32(base_addr, c & 0xff);
91}
92
93static void early_printk_uart16550_write(struct console *unused,
94 const char *s, unsigned n)
95{
96 while (*s && n-- > 0) {
97 early_printk_uart16550_putc(*s);
98 if (*s == '\n')
99 early_printk_uart16550_putc('\r');
100 s++;
101 }
102}
103
104static struct console early_serial_uart16550_console = {
105 .name = "earlyser",
106 .write = early_printk_uart16550_write,
107 .flags = CON_PRINTBUFFER,
108 .index = -1,
109};
110#endif /* CONFIG_SERIAL_8250_CONSOLE */
111
112static struct console *early_console;
67 113
68void early_printk(const char *fmt, ...) 114void early_printk(const char *fmt, ...)
69{ 115{
@@ -84,20 +130,43 @@ int __init setup_early_printk(char *opt)
84 if (early_console_initialized) 130 if (early_console_initialized)
85 return 1; 131 return 1;
86 132
133#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
87 base_addr = early_uartlite_console(); 134 base_addr = early_uartlite_console();
88 if (base_addr) { 135 if (base_addr) {
89 early_console_initialized = 1; 136 early_console_initialized = 1;
90#ifdef CONFIG_MMU 137#ifdef CONFIG_MMU
91 early_console_reg_tlb_alloc(base_addr); 138 early_console_reg_tlb_alloc(base_addr);
92#endif 139#endif
140 early_console = &early_serial_uartlite_console;
93 early_printk("early_printk_console is enabled at 0x%08x\n", 141 early_printk("early_printk_console is enabled at 0x%08x\n",
94 base_addr); 142 base_addr);
95 143
96 /* register_console(early_console); */ 144 /* register_console(early_console); */
97 145
98 return 0; 146 return 0;
99 } else 147 }
100 return 1; 148#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
149
150#ifdef CONFIG_SERIAL_8250_CONSOLE
151 base_addr = early_uart16550_console();
152 base_addr &= ~3; /* clear register offset */
153 if (base_addr) {
154 early_console_initialized = 1;
155#ifdef CONFIG_MMU
156 early_console_reg_tlb_alloc(base_addr);
157#endif
158 early_console = &early_serial_uart16550_console;
159
160 early_printk("early_printk_console is enabled at 0x%08x\n",
161 base_addr);
162
163 /* register_console(early_console); */
164
165 return 0;
166 }
167#endif /* CONFIG_SERIAL_8250_CONSOLE */
168
169 return 1;
101} 170}
102 171
103void __init disable_early_printk(void) 172void __init disable_early_printk(void)
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 304882e56459..819238b8a429 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -186,6 +186,8 @@
186 swi r13, r1, PTO+PT_R13; /* Save SDA2 */ \ 186 swi r13, r1, PTO+PT_R13; /* Save SDA2 */ \
187 swi r14, r1, PTO+PT_PC; /* PC, before IRQ/trap */ \ 187 swi r14, r1, PTO+PT_PC; /* PC, before IRQ/trap */ \
188 swi r15, r1, PTO+PT_R15; /* Save LP */ \ 188 swi r15, r1, PTO+PT_R15; /* Save LP */ \
189 swi r16, r1, PTO+PT_R16; \
190 swi r17, r1, PTO+PT_R17; \
189 swi r18, r1, PTO+PT_R18; /* Save asm scratch reg */ \ 191 swi r18, r1, PTO+PT_R18; /* Save asm scratch reg */ \
190 swi r19, r1, PTO+PT_R19; \ 192 swi r19, r1, PTO+PT_R19; \
191 swi r20, r1, PTO+PT_R20; \ 193 swi r20, r1, PTO+PT_R20; \
@@ -220,6 +222,8 @@
220 lwi r13, r1, PTO+PT_R13; /* restore SDA2 */ \ 222 lwi r13, r1, PTO+PT_R13; /* restore SDA2 */ \
221 lwi r14, r1, PTO+PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\ 223 lwi r14, r1, PTO+PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\
222 lwi r15, r1, PTO+PT_R15; /* restore LP */ \ 224 lwi r15, r1, PTO+PT_R15; /* restore LP */ \
225 lwi r16, r1, PTO+PT_R16; \
226 lwi r17, r1, PTO+PT_R17; \
223 lwi r18, r1, PTO+PT_R18; /* restore asm scratch reg */ \ 227 lwi r18, r1, PTO+PT_R18; /* restore asm scratch reg */ \
224 lwi r19, r1, PTO+PT_R19; \ 228 lwi r19, r1, PTO+PT_R19; \
225 lwi r20, r1, PTO+PT_R20; \ 229 lwi r20, r1, PTO+PT_R20; \
@@ -295,6 +299,8 @@ C_ENTRY(_user_exception):
295 /* addik r1, r1, -STATE_SAVE_SIZE; */ 299 /* addik r1, r1, -STATE_SAVE_SIZE; */
296 addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; 300 addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE;
297 SAVE_REGS 301 SAVE_REGS
302 swi r0, r1, PTO + PT_R3
303 swi r0, r1, PTO + PT_R4
298 304
299 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 305 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
300 swi r11, r1, PTO+PT_R1; /* Store user SP. */ 306 swi r11, r1, PTO+PT_R1; /* Store user SP. */
@@ -458,14 +464,8 @@ C_ENTRY(sys_execve):
458 addik r8, r1, PTO; /* add user context as 4th arg */ 464 addik r8, r1, PTO; /* add user context as 4th arg */
459 465
460C_ENTRY(sys_rt_sigreturn_wrapper): 466C_ENTRY(sys_rt_sigreturn_wrapper):
461 swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ 467 brid sys_rt_sigreturn /* Do real work */
462 swi r4, r1, PTO+PT_R4;
463 brlid r15, sys_rt_sigreturn /* Do real work */
464 addik r5, r1, PTO; /* add user context as 1st arg */ 468 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 469
470/* 470/*
471 * HW EXCEPTION rutine start 471 * HW EXCEPTION rutine start
@@ -765,9 +765,7 @@ C_ENTRY(_debug_exception):
765 /* save all regs to pt_reg structure */ 765 /* save all regs to pt_reg structure */
766 swi r0, r1, PTO+PT_R0; /* R0 must be saved too */ 766 swi r0, r1, PTO+PT_R0; /* R0 must be saved too */
767 swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */ 767 swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */
768 swi r16, r1, PTO+PT_R16
769 swi r16, r1, PTO+PT_PC; /* PC and r16 are the same */ 768 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 */ 769 /* save special purpose registers to pt_regs */
772 mfs r11, rear; 770 mfs r11, rear;
773 swi r11, r1, PTO+PT_EAR; 771 swi r11, r1, PTO+PT_EAR;
@@ -801,8 +799,6 @@ C_ENTRY(_debug_exception):
801 799
802 addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ 800 addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */
803 SAVE_REGS; 801 SAVE_REGS;
804 swi r17, r1, PTO+PT_R17;
805 swi r16, r1, PTO+PT_R16;
806 swi r16, r1, PTO+PT_PC; /* Save LP */ 802 swi r16, r1, PTO+PT_PC; /* Save LP */
807 swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */ 803 swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */
808 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 804 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
@@ -848,8 +844,6 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
848 tophys(r1,r1); 844 tophys(r1,r1);
849 /* MS: Restore all regs */ 845 /* MS: Restore all regs */
850 RESTORE_REGS 846 RESTORE_REGS
851 lwi r17, r1, PTO+PT_R17;
852 lwi r16, r1, PTO+PT_R16;
853 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */ 847 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */
854 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */ 848 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
855DBTRAP_return_user: /* MS: Make global symbol for debugging */ 849DBTRAP_return_user: /* MS: Make global symbol for debugging */
@@ -863,7 +857,6 @@ DBTRAP_return_user: /* MS: Make global symbol for debugging */
863 RESTORE_REGS 857 RESTORE_REGS
864 lwi r14, r1, PTO+PT_R14; 858 lwi r14, r1, PTO+PT_R14;
865 lwi r16, r1, PTO+PT_PC; 859 lwi r16, r1, PTO+PT_PC;
866 lwi r17, r1, PTO+PT_R17;
867 addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */ 860 addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */
868 tovirt(r1,r1); 861 tovirt(r1,r1);
869DBTRAP_return_kernel: /* MS: Make global symbol for debugging */ 862DBTRAP_return_kernel: /* MS: Make global symbol for debugging */
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
index b98ee8d0c1cd..478f2943ede7 100644
--- a/arch/microblaze/kernel/exceptions.c
+++ b/arch/microblaze/kernel/exceptions.c
@@ -72,7 +72,6 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
72 int fsr, int addr) 72 int fsr, int addr)
73{ 73{
74#ifdef CONFIG_MMU 74#ifdef CONFIG_MMU
75 int code;
76 addr = regs->pc; 75 addr = regs->pc;
77#endif 76#endif
78 77
@@ -86,8 +85,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
86 switch (type & 0x1F) { 85 switch (type & 0x1F) {
87 case MICROBLAZE_ILL_OPCODE_EXCEPTION: 86 case MICROBLAZE_ILL_OPCODE_EXCEPTION:
88 if (user_mode(regs)) { 87 if (user_mode(regs)) {
89 pr_debug(KERN_WARNING "Illegal opcode exception " \ 88 pr_debug("Illegal opcode exception in user mode\n");
90 "in user mode.\n");
91 _exception(SIGILL, regs, ILL_ILLOPC, addr); 89 _exception(SIGILL, regs, ILL_ILLOPC, addr);
92 return; 90 return;
93 } 91 }
@@ -97,8 +95,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
97 break; 95 break;
98 case MICROBLAZE_IBUS_EXCEPTION: 96 case MICROBLAZE_IBUS_EXCEPTION:
99 if (user_mode(regs)) { 97 if (user_mode(regs)) {
100 pr_debug(KERN_WARNING "Instruction bus error " \ 98 pr_debug("Instruction bus error exception in user mode\n");
101 "exception in user mode.\n");
102 _exception(SIGBUS, regs, BUS_ADRERR, addr); 99 _exception(SIGBUS, regs, BUS_ADRERR, addr);
103 return; 100 return;
104 } 101 }
@@ -108,8 +105,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
108 break; 105 break;
109 case MICROBLAZE_DBUS_EXCEPTION: 106 case MICROBLAZE_DBUS_EXCEPTION:
110 if (user_mode(regs)) { 107 if (user_mode(regs)) {
111 pr_debug(KERN_WARNING "Data bus error exception " \ 108 pr_debug("Data bus error exception in user mode\n");
112 "in user mode.\n");
113 _exception(SIGBUS, regs, BUS_ADRERR, addr); 109 _exception(SIGBUS, regs, BUS_ADRERR, addr);
114 return; 110 return;
115 } 111 }
@@ -119,8 +115,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
119 break; 115 break;
120 case MICROBLAZE_DIV_ZERO_EXCEPTION: 116 case MICROBLAZE_DIV_ZERO_EXCEPTION:
121 if (user_mode(regs)) { 117 if (user_mode(regs)) {
122 pr_debug(KERN_WARNING "Divide by zero exception " \ 118 pr_debug("Divide by zero exception in user mode\n");
123 "in user mode\n");
124 _exception(SIGILL, regs, FPE_INTDIV, addr); 119 _exception(SIGILL, regs, FPE_INTDIV, addr);
125 return; 120 return;
126 } 121 }
@@ -129,7 +124,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
129 die("Divide by zero exception", regs, SIGBUS); 124 die("Divide by zero exception", regs, SIGBUS);
130 break; 125 break;
131 case MICROBLAZE_FPU_EXCEPTION: 126 case MICROBLAZE_FPU_EXCEPTION:
132 pr_debug(KERN_WARNING "FPU exception\n"); 127 pr_debug("FPU exception\n");
133 /* IEEE FP exception */ 128 /* IEEE FP exception */
134 /* I removed fsr variable and use code var for storing fsr */ 129 /* I removed fsr variable and use code var for storing fsr */
135 if (fsr & FSR_IO) 130 if (fsr & FSR_IO)
@@ -147,14 +142,8 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
147 142
148#ifdef CONFIG_MMU 143#ifdef CONFIG_MMU
149 case MICROBLAZE_PRIVILEGED_EXCEPTION: 144 case MICROBLAZE_PRIVILEGED_EXCEPTION:
150 pr_debug(KERN_WARNING "Privileged exception\n"); 145 pr_debug("Privileged exception\n");
151 /* "brk r0,r0" - used as debug breakpoint - old toolchain */ 146 _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; 147 break;
159#endif 148#endif
160 default: 149 default:
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/intc.c b/arch/microblaze/kernel/intc.c
index 03172c1da770..d61ea33aff7c 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -126,11 +126,8 @@ void __init init_IRQ(void)
126 0 126 0
127 }; 127 };
128#endif 128#endif
129 static char *intc_list[] = { 129 const char * const intc_list[] = {
130 "xlnx,xps-intc-1.00.a", 130 "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 131 NULL
135 }; 132 };
136 133
@@ -141,12 +138,15 @@ void __init init_IRQ(void)
141 } 138 }
142 BUG_ON(!intc); 139 BUG_ON(!intc);
143 140
144 intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL); 141 intc_baseaddr = be32_to_cpup(of_get_property(intc,
142 "reg", NULL));
145 intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE); 143 intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
146 nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL); 144 nr_irq = be32_to_cpup(of_get_property(intc,
145 "xlnx,num-intr-inputs", NULL));
147 146
148 intr_type = 147 intr_type =
149 *(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL); 148 be32_to_cpup(of_get_property(intc,
149 "xlnx,kind-of-intr", NULL));
150 if (intr_type >= (1 << (nr_irq + 1))) 150 if (intr_type >= (1 << (nr_irq + 1)))
151 printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n"); 151 printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");
152 152
diff --git a/arch/microblaze/kernel/kgdb.c b/arch/microblaze/kernel/kgdb.c
index bfc006b7f2d8..09a5e8286137 100644
--- a/arch/microblaze/kernel/kgdb.c
+++ b/arch/microblaze/kernel/kgdb.c
@@ -80,7 +80,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
80void microblaze_kgdb_break(struct pt_regs *regs) 80void microblaze_kgdb_break(struct pt_regs *regs)
81{ 81{
82 if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0) 82 if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0)
83 return 0; 83 return;
84 84
85 /* Jump over the first arch_kgdb_breakpoint which is barrier to 85 /* Jump over the first arch_kgdb_breakpoint which is barrier to
86 * get kgdb work. The same solution is used for powerpc */ 86 * get kgdb work. The same solution is used for powerpc */
@@ -114,7 +114,6 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
114{ 114{
115 char *ptr; 115 char *ptr;
116 unsigned long address; 116 unsigned long address;
117 int cpu = smp_processor_id();
118 117
119 switch (remcom_in_buffer[0]) { 118 switch (remcom_in_buffer[0]) {
120 case 'c': 119 case 'c':
@@ -143,5 +142,9 @@ void kgdb_arch_exit(void)
143 * Global data 142 * Global data
144 */ 143 */
145struct kgdb_arch arch_kgdb_ops = { 144struct kgdb_arch arch_kgdb_ops = {
145#ifdef __MICROBLAZEEL__
146 .gdb_bpt_instr = {0x18, 0x00, 0x0c, 0xba}, /* brki r16, 0x18 */
147#else
146 .gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */ 148 .gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */
149#endif
147}; 150};
diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c
index ff85f7718035..5cb034174005 100644
--- a/arch/microblaze/kernel/microblaze_ksyms.c
+++ b/arch/microblaze/kernel/microblaze_ksyms.c
@@ -15,37 +15,13 @@
15#include <linux/syscalls.h> 15#include <linux/syscalls.h>
16 16
17#include <asm/checksum.h> 17#include <asm/checksum.h>
18#include <asm/cacheflush.h>
18#include <linux/io.h> 19#include <linux/io.h>
19#include <asm/page.h> 20#include <asm/page.h>
20#include <asm/system.h> 21#include <asm/system.h>
21#include <linux/ftrace.h> 22#include <linux/ftrace.h>
22#include <linux/uaccess.h> 23#include <linux/uaccess.h>
23 24
24/*
25 * libgcc functions - functions that are used internally by the
26 * compiler... (prototypes are not correct though, but that
27 * doesn't really matter since they're not versioned).
28 */
29extern void __ashldi3(void);
30EXPORT_SYMBOL(__ashldi3);
31extern void __ashrdi3(void);
32EXPORT_SYMBOL(__ashrdi3);
33extern void __divsi3(void);
34EXPORT_SYMBOL(__divsi3);
35extern void __lshrdi3(void);
36EXPORT_SYMBOL(__lshrdi3);
37extern void __modsi3(void);
38EXPORT_SYMBOL(__modsi3);
39extern void __mulsi3(void);
40EXPORT_SYMBOL(__mulsi3);
41extern void __muldi3(void);
42EXPORT_SYMBOL(__muldi3);
43extern void __ucmpdi2(void);
44EXPORT_SYMBOL(__ucmpdi2);
45extern void __udivsi3(void);
46EXPORT_SYMBOL(__udivsi3);
47extern void __umodsi3(void);
48EXPORT_SYMBOL(__umodsi3);
49extern char *_ebss; 25extern char *_ebss;
50EXPORT_SYMBOL_GPL(_ebss); 26EXPORT_SYMBOL_GPL(_ebss);
51#ifdef CONFIG_FUNCTION_TRACER 27#ifdef CONFIG_FUNCTION_TRACER
@@ -63,3 +39,9 @@ EXPORT_SYMBOL(__strncpy_user);
63EXPORT_SYMBOL(memcpy); 39EXPORT_SYMBOL(memcpy);
64EXPORT_SYMBOL(memmove); 40EXPORT_SYMBOL(memmove);
65#endif 41#endif
42
43#ifdef CONFIG_MMU
44EXPORT_SYMBOL(empty_zero_page);
45#endif
46
47EXPORT_SYMBOL(mbc);
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index bacbd3d41ec7..a105301e2b7f 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -72,11 +72,12 @@ static int __init early_init_dt_scan_serial(unsigned long node,
72/* find compatible node with uartlite */ 72/* find compatible node with uartlite */
73 p = of_get_flat_dt_prop(node, "compatible", &l); 73 p = of_get_flat_dt_prop(node, "compatible", &l);
74 if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) && 74 if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
75 (strncmp(p, "xlnx,opb-uartlite", 17) != 0)) 75 (strncmp(p, "xlnx,opb-uartlite", 17) != 0) &&
76 (strncmp(p, "xlnx,axi-uartlite", 17) != 0))
76 return 0; 77 return 0;
77 78
78 addr = of_get_flat_dt_prop(node, "reg", &l); 79 addr = of_get_flat_dt_prop(node, "reg", &l);
79 return *addr; /* return address */ 80 return be32_to_cpup(addr); /* return address */
80} 81}
81 82
82/* this function is looking for early uartlite console - Microblaze specific */ 83/* this function is looking for early uartlite console - Microblaze specific */
@@ -84,6 +85,40 @@ int __init early_uartlite_console(void)
84{ 85{
85 return of_scan_flat_dt(early_init_dt_scan_serial, NULL); 86 return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
86} 87}
88
89/* MS this is Microblaze specifig function */
90static int __init early_init_dt_scan_serial_full(unsigned long node,
91 const char *uname, int depth, void *data)
92{
93 unsigned long l;
94 char *p;
95 unsigned int addr;
96
97 pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
98
99/* find all serial nodes */
100 if (strncmp(uname, "serial", 6) != 0)
101 return 0;
102
103 early_init_dt_check_for_initrd(node);
104
105/* find compatible node with uartlite */
106 p = of_get_flat_dt_prop(node, "compatible", &l);
107
108 if ((strncmp(p, "xlnx,xps-uart16550", 18) != 0) &&
109 (strncmp(p, "xlnx,axi-uart16550", 18) != 0))
110 return 0;
111
112 addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l);
113 addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l);
114 return be32_to_cpu(addr); /* return address */
115}
116
117/* this function is looking for early uartlite console - Microblaze specific */
118int __init early_uart16550_console(void)
119{
120 return of_scan_flat_dt(early_init_dt_scan_serial_full, NULL);
121}
87#endif 122#endif
88 123
89void __init early_init_devtree(void *params) 124void __init early_init_devtree(void *params)
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index f5f768842354..bb1558e4b283 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -92,12 +92,6 @@ inline unsigned get_romfs_len(unsigned *addr)
92} 92}
93#endif /* CONFIG_MTD_UCLINUX_EBSS */ 93#endif /* CONFIG_MTD_UCLINUX_EBSS */
94 94
95#if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE)
96#define eprintk early_printk
97#else
98#define eprintk printk
99#endif
100
101void __init machine_early_init(const char *cmdline, unsigned int ram, 95void __init machine_early_init(const char *cmdline, unsigned int ram,
102 unsigned int fdt, unsigned int msr) 96 unsigned int fdt, unsigned int msr)
103{ 97{
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index 03376dc814c9..e88a930fd1e3 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -372,3 +372,6 @@ 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 */
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index b1380ae93ae1..a5aa33db1df3 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
41unsigned int freq_div_hz;
42unsigned int timer_clock_freq;
43
41#define TCSR0 (0x00) 44#define TCSR0 (0x00)
42#define TLR0 (0x04) 45#define TLR0 (0x04)
43#define TCR0 (0x08) 46#define TCR0 (0x08)
@@ -115,7 +118,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode,
115 switch (mode) { 118 switch (mode) {
116 case CLOCK_EVT_MODE_PERIODIC: 119 case CLOCK_EVT_MODE_PERIODIC:
117 printk(KERN_INFO "%s: periodic\n", __func__); 120 printk(KERN_INFO "%s: periodic\n", __func__);
118 microblaze_timer0_start_periodic(cpuinfo.freq_div_hz); 121 microblaze_timer0_start_periodic(freq_div_hz);
119 break; 122 break;
120 case CLOCK_EVT_MODE_ONESHOT: 123 case CLOCK_EVT_MODE_ONESHOT:
121 printk(KERN_INFO "%s: oneshot\n", __func__); 124 printk(KERN_INFO "%s: oneshot\n", __func__);
@@ -168,7 +171,7 @@ static struct irqaction timer_irqaction = {
168static __init void microblaze_clockevent_init(void) 171static __init void microblaze_clockevent_init(void)
169{ 172{
170 clockevent_microblaze_timer.mult = 173 clockevent_microblaze_timer.mult =
171 div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, 174 div_sc(timer_clock_freq, NSEC_PER_SEC,
172 clockevent_microblaze_timer.shift); 175 clockevent_microblaze_timer.shift);
173 clockevent_microblaze_timer.max_delta_ns = 176 clockevent_microblaze_timer.max_delta_ns =
174 clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer); 177 clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
@@ -201,7 +204,7 @@ static struct cyclecounter microblaze_cc = {
201 204
202int __init init_microblaze_timecounter(void) 205int __init init_microblaze_timecounter(void)
203{ 206{
204 microblaze_cc.mult = div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, 207 microblaze_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
205 microblaze_cc.shift); 208 microblaze_cc.shift);
206 209
207 timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock()); 210 timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock());
@@ -221,7 +224,7 @@ static struct clocksource clocksource_microblaze = {
221static int __init microblaze_clocksource_init(void) 224static int __init microblaze_clocksource_init(void)
222{ 225{
223 clocksource_microblaze.mult = 226 clocksource_microblaze.mult =
224 clocksource_hz2mult(cpuinfo.cpu_clock_freq, 227 clocksource_hz2mult(timer_clock_freq,
225 clocksource_microblaze.shift); 228 clocksource_microblaze.shift);
226 if (clocksource_register(&clocksource_microblaze)) 229 if (clocksource_register(&clocksource_microblaze))
227 panic("failed to register clocksource"); 230 panic("failed to register clocksource");
@@ -247,6 +250,7 @@ void __init time_init(void)
247 u32 irq, i = 0; 250 u32 irq, i = 0;
248 u32 timer_num = 1; 251 u32 timer_num = 1;
249 struct device_node *timer = NULL; 252 struct device_node *timer = NULL;
253 const void *prop;
250#ifdef CONFIG_SELFMOD_TIMER 254#ifdef CONFIG_SELFMOD_TIMER
251 unsigned int timer_baseaddr = 0; 255 unsigned int timer_baseaddr = 0;
252 int arr_func[] = { 256 int arr_func[] = {
@@ -258,12 +262,10 @@ void __init time_init(void)
258 0 262 0
259 }; 263 };
260#endif 264#endif
261 char *timer_list[] = { 265 const char * const timer_list[] = {
262 "xlnx,xps-timer-1.00.a", 266 "xlnx,xps-timer-1.00.a",
263 "xlnx,opb-timer-1.00.b", 267 NULL
264 "xlnx,opb-timer-1.00.a", 268 };
265 NULL
266 };
267 269
268 for (i = 0; timer_list[i] != NULL; i++) { 270 for (i = 0; timer_list[i] != NULL; i++) {
269 timer = of_find_compatible_node(NULL, NULL, timer_list[i]); 271 timer = of_find_compatible_node(NULL, NULL, timer_list[i]);
@@ -272,13 +274,13 @@ void __init time_init(void)
272 } 274 }
273 BUG_ON(!timer); 275 BUG_ON(!timer);
274 276
275 timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL); 277 timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL));
276 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); 278 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
277 irq = *(int *) of_get_property(timer, "interrupts", NULL); 279 irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL));
278 timer_num = 280 timer_num = be32_to_cpup(of_get_property(timer,
279 *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL); 281 "xlnx,one-timer-only", NULL));
280 if (timer_num) { 282 if (timer_num) {
281 printk(KERN_EMERG "Please enable two timers in HW\n"); 283 eprintk(KERN_EMERG "Please enable two timers in HW\n");
282 BUG(); 284 BUG();
283 } 285 }
284 286
@@ -288,7 +290,14 @@ void __init time_init(void)
288 printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", 290 printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
289 timer_list[i], timer_baseaddr, irq); 291 timer_list[i], timer_baseaddr, irq);
290 292
291 cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ; 293 /* If there is clock-frequency property than use it */
294 prop = of_get_property(timer, "clock-frequency", NULL);
295 if (prop)
296 timer_clock_freq = be32_to_cpup(prop);
297 else
298 timer_clock_freq = cpuinfo.cpu_clock_freq;
299
300 freq_div_hz = timer_clock_freq / HZ;
292 301
293 setup_irq(irq, &timer_irqaction); 302 setup_irq(irq, &timer_irqaction);
294#ifdef CONFIG_HEART_BEAT 303#ifdef CONFIG_HEART_BEAT
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
index a09f2962fbec..96a88c31fe48 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -8,7 +8,6 @@
8 * for more details. 8 * for more details.
9 */ 9 */
10 10
11OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
12OUTPUT_ARCH(microblaze) 11OUTPUT_ARCH(microblaze)
13ENTRY(microblaze_start) 12ENTRY(microblaze_start)
14 13
@@ -16,7 +15,11 @@ ENTRY(microblaze_start)
16#include <asm-generic/vmlinux.lds.h> 15#include <asm-generic/vmlinux.lds.h>
17#include <asm/thread_info.h> 16#include <asm/thread_info.h>
18 17
18#ifdef __MICROBLAZEEL__
19jiffies = jiffies_64;
20#else
19jiffies = jiffies_64 + 4; 21jiffies = jiffies_64 + 4;
22#endif
20 23
21SECTIONS { 24SECTIONS {
22 . = CONFIG_KERNEL_START; 25 . = CONFIG_KERNEL_START;
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile
index 4dfe47d3cd91..f1fcbff3da25 100644
--- a/arch/microblaze/lib/Makefile
+++ b/arch/microblaze/lib/Makefile
@@ -11,3 +11,13 @@ lib-y += memcpy.o memmove.o
11endif 11endif
12 12
13lib-y += uaccess_old.o 13lib-y += uaccess_old.o
14
15lib-y += ashldi3.o
16lib-y += ashrdi3.o
17lib-y += divsi3.o
18lib-y += lshrdi3.o
19lib-y += modsi3.o
20lib-y += muldi3.o
21lib-y += mulsi3.o
22lib-y += udivsi3.o
23lib-y += umodsi3.o
diff --git a/arch/microblaze/lib/ashldi3.c b/arch/microblaze/lib/ashldi3.c
new file mode 100644
index 000000000000..beb80f316095
--- /dev/null
+++ b/arch/microblaze/lib/ashldi3.c
@@ -0,0 +1,29 @@
1#include <linux/module.h>
2
3#include "libgcc.h"
4
5long long __ashldi3(long long u, word_type b)
6{
7 DWunion uu, w;
8 word_type bm;
9
10 if (b == 0)
11 return u;
12
13 uu.ll = u;
14 bm = 32 - b;
15
16 if (bm <= 0) {
17 w.s.low = 0;
18 w.s.high = (unsigned int) uu.s.low << -bm;
19 } else {
20 const unsigned int carries = (unsigned int) uu.s.low >> bm;
21
22 w.s.low = (unsigned int) uu.s.low << b;
23 w.s.high = ((unsigned int) uu.s.high << b) | carries;
24 }
25
26 return w.ll;
27}
28
29EXPORT_SYMBOL(__ashldi3);
diff --git a/arch/microblaze/lib/ashrdi3.c b/arch/microblaze/lib/ashrdi3.c
new file mode 100644
index 000000000000..c884a912b660
--- /dev/null
+++ b/arch/microblaze/lib/ashrdi3.c
@@ -0,0 +1,31 @@
1#include <linux/module.h>
2
3#include "libgcc.h"
4
5long long __ashrdi3(long long u, word_type b)
6{
7 DWunion uu, w;
8 word_type bm;
9
10 if (b == 0)
11 return u;
12
13 uu.ll = u;
14 bm = 32 - b;
15
16 if (bm <= 0) {
17 /* w.s.high = 1..1 or 0..0 */
18 w.s.high =
19 uu.s.high >> 31;
20 w.s.low = uu.s.high >> -bm;
21 } else {
22 const unsigned int carries = (unsigned int) uu.s.high << bm;
23
24 w.s.high = uu.s.high >> b;
25 w.s.low = ((unsigned int) uu.s.low >> b) | carries;
26 }
27
28 return w.ll;
29}
30
31EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/microblaze/lib/divsi3.S b/arch/microblaze/lib/divsi3.S
new file mode 100644
index 000000000000..595b02d6e86b
--- /dev/null
+++ b/arch/microblaze/lib/divsi3.S
@@ -0,0 +1,73 @@
1#include <linux/linkage.h>
2
3/*
4* Divide operation for 32 bit integers.
5* Input : Dividend in Reg r5
6* Divisor in Reg r6
7* Output: Result in Reg r3
8*/
9 .text
10 .globl __divsi3
11 .type __divsi3, @function
12 .ent __divsi3
13__divsi3:
14 .frame r1, 0, r15
15
16 addik r1, r1, -16
17 swi r28, r1, 0
18 swi r29, r1, 4
19 swi r30, r1, 8
20 swi r31, r1, 12
21
22 beqi r6, div_by_zero /* div_by_zero - division error */
23 beqi r5, result_is_zero /* result is zero */
24 bgeid r5, r5_pos
25 xor r28, r5, r6 /* get the sign of the result */
26 rsubi r5, r5, 0 /* make r5 positive */
27r5_pos:
28 bgei r6, r6_pos
29 rsubi r6, r6, 0 /* make r6 positive */
30r6_pos:
31 addik r30, r0, 0 /* clear mod */
32 addik r3, r0, 0 /* clear div */
33 addik r29, r0, 32 /* initialize the loop count */
34
35 /* first part try to find the first '1' in the r5 */
36div0:
37 blti r5, div2 /* this traps r5 == 0x80000000 */
38div1:
39 add r5, r5, r5 /* left shift logical r5 */
40 bgtid r5, div1
41 addik r29, r29, -1
42div2:
43 /* left shift logical r5 get the '1' into the carry */
44 add r5, r5, r5
45 addc r30, r30, r30 /* move that bit into the mod register */
46 rsub r31, r6, r30 /* try to subtract (r30 a r6) */
47 blti r31, mod_too_small
48 /* move the r31 to mod since the result was positive */
49 or r30, r0, r31
50 addik r3, r3, 1
51mod_too_small:
52 addik r29, r29, -1
53 beqi r29, loop_end
54 add r3, r3, r3 /* shift in the '1' into div */
55 bri div2 /* div2 */
56loop_end:
57 bgei r28, return_here
58 brid return_here
59 rsubi r3, r3, 0 /* negate the result */
60div_by_zero:
61result_is_zero:
62 or r3, r0, r0 /* set result to 0 */
63return_here:
64/* restore values of csrs and that of r3 and the divisor and the dividend */
65 lwi r28, r1, 0
66 lwi r29, r1, 4
67 lwi r30, r1, 8
68 lwi r31, r1, 12
69 rtsd r15, 8
70 addik r1, r1, 16
71
72.size __divsi3, . - __divsi3
73.end __divsi3
diff --git a/arch/microblaze/lib/libgcc.h b/arch/microblaze/lib/libgcc.h
new file mode 100644
index 000000000000..05909d58e2fe
--- /dev/null
+++ b/arch/microblaze/lib/libgcc.h
@@ -0,0 +1,25 @@
1#ifndef __ASM_LIBGCC_H
2#define __ASM_LIBGCC_H
3
4#include <asm/byteorder.h>
5
6typedef int word_type __attribute__ ((mode (__word__)));
7
8#ifdef __BIG_ENDIAN
9struct DWstruct {
10 int high, low;
11};
12#elif defined(__LITTLE_ENDIAN)
13struct DWstruct {
14 int low, high;
15};
16#else
17#error I feel sick.
18#endif
19
20typedef union {
21 struct DWstruct s;
22 long long ll;
23} DWunion;
24
25#endif /* __ASM_LIBGCC_H */
diff --git a/arch/microblaze/lib/lshrdi3.c b/arch/microblaze/lib/lshrdi3.c
new file mode 100644
index 000000000000..dcf8d6810b7c
--- /dev/null
+++ b/arch/microblaze/lib/lshrdi3.c
@@ -0,0 +1,29 @@
1#include <linux/module.h>
2
3#include "libgcc.h"
4
5long long __lshrdi3(long long u, word_type b)
6{
7 DWunion uu, w;
8 word_type bm;
9
10 if (b == 0)
11 return u;
12
13 uu.ll = u;
14 bm = 32 - b;
15
16 if (bm <= 0) {
17 w.s.high = 0;
18 w.s.low = (unsigned int) uu.s.high >> -bm;
19 } else {
20 const unsigned int carries = (unsigned int) uu.s.high << bm;
21
22 w.s.high = (unsigned int) uu.s.high >> b;
23 w.s.low = ((unsigned int) uu.s.low >> b) | carries;
24 }
25
26 return w.ll;
27}
28
29EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c
index 014bac92bdff..cc495d7d99cc 100644
--- a/arch/microblaze/lib/memcpy.c
+++ b/arch/microblaze/lib/memcpy.c
@@ -33,17 +33,24 @@
33#include <asm/system.h> 33#include <asm/system.h>
34 34
35#ifdef __HAVE_ARCH_MEMCPY 35#ifdef __HAVE_ARCH_MEMCPY
36#ifndef CONFIG_OPT_LIB_FUNCTION
36void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c) 37void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
37{ 38{
38 const char *src = v_src; 39 const char *src = v_src;
39 char *dst = v_dst; 40 char *dst = v_dst;
40#ifndef CONFIG_OPT_LIB_FUNCTION 41
41 /* Simple, byte oriented memcpy. */ 42 /* Simple, byte oriented memcpy. */
42 while (c--) 43 while (c--)
43 *dst++ = *src++; 44 *dst++ = *src++;
44 45
45 return v_dst; 46 return v_dst;
46#else 47}
48#else /* CONFIG_OPT_LIB_FUNCTION */
49void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
50{
51 const char *src = v_src;
52 char *dst = v_dst;
53
47 /* The following code tries to optimize the copy by using unsigned 54 /* The following code tries to optimize the copy by using unsigned
48 * alignment. This will work fine if both source and destination are 55 * alignment. This will work fine if both source and destination are
49 * aligned on the same boundary. However, if they are aligned on 56 * aligned on the same boundary. However, if they are aligned on
@@ -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;
@@ -150,7 +184,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
150 } 184 }
151 185
152 return v_dst; 186 return v_dst;
153#endif
154} 187}
188#endif /* CONFIG_OPT_LIB_FUNCTION */
155EXPORT_SYMBOL(memcpy); 189EXPORT_SYMBOL(memcpy);
156#endif /* __HAVE_ARCH_MEMCPY */ 190#endif /* __HAVE_ARCH_MEMCPY */
diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c
index 0929198c5e68..123e3616f2dd 100644
--- a/arch/microblaze/lib/memmove.c
+++ b/arch/microblaze/lib/memmove.c
@@ -31,16 +31,12 @@
31#include <linux/string.h> 31#include <linux/string.h>
32 32
33#ifdef __HAVE_ARCH_MEMMOVE 33#ifdef __HAVE_ARCH_MEMMOVE
34#ifndef CONFIG_OPT_LIB_FUNCTION
34void *memmove(void *v_dst, const void *v_src, __kernel_size_t c) 35void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
35{ 36{
36 const char *src = v_src; 37 const char *src = v_src;
37 char *dst = v_dst; 38 char *dst = v_dst;
38 39
39#ifdef CONFIG_OPT_LIB_FUNCTION
40 const uint32_t *i_src;
41 uint32_t *i_dst;
42#endif
43
44 if (!c) 40 if (!c)
45 return v_dst; 41 return v_dst;
46 42
@@ -48,7 +44,6 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
48 if (v_dst <= v_src) 44 if (v_dst <= v_src)
49 return memcpy(v_dst, v_src, c); 45 return memcpy(v_dst, v_src, c);
50 46
51#ifndef CONFIG_OPT_LIB_FUNCTION
52 /* copy backwards, from end to beginning */ 47 /* copy backwards, from end to beginning */
53 src += c; 48 src += c;
54 dst += c; 49 dst += c;
@@ -58,7 +53,22 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
58 *--dst = *--src; 53 *--dst = *--src;
59 54
60 return v_dst; 55 return v_dst;
61#else 56}
57#else /* CONFIG_OPT_LIB_FUNCTION */
58void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
59{
60 const char *src = v_src;
61 char *dst = v_dst;
62 const uint32_t *i_src;
63 uint32_t *i_dst;
64
65 if (!c)
66 return v_dst;
67
68 /* Use memcpy when source is higher than dest */
69 if (v_dst <= v_src)
70 return memcpy(v_dst, v_src, c);
71
62 /* The following code tries to optimize the copy by using unsigned 72 /* The following code tries to optimize the copy by using unsigned
63 * alignment. This will work fine if both source and destination are 73 * alignment. This will work fine if both source and destination are
64 * aligned on the same boundary. However, if they are aligned on 74 * aligned on the same boundary. However, if they are aligned on
@@ -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;
@@ -169,7 +206,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
169 *--dst = *--src; 206 *--dst = *--src;
170 } 207 }
171 return v_dst; 208 return v_dst;
172#endif
173} 209}
210#endif /* CONFIG_OPT_LIB_FUNCTION */
174EXPORT_SYMBOL(memmove); 211EXPORT_SYMBOL(memmove);
175#endif /* __HAVE_ARCH_MEMMOVE */ 212#endif /* __HAVE_ARCH_MEMMOVE */
diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c
index ecfb663e1fc1..834565d1607e 100644
--- a/arch/microblaze/lib/memset.c
+++ b/arch/microblaze/lib/memset.c
@@ -31,17 +31,30 @@
31#include <linux/string.h> 31#include <linux/string.h>
32 32
33#ifdef __HAVE_ARCH_MEMSET 33#ifdef __HAVE_ARCH_MEMSET
34#ifndef CONFIG_OPT_LIB_FUNCTION
35void *memset(void *v_src, int c, __kernel_size_t n)
36{
37 char *src = v_src;
38
39 /* Truncate c to 8 bits */
40 c = (c & 0xFF);
41
42 /* Simple, byte oriented memset or the rest of count. */
43 while (n--)
44 *src++ = c;
45
46 return v_src;
47}
48#else /* CONFIG_OPT_LIB_FUNCTION */
34void *memset(void *v_src, int c, __kernel_size_t n) 49void *memset(void *v_src, int c, __kernel_size_t n)
35{ 50{
36 char *src = v_src; 51 char *src = v_src;
37#ifdef CONFIG_OPT_LIB_FUNCTION
38 uint32_t *i_src; 52 uint32_t *i_src;
39 uint32_t w32 = 0; 53 uint32_t w32 = 0;
40#endif 54
41 /* Truncate c to 8 bits */ 55 /* Truncate c to 8 bits */
42 c = (c & 0xFF); 56 c = (c & 0xFF);
43 57
44#ifdef CONFIG_OPT_LIB_FUNCTION
45 if (unlikely(c)) { 58 if (unlikely(c)) {
46 /* Make a repeating word out of it */ 59 /* Make a repeating word out of it */
47 w32 = c; 60 w32 = c;
@@ -72,12 +85,13 @@ void *memset(void *v_src, int c, __kernel_size_t n)
72 85
73 src = (void *)i_src; 86 src = (void *)i_src;
74 } 87 }
75#endif 88
76 /* Simple, byte oriented memset or the rest of count. */ 89 /* Simple, byte oriented memset or the rest of count. */
77 while (n--) 90 while (n--)
78 *src++ = c; 91 *src++ = c;
79 92
80 return v_src; 93 return v_src;
81} 94}
95#endif /* CONFIG_OPT_LIB_FUNCTION */
82EXPORT_SYMBOL(memset); 96EXPORT_SYMBOL(memset);
83#endif /* __HAVE_ARCH_MEMSET */ 97#endif /* __HAVE_ARCH_MEMSET */
diff --git a/arch/microblaze/lib/modsi3.S b/arch/microblaze/lib/modsi3.S
new file mode 100644
index 000000000000..84e0bee6e8c7
--- /dev/null
+++ b/arch/microblaze/lib/modsi3.S
@@ -0,0 +1,73 @@
1#include <linux/linkage.h>
2
3/*
4* modulo operation for 32 bit integers.
5* Input : op1 in Reg r5
6* op2 in Reg r6
7* Output: op1 mod op2 in Reg r3
8*/
9
10 .text
11 .globl __modsi3
12 .type __modsi3, @function
13 .ent __modsi3
14
15__modsi3:
16 .frame r1, 0, r15
17
18 addik r1, r1, -16
19 swi r28, r1, 0
20 swi r29, r1, 4
21 swi r30, r1, 8
22 swi r31, r1, 12
23
24 beqi r6, div_by_zero /* div_by_zero division error */
25 beqi r5, result_is_zero /* result is zero */
26 bgeid r5, r5_pos
27 /* get the sign of the result [ depends only on the first arg] */
28 add r28, r5, r0
29 rsubi r5, r5, 0 /* make r5 positive */
30r5_pos:
31 bgei r6, r6_pos
32 rsubi r6, r6, 0 /* make r6 positive */
33r6_pos:
34 addik r3, r0, 0 /* clear mod */
35 addik r30, r0, 0 /* clear div */
36 addik r29, r0, 32 /* initialize the loop count */
37/* first part try to find the first '1' in the r5 */
38div1:
39 add r5, r5, r5 /* left shift logical r5 */
40 bgeid r5, div1
41 addik r29, r29, -1
42div2:
43 /* left shift logical r5 get the '1' into the carry */
44 add r5, r5, r5
45 addc r3, r3, r3 /* move that bit into the mod register */
46 rsub r31, r6, r3 /* try to subtract (r30 a r6) */
47 blti r31, mod_too_small
48 /* move the r31 to mod since the result was positive */
49 or r3, r0, r31
50 addik r30, r30, 1
51mod_too_small:
52 addik r29, r29, -1
53 beqi r29, loop_end
54 add r30, r30, r30 /* shift in the '1' into div */
55 bri div2 /* div2 */
56loop_end:
57 bgei r28, return_here
58 brid return_here
59 rsubi r3, r3, 0 /* negate the result */
60div_by_zero:
61result_is_zero:
62 or r3, r0, r0 /* set result to 0 [both mod as well as div are 0] */
63return_here:
64/* restore values of csrs and that of r3 and the divisor and the dividend */
65 lwi r28, r1, 0
66 lwi r29, r1, 4
67 lwi r30, r1, 8
68 lwi r31, r1, 12
69 rtsd r15, 8
70 addik r1, r1, 16
71
72.size __modsi3, . - __modsi3
73.end __modsi3
diff --git a/arch/microblaze/lib/muldi3.S b/arch/microblaze/lib/muldi3.S
new file mode 100644
index 000000000000..ceeaa8c407f2
--- /dev/null
+++ b/arch/microblaze/lib/muldi3.S
@@ -0,0 +1,121 @@
1#include <linux/linkage.h>
2
3/*
4 * Multiply operation for 64 bit integers, for devices with hard multiply
5 * Input : Operand1[H] in Reg r5
6 * Operand1[L] in Reg r6
7 * Operand2[H] in Reg r7
8 * Operand2[L] in Reg r8
9 * Output: Result[H] in Reg r3
10 * Result[L] in Reg r4
11 *
12 * Explaination:
13 *
14 * Both the input numbers are divided into 16 bit number as follows
15 * op1 = A B C D
16 * op2 = E F G H
17 * result = D * H
18 * + (C * H + D * G) << 16
19 * + (B * H + C * G + D * F) << 32
20 * + (A * H + B * G + C * F + D * E) << 48
21 *
22 * Only 64 bits of the output are considered
23 */
24
25 .text
26 .globl __muldi3
27 .type __muldi3, @function
28 .ent __muldi3
29
30__muldi3:
31 addi r1, r1, -40
32
33/* Save the input operands on the caller's stack */
34 swi r5, r1, 44
35 swi r6, r1, 48
36 swi r7, r1, 52
37 swi r8, r1, 56
38
39/* Store all the callee saved registers */
40 sw r20, r1, r0
41 swi r21, r1, 4
42 swi r22, r1, 8
43 swi r23, r1, 12
44 swi r24, r1, 16
45 swi r25, r1, 20
46 swi r26, r1, 24
47 swi r27, r1, 28
48
49/* Load all the 16 bit values for A thru H */
50 lhui r20, r1, 44 /* A */
51 lhui r21, r1, 46 /* B */
52 lhui r22, r1, 48 /* C */
53 lhui r23, r1, 50 /* D */
54 lhui r24, r1, 52 /* E */
55 lhui r25, r1, 54 /* F */
56 lhui r26, r1, 56 /* G */
57 lhui r27, r1, 58 /* H */
58
59/* D * H ==> LSB of the result on stack ==> Store1 */
60 mul r9, r23, r27
61 swi r9, r1, 36 /* Pos2 and Pos3 */
62
63/* Hi (Store1) + C * H + D * G ==> Store2 ==> Pos1 and Pos2 */
64/* Store the carry generated in position 2 for Pos 3 */
65 lhui r11, r1, 36 /* Pos2 */
66 mul r9, r22, r27 /* C * H */
67 mul r10, r23, r26 /* D * G */
68 add r9, r9, r10
69 addc r12, r0, r0
70 add r9, r9, r11
71 addc r12, r12, r0 /* Store the Carry */
72 shi r9, r1, 36 /* Store Pos2 */
73 swi r9, r1, 32
74 lhui r11, r1, 32
75 shi r11, r1, 34 /* Store Pos1 */
76
77/* Hi (Store2) + B * H + C * G + D * F ==> Store3 ==> Pos0 and Pos1 */
78 mul r9, r21, r27 /* B * H */
79 mul r10, r22, r26 /* C * G */
80 mul r7, r23, r25 /* D * F */
81 add r9, r9, r11
82 add r9, r9, r10
83 add r9, r9, r7
84 swi r9, r1, 32 /* Pos0 and Pos1 */
85
86/* Hi (Store3) + A * H + B * G + C * F + D * E ==> Store3 ==> Pos0 */
87 lhui r11, r1, 32 /* Pos0 */
88 mul r9, r20, r27 /* A * H */
89 mul r10, r21, r26 /* B * G */
90 mul r7, r22, r25 /* C * F */
91 mul r8, r23, r24 /* D * E */
92 add r9, r9, r11
93 add r9, r9, r10
94 add r9, r9, r7
95 add r9, r9, r8
96 sext16 r9, r9 /* Sign extend the MSB */
97 shi r9, r1, 32
98
99/* Move results to r3 and r4 */
100 lhui r3, r1, 32
101 add r3, r3, r12
102 shi r3, r1, 32
103 lwi r3, r1, 32 /* Hi Part */
104 lwi r4, r1, 36 /* Lo Part */
105
106/* Restore Callee saved registers */
107 lw r20, r1, r0
108 lwi r21, r1, 4
109 lwi r22, r1, 8
110 lwi r23, r1, 12
111 lwi r24, r1, 16
112 lwi r25, r1, 20
113 lwi r26, r1, 24
114 lwi r27, r1, 28
115
116/* Restore Frame and return */
117 rtsd r15, 8
118 addi r1, r1, 40
119
120.size __muldi3, . - __muldi3
121.end __muldi3
diff --git a/arch/microblaze/lib/mulsi3.S b/arch/microblaze/lib/mulsi3.S
new file mode 100644
index 000000000000..90bd7b93afe6
--- /dev/null
+++ b/arch/microblaze/lib/mulsi3.S
@@ -0,0 +1,46 @@
1#include <linux/linkage.h>
2
3/*
4 * Multiply operation for 32 bit integers.
5 * Input : Operand1 in Reg r5
6 * Operand2 in Reg r6
7 * Output: Result [op1 * op2] in Reg r3
8 */
9 .text
10 .globl __mulsi3
11 .type __mulsi3, @function
12 .ent __mulsi3
13
14__mulsi3:
15 .frame r1, 0, r15
16 add r3, r0, r0
17 beqi r5, result_is_zero /* multiply by zero */
18 beqi r6, result_is_zero /* multiply by zero */
19 bgeid r5, r5_pos
20 xor r4, r5, r6 /* get the sign of the result */
21 rsubi r5, r5, 0 /* make r5 positive */
22r5_pos:
23 bgei r6, r6_pos
24 rsubi r6, r6, 0 /* make r6 positive */
25r6_pos:
26 bri l1
27l2:
28 add r5, r5, r5
29l1:
30 srl r6, r6
31 addc r7, r0, r0
32 beqi r7, l2
33 bneid r6, l2
34 add r3, r3, r5
35 blti r4, negateresult
36 rtsd r15, 8
37 nop
38negateresult:
39 rtsd r15, 8
40 rsub r3, r3, r0
41result_is_zero:
42 rtsd r15, 8
43 addi r3, r0, 0
44
45.size __mulsi3, . - __mulsi3
46.end __mulsi3
diff --git a/arch/microblaze/lib/udivsi3.S b/arch/microblaze/lib/udivsi3.S
new file mode 100644
index 000000000000..64cf57e4bb85
--- /dev/null
+++ b/arch/microblaze/lib/udivsi3.S
@@ -0,0 +1,84 @@
1#include <linux/linkage.h>
2
3/*
4* Unsigned divide operation.
5* Input : Divisor in Reg r5
6* Dividend in Reg r6
7* Output: Result in Reg r3
8*/
9
10 .text
11 .globl __udivsi3
12 .type __udivsi3, @function
13 .ent __udivsi3
14
15__udivsi3:
16
17 .frame r1, 0, r15
18
19 addik r1, r1, -12
20 swi r29, r1, 0
21 swi r30, r1, 4
22 swi r31, r1, 8
23
24 beqi r6, div_by_zero /* div_by_zero /* division error */
25 beqid r5, result_is_zero /* result is zero */
26 addik r30, r0, 0 /* clear mod */
27 addik r29, r0, 32 /* initialize the loop count */
28
29/* check if r6 and r5 are equal - if yes, return 1 */
30 rsub r18, r5, r6
31 beqid r18, return_here
32 addik r3, r0, 1
33
34/* check if (uns)r6 is greater than (uns)r5. in that case, just return 0 */
35 xor r18, r5, r6
36 bgeid r18, 16
37 add r3, r0, r0 /* we would anyways clear r3 */
38 blti r6, return_here /* r6[bit 31 = 1] hence is greater */
39 bri checkr6
40 rsub r18, r6, r5 /* microblazecmp */
41 blti r18, return_here
42
43/* if r6 [bit 31] is set, then return result as 1 */
44checkr6:
45 bgti r6, div0
46 brid return_here
47 addik r3, r0, 1
48
49/* first part try to find the first '1' in the r5 */
50div0:
51 blti r5, div2
52div1:
53 add r5, r5, r5 /* left shift logical r5 */
54 bgtid r5, div1
55 addik r29, r29, -1
56div2:
57/* left shift logical r5 get the '1' into the carry */
58 add r5, r5, r5
59 addc r30, r30, r30 /* move that bit into the mod register */
60 rsub r31, r6, r30 /* try to subtract (r30 a r6) */
61 blti r31, mod_too_small
62/* move the r31 to mod since the result was positive */
63 or r30, r0, r31
64 addik r3, r3, 1
65mod_too_small:
66 addik r29, r29, -1
67 beqi r29, loop_end
68 add r3, r3, r3 /* shift in the '1' into div */
69 bri div2 /* div2 */
70loop_end:
71 bri return_here
72div_by_zero:
73result_is_zero:
74 or r3, r0, r0 /* set result to 0 */
75return_here:
76/* restore values of csrs and that of r3 and the divisor and the dividend */
77 lwi r29, r1, 0
78 lwi r30, r1, 4
79 lwi r31, r1, 8
80 rtsd r15, 8
81 addik r1, r1, 12
82
83.size __udivsi3, . - __udivsi3
84.end __udivsi3
diff --git a/arch/microblaze/lib/umodsi3.S b/arch/microblaze/lib/umodsi3.S
new file mode 100644
index 000000000000..17d16bafae58
--- /dev/null
+++ b/arch/microblaze/lib/umodsi3.S
@@ -0,0 +1,86 @@
1#include <linux/linkage.h>
2
3/*
4 * Unsigned modulo operation for 32 bit integers.
5 * Input : op1 in Reg r5
6 * op2 in Reg r6
7 * Output: op1 mod op2 in Reg r3
8 */
9
10 .text
11 .globl __umodsi3
12 .type __umodsi3, @function
13 .ent __umodsi3
14
15__umodsi3:
16 .frame r1, 0, r15
17
18 addik r1, r1, -12
19 swi r29, r1, 0
20 swi r30, r1, 4
21 swi r31, r1, 8
22
23 beqi r6, div_by_zero /* div_by_zero - division error */
24 beqid r5, result_is_zero /* result is zero */
25 addik r3, r0, 0 /* clear div */
26 addik r30, r0, 0 /* clear mod */
27 addik r29, r0, 32 /* initialize the loop count */
28
29/* check if r6 and r5 are equal /* if yes, return 0 */
30 rsub r18, r5, r6
31 beqi r18, return_here
32
33/* check if (uns)r6 is greater than (uns)r5. in that case, just return r5 */
34 xor r18, r5, r6
35 bgeid r18, 16
36 addik r3, r5, 0
37 blti r6, return_here
38 bri $lcheckr6
39 rsub r18, r5, r6 /* microblazecmp */
40 bgti r18, return_here
41
42/* if r6 [bit 31] is set, then return result as r5-r6 */
43$lcheckr6:
44 bgtid r6, div0
45 addik r3, r0, 0
46 addik r18, r0, 0x7fffffff
47 and r5, r5, r18
48 and r6, r6, r18
49 brid return_here
50 rsub r3, r6, r5
51/* first part: try to find the first '1' in the r5 */
52div0:
53 blti r5, div2
54div1:
55 add r5, r5, r5 /* left shift logical r5 */
56 bgeid r5, div1
57 addik r29, r29, -1
58div2:
59 /* left shift logical r5 get the '1' into the carry */
60 add r5, r5, r5
61 addc r3, r3, r3 /* move that bit into the mod register */
62 rsub r31, r6, r3 /* try to subtract (r3 a r6) */
63 blti r31, mod_too_small
64 /* move the r31 to mod since the result was positive */
65 or r3, r0, r31
66 addik r30, r30, 1
67mod_too_small:
68 addik r29, r29, -1
69 beqi r29, loop_end
70 add r30, r30, r30 /* shift in the '1' into div */
71 bri div2 /* div2 */
72loop_end:
73 bri return_here
74div_by_zero:
75result_is_zero:
76 or r3, r0, r0 /* set result to 0 */
77return_here:
78/* restore values of csrs and that of r3 and the divisor and the dividend */
79 lwi r29, r1, 0
80 lwi r30, r1, 4
81 lwi r31, r1, 8
82 rtsd r15, 8
83 addik r1, r1, 12
84
85.size __umodsi3, . - __umodsi3
86.end __umodsi3
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 55ef532f32be..e363615d6798 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -60,21 +60,6 @@ struct dma_map_ops *get_pci_dma_ops(void)
60} 60}
61EXPORT_SYMBOL(get_pci_dma_ops); 61EXPORT_SYMBOL(get_pci_dma_ops);
62 62
63int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
64{
65 return dma_set_mask(&dev->dev, mask);
66}
67
68int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
69{
70 int rc;
71
72 rc = dma_set_mask(&dev->dev, mask);
73 dev->dev.coherent_dma_mask = dev->dma_mask;
74
75 return rc;
76}
77
78struct pci_controller *pcibios_alloc_controller(struct device_node *dev) 63struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
79{ 64{
80 struct pci_controller *phb; 65 struct pci_controller *phb;
@@ -1075,8 +1060,6 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
1075 bus->number, bus->self ? pci_name(bus->self) : "PHB"); 1060 bus->number, bus->self ? pci_name(bus->self) : "PHB");
1076 1061
1077 list_for_each_entry(dev, &bus->devices, bus_list) { 1062 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 */ 1063 /* Setup OF node pointer in archdata */
1081 dev->dev.of_node = pci_device_to_OF_node(dev); 1064 dev->dev.of_node = pci_device_to_OF_node(dev);
1082 1065
@@ -1086,8 +1069,8 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
1086 set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); 1069 set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
1087 1070
1088 /* Hook up default DMA ops */ 1071 /* Hook up default DMA ops */
1089 sd->dma_ops = pci_dma_ops; 1072 set_dma_ops(&dev->dev, pci_dma_ops);
1090 sd->dma_data = (void *)PCI_DRAM_OFFSET; 1073 dev->dev.archdata.dma_data = (void *)PCI_DRAM_OFFSET;
1091 1074
1092 /* Read default IRQs and fixup if necessary */ 1075 /* Read default IRQs and fixup if necessary */
1093 pci_read_irq_line(dev); 1076 pci_read_irq_line(dev);
diff --git a/arch/microblaze/platform/generic/system.dts b/arch/microblaze/platform/generic/system.dts
index 2d5c41767cd0..3f85df2b73b3 100644
--- a/arch/microblaze/platform/generic/system.dts
+++ b/arch/microblaze/platform/generic/system.dts
@@ -85,6 +85,7 @@
85 xlnx,dynamic-bus-sizing = <0x1>; 85 xlnx,dynamic-bus-sizing = <0x1>;
86 xlnx,edge-is-positive = <0x1>; 86 xlnx,edge-is-positive = <0x1>;
87 xlnx,family = "virtex5"; 87 xlnx,family = "virtex5";
88 xlnx,endianness = <0x1>;
88 xlnx,fpu-exception = <0x1>; 89 xlnx,fpu-exception = <0x1>;
89 xlnx,fsl-data-size = <0x20>; 90 xlnx,fsl-data-size = <0x20>;
90 xlnx,fsl-exception = <0x0>; 91 xlnx,fsl-exception = <0x0>;
@@ -218,6 +219,7 @@
218 #address-cells = <1>; 219 #address-cells = <1>;
219 #size-cells = <1>; 220 #size-cells = <1>;
220 compatible = "xlnx,compound"; 221 compatible = "xlnx,compound";
222 ranges ;
221 ethernet@81c00000 { 223 ethernet@81c00000 {
222 compatible = "xlnx,xps-ll-temac-1.01.b", "xlnx,xps-ll-temac-1.00.a"; 224 compatible = "xlnx,xps-ll-temac-1.01.b", "xlnx,xps-ll-temac-1.00.a";
223 device_type = "network"; 225 device_type = "network";
@@ -332,6 +334,7 @@
332 #address-cells = <1>; 334 #address-cells = <1>;
333 #size-cells = <1>; 335 #size-cells = <1>;
334 compatible = "xlnx,mpmc-4.02.a"; 336 compatible = "xlnx,mpmc-4.02.a";
337 ranges ;
335 PIM3: sdma@84600180 { 338 PIM3: sdma@84600180 {
336 compatible = "xlnx,ll-dma-1.00.a"; 339 compatible = "xlnx,ll-dma-1.00.a";
337 interrupt-parent = <&xps_intc_0>; 340 interrupt-parent = <&xps_intc_0>;
diff --git a/arch/microblaze/platform/platform.c b/arch/microblaze/platform/platform.c
index 5b89b58c5aed..b9529caa507a 100644
--- a/arch/microblaze/platform/platform.c
+++ b/arch/microblaze/platform/platform.c
@@ -17,9 +17,6 @@
17 17
18static struct of_device_id xilinx_of_bus_ids[] __initdata = { 18static struct of_device_id xilinx_of_bus_ids[] __initdata = {
19 { .compatible = "simple-bus", }, 19 { .compatible = "simple-bus", },
20 { .compatible = "xlnx,plb-v46-1.00.a", },
21 { .compatible = "xlnx,opb-v20-1.10.c", },
22 { .compatible = "xlnx,opb-v20-1.10.b", },
23 { .compatible = "xlnx,compound", }, 20 { .compatible = "xlnx,compound", },
24 {} 21 {}
25}; 22};