diff options
Diffstat (limited to 'arch/microblaze')
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 | ||
124 | config 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 | |||
124 | endmenu | 141 | endmenu |
125 | 142 | ||
126 | menu "Advanced setup" | 143 | menu "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 | ||
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. |
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) | |||
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/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); | |||
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 | 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 | */ | ||
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..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); | |||
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..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 */ |
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 | /* |
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 | ||
212 | int cpu_has_pvr(void); | 216 | int cpu_has_pvr(void); |
213 | void get_pvr(struct pvr_s *pvr); | 217 | 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/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 @@ | |||
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.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 | ||
460 | C_ENTRY(sys_rt_sigreturn_wrapper): | 466 | C_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 */ |
855 | DBTRAP_return_user: /* MS: Make global symbol for debugging */ | 849 | DBTRAP_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); |
869 | DBTRAP_return_kernel: /* MS: Make global symbol for debugging */ | 862 | DBTRAP_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) | |||
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..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 | */ | ||
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); |
51 | #ifdef CONFIG_FUNCTION_TRACER | 27 | #ifdef CONFIG_FUNCTION_TRACER |
@@ -63,3 +39,9 @@ EXPORT_SYMBOL(__strncpy_user); | |||
63 | EXPORT_SYMBOL(memcpy); | 39 | EXPORT_SYMBOL(memcpy); |
64 | EXPORT_SYMBOL(memmove); | 40 | EXPORT_SYMBOL(memmove); |
65 | #endif | 41 | #endif |
42 | |||
43 | #ifdef CONFIG_MMU | ||
44 | EXPORT_SYMBOL(empty_zero_page); | ||
45 | #endif | ||
46 | |||
47 | EXPORT_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 */ | ||
90 | static 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 */ | ||
118 | int __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 | ||
89 | void __init early_init_devtree(void *params) | 124 | void __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 | |||
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 | { |
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 | ||
41 | unsigned int freq_div_hz; | ||
42 | 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); |
@@ -201,7 +204,7 @@ static struct cyclecounter microblaze_cc = { | |||
201 | 204 | ||
202 | int __init init_microblaze_timecounter(void) | 205 | 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()); |
@@ -221,7 +224,7 @@ static struct clocksource clocksource_microblaze = { | |||
221 | static int __init microblaze_clocksource_init(void) | 224 | static 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 | ||
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; |
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 | |||
11 | endif | 11 | endif |
12 | 12 | ||
13 | lib-y += uaccess_old.o | 13 | lib-y += uaccess_old.o |
14 | |||
15 | lib-y += ashldi3.o | ||
16 | lib-y += ashrdi3.o | ||
17 | lib-y += divsi3.o | ||
18 | lib-y += lshrdi3.o | ||
19 | lib-y += modsi3.o | ||
20 | lib-y += muldi3.o | ||
21 | lib-y += mulsi3.o | ||
22 | lib-y += udivsi3.o | ||
23 | 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/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..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 | ||
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 |
@@ -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 */ | ||
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..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 | ||
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 |
@@ -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 */ | ||
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..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 | ||
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; |
@@ -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.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 */ | ||
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/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 | } |
61 | EXPORT_SYMBOL(get_pci_dma_ops); | 61 | EXPORT_SYMBOL(get_pci_dma_ops); |
62 | 62 | ||
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) | 63 | struct 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 | ||
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 | }; |