Prechádzať zdrojové kódy

Merge branch 'next' of git://git.monstr.eu/linux-2.6-microblaze

* 'next' of git://git.monstr.eu/linux-2.6-microblaze: (42 commits)
  microblaze: Fix build with make 3.82
  fbdev/xilinxfb: Microblaze driver support
  microblaze: Support C optimized lib functions for little-endian
  microblaze: Separate library optimized functions
  microblaze: Support timer on AXI lite
  microblaze: Add support for little-endian Microblaze
  microblaze: KGDB little endian support
  microblaze: Add PVR for endians plus detection
  net: emaclite: Add support for little-endian platforms
  microblaze: trivial: Add comment for AXI pvr
  microblaze: pci-common cleanup
  microblaze: Support early console on uart16550
  microblaze: Do not compile early console support for uartlite if is disabled
  microblaze: Setup early console dynamically
  microblaze: Rename all uartlite early printk functions
  microblaze: remove early printk uarlite console dependency from header
  microblaze: Remove additional compatible properties
  microblaze: Remove hardcoded asm instraction for PVR loading
  microblaze: Use static const char * const where possible
  microblaze: Define VMALLOC_START/END
  ...
Linus Torvalds 14 rokov pred
rodič
commit
e0e170bd7d
56 zmenil súbory, kde vykonal 1038 pridanie a 201 odobranie
  1. 17 0
      arch/microblaze/Kconfig
  2. 1 1
      arch/microblaze/Kconfig.debug
  3. 6 5
      arch/microblaze/Makefile
  4. 4 0
      arch/microblaze/include/asm/byteorder.h
  5. 7 2
      arch/microblaze/include/asm/checksum.h
  6. 3 2
      arch/microblaze/include/asm/cpuinfo.h
  7. 1 1
      arch/microblaze/include/asm/elf.h
  8. 1 4
      arch/microblaze/include/asm/gpio.h
  9. 2 0
      arch/microblaze/include/asm/io.h
  10. 0 3
      arch/microblaze/include/asm/page.h
  11. 2 0
      arch/microblaze/include/asm/pci.h
  12. 2 1
      arch/microblaze/include/asm/pgalloc.h
  13. 7 0
      arch/microblaze/include/asm/pgtable.h
  14. 1 0
      arch/microblaze/include/asm/prom.h
  15. 9 5
      arch/microblaze/include/asm/pvr.h
  16. 16 0
      arch/microblaze/include/asm/seccomp.h
  17. 6 0
      arch/microblaze/include/asm/setup.h
  18. 8 12
      arch/microblaze/include/asm/thread_info.h
  19. 9 3
      arch/microblaze/include/asm/unaligned.h
  20. 4 1
      arch/microblaze/include/asm/unistd.h
  21. 1 0
      arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
  22. 1 0
      arch/microblaze/kernel/cpu/cpuinfo-static.c
  23. 2 0
      arch/microblaze/kernel/cpu/cpuinfo.c
  24. 2 1
      arch/microblaze/kernel/cpu/mb.c
  25. 1 1
      arch/microblaze/kernel/cpu/pvr.c
  26. 78 9
      arch/microblaze/kernel/early_printk.c
  27. 7 14
      arch/microblaze/kernel/entry.S
  28. 7 18
      arch/microblaze/kernel/exceptions.c
  29. 5 6
      arch/microblaze/kernel/heartbeat.c
  30. 7 7
      arch/microblaze/kernel/intc.c
  31. 5 2
      arch/microblaze/kernel/kgdb.c
  32. 7 25
      arch/microblaze/kernel/microblaze_ksyms.c
  33. 37 2
      arch/microblaze/kernel/prom.c
  34. 0 6
      arch/microblaze/kernel/setup.c
  35. 3 0
      arch/microblaze/kernel/syscall_table.S
  36. 25 16
      arch/microblaze/kernel/timer.c
  37. 4 1
      arch/microblaze/kernel/vmlinux.lds.S
  38. 10 0
      arch/microblaze/lib/Makefile
  39. 29 0
      arch/microblaze/lib/ashldi3.c
  40. 31 0
      arch/microblaze/lib/ashrdi3.c
  41. 73 0
      arch/microblaze/lib/divsi3.S
  42. 25 0
      arch/microblaze/lib/libgcc.h
  43. 29 0
      arch/microblaze/lib/lshrdi3.c
  44. 40 6
      arch/microblaze/lib/memcpy.c
  45. 48 11
      arch/microblaze/lib/memmove.c
  46. 18 4
      arch/microblaze/lib/memset.c
  47. 73 0
      arch/microblaze/lib/modsi3.S
  48. 121 0
      arch/microblaze/lib/muldi3.S
  49. 46 0
      arch/microblaze/lib/mulsi3.S
  50. 84 0
      arch/microblaze/lib/udivsi3.S
  51. 86 0
      arch/microblaze/lib/umodsi3.S
  52. 2 19
      arch/microblaze/pci/pci-common.c
  53. 3 0
      arch/microblaze/platform/generic/system.dts
  54. 0 3
      arch/microblaze/platform/platform.c
  55. 4 4
      drivers/net/xilinx_emaclite.c
  56. 18 6
      drivers/video/xilinxfb.c

+ 17 - 0
arch/microblaze/Kconfig

@@ -121,6 +121,23 @@ config CMDLINE_FORCE
 	  Set this to have arguments from the default kernel command string
 	  Set this to have arguments from the default kernel command string
 	  override those passed by the boot loader.
 	  override those passed by the boot loader.
 
 
+config SECCOMP
+	bool "Enable seccomp to safely compute untrusted bytecode"
+	depends on PROC_FS
+	default y
+	help
+	  This kernel feature is useful for number crunching applications
+	  that may need to compute untrusted bytecode during their
+	  execution. By using pipes or other transports made available to
+	  the process as file descriptors supporting the read/write
+	  syscalls, it's possible to isolate those applications in
+	  their own address space using seccomp. Once seccomp is
+	  enabled via /proc/<pid>/seccomp, it cannot be disabled
+	  and the task is only allowed to execute a few safe syscalls
+	  defined by each seccomp mode.
+
+	  If unsure, say Y. Only embedded should say N here.
+
 endmenu
 endmenu
 
 
 menu "Advanced setup"
 menu "Advanced setup"

+ 1 - 1
arch/microblaze/Kconfig.debug

@@ -10,7 +10,7 @@ source "lib/Kconfig.debug"
 
 
 config EARLY_PRINTK
 config EARLY_PRINTK
 	bool "Early printk function for kernel"
 	bool "Early printk function for kernel"
-	depends on SERIAL_UARTLITE_CONSOLE
+	depends on SERIAL_UARTLITE_CONSOLE || SERIAL_8250_CONSOLE
 	default n
 	default n
 	help
 	help
 	  This option turns on/off early printk messages to console.
 	  This option turns on/off early printk messages to console.

+ 6 - 5
arch/microblaze/Makefile

@@ -42,11 +42,8 @@ KBUILD_CFLAGS += -ffixed-r31 $(CPUFLAGS-1) $(CPUFLAGS-2)
 LDFLAGS		:=
 LDFLAGS		:=
 LDFLAGS_vmlinux	:=
 LDFLAGS_vmlinux	:=
 
 
-LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
-
 head-y := arch/microblaze/kernel/head.o
 head-y := arch/microblaze/kernel/head.o
 libs-y += arch/microblaze/lib/
 libs-y += arch/microblaze/lib/
-libs-y += $(LIBGCC)
 core-y += arch/microblaze/kernel/
 core-y += arch/microblaze/kernel/
 core-y += arch/microblaze/mm/
 core-y += arch/microblaze/mm/
 core-y += arch/microblaze/platform/
 core-y += arch/microblaze/platform/
@@ -72,12 +69,16 @@ export MMU DTB
 
 
 all: linux.bin
 all: linux.bin
 
 
-BOOT_TARGETS = linux.bin linux.bin.gz simpleImage.%
+# With make 3.82 we cannot mix normal and wildcard targets
+BOOT_TARGETS1 = linux.bin linux.bin.gz
+BOOT_TARGETS2 = simpleImage.%
 
 
 archclean:
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
 	$(Q)$(MAKE) $(clean)=$(boot)
 
 
-$(BOOT_TARGETS): vmlinux
+$(BOOT_TARGETS1): vmlinux
+	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+$(BOOT_TARGETS2): vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 
 define archhelp
 define archhelp

+ 4 - 0
arch/microblaze/include/asm/byteorder.h

@@ -1,6 +1,10 @@
 #ifndef _ASM_MICROBLAZE_BYTEORDER_H
 #ifndef _ASM_MICROBLAZE_BYTEORDER_H
 #define _ASM_MICROBLAZE_BYTEORDER_H
 #define _ASM_MICROBLAZE_BYTEORDER_H
 
 
+#ifdef __MICROBLAZEEL__
+#include <linux/byteorder/little_endian.h>
+#else
 #include <linux/byteorder/big_endian.h>
 #include <linux/byteorder/big_endian.h>
+#endif
 
 
 #endif /* _ASM_MICROBLAZE_BYTEORDER_H */
 #endif /* _ASM_MICROBLAZE_BYTEORDER_H */

+ 7 - 2
arch/microblaze/include/asm/checksum.h

@@ -24,8 +24,13 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
 		"addc %0, %0, %3\n\t"
 		"addc %0, %0, %3\n\t"
 		"addc %0, %0, r0\n\t"
 		"addc %0, %0, r0\n\t"
 		: "+&d" (sum)
 		: "+&d" (sum)
-		: "d" (saddr), "d" (daddr), "d" (len + proto));
-
+		: "d" (saddr), "d" (daddr),
+#ifdef __MICROBLAZEEL__
+	"d" ((len + proto) << 8)
+#else
+	"d" (len + proto)
+#endif
+);
 	return sum;
 	return sum;
 }
 }
 
 

+ 3 - 2
arch/microblaze/include/asm/cpuinfo.h

@@ -38,6 +38,7 @@ struct cpuinfo {
 	u32 use_exc;
 	u32 use_exc;
 	u32 ver_code;
 	u32 ver_code;
 	u32 mmu;
 	u32 mmu;
+	u32 endian;
 
 
 	/* CPU caches */
 	/* CPU caches */
 	u32 use_icache;
 	u32 use_icache;
@@ -76,7 +77,6 @@ struct cpuinfo {
 	u32 num_rd_brk;
 	u32 num_rd_brk;
 	u32 num_wr_brk;
 	u32 num_wr_brk;
 	u32 cpu_clock_freq; /* store real freq of cpu */
 	u32 cpu_clock_freq; /* store real freq of cpu */
-	u32 freq_div_hz; /* store freq/HZ */
 
 
 	/* FPGA family */
 	/* FPGA family */
 	u32 fpga_family_code;
 	u32 fpga_family_code;
@@ -97,7 +97,8 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu);
 static inline unsigned int fcpu(struct device_node *cpu, char *n)
 static inline unsigned int fcpu(struct device_node *cpu, char *n)
 {
 {
 	int *val;
 	int *val;
-	return (val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0;
+	return (val = (int *) of_get_property(cpu, n, NULL)) ?
+							be32_to_cpup(val) : 0;
 }
 }
 
 
 #endif /* _ASM_MICROBLAZE_CPUINFO_H */
 #endif /* _ASM_MICROBLAZE_CPUINFO_H */

+ 1 - 1
arch/microblaze/include/asm/elf.h

@@ -71,7 +71,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
 
 #define ELF_ET_DYN_BASE         (0x08000000)
 #define ELF_ET_DYN_BASE         (0x08000000)
 
 
-#ifdef __LITTLE_ENDIAN__
+#ifdef __MICROBLAZEEL__
 #define ELF_DATA	ELFDATA2LSB
 #define ELF_DATA	ELFDATA2LSB
 #else
 #else
 #define ELF_DATA	ELFDATA2MSB
 #define ELF_DATA	ELFDATA2MSB

+ 1 - 4
arch/microblaze/include/asm/gpio.h

@@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio)
 	return __gpio_cansleep(gpio);
 	return __gpio_cansleep(gpio);
 }
 }
 
 
-/*
- * Not implemented, yet.
- */
 static inline int gpio_to_irq(unsigned int gpio)
 static inline int gpio_to_irq(unsigned int gpio)
 {
 {
-	return -ENOSYS;
+	return __gpio_to_irq(gpio);
 }
 }
 
 
 static inline int irq_to_gpio(unsigned int irq)
 static inline int irq_to_gpio(unsigned int irq)

+ 2 - 0
arch/microblaze/include/asm/io.h

@@ -243,6 +243,8 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size,
 #define out_8(a, v) __raw_writeb((v), (a))
 #define out_8(a, v) __raw_writeb((v), (a))
 #define in_8(a) __raw_readb(a)
 #define in_8(a) __raw_readb(a)
 
 
+#define mmiowb()
+
 #define ioport_map(port, nr)	((void __iomem *)(port))
 #define ioport_map(port, nr)	((void __iomem *)(port))
 #define ioport_unmap(addr)
 #define ioport_unmap(addr)
 
 

+ 0 - 3
arch/microblaze/include/asm/page.h

@@ -205,9 +205,6 @@ extern int page_is_ram(unsigned long pfn);
 #define TOPHYS(addr)  __virt_to_phys(addr)
 #define TOPHYS(addr)  __virt_to_phys(addr)
 
 
 #ifdef CONFIG_MMU
 #ifdef CONFIG_MMU
-#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
-#define WANT_PAGE_VIRTUAL 1 /* page alloc 2 relies on this */
-#endif
 
 
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)

+ 2 - 0
arch/microblaze/include/asm/pci.h

@@ -165,5 +165,7 @@ extern void __init xilinx_pci_init(void);
 static inline void __init xilinx_pci_init(void) { return; }
 static inline void __init xilinx_pci_init(void) { return; }
 #endif
 #endif
 
 
+#include <asm-generic/pci-dma-compat.h>
+
 #endif	/* __KERNEL__ */
 #endif	/* __KERNEL__ */
 #endif /* __ASM_MICROBLAZE_PCI_H */
 #endif /* __ASM_MICROBLAZE_PCI_H */

+ 2 - 1
arch/microblaze/include/asm/pgalloc.h

@@ -165,7 +165,8 @@ extern inline void pte_free(struct mm_struct *mm, struct page *ptepage)
 
 
 #define __pte_free_tlb(tlb, pte, addr)	pte_free((tlb)->mm, (pte))
 #define __pte_free_tlb(tlb, pte, addr)	pte_free((tlb)->mm, (pte))
 
 
-#define pmd_populate(mm, pmd, pte)	(pmd_val(*(pmd)) = page_address(pte))
+#define pmd_populate(mm, pmd, pte) \
+			(pmd_val(*(pmd)) = (unsigned long)page_address(pte))
 
 
 #define pmd_populate_kernel(mm, pmd, pte) \
 #define pmd_populate_kernel(mm, pmd, pte) \
 		(pmd_val(*(pmd)) = (unsigned long) (pte))
 		(pmd_val(*(pmd)) = (unsigned long) (pte))

+ 7 - 0
arch/microblaze/include/asm/pgtable.h

@@ -57,6 +57,13 @@ static inline int pte_file(pte_t pte) { return 0; }
 
 
 #define pgprot_noncached_wc(prot)	prot
 #define pgprot_noncached_wc(prot)	prot
 
 
+/*
+ * All 32bit addresses are effectively valid for vmalloc...
+ * Sort of meaningless for non-VM targets.
+ */
+#define	VMALLOC_START	0
+#define	VMALLOC_END	0xffffffff
+
 #else /* CONFIG_MMU */
 #else /* CONFIG_MMU */
 
 
 #include <asm-generic/4level-fixup.h>
 #include <asm-generic/4level-fixup.h>

+ 1 - 0
arch/microblaze/include/asm/prom.h

@@ -27,6 +27,7 @@
 
 
 /* Other Prototypes */
 /* Other Prototypes */
 extern int early_uartlite_console(void);
 extern int early_uartlite_console(void);
+extern int early_uart16550_console(void);
 
 
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
 /*
 /*

+ 9 - 5
arch/microblaze/include/asm/pvr.h

@@ -30,7 +30,9 @@ struct pvr_s {
 #define PVR0_USE_EXC_MASK		0x04000000
 #define PVR0_USE_EXC_MASK		0x04000000
 #define PVR0_USE_ICACHE_MASK		0x02000000
 #define PVR0_USE_ICACHE_MASK		0x02000000
 #define PVR0_USE_DCACHE_MASK		0x01000000
 #define PVR0_USE_DCACHE_MASK		0x01000000
-#define PVR0_USE_MMU			0x00800000	/* new */
+#define PVR0_USE_MMU			0x00800000
+#define PVR0_USE_BTC			0x00400000
+#define PVR0_ENDI			0x00200000
 #define PVR0_VERSION_MASK		0x0000FF00
 #define PVR0_VERSION_MASK		0x0000FF00
 #define PVR0_USER1_MASK			0x000000FF
 #define PVR0_USER1_MASK			0x000000FF
 
 
@@ -38,9 +40,9 @@ struct pvr_s {
 #define PVR1_USER2_MASK			0xFFFFFFFF
 #define PVR1_USER2_MASK			0xFFFFFFFF
 
 
 /* Configuration PVR masks */
 /* Configuration PVR masks */
-#define PVR2_D_OPB_MASK			0x80000000
+#define PVR2_D_OPB_MASK			0x80000000 /* or AXI */
 #define PVR2_D_LMB_MASK			0x40000000
 #define PVR2_D_LMB_MASK			0x40000000
-#define PVR2_I_OPB_MASK			0x20000000
+#define PVR2_I_OPB_MASK			0x20000000 /* or AXI */
 #define PVR2_I_LMB_MASK			0x10000000
 #define PVR2_I_LMB_MASK			0x10000000
 #define PVR2_INTERRUPT_IS_EDGE_MASK	0x08000000
 #define PVR2_INTERRUPT_IS_EDGE_MASK	0x08000000
 #define PVR2_EDGE_IS_POSITIVE_MASK	0x04000000
 #define PVR2_EDGE_IS_POSITIVE_MASK	0x04000000
@@ -63,8 +65,8 @@ struct pvr_s {
 #define PVR2_OPCODE_0x0_ILL_MASK	0x00000040
 #define PVR2_OPCODE_0x0_ILL_MASK	0x00000040
 #define PVR2_UNALIGNED_EXC_MASK		0x00000020
 #define PVR2_UNALIGNED_EXC_MASK		0x00000020
 #define PVR2_ILL_OPCODE_EXC_MASK	0x00000010
 #define PVR2_ILL_OPCODE_EXC_MASK	0x00000010
-#define PVR2_IOPB_BUS_EXC_MASK		0x00000008
-#define PVR2_DOPB_BUS_EXC_MASK		0x00000004
+#define PVR2_IOPB_BUS_EXC_MASK		0x00000008 /* or AXI */
+#define PVR2_DOPB_BUS_EXC_MASK		0x00000004 /* or AXI */
 #define PVR2_DIV_ZERO_EXC_MASK		0x00000002
 #define PVR2_DIV_ZERO_EXC_MASK		0x00000002
 #define PVR2_FPU_EXC_MASK		0x00000001
 #define PVR2_FPU_EXC_MASK		0x00000001
 
 
@@ -208,6 +210,8 @@ struct pvr_s {
 #define PVR_MMU_TLB_ACCESS(pvr)	(pvr.pvr[11] & PVR11_MMU_TLB_ACCESS)
 #define PVR_MMU_TLB_ACCESS(pvr)	(pvr.pvr[11] & PVR11_MMU_TLB_ACCESS)
 #define PVR_MMU_ZONES(pvr)	(pvr.pvr[11] & PVR11_MMU_ZONES)
 #define PVR_MMU_ZONES(pvr)	(pvr.pvr[11] & PVR11_MMU_ZONES)
 
 
+/* endian */
+#define PVR_ENDIAN(pvr)	(pvr.pvr[0] & PVR0_ENDI)
 
 
 int cpu_has_pvr(void);
 int cpu_has_pvr(void);
 void get_pvr(struct pvr_s *pvr);
 void get_pvr(struct pvr_s *pvr);

+ 16 - 0
arch/microblaze/include/asm/seccomp.h

@@ -0,0 +1,16 @@
+#ifndef _ASM_MICROBLAZE_SECCOMP_H
+#define _ASM_MICROBLAZE_SECCOMP_H
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read		__NR_read
+#define __NR_seccomp_write		__NR_write
+#define __NR_seccomp_exit		__NR_exit
+#define __NR_seccomp_sigreturn		__NR_sigreturn
+
+#define __NR_seccomp_read_32		__NR_read
+#define __NR_seccomp_write_32		__NR_write
+#define __NR_seccomp_exit_32		__NR_exit
+#define __NR_seccomp_sigreturn_32	__NR_sigreturn
+
+#endif	/* _ASM_MICROBLAZE_SECCOMP_H */

+ 6 - 0
arch/microblaze/include/asm/setup.h

@@ -25,6 +25,12 @@ void early_printk(const char *fmt, ...);
 int setup_early_printk(char *opt);
 int setup_early_printk(char *opt);
 void disable_early_printk(void);
 void disable_early_printk(void);
 
 
+#if defined(CONFIG_EARLY_PRINTK)
+#define eprintk early_printk
+#else
+#define eprintk printk
+#endif
+
 void heartbeat(void);
 void heartbeat(void);
 void setup_heartbeat(void);
 void setup_heartbeat(void);
 
 

+ 8 - 12
arch/microblaze/include/asm/thread_info.h

@@ -127,23 +127,19 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SECCOMP		10      /* secure computing */
 #define TIF_SECCOMP		10      /* secure computing */
 #define TIF_FREEZE		14	/* Freezing for suspend */
 #define TIF_FREEZE		14	/* Freezing for suspend */
 
 
-/* FIXME change in entry.S */
-#define TIF_KERNEL_TRACE	8	/* kernel trace active */
-
 /* true if poll_idle() is polling TIF_NEED_RESCHED */
 /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_POLLING_NRFLAG	16
 #define TIF_POLLING_NRFLAG	16
 
 
-#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
-#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
-#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
-#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
-#define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
-#define _TIF_IRET		(1<<TIF_IRET)
-#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
-#define _TIF_FREEZE		(1<<TIF_FREEZE)
+#define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
+#define _TIF_IRET		(1 << TIF_IRET)
+#define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE		(1 << TIF_FREEZE)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
-#define _TIF_KERNEL_TRACE	(1 << TIF_KERNEL_TRACE)
 
 
 /* work to do in syscall trace */
 /* work to do in syscall trace */
 #define _TIF_WORK_SYSCALL_MASK  (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
 #define _TIF_WORK_SYSCALL_MASK  (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \

+ 9 - 3
arch/microblaze/include/asm/unaligned.h

@@ -12,12 +12,18 @@
 
 
 # ifdef __KERNEL__
 # ifdef __KERNEL__
 
 
-# include <linux/unaligned/be_struct.h>
+# include <linux/unaligned/be_byteshift.h>
 # include <linux/unaligned/le_byteshift.h>
 # include <linux/unaligned/le_byteshift.h>
 # include <linux/unaligned/generic.h>
 # include <linux/unaligned/generic.h>
 
 
-# define get_unaligned	__get_unaligned_be
-# define put_unaligned	__put_unaligned_be
+
+#  ifdef __MICROBLAZEEL__
+#   define get_unaligned	__get_unaligned_le
+#   define put_unaligned	__put_unaligned_le
+#  else
+#   define get_unaligned	__get_unaligned_be
+#   define put_unaligned	__put_unaligned_be
+#  endif
 
 
 # endif	/* __KERNEL__ */
 # endif	/* __KERNEL__ */
 #endif /* _ASM_MICROBLAZE_UNALIGNED_H */
 #endif /* _ASM_MICROBLAZE_UNALIGNED_H */

+ 4 - 1
arch/microblaze/include/asm/unistd.h

@@ -383,8 +383,11 @@
 #define __NR_rt_tgsigqueueinfo	365 /* new */
 #define __NR_rt_tgsigqueueinfo	365 /* new */
 #define __NR_perf_event_open	366 /* new */
 #define __NR_perf_event_open	366 /* new */
 #define __NR_recvmmsg		367 /* new */
 #define __NR_recvmmsg		367 /* new */
+#define __NR_fanotify_init	368
+#define __NR_fanotify_mark	369
+#define __NR_prlimit64		370
 
 
-#define __NR_syscalls		368
+#define __NR_syscalls		371
 
 
 #ifdef __KERNEL__
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 #ifndef __ASSEMBLY__

+ 1 - 0
arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c

@@ -72,6 +72,7 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
 	CI(pvr_user2, USER2);
 	CI(pvr_user2, USER2);
 
 
 	CI(mmu, USE_MMU);
 	CI(mmu, USE_MMU);
+	CI(endian, ENDIAN);
 
 
 	CI(use_icache, USE_ICACHE);
 	CI(use_icache, USE_ICACHE);
 	CI(icache_tagbits, ICACHE_ADDR_TAG_BITS);
 	CI(icache_tagbits, ICACHE_ADDR_TAG_BITS);

+ 1 - 0
arch/microblaze/kernel/cpu/cpuinfo-static.c

@@ -119,6 +119,7 @@ void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
 	ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2");
 	ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2");
 
 
 	ci->mmu = fcpu(cpu, "xlnx,use-mmu");
 	ci->mmu = fcpu(cpu, "xlnx,use-mmu");
+	ci->endian = fcpu(cpu, "xlnx,endianness");
 
 
 	ci->ver_code = 0;
 	ci->ver_code = 0;
 	ci->fpga_family_code = 0;
 	ci->fpga_family_code = 0;

+ 2 - 0
arch/microblaze/kernel/cpu/cpuinfo.c

@@ -30,6 +30,8 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
 	{"7.20.c", 0x0e},
 	{"7.20.c", 0x0e},
 	{"7.20.d", 0x0f},
 	{"7.20.d", 0x0f},
 	{"7.30.a", 0x10},
 	{"7.30.a", 0x10},
+	{"7.30.b", 0x11},
+	{"8.00.a", 0x12},
 	{NULL, 0},
 	{NULL, 0},
 };
 };
 
 

+ 2 - 1
arch/microblaze/kernel/cpu/mb.c

@@ -51,11 +51,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 	count = seq_printf(m,
 	count = seq_printf(m,
 			"CPU-Family:	MicroBlaze\n"
 			"CPU-Family:	MicroBlaze\n"
 			"FPGA-Arch:	%s\n"
 			"FPGA-Arch:	%s\n"
-			"CPU-Ver:	%s\n"
+			"CPU-Ver:	%s, %s endian\n"
 			"CPU-MHz:	%d.%02d\n"
 			"CPU-MHz:	%d.%02d\n"
 			"BogoMips:	%lu.%02lu\n",
 			"BogoMips:	%lu.%02lu\n",
 			fpga_family,
 			fpga_family,
 			cpu_ver,
 			cpu_ver,
+			cpuinfo.endian ? "little" : "big",
 			cpuinfo.cpu_clock_freq /
 			cpuinfo.cpu_clock_freq /
 			1000000,
 			1000000,
 			cpuinfo.cpu_clock_freq %
 			cpuinfo.cpu_clock_freq %

+ 1 - 1
arch/microblaze/kernel/cpu/pvr.c

@@ -27,7 +27,7 @@
 	register unsigned tmp __asm__("r3");			\
 	register unsigned tmp __asm__("r3");			\
 	tmp = 0x0;	/* Prevent warning about unused */	\
 	tmp = 0x0;	/* Prevent warning about unused */	\
 	__asm__ __volatile__ (					\
 	__asm__ __volatile__ (					\
-			".byte 0x94,0x60,0xa0, " #pvrid "\n\t"	\
+			"mfs	%0, rpvr" #pvrid ";"	\
 			: "=r" (tmp) : : "memory"); 		\
 			: "=r" (tmp) : : "memory"); 		\
 	val = tmp;						\
 	val = tmp;						\
 }
 }

+ 78 - 9
arch/microblaze/kernel/early_printk.c

@@ -24,7 +24,8 @@
 static u32 early_console_initialized;
 static u32 early_console_initialized;
 static u32 base_addr;
 static u32 base_addr;
 
 
-static void early_printk_putc(char c)
+#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
+static void early_printk_uartlite_putc(char c)
 {
 {
 	/*
 	/*
 	 * Limit how many times we'll spin waiting for TX FIFO status.
 	 * Limit how many times we'll spin waiting for TX FIFO status.
@@ -45,25 +46,70 @@ static void early_printk_putc(char c)
 		out_be32(base_addr + 4, c & 0xff);
 		out_be32(base_addr + 4, c & 0xff);
 }
 }
 
 
-static void early_printk_write(struct console *unused,
+static void early_printk_uartlite_write(struct console *unused,
 					const char *s, unsigned n)
 					const char *s, unsigned n)
 {
 {
 	while (*s && n-- > 0) {
 	while (*s && n-- > 0) {
-		early_printk_putc(*s);
+		early_printk_uartlite_putc(*s);
 		if (*s == '\n')
 		if (*s == '\n')
-			early_printk_putc('\r');
+			early_printk_uartlite_putc('\r');
 		s++;
 		s++;
 	}
 	}
 }
 }
 
 
-static struct console early_serial_console = {
+static struct console early_serial_uartlite_console = {
 	.name = "earlyser",
 	.name = "earlyser",
-	.write = early_printk_write,
+	.write = early_printk_uartlite_write,
 	.flags = CON_PRINTBUFFER,
 	.flags = CON_PRINTBUFFER,
 	.index = -1,
 	.index = -1,
 };
 };
+#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
 
 
-static struct console *early_console = &early_serial_console;
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static void early_printk_uart16550_putc(char c)
+{
+	/*
+	 * Limit how many times we'll spin waiting for TX FIFO status.
+	 * This will prevent lockups if the base address is incorrectly
+	 * set, or any other issue on the UARTLITE.
+	 * This limit is pretty arbitrary, unless we are at about 10 baud
+	 * we'll never timeout on a working UART.
+	 */
+
+	#define UART_LSR_TEMT	0x40 /* Transmitter empty */
+	#define UART_LSR_THRE	0x20 /* Transmit-hold-register empty */
+	#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+	unsigned retries = 10000;
+
+	while (--retries &&
+		!((in_be32(base_addr + 0x14) & BOTH_EMPTY) == BOTH_EMPTY))
+		;
+
+	if (retries)
+		out_be32(base_addr, c & 0xff);
+}
+
+static void early_printk_uart16550_write(struct console *unused,
+					const char *s, unsigned n)
+{
+	while (*s && n-- > 0) {
+		early_printk_uart16550_putc(*s);
+		if (*s == '\n')
+			early_printk_uart16550_putc('\r');
+		s++;
+	}
+}
+
+static struct console early_serial_uart16550_console = {
+	.name = "earlyser",
+	.write = early_printk_uart16550_write,
+	.flags = CON_PRINTBUFFER,
+	.index = -1,
+};
+#endif /* CONFIG_SERIAL_8250_CONSOLE */
+
+static struct console *early_console;
 
 
 void early_printk(const char *fmt, ...)
 void early_printk(const char *fmt, ...)
 {
 {
@@ -84,20 +130,43 @@ int __init setup_early_printk(char *opt)
 	if (early_console_initialized)
 	if (early_console_initialized)
 		return 1;
 		return 1;
 
 
+#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
 	base_addr = early_uartlite_console();
 	base_addr = early_uartlite_console();
 	if (base_addr) {
 	if (base_addr) {
 		early_console_initialized = 1;
 		early_console_initialized = 1;
 #ifdef CONFIG_MMU
 #ifdef CONFIG_MMU
 		early_console_reg_tlb_alloc(base_addr);
 		early_console_reg_tlb_alloc(base_addr);
 #endif
 #endif
+		early_console = &early_serial_uartlite_console;
 		early_printk("early_printk_console is enabled at 0x%08x\n",
 		early_printk("early_printk_console is enabled at 0x%08x\n",
 							base_addr);
 							base_addr);
 
 
 		/* register_console(early_console); */
 		/* register_console(early_console); */
 
 
 		return 0;
 		return 0;
-	} else
-		return 1;
+	}
+#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+	base_addr = early_uart16550_console();
+	base_addr &= ~3; /* clear register offset */
+	if (base_addr) {
+		early_console_initialized = 1;
+#ifdef CONFIG_MMU
+		early_console_reg_tlb_alloc(base_addr);
+#endif
+		early_console = &early_serial_uart16550_console;
+
+		early_printk("early_printk_console is enabled at 0x%08x\n",
+							base_addr);
+
+		/* register_console(early_console); */
+
+		return 0;
+	}
+#endif /* CONFIG_SERIAL_8250_CONSOLE */
+
+	return 1;
 }
 }
 
 
 void __init disable_early_printk(void)
 void __init disable_early_printk(void)

+ 7 - 14
arch/microblaze/kernel/entry.S

@@ -186,6 +186,8 @@
 	swi	r13, r1, PTO+PT_R13;	/* Save SDA2 */			\
 	swi	r13, r1, PTO+PT_R13;	/* Save SDA2 */			\
 	swi	r14, r1, PTO+PT_PC;	/* PC, before IRQ/trap */	\
 	swi	r14, r1, PTO+PT_PC;	/* PC, before IRQ/trap */	\
 	swi	r15, r1, PTO+PT_R15;	/* Save LP */			\
 	swi	r15, r1, PTO+PT_R15;	/* Save LP */			\
+	swi	r16, r1, PTO+PT_R16;					\
+	swi	r17, r1, PTO+PT_R17;					\
 	swi	r18, r1, PTO+PT_R18;	/* Save asm scratch reg */	\
 	swi	r18, r1, PTO+PT_R18;	/* Save asm scratch reg */	\
 	swi	r19, r1, PTO+PT_R19;					\
 	swi	r19, r1, PTO+PT_R19;					\
 	swi	r20, r1, PTO+PT_R20;					\
 	swi	r20, r1, PTO+PT_R20;					\
@@ -220,6 +222,8 @@
 	lwi	r13, r1, PTO+PT_R13;	/* restore SDA2 */		\
 	lwi	r13, r1, PTO+PT_R13;	/* restore SDA2 */		\
 	lwi	r14, r1, PTO+PT_PC;	/* RESTORE_LINK PC, before IRQ/trap */\
 	lwi	r14, r1, PTO+PT_PC;	/* RESTORE_LINK PC, before IRQ/trap */\
 	lwi	r15, r1, PTO+PT_R15;	/* restore LP */		\
 	lwi	r15, r1, PTO+PT_R15;	/* restore LP */		\
+	lwi	r16, r1, PTO+PT_R16;					\
+	lwi	r17, r1, PTO+PT_R17;					\
 	lwi	r18, r1, PTO+PT_R18;	/* restore asm scratch reg */	\
 	lwi	r18, r1, PTO+PT_R18;	/* restore asm scratch reg */	\
 	lwi	r19, r1, PTO+PT_R19;					\
 	lwi	r19, r1, PTO+PT_R19;					\
 	lwi	r20, r1, PTO+PT_R20;					\
 	lwi	r20, r1, PTO+PT_R20;					\
@@ -295,6 +299,8 @@ C_ENTRY(_user_exception):
 	/* addik	r1, r1, -STATE_SAVE_SIZE; */
 	/* addik	r1, r1, -STATE_SAVE_SIZE; */
 	addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE;
 	addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE;
 	SAVE_REGS
 	SAVE_REGS
+	swi	r0, r1, PTO + PT_R3
+	swi	r0, r1, PTO + PT_R4
 
 
 	lwi	r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
 	lwi	r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
 	swi	r11, r1, PTO+PT_R1;		/* Store user SP.  */
 	swi	r11, r1, PTO+PT_R1;		/* Store user SP.  */
@@ -458,14 +464,8 @@ C_ENTRY(sys_execve):
 	addik	r8, r1, PTO;		/* add user context as 4th arg */
 	addik	r8, r1, PTO;		/* add user context as 4th arg */
 
 
 C_ENTRY(sys_rt_sigreturn_wrapper):
 C_ENTRY(sys_rt_sigreturn_wrapper):
-	swi	r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
-	swi	r4, r1, PTO+PT_R4;
-	brlid	r15, sys_rt_sigreturn	/* Do real work */
+	brid	sys_rt_sigreturn	/* Do real work */
 	addik	r5, r1, PTO;		/* add user context as 1st arg */
 	addik	r5, r1, PTO;		/* add user context as 1st arg */
-	lwi	r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
-	lwi	r4, r1, PTO+PT_R4;
-	bri ret_from_trap /* fall through will not work here due to align */
-	nop;
 
 
 /*
 /*
  * HW EXCEPTION rutine start
  * HW EXCEPTION rutine start
@@ -765,9 +765,7 @@ C_ENTRY(_debug_exception):
 	/* save all regs to pt_reg structure */
 	/* save all regs to pt_reg structure */
 	swi	r0, r1, PTO+PT_R0;	/* R0 must be saved too */
 	swi	r0, r1, PTO+PT_R0;	/* R0 must be saved too */
 	swi	r14, r1, PTO+PT_R14	/* rewrite saved R14 value */
 	swi	r14, r1, PTO+PT_R14	/* rewrite saved R14 value */
-	swi	r16, r1, PTO+PT_R16
 	swi	r16, r1, PTO+PT_PC; /* PC and r16 are the same */
 	swi	r16, r1, PTO+PT_PC; /* PC and r16 are the same */
-	swi	r17, r1, PTO+PT_R17
 	/* save special purpose registers to pt_regs */
 	/* save special purpose registers to pt_regs */
 	mfs	r11, rear;
 	mfs	r11, rear;
 	swi	r11, r1, PTO+PT_EAR;
 	swi	r11, r1, PTO+PT_EAR;
@@ -801,8 +799,6 @@ C_ENTRY(_debug_exception):
 
 
 	addik	r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack.  */
 	addik	r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack.  */
 	SAVE_REGS;
 	SAVE_REGS;
-	swi	r17, r1, PTO+PT_R17;
-	swi	r16, r1, PTO+PT_R16;
 	swi	r16, r1, PTO+PT_PC;	/* Save LP */
 	swi	r16, r1, PTO+PT_PC;	/* Save LP */
 	swi	r0, r1, PTO + PT_MODE; /* Was in user-mode.  */
 	swi	r0, r1, PTO + PT_MODE; /* Was in user-mode.  */
 	lwi	r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
 	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 */
 	tophys(r1,r1);
 	tophys(r1,r1);
 	/* MS: Restore all regs */
 	/* MS: Restore all regs */
 	RESTORE_REGS
 	RESTORE_REGS
-	lwi	r17, r1, PTO+PT_R17;
-	lwi	r16, r1, PTO+PT_R16;
 	addik	r1, r1, STATE_SAVE_SIZE	 /* Clean up stack space */
 	addik	r1, r1, STATE_SAVE_SIZE	 /* Clean up stack space */
 	lwi	r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
 	lwi	r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
 DBTRAP_return_user: /* MS: Make global symbol for debugging */
 DBTRAP_return_user: /* MS: Make global symbol for debugging */
@@ -863,7 +857,6 @@ DBTRAP_return_user: /* MS: Make global symbol for debugging */
 	RESTORE_REGS
 	RESTORE_REGS
 	lwi	r14, r1, PTO+PT_R14;
 	lwi	r14, r1, PTO+PT_R14;
 	lwi	r16, r1, PTO+PT_PC;
 	lwi	r16, r1, PTO+PT_PC;
-	lwi	r17, r1, PTO+PT_R17;
 	addik	r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */
 	addik	r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */
 	tovirt(r1,r1);
 	tovirt(r1,r1);
 DBTRAP_return_kernel: /* MS: Make global symbol for debugging */
 DBTRAP_return_kernel: /* MS: Make global symbol for debugging */

+ 7 - 18
arch/microblaze/kernel/exceptions.c

@@ -72,7 +72,6 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
 							int fsr, int addr)
 							int fsr, int addr)
 {
 {
 #ifdef CONFIG_MMU
 #ifdef CONFIG_MMU
-	int code;
 	addr = regs->pc;
 	addr = regs->pc;
 #endif
 #endif
 
 
@@ -86,8 +85,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
 	switch (type & 0x1F) {
 	switch (type & 0x1F) {
 	case MICROBLAZE_ILL_OPCODE_EXCEPTION:
 	case MICROBLAZE_ILL_OPCODE_EXCEPTION:
 		if (user_mode(regs)) {
 		if (user_mode(regs)) {
-			pr_debug(KERN_WARNING "Illegal opcode exception " \
-							"in user mode.\n");
+			pr_debug("Illegal opcode exception in user mode\n");
 			_exception(SIGILL, regs, ILL_ILLOPC, addr);
 			_exception(SIGILL, regs, ILL_ILLOPC, addr);
 			return;
 			return;
 		}
 		}
@@ -97,8 +95,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
 		break;
 		break;
 	case MICROBLAZE_IBUS_EXCEPTION:
 	case MICROBLAZE_IBUS_EXCEPTION:
 		if (user_mode(regs)) {
 		if (user_mode(regs)) {
-			pr_debug(KERN_WARNING "Instruction bus error " \
-						"exception in user mode.\n");
+			pr_debug("Instruction bus error exception in user mode\n");
 			_exception(SIGBUS, regs, BUS_ADRERR, addr);
 			_exception(SIGBUS, regs, BUS_ADRERR, addr);
 			return;
 			return;
 		}
 		}
@@ -108,8 +105,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
 		break;
 		break;
 	case MICROBLAZE_DBUS_EXCEPTION:
 	case MICROBLAZE_DBUS_EXCEPTION:
 		if (user_mode(regs)) {
 		if (user_mode(regs)) {
-			pr_debug(KERN_WARNING "Data bus error exception " \
-							"in user mode.\n");
+			pr_debug("Data bus error exception in user mode\n");
 			_exception(SIGBUS, regs, BUS_ADRERR, addr);
 			_exception(SIGBUS, regs, BUS_ADRERR, addr);
 			return;
 			return;
 		}
 		}
@@ -119,8 +115,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
 		break;
 		break;
 	case MICROBLAZE_DIV_ZERO_EXCEPTION:
 	case MICROBLAZE_DIV_ZERO_EXCEPTION:
 		if (user_mode(regs)) {
 		if (user_mode(regs)) {
-			pr_debug(KERN_WARNING "Divide by zero exception " \
-							"in user mode\n");
+			pr_debug("Divide by zero exception in user mode\n");
 			_exception(SIGILL, regs, FPE_INTDIV, addr);
 			_exception(SIGILL, regs, FPE_INTDIV, addr);
 			return;
 			return;
 		}
 		}
@@ -129,7 +124,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
 		die("Divide by zero exception", regs, SIGBUS);
 		die("Divide by zero exception", regs, SIGBUS);
 		break;
 		break;
 	case MICROBLAZE_FPU_EXCEPTION:
 	case MICROBLAZE_FPU_EXCEPTION:
-		pr_debug(KERN_WARNING "FPU exception\n");
+		pr_debug("FPU exception\n");
 		/* IEEE FP exception */
 		/* IEEE FP exception */
 		/* I removed fsr variable and use code var for storing fsr */
 		/* I removed fsr variable and use code var for storing fsr */
 		if (fsr & FSR_IO)
 		if (fsr & FSR_IO)
@@ -147,14 +142,8 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
 
 
 #ifdef CONFIG_MMU
 #ifdef CONFIG_MMU
 	case MICROBLAZE_PRIVILEGED_EXCEPTION:
 	case MICROBLAZE_PRIVILEGED_EXCEPTION:
-		pr_debug(KERN_WARNING "Privileged exception\n");
-		/* "brk r0,r0" - used as debug breakpoint - old toolchain */
-		if (get_user(code, (unsigned long *)regs->pc) == 0
-			&& code == 0x980c0000) {
-			_exception(SIGTRAP, regs, TRAP_BRKPT, addr);
-		} else {
-			_exception(SIGILL, regs, ILL_PRVOPC, addr);
-		}
+		pr_debug("Privileged exception\n");
+		_exception(SIGILL, regs, ILL_PRVOPC, addr);
 		break;
 		break;
 #endif
 #endif
 	default:
 	default:

+ 5 - 6
arch/microblaze/kernel/heartbeat.c

@@ -47,11 +47,10 @@ void setup_heartbeat(void)
 	struct device_node *gpio = NULL;
 	struct device_node *gpio = NULL;
 	int *prop;
 	int *prop;
 	int j;
 	int j;
-	char *gpio_list[] = {
-				"xlnx,xps-gpio-1.00.a",
-				"xlnx,opb-gpio-1.00.a",
-				NULL
-			};
+	const char * const gpio_list[] = {
+		"xlnx,xps-gpio-1.00.a",
+		NULL
+	};
 
 
 	for (j = 0; gpio_list[j] != NULL; j++) {
 	for (j = 0; gpio_list[j] != NULL; j++) {
 		gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]);
 		gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]);
@@ -60,7 +59,7 @@ void setup_heartbeat(void)
 	}
 	}
 
 
 	if (gpio) {
 	if (gpio) {
-		base_addr = *(int *) of_get_property(gpio, "reg", NULL);
+		base_addr = be32_to_cpup(of_get_property(gpio, "reg", NULL));
 		base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
 		base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
 		printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
 		printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
 
 

+ 7 - 7
arch/microblaze/kernel/intc.c

@@ -126,11 +126,8 @@ void __init init_IRQ(void)
 				0
 				0
 			};
 			};
 #endif
 #endif
-	static char *intc_list[] = {
+	const char * const intc_list[] = {
 				"xlnx,xps-intc-1.00.a",
 				"xlnx,xps-intc-1.00.a",
-				"xlnx,opb-intc-1.00.c",
-				"xlnx,opb-intc-1.00.b",
-				"xlnx,opb-intc-1.00.a",
 				NULL
 				NULL
 			};
 			};
 
 
@@ -141,12 +138,15 @@ void __init init_IRQ(void)
 	}
 	}
 	BUG_ON(!intc);
 	BUG_ON(!intc);
 
 
-	intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL);
+	intc_baseaddr = be32_to_cpup(of_get_property(intc,
+								"reg", NULL));
 	intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
 	intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
-	nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL);
+	nr_irq = be32_to_cpup(of_get_property(intc,
+						"xlnx,num-intr-inputs", NULL));
 
 
 	intr_type =
 	intr_type =
-		*(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL);
+		be32_to_cpup(of_get_property(intc,
+						"xlnx,kind-of-intr", NULL));
 	if (intr_type >= (1 << (nr_irq + 1)))
 	if (intr_type >= (1 << (nr_irq + 1)))
 		printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");
 		printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");
 
 

+ 5 - 2
arch/microblaze/kernel/kgdb.c

@@ -80,7 +80,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 void microblaze_kgdb_break(struct pt_regs *regs)
 void microblaze_kgdb_break(struct pt_regs *regs)
 {
 {
 	if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0)
 	if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0)
-		return 0;
+		return;
 
 
 	/* Jump over the first arch_kgdb_breakpoint which is barrier to
 	/* Jump over the first arch_kgdb_breakpoint which is barrier to
 	 * get kgdb work. The same solution is used for powerpc */
 	 * 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,
 {
 {
 	char *ptr;
 	char *ptr;
 	unsigned long address;
 	unsigned long address;
-	int cpu = smp_processor_id();
 
 
 	switch (remcom_in_buffer[0]) {
 	switch (remcom_in_buffer[0]) {
 	case 'c':
 	case 'c':
@@ -143,5 +142,9 @@ void kgdb_arch_exit(void)
  * Global data
  * Global data
  */
  */
 struct kgdb_arch arch_kgdb_ops = {
 struct kgdb_arch arch_kgdb_ops = {
+#ifdef __MICROBLAZEEL__
+	.gdb_bpt_instr = {0x18, 0x00, 0x0c, 0xba}, /* brki r16, 0x18 */
+#else
 	.gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */
 	.gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */
+#endif
 };
 };

+ 7 - 25
arch/microblaze/kernel/microblaze_ksyms.c

@@ -15,37 +15,13 @@
 #include <linux/syscalls.h>
 #include <linux/syscalls.h>
 
 
 #include <asm/checksum.h>
 #include <asm/checksum.h>
+#include <asm/cacheflush.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/system.h>
 #include <asm/system.h>
 #include <linux/ftrace.h>
 #include <linux/ftrace.h>
 #include <linux/uaccess.h>
 #include <linux/uaccess.h>
 
 
-/*
- * libgcc functions - functions that are used internally by the
- * compiler... (prototypes are not correct though, but that
- * doesn't really matter since they're not versioned).
- */
-extern void __ashldi3(void);
-EXPORT_SYMBOL(__ashldi3);
-extern void __ashrdi3(void);
-EXPORT_SYMBOL(__ashrdi3);
-extern void __divsi3(void);
-EXPORT_SYMBOL(__divsi3);
-extern void __lshrdi3(void);
-EXPORT_SYMBOL(__lshrdi3);
-extern void __modsi3(void);
-EXPORT_SYMBOL(__modsi3);
-extern void __mulsi3(void);
-EXPORT_SYMBOL(__mulsi3);
-extern void __muldi3(void);
-EXPORT_SYMBOL(__muldi3);
-extern void __ucmpdi2(void);
-EXPORT_SYMBOL(__ucmpdi2);
-extern void __udivsi3(void);
-EXPORT_SYMBOL(__udivsi3);
-extern void __umodsi3(void);
-EXPORT_SYMBOL(__umodsi3);
 extern char *_ebss;
 extern char *_ebss;
 EXPORT_SYMBOL_GPL(_ebss);
 EXPORT_SYMBOL_GPL(_ebss);
 #ifdef CONFIG_FUNCTION_TRACER
 #ifdef CONFIG_FUNCTION_TRACER
@@ -63,3 +39,9 @@ EXPORT_SYMBOL(__strncpy_user);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memmove);
 EXPORT_SYMBOL(memmove);
 #endif
 #endif
+
+#ifdef CONFIG_MMU
+EXPORT_SYMBOL(empty_zero_page);
+#endif
+
+EXPORT_SYMBOL(mbc);

+ 37 - 2
arch/microblaze/kernel/prom.c

@@ -72,11 +72,12 @@ static int __init early_init_dt_scan_serial(unsigned long node,
 /* find compatible node with uartlite */
 /* find compatible node with uartlite */
 	p = of_get_flat_dt_prop(node, "compatible", &l);
 	p = of_get_flat_dt_prop(node, "compatible", &l);
 	if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
 	if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
-			(strncmp(p, "xlnx,opb-uartlite", 17) != 0))
+			(strncmp(p, "xlnx,opb-uartlite", 17) != 0) &&
+			(strncmp(p, "xlnx,axi-uartlite", 17) != 0))
 		return 0;
 		return 0;
 
 
 	addr = of_get_flat_dt_prop(node, "reg", &l);
 	addr = of_get_flat_dt_prop(node, "reg", &l);
-	return *addr; /* return address */
+	return be32_to_cpup(addr); /* return address */
 }
 }
 
 
 /* this function is looking for early uartlite console - Microblaze specific */
 /* this function is looking for early uartlite console - Microblaze specific */
@@ -84,6 +85,40 @@ int __init early_uartlite_console(void)
 {
 {
 	return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
 	return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
 }
 }
+
+/* MS this is Microblaze specifig function */
+static int __init early_init_dt_scan_serial_full(unsigned long node,
+				const char *uname, int depth, void *data)
+{
+	unsigned long l;
+	char *p;
+	unsigned int addr;
+
+	pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+
+/* find all serial nodes */
+	if (strncmp(uname, "serial", 6) != 0)
+		return 0;
+
+	early_init_dt_check_for_initrd(node);
+
+/* find compatible node with uartlite */
+	p = of_get_flat_dt_prop(node, "compatible", &l);
+
+	if ((strncmp(p, "xlnx,xps-uart16550", 18) != 0) &&
+		(strncmp(p, "xlnx,axi-uart16550", 18) != 0))
+		return 0;
+
+	addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l);
+	addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l);
+	return be32_to_cpu(addr); /* return address */
+}
+
+/* this function is looking for early uartlite console - Microblaze specific */
+int __init early_uart16550_console(void)
+{
+	return of_scan_flat_dt(early_init_dt_scan_serial_full, NULL);
+}
 #endif
 #endif
 
 
 void __init early_init_devtree(void *params)
 void __init early_init_devtree(void *params)

+ 0 - 6
arch/microblaze/kernel/setup.c

@@ -92,12 +92,6 @@ inline unsigned get_romfs_len(unsigned *addr)
 }
 }
 #endif	/* CONFIG_MTD_UCLINUX_EBSS */
 #endif	/* CONFIG_MTD_UCLINUX_EBSS */
 
 
-#if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE)
-#define eprintk early_printk
-#else
-#define eprintk printk
-#endif
-
 void __init machine_early_init(const char *cmdline, unsigned int ram,
 void __init machine_early_init(const char *cmdline, unsigned int ram,
 		unsigned int fdt, unsigned int msr)
 		unsigned int fdt, unsigned int msr)
 {
 {

+ 3 - 0
arch/microblaze/kernel/syscall_table.S

@@ -372,3 +372,6 @@ ENTRY(sys_call_table)
 	.long sys_rt_tgsigqueueinfo	/* 365 */
 	.long sys_rt_tgsigqueueinfo	/* 365 */
 	.long sys_perf_event_open
 	.long sys_perf_event_open
 	.long sys_recvmmsg
 	.long sys_recvmmsg
+	.long sys_fanotify_init
+	.long sys_fanotify_mark
+	.long sys_prlimit64	/* 370 */

+ 25 - 16
arch/microblaze/kernel/timer.c

@@ -38,6 +38,9 @@ static unsigned int timer_baseaddr;
 #define TIMER_BASE	timer_baseaddr
 #define TIMER_BASE	timer_baseaddr
 #endif
 #endif
 
 
+unsigned int freq_div_hz;
+unsigned int timer_clock_freq;
+
 #define TCSR0	(0x00)
 #define TCSR0	(0x00)
 #define TLR0	(0x04)
 #define TLR0	(0x04)
 #define TCR0	(0x08)
 #define TCR0	(0x08)
@@ -115,7 +118,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode,
 	switch (mode) {
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
 	case CLOCK_EVT_MODE_PERIODIC:
 		printk(KERN_INFO "%s: periodic\n", __func__);
 		printk(KERN_INFO "%s: periodic\n", __func__);
-		microblaze_timer0_start_periodic(cpuinfo.freq_div_hz);
+		microblaze_timer0_start_periodic(freq_div_hz);
 		break;
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 	case CLOCK_EVT_MODE_ONESHOT:
 		printk(KERN_INFO "%s: oneshot\n", __func__);
 		printk(KERN_INFO "%s: oneshot\n", __func__);
@@ -168,7 +171,7 @@ static struct irqaction timer_irqaction = {
 static __init void microblaze_clockevent_init(void)
 static __init void microblaze_clockevent_init(void)
 {
 {
 	clockevent_microblaze_timer.mult =
 	clockevent_microblaze_timer.mult =
-		div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC,
+		div_sc(timer_clock_freq, NSEC_PER_SEC,
 				clockevent_microblaze_timer.shift);
 				clockevent_microblaze_timer.shift);
 	clockevent_microblaze_timer.max_delta_ns =
 	clockevent_microblaze_timer.max_delta_ns =
 		clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
 		clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
@@ -201,7 +204,7 @@ static struct cyclecounter microblaze_cc = {
 
 
 int __init init_microblaze_timecounter(void)
 int __init init_microblaze_timecounter(void)
 {
 {
-	microblaze_cc.mult = div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC,
+	microblaze_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
 				microblaze_cc.shift);
 				microblaze_cc.shift);
 
 
 	timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock());
 	timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock());
@@ -221,7 +224,7 @@ static struct clocksource clocksource_microblaze = {
 static int __init microblaze_clocksource_init(void)
 static int __init microblaze_clocksource_init(void)
 {
 {
 	clocksource_microblaze.mult =
 	clocksource_microblaze.mult =
-			clocksource_hz2mult(cpuinfo.cpu_clock_freq,
+			clocksource_hz2mult(timer_clock_freq,
 						clocksource_microblaze.shift);
 						clocksource_microblaze.shift);
 	if (clocksource_register(&clocksource_microblaze))
 	if (clocksource_register(&clocksource_microblaze))
 		panic("failed to register clocksource");
 		panic("failed to register clocksource");
@@ -247,6 +250,7 @@ void __init time_init(void)
 	u32 irq, i = 0;
 	u32 irq, i = 0;
 	u32 timer_num = 1;
 	u32 timer_num = 1;
 	struct device_node *timer = NULL;
 	struct device_node *timer = NULL;
+	const void *prop;
 #ifdef CONFIG_SELFMOD_TIMER
 #ifdef CONFIG_SELFMOD_TIMER
 	unsigned int timer_baseaddr = 0;
 	unsigned int timer_baseaddr = 0;
 	int arr_func[] = {
 	int arr_func[] = {
@@ -258,12 +262,10 @@ void __init time_init(void)
 				0
 				0
 			};
 			};
 #endif
 #endif
-	char *timer_list[] = {
-				"xlnx,xps-timer-1.00.a",
-				"xlnx,opb-timer-1.00.b",
-				"xlnx,opb-timer-1.00.a",
-				NULL
-			};
+	const char * const timer_list[] = {
+		"xlnx,xps-timer-1.00.a",
+		NULL
+	};
 
 
 	for (i = 0; timer_list[i] != NULL; i++) {
 	for (i = 0; timer_list[i] != NULL; i++) {
 		timer = of_find_compatible_node(NULL, NULL, timer_list[i]);
 		timer = of_find_compatible_node(NULL, NULL, timer_list[i]);
@@ -272,13 +274,13 @@ void __init time_init(void)
 	}
 	}
 	BUG_ON(!timer);
 	BUG_ON(!timer);
 
 
-	timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL);
+	timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL));
 	timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
 	timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
-	irq = *(int *) of_get_property(timer, "interrupts", NULL);
-	timer_num =
-		*(int *) of_get_property(timer, "xlnx,one-timer-only", NULL);
+	irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL));
+	timer_num = be32_to_cpup(of_get_property(timer,
+						"xlnx,one-timer-only", NULL));
 	if (timer_num) {
 	if (timer_num) {
-		printk(KERN_EMERG "Please enable two timers in HW\n");
+		eprintk(KERN_EMERG "Please enable two timers in HW\n");
 		BUG();
 		BUG();
 	}
 	}
 
 
@@ -288,7 +290,14 @@ void __init time_init(void)
 	printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
 	printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
 		timer_list[i], timer_baseaddr, irq);
 		timer_list[i], timer_baseaddr, irq);
 
 
-	cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ;
+	/* If there is clock-frequency property than use it */
+	prop = of_get_property(timer, "clock-frequency", NULL);
+	if (prop)
+		timer_clock_freq = be32_to_cpup(prop);
+	else
+		timer_clock_freq = cpuinfo.cpu_clock_freq;
+
+	freq_div_hz = timer_clock_freq / HZ;
 
 
 	setup_irq(irq, &timer_irqaction);
 	setup_irq(irq, &timer_irqaction);
 #ifdef CONFIG_HEART_BEAT
 #ifdef CONFIG_HEART_BEAT

+ 4 - 1
arch/microblaze/kernel/vmlinux.lds.S

@@ -8,7 +8,6 @@
  * for more details.
  * for more details.
  */
  */
 
 
-OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
 OUTPUT_ARCH(microblaze)
 OUTPUT_ARCH(microblaze)
 ENTRY(microblaze_start)
 ENTRY(microblaze_start)
 
 
@@ -16,7 +15,11 @@ ENTRY(microblaze_start)
 #include <asm-generic/vmlinux.lds.h>
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/thread_info.h>
 #include <asm/thread_info.h>
 
 
+#ifdef __MICROBLAZEEL__
+jiffies = jiffies_64;
+#else
 jiffies = jiffies_64 + 4;
 jiffies = jiffies_64 + 4;
+#endif
 
 
 SECTIONS {
 SECTIONS {
 	. = CONFIG_KERNEL_START;
 	. = CONFIG_KERNEL_START;

+ 10 - 0
arch/microblaze/lib/Makefile

@@ -11,3 +11,13 @@ lib-y += memcpy.o memmove.o
 endif
 endif
 
 
 lib-y += uaccess_old.o
 lib-y += uaccess_old.o
+
+lib-y += ashldi3.o
+lib-y += ashrdi3.o
+lib-y += divsi3.o
+lib-y += lshrdi3.o
+lib-y += modsi3.o
+lib-y += muldi3.o
+lib-y += mulsi3.o
+lib-y += udivsi3.o
+lib-y += umodsi3.o

+ 29 - 0
arch/microblaze/lib/ashldi3.c

@@ -0,0 +1,29 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __ashldi3(long long u, word_type b)
+{
+	DWunion uu, w;
+	word_type bm;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+	bm = 32 - b;
+
+	if (bm <= 0) {
+		w.s.low = 0;
+		w.s.high = (unsigned int) uu.s.low << -bm;
+	} else {
+		const unsigned int carries = (unsigned int) uu.s.low >> bm;
+
+		w.s.low = (unsigned int) uu.s.low << b;
+		w.s.high = ((unsigned int) uu.s.high << b) | carries;
+	}
+
+	return w.ll;
+}
+
+EXPORT_SYMBOL(__ashldi3);

+ 31 - 0
arch/microblaze/lib/ashrdi3.c

@@ -0,0 +1,31 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __ashrdi3(long long u, word_type b)
+{
+	DWunion uu, w;
+	word_type bm;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+	bm = 32 - b;
+
+	if (bm <= 0) {
+		/* w.s.high = 1..1 or 0..0 */
+		w.s.high =
+		    uu.s.high >> 31;
+		w.s.low = uu.s.high >> -bm;
+	} else {
+		const unsigned int carries = (unsigned int) uu.s.high << bm;
+
+		w.s.high = uu.s.high >> b;
+		w.s.low = ((unsigned int) uu.s.low >> b) | carries;
+	}
+
+	return w.ll;
+}
+
+EXPORT_SYMBOL(__ashrdi3);

+ 73 - 0
arch/microblaze/lib/divsi3.S

@@ -0,0 +1,73 @@
+#include <linux/linkage.h>
+
+/*
+* Divide operation for 32 bit integers.
+*	Input :	Dividend in Reg r5
+*		Divisor in Reg r6
+*	Output: Result in Reg r3
+*/
+	.text
+	.globl	__divsi3
+	.type __divsi3, @function
+	.ent __divsi3
+__divsi3:
+	.frame	r1, 0, r15
+
+	addik	r1, r1, -16
+	swi	r28, r1, 0
+	swi	r29, r1, 4
+	swi	r30, r1, 8
+	swi	r31, r1, 12
+
+	beqi	r6, div_by_zero /* div_by_zero - division error */
+	beqi	r5, result_is_zero /* result is zero */
+	bgeid	r5, r5_pos
+	xor	r28, r5, r6 /* get the sign of the result */
+	rsubi	r5, r5, 0 /* make r5 positive */
+r5_pos:
+	bgei	r6, r6_pos
+	rsubi	r6, r6, 0 /* make r6 positive */
+r6_pos:
+	addik	r30, r0, 0 /* clear mod */
+	addik	r3, r0, 0 /* clear div */
+	addik	r29, r0, 32 /* initialize the loop count */
+
+	/* first part try to find the first '1' in the r5 */
+div0:
+	blti	r5, div2 /* this traps r5 == 0x80000000 */
+div1:
+	add	r5, r5, r5 /* left shift logical r5 */
+	bgtid	r5, div1
+	addik	r29, r29, -1
+div2:
+	/* left shift logical r5 get the '1' into the carry */
+	add	r5, r5, r5
+	addc	r30, r30, r30 /* move that bit into the mod register */
+	rsub	r31, r6, r30 /* try to subtract (r30 a r6) */
+	blti	r31, mod_too_small
+	/* move the r31 to mod since the result was positive */
+	or	r30, r0, r31
+	addik	r3, r3, 1
+mod_too_small:
+	addik	r29, r29, -1
+	beqi	r29, loop_end
+	add	r3, r3, r3 /* shift in the '1' into div */
+	bri	div2 /* div2 */
+loop_end:
+	bgei	r28, return_here
+	brid	return_here
+	rsubi	r3, r3, 0 /* negate the result */
+div_by_zero:
+result_is_zero:
+	or	r3, r0, r0 /* set result to 0 */
+return_here:
+/* restore values of csrs and that of r3 and the divisor and the dividend */
+	lwi	r28, r1, 0
+	lwi	r29, r1, 4
+	lwi	r30, r1, 8
+	lwi	r31, r1, 12
+	rtsd	r15, 8
+	addik	r1, r1, 16
+
+.size __divsi3, . - __divsi3
+.end __divsi3

+ 25 - 0
arch/microblaze/lib/libgcc.h

@@ -0,0 +1,25 @@
+#ifndef __ASM_LIBGCC_H
+#define __ASM_LIBGCC_H
+
+#include <asm/byteorder.h>
+
+typedef int word_type __attribute__ ((mode (__word__)));
+
+#ifdef __BIG_ENDIAN
+struct DWstruct {
+	int high, low;
+};
+#elif defined(__LITTLE_ENDIAN)
+struct DWstruct {
+	int low, high;
+};
+#else
+#error I feel sick.
+#endif
+
+typedef union {
+	struct DWstruct s;
+	long long ll;
+} DWunion;
+
+#endif /* __ASM_LIBGCC_H */

+ 29 - 0
arch/microblaze/lib/lshrdi3.c

@@ -0,0 +1,29 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __lshrdi3(long long u, word_type b)
+{
+	DWunion uu, w;
+	word_type bm;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+	bm = 32 - b;
+
+	if (bm <= 0) {
+		w.s.high = 0;
+		w.s.low = (unsigned int) uu.s.high >> -bm;
+	} else {
+		const unsigned int carries = (unsigned int) uu.s.high << bm;
+
+		w.s.high = (unsigned int) uu.s.high >> b;
+		w.s.low = ((unsigned int) uu.s.low >> b) | carries;
+	}
+
+	return w.ll;
+}
+
+EXPORT_SYMBOL(__lshrdi3);

+ 40 - 6
arch/microblaze/lib/memcpy.c

@@ -33,17 +33,24 @@
 #include <asm/system.h>
 #include <asm/system.h>
 
 
 #ifdef __HAVE_ARCH_MEMCPY
 #ifdef __HAVE_ARCH_MEMCPY
+#ifndef CONFIG_OPT_LIB_FUNCTION
 void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
 void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
 {
 {
 	const char *src = v_src;
 	const char *src = v_src;
 	char *dst = v_dst;
 	char *dst = v_dst;
-#ifndef CONFIG_OPT_LIB_FUNCTION
+
 	/* Simple, byte oriented memcpy. */
 	/* Simple, byte oriented memcpy. */
 	while (c--)
 	while (c--)
 		*dst++ = *src++;
 		*dst++ = *src++;
 
 
 	return v_dst;
 	return v_dst;
-#else
+}
+#else /* CONFIG_OPT_LIB_FUNCTION */
+void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
+{
+	const char *src = v_src;
+	char *dst = v_dst;
+
 	/* The following code tries to optimize the copy by using unsigned
 	/* The following code tries to optimize the copy by using unsigned
 	 * alignment. This will work fine if both source and destination are
 	 * alignment. This will work fine if both source and destination are
 	 * aligned on the same boundary. However, if they are aligned on
 	 * 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)
 		case 0x1:	/* Unaligned - Off by 1 */
 		case 0x1:	/* Unaligned - Off by 1 */
 			/* Word align the source */
 			/* Word align the source */
 			i_src = (const void *) ((unsigned)src & ~3);
 			i_src = (const void *) ((unsigned)src & ~3);
-
+#ifndef __MICROBLAZEEL__
 			/* Load the holding buffer */
 			/* Load the holding buffer */
 			buf_hold = *i_src++ << 8;
 			buf_hold = *i_src++ << 8;
 
 
@@ -95,7 +102,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
 				*i_dst++ = buf_hold | value >> 24;
 				*i_dst++ = buf_hold | value >> 24;
 				buf_hold = value << 8;
 				buf_hold = value << 8;
 			}
 			}
+#else
+			/* Load the holding buffer */
+			buf_hold = (*i_src++ & 0xFFFFFF00) >>8;
 
 
+			for (; c >= 4; c -= 4) {
+				value = *i_src++;
+				*i_dst++ = buf_hold | ((value & 0xFF) << 24);
+				buf_hold = (value & 0xFFFFFF00) >>8;
+			}
+#endif
 			/* Realign the source */
 			/* Realign the source */
 			src = (const void *)i_src;
 			src = (const void *)i_src;
 			src -= 3;
 			src -= 3;
@@ -103,7 +119,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
 		case 0x2:	/* Unaligned - Off by 2 */
 		case 0x2:	/* Unaligned - Off by 2 */
 			/* Word align the source */
 			/* Word align the source */
 			i_src = (const void *) ((unsigned)src & ~3);
 			i_src = (const void *) ((unsigned)src & ~3);
-
+#ifndef __MICROBLAZEEL__
 			/* Load the holding buffer */
 			/* Load the holding buffer */
 			buf_hold = *i_src++ << 16;
 			buf_hold = *i_src++ << 16;
 
 
@@ -112,7 +128,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
 				*i_dst++ = buf_hold | value >> 16;
 				*i_dst++ = buf_hold | value >> 16;
 				buf_hold = value << 16;
 				buf_hold = value << 16;
 			}
 			}
+#else
+			/* Load the holding buffer */
+			buf_hold = (*i_src++ & 0xFFFF0000 )>>16;
 
 
+			for (; c >= 4; c -= 4) {
+				value = *i_src++;
+				*i_dst++ = buf_hold | ((value & 0xFFFF)<<16);
+				buf_hold = (value & 0xFFFF0000) >>16;
+			}
+#endif
 			/* Realign the source */
 			/* Realign the source */
 			src = (const void *)i_src;
 			src = (const void *)i_src;
 			src -= 2;
 			src -= 2;
@@ -120,7 +145,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
 		case 0x3:	/* Unaligned - Off by 3 */
 		case 0x3:	/* Unaligned - Off by 3 */
 			/* Word align the source */
 			/* Word align the source */
 			i_src = (const void *) ((unsigned)src & ~3);
 			i_src = (const void *) ((unsigned)src & ~3);
-
+#ifndef __MICROBLAZEEL__
 			/* Load the holding buffer */
 			/* Load the holding buffer */
 			buf_hold = *i_src++ << 24;
 			buf_hold = *i_src++ << 24;
 
 
@@ -129,7 +154,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
 				*i_dst++ = buf_hold | value >> 8;
 				*i_dst++ = buf_hold | value >> 8;
 				buf_hold = value << 24;
 				buf_hold = value << 24;
 			}
 			}
+#else
+			/* Load the holding buffer */
+			buf_hold = (*i_src++ & 0xFF000000) >> 24;
 
 
+			for (; c >= 4; c -= 4) {
+				value = *i_src++;
+				*i_dst++ = buf_hold | ((value & 0xFFFFFF) << 8);
+				buf_hold = (value & 0xFF000000) >> 24;
+			}
+#endif
 			/* Realign the source */
 			/* Realign the source */
 			src = (const void *)i_src;
 			src = (const void *)i_src;
 			src -= 1;
 			src -= 1;
@@ -150,7 +184,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
 	}
 	}
 
 
 	return v_dst;
 	return v_dst;
-#endif
 }
 }
+#endif /* CONFIG_OPT_LIB_FUNCTION */
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memcpy);
 #endif /* __HAVE_ARCH_MEMCPY */
 #endif /* __HAVE_ARCH_MEMCPY */

+ 48 - 11
arch/microblaze/lib/memmove.c

@@ -31,16 +31,12 @@
 #include <linux/string.h>
 #include <linux/string.h>
 
 
 #ifdef __HAVE_ARCH_MEMMOVE
 #ifdef __HAVE_ARCH_MEMMOVE
+#ifndef CONFIG_OPT_LIB_FUNCTION
 void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
 void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
 {
 {
 	const char *src = v_src;
 	const char *src = v_src;
 	char *dst = v_dst;
 	char *dst = v_dst;
 
 
-#ifdef CONFIG_OPT_LIB_FUNCTION
-	const uint32_t *i_src;
-	uint32_t *i_dst;
-#endif
-
 	if (!c)
 	if (!c)
 		return v_dst;
 		return v_dst;
 
 
@@ -48,7 +44,6 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
 	if (v_dst <= v_src)
 	if (v_dst <= v_src)
 		return memcpy(v_dst, v_src, c);
 		return memcpy(v_dst, v_src, c);
 
 
-#ifndef CONFIG_OPT_LIB_FUNCTION
 	/* copy backwards, from end to beginning */
 	/* copy backwards, from end to beginning */
 	src += c;
 	src += c;
 	dst += c;
 	dst += c;
@@ -58,7 +53,22 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
 		*--dst = *--src;
 		*--dst = *--src;
 
 
 	return v_dst;
 	return v_dst;
-#else
+}
+#else /* CONFIG_OPT_LIB_FUNCTION */
+void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
+{
+	const char *src = v_src;
+	char *dst = v_dst;
+	const uint32_t *i_src;
+	uint32_t *i_dst;
+
+	if (!c)
+		return v_dst;
+
+	/* Use memcpy when source is higher than dest */
+	if (v_dst <= v_src)
+		return memcpy(v_dst, v_src, c);
+
 	/* The following code tries to optimize the copy by using unsigned
 	/* The following code tries to optimize the copy by using unsigned
 	 * alignment. This will work fine if both source and destination are
 	 * alignment. This will work fine if both source and destination are
 	 * aligned on the same boundary. However, if they are aligned on
 	 * 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)
 		case 0x1:	/* Unaligned - Off by 1 */
 		case 0x1:	/* Unaligned - Off by 1 */
 			/* Word align the source */
 			/* Word align the source */
 			i_src = (const void *) (((unsigned)src + 4) & ~3);
 			i_src = (const void *) (((unsigned)src + 4) & ~3);
-
+#ifndef __MICROBLAZEEL__
 			/* Load the holding buffer */
 			/* Load the holding buffer */
 			buf_hold = *--i_src >> 24;
 			buf_hold = *--i_src >> 24;
 
 
@@ -113,7 +123,16 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
 				*--i_dst = buf_hold << 8 | value;
 				*--i_dst = buf_hold << 8 | value;
 				buf_hold = value >> 24;
 				buf_hold = value >> 24;
 			}
 			}
+#else
+			/* Load the holding buffer */
+			buf_hold = (*--i_src & 0xFF) << 24;
 
 
+			for (; c >= 4; c -= 4) {
+				value = *--i_src;
+				*--i_dst = buf_hold | ((value & 0xFFFFFF00)>>8);
+				buf_hold = (value  & 0xFF) << 24;
+			}
+#endif
 			/* Realign the source */
 			/* Realign the source */
 			src = (const void *)i_src;
 			src = (const void *)i_src;
 			src += 1;
 			src += 1;
@@ -121,7 +140,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
 		case 0x2:	/* Unaligned - Off by 2 */
 		case 0x2:	/* Unaligned - Off by 2 */
 			/* Word align the source */
 			/* Word align the source */
 			i_src = (const void *) (((unsigned)src + 4) & ~3);
 			i_src = (const void *) (((unsigned)src + 4) & ~3);
-
+#ifndef __MICROBLAZEEL__
 			/* Load the holding buffer */
 			/* Load the holding buffer */
 			buf_hold = *--i_src >> 16;
 			buf_hold = *--i_src >> 16;
 
 
@@ -130,7 +149,16 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
 				*--i_dst = buf_hold << 16 | value;
 				*--i_dst = buf_hold << 16 | value;
 				buf_hold = value >> 16;
 				buf_hold = value >> 16;
 			}
 			}
+#else
+			/* Load the holding buffer */
+			buf_hold = (*--i_src & 0xFFFF) << 16;
 
 
+			for (; c >= 4; c -= 4) {
+				value = *--i_src;
+				*--i_dst = buf_hold | ((value & 0xFFFF0000)>>16);
+				buf_hold = (value & 0xFFFF) << 16;
+			}
+#endif
 			/* Realign the source */
 			/* Realign the source */
 			src = (const void *)i_src;
 			src = (const void *)i_src;
 			src += 2;
 			src += 2;
@@ -138,7 +166,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
 		case 0x3:	/* Unaligned - Off by 3 */
 		case 0x3:	/* Unaligned - Off by 3 */
 			/* Word align the source */
 			/* Word align the source */
 			i_src = (const void *) (((unsigned)src + 4) & ~3);
 			i_src = (const void *) (((unsigned)src + 4) & ~3);
-
+#ifndef __MICROBLAZEEL__
 			/* Load the holding buffer */
 			/* Load the holding buffer */
 			buf_hold = *--i_src >> 8;
 			buf_hold = *--i_src >> 8;
 
 
@@ -147,7 +175,16 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
 				*--i_dst = buf_hold << 24 | value;
 				*--i_dst = buf_hold << 24 | value;
 				buf_hold = value >> 8;
 				buf_hold = value >> 8;
 			}
 			}
+#else
+			/* Load the holding buffer */
+			buf_hold = (*--i_src & 0xFFFFFF) << 8;
 
 
+			for (; c >= 4; c -= 4) {
+				value = *--i_src;
+				*--i_dst = buf_hold | ((value & 0xFF000000)>> 24);
+				buf_hold = (value & 0xFFFFFF) << 8;;
+			}
+#endif
 			/* Realign the source */
 			/* Realign the source */
 			src = (const void *)i_src;
 			src = (const void *)i_src;
 			src += 3;
 			src += 3;
@@ -169,7 +206,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
 		*--dst = *--src;
 		*--dst = *--src;
 	}
 	}
 	return v_dst;
 	return v_dst;
-#endif
 }
 }
+#endif /* CONFIG_OPT_LIB_FUNCTION */
 EXPORT_SYMBOL(memmove);
 EXPORT_SYMBOL(memmove);
 #endif /* __HAVE_ARCH_MEMMOVE */
 #endif /* __HAVE_ARCH_MEMMOVE */

+ 18 - 4
arch/microblaze/lib/memset.c

@@ -31,17 +31,30 @@
 #include <linux/string.h>
 #include <linux/string.h>
 
 
 #ifdef __HAVE_ARCH_MEMSET
 #ifdef __HAVE_ARCH_MEMSET
+#ifndef CONFIG_OPT_LIB_FUNCTION
+void *memset(void *v_src, int c, __kernel_size_t n)
+{
+	char *src = v_src;
+
+	/* Truncate c to 8 bits */
+	c = (c & 0xFF);
+
+	/* Simple, byte oriented memset or the rest of count. */
+	while (n--)
+		*src++ = c;
+
+	return v_src;
+}
+#else /* CONFIG_OPT_LIB_FUNCTION */
 void *memset(void *v_src, int c, __kernel_size_t n)
 void *memset(void *v_src, int c, __kernel_size_t n)
 {
 {
 	char *src = v_src;
 	char *src = v_src;
-#ifdef CONFIG_OPT_LIB_FUNCTION
 	uint32_t *i_src;
 	uint32_t *i_src;
 	uint32_t w32 = 0;
 	uint32_t w32 = 0;
-#endif
+
 	/* Truncate c to 8 bits */
 	/* Truncate c to 8 bits */
 	c = (c & 0xFF);
 	c = (c & 0xFF);
 
 
-#ifdef CONFIG_OPT_LIB_FUNCTION
 	if (unlikely(c)) {
 	if (unlikely(c)) {
 		/* Make a repeating word out of it */
 		/* Make a repeating word out of it */
 		w32 = c;
 		w32 = c;
@@ -72,12 +85,13 @@ void *memset(void *v_src, int c, __kernel_size_t n)
 
 
 		src  = (void *)i_src;
 		src  = (void *)i_src;
 	}
 	}
-#endif
+
 	/* Simple, byte oriented memset or the rest of count. */
 	/* Simple, byte oriented memset or the rest of count. */
 	while (n--)
 	while (n--)
 		*src++ = c;
 		*src++ = c;
 
 
 	return v_src;
 	return v_src;
 }
 }
+#endif /* CONFIG_OPT_LIB_FUNCTION */
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(memset);
 #endif /* __HAVE_ARCH_MEMSET */
 #endif /* __HAVE_ARCH_MEMSET */

+ 73 - 0
arch/microblaze/lib/modsi3.S

@@ -0,0 +1,73 @@
+#include <linux/linkage.h>
+
+/*
+* modulo operation for 32 bit integers.
+*	Input :	op1 in Reg r5
+*		op2 in Reg r6
+*	Output: op1 mod op2 in Reg r3
+*/
+
+	.text
+	.globl	__modsi3
+	.type __modsi3,  @function
+	.ent __modsi3
+
+__modsi3:
+	.frame	r1, 0, r15
+
+	addik	r1, r1, -16
+	swi	r28, r1, 0
+	swi	r29, r1, 4
+	swi	r30, r1, 8
+	swi	r31, r1, 12
+
+	beqi	r6, div_by_zero /* div_by_zero division error */
+	beqi	r5, result_is_zero /* result is zero */
+	bgeid	r5, r5_pos
+	/* get the sign of the result [ depends only on the first arg] */
+	add	r28, r5, r0
+	rsubi	r5, r5, 0	 /* make r5 positive */
+r5_pos:
+	bgei	r6, r6_pos
+	rsubi	r6, r6, 0	 /* make r6 positive */
+r6_pos:
+	addik	r3, r0, 0 /* clear mod */
+	addik	r30, r0, 0 /* clear div */
+	addik	r29, r0, 32 /* initialize the loop count */
+/* first part try to find the first '1' in the r5 */
+div1:
+	add	r5, r5, r5 /* left shift logical r5 */
+	bgeid	r5, div1
+	addik	r29, r29, -1
+div2:
+	/* left shift logical r5 get the '1' into the carry */
+	add	r5, r5, r5
+	addc	r3, r3, r3 /* move that bit into the mod register */
+	rsub	r31, r6, r3 /* try to subtract (r30 a r6) */
+	blti	r31, mod_too_small
+	/* move the r31 to mod since the result was positive */
+	or	r3, r0, r31
+	addik	r30, r30, 1
+mod_too_small:
+	addik	r29, r29, -1
+	beqi	r29, loop_end
+	add	r30, r30, r30 /* shift in the '1' into div */
+	bri	div2 /* div2 */
+loop_end:
+	bgei	r28, return_here
+	brid	return_here
+	rsubi	r3, r3, 0 /* negate the result */
+div_by_zero:
+result_is_zero:
+	or	r3, r0, r0 /* set result to 0 [both mod as well as div are 0] */
+return_here:
+/* restore values of csrs and that of r3 and the divisor and the dividend */
+	lwi	r28, r1, 0
+	lwi	r29, r1, 4
+	lwi	r30, r1, 8
+	lwi	r31, r1, 12
+	rtsd	r15, 8
+	addik	r1, r1, 16
+
+.size __modsi3,  . - __modsi3
+.end __modsi3

+ 121 - 0
arch/microblaze/lib/muldi3.S

@@ -0,0 +1,121 @@
+#include <linux/linkage.h>
+
+/*
+ * Multiply operation for 64 bit integers, for devices with hard multiply
+ *	Input :	Operand1[H] in Reg r5
+ *		Operand1[L] in Reg r6
+ *		Operand2[H] in Reg r7
+ *		Operand2[L] in Reg r8
+ *	Output: Result[H] in Reg r3
+ *		Result[L] in Reg r4
+ *
+ * Explaination:
+ *
+ *	Both the input numbers are divided into 16 bit number as follows
+ *		op1 = A B C D
+ *		op2 = E F G H
+ *	result = D * H
+ *		 + (C * H + D * G) << 16
+ *		 + (B * H + C * G + D * F) << 32
+ *		 + (A * H + B * G + C * F + D * E) << 48
+ *
+ *	Only 64 bits of the output are considered
+ */
+
+	.text
+	.globl	__muldi3
+	.type __muldi3, @function
+	.ent __muldi3
+
+__muldi3:
+	addi	r1, r1, -40
+
+/* Save the input operands on the caller's stack */
+	swi	r5, r1, 44
+	swi	r6, r1, 48
+	swi	r7, r1, 52
+	swi	r8, r1, 56
+
+/* Store all the callee saved registers */
+	sw	r20, r1, r0
+	swi	r21, r1, 4
+	swi	r22, r1, 8
+	swi	r23, r1, 12
+	swi	r24, r1, 16
+	swi	r25, r1, 20
+	swi	r26, r1, 24
+	swi	r27, r1, 28
+
+/* Load all the 16 bit values for A thru H */
+	lhui	r20, r1, 44 /* A */
+	lhui	r21, r1, 46 /* B */
+	lhui	r22, r1, 48 /* C */
+	lhui	r23, r1, 50 /* D */
+	lhui	r24, r1, 52 /* E */
+	lhui	r25, r1, 54 /* F */
+	lhui	r26, r1, 56 /* G */
+	lhui	r27, r1, 58 /* H */
+
+/* D * H ==> LSB of the result on stack ==> Store1 */
+	mul	r9, r23, r27
+	swi	r9, r1, 36 /* Pos2 and Pos3 */
+
+/* Hi (Store1) + C * H + D * G ==> Store2 ==> Pos1 and Pos2 */
+/* Store the carry generated in position 2 for Pos 3 */
+	lhui	r11, r1, 36 /* Pos2 */
+	mul	r9, r22, r27 /* C * H */
+	mul	r10, r23, r26 /* D * G */
+	add	r9, r9, r10
+	addc	r12, r0, r0
+	add	r9, r9, r11
+	addc	r12, r12, r0 /* Store the Carry */
+	shi	r9, r1, 36 /* Store Pos2 */
+	swi	r9, r1, 32
+	lhui	r11, r1, 32
+	shi	r11, r1, 34 /* Store Pos1 */
+
+/* Hi (Store2) + B * H + C * G + D * F ==> Store3 ==> Pos0 and Pos1 */
+	mul	r9, r21, r27 /* B * H */
+	mul	r10, r22, r26 /* C * G */
+	mul	r7, r23, r25 /* D * F */
+	add	r9, r9, r11
+	add	r9, r9, r10
+	add	r9, r9, r7
+	swi	r9, r1, 32 /* Pos0 and Pos1 */
+
+/* Hi (Store3) + A * H + B * G + C * F + D * E ==> Store3 ==> Pos0 */
+	lhui	r11, r1, 32 /* Pos0 */
+	mul	r9, r20, r27 /* A * H */
+	mul	r10, r21, r26 /* B * G */
+	mul	r7, r22, r25 /* C * F */
+	mul	r8, r23, r24 /* D * E */
+	add	r9, r9, r11
+	add 	r9, r9, r10
+	add	r9, r9, r7
+	add	r9, r9, r8
+	sext16	r9, r9 /* Sign extend the MSB */
+	shi	r9, r1, 32
+
+/* Move results to r3 and r4 */
+	lhui	r3, r1, 32
+	add	r3, r3, r12
+	shi	r3, r1, 32
+	lwi	r3, r1, 32 /* Hi Part */
+	lwi	r4, r1, 36 /* Lo Part */
+
+/* Restore Callee saved registers */
+	lw	r20, r1, r0
+	lwi	r21, r1, 4
+	lwi	r22, r1, 8
+	lwi	r23, r1, 12
+	lwi	r24, r1, 16
+	lwi	r25, r1, 20
+	lwi	r26, r1, 24
+	lwi	r27, r1, 28
+
+/* Restore Frame and return */
+	rtsd	r15, 8
+	addi	r1, r1, 40
+
+.size __muldi3, . - __muldi3
+.end __muldi3

+ 46 - 0
arch/microblaze/lib/mulsi3.S

@@ -0,0 +1,46 @@
+#include <linux/linkage.h>
+
+/*
+ * Multiply operation for 32 bit integers.
+ *	Input :	Operand1 in Reg r5
+ *		Operand2 in Reg r6
+ *	Output: Result [op1 * op2] in Reg r3
+ */
+	.text
+	.globl	__mulsi3
+	.type __mulsi3,  @function
+	.ent __mulsi3
+
+__mulsi3:
+	.frame	r1, 0, r15
+	add	r3, r0, r0
+	beqi	r5, result_is_zero /* multiply by zero */
+	beqi	r6, result_is_zero /* multiply by zero */
+	bgeid	r5, r5_pos
+	xor	r4, r5, r6 /* get the sign of the result */
+	rsubi	r5, r5, 0 /* make r5 positive */
+r5_pos:
+	bgei	r6, r6_pos
+	rsubi	r6, r6, 0 /* make r6 positive */
+r6_pos:
+	bri	l1
+l2:
+	add	r5, r5, r5
+l1:
+	srl	r6, r6
+	addc	r7, r0, r0
+	beqi	r7, l2
+	bneid	r6, l2
+	add	r3, r3, r5
+	blti	r4, negateresult
+	rtsd	r15, 8
+	nop
+negateresult:
+	rtsd	r15, 8
+	rsub	r3, r3, r0
+result_is_zero:
+	rtsd	r15, 8
+	addi	r3, r0, 0
+
+.size __mulsi3,  . - __mulsi3
+.end __mulsi3

+ 84 - 0
arch/microblaze/lib/udivsi3.S

@@ -0,0 +1,84 @@
+#include <linux/linkage.h>
+
+/*
+* Unsigned divide operation.
+*	Input :	Divisor in Reg r5
+*		Dividend in Reg r6
+*	Output: Result in Reg r3
+*/
+
+	.text
+	.globl	__udivsi3
+	.type __udivsi3, @function
+	.ent __udivsi3
+
+__udivsi3:
+
+	.frame	r1, 0, r15
+
+	addik	r1, r1, -12
+	swi	r29, r1, 0
+	swi	r30, r1, 4
+	swi	r31, r1, 8
+
+	beqi	r6, div_by_zero /* div_by_zero /* division error */
+	beqid	r5, result_is_zero /* result is zero */
+	addik	r30, r0, 0 /* clear mod */
+	addik	r29, r0, 32 /* initialize the loop count */
+
+/* check if r6 and r5 are equal - if yes, return 1 */
+	rsub	r18, r5, r6
+	beqid	r18, return_here
+	addik	r3, r0, 1
+
+/* check if (uns)r6 is greater than (uns)r5. in that case, just return 0 */
+	xor	r18, r5, r6
+	bgeid	r18, 16
+	add	r3, r0, r0 /* we would anyways clear r3 */
+	blti	r6, return_here /* r6[bit 31 = 1] hence is greater */
+	bri	checkr6
+	rsub	r18, r6, r5 /* microblazecmp */
+	blti	r18, return_here
+
+/* if r6 [bit 31] is set, then return result as 1 */
+checkr6:
+	bgti	r6, div0
+	brid	return_here
+	addik	r3, r0, 1
+
+/* first part try to find the first '1' in the r5 */
+div0:
+	blti	r5, div2
+div1:
+	add	r5, r5, r5 /* left shift logical r5 */
+	bgtid	r5, div1
+	addik	r29, r29, -1
+div2:
+/* left shift logical r5 get the '1' into the carry */
+	add	r5, r5, r5
+	addc	r30, r30, r30 /* move that bit into the mod register */
+	rsub	r31, r6, r30 /* try to subtract (r30 a r6) */
+	blti	r31, mod_too_small
+/* move the r31 to mod since the result was positive */
+	or	r30, r0, r31
+	addik	r3, r3, 1
+mod_too_small:
+	addik	r29, r29, -1
+	beqi	r29, loop_end
+	add	r3, r3, r3 /* shift in the '1' into div */
+	bri	div2 /* div2 */
+loop_end:
+	bri	return_here
+div_by_zero:
+result_is_zero:
+	or	r3, r0, r0 /* set result to 0 */
+return_here:
+/* restore values of csrs and that of r3 and the divisor and the dividend */
+	lwi	r29, r1, 0
+	lwi	r30, r1, 4
+	lwi	r31, r1, 8
+	rtsd	r15, 8
+	addik	r1, r1, 12
+
+.size __udivsi3, . - __udivsi3
+.end __udivsi3

+ 86 - 0
arch/microblaze/lib/umodsi3.S

@@ -0,0 +1,86 @@
+#include <linux/linkage.h>
+
+/*
+ * Unsigned modulo operation for 32 bit integers.
+ *	Input :	op1 in Reg r5
+ *		op2 in Reg r6
+ *	Output: op1 mod op2 in Reg r3
+ */
+
+	.text
+	.globl	__umodsi3
+	.type __umodsi3, @function
+	.ent __umodsi3
+
+__umodsi3:
+	.frame	r1, 0, r15
+
+	addik	r1, r1, -12
+	swi	r29, r1, 0
+	swi	r30, r1, 4
+	swi	r31, r1, 8
+
+	beqi	r6, div_by_zero /* div_by_zero - division error */
+	beqid	r5, result_is_zero /* result is zero */
+	addik	r3, r0, 0 /* clear div */
+	addik	r30, r0, 0 /* clear mod */
+	addik	r29, r0, 32 /* initialize the loop count */
+
+/* check if r6 and r5 are equal /* if yes, return 0 */
+	rsub	r18, r5, r6
+	beqi	r18, return_here
+
+/* check if (uns)r6 is greater than (uns)r5. in that case, just return r5 */
+	xor	r18, r5, r6
+	bgeid	r18, 16
+	addik	r3, r5, 0
+	blti	r6, return_here
+	bri	$lcheckr6
+	rsub	r18, r5, r6 /* microblazecmp */
+	bgti	r18, return_here
+
+/* if r6 [bit 31] is set, then return result as r5-r6 */
+$lcheckr6:
+	bgtid	r6, div0
+	addik	r3, r0, 0
+	addik	r18, r0, 0x7fffffff
+	and	r5, r5, r18
+	and	r6, r6, r18
+	brid	return_here
+	rsub	r3, r6, r5
+/* first part: try to find the first '1' in the r5 */
+div0:
+	blti	r5, div2
+div1:
+	add	r5, r5, r5 /* left shift logical r5 */
+	bgeid	r5, div1
+	addik	r29, r29, -1
+div2:
+	/* left shift logical r5 get the '1' into the carry */
+	add	r5, r5, r5
+	addc	r3, r3, r3 /* move that bit into the mod register */
+	rsub	r31, r6, r3 /* try to subtract (r3 a r6) */
+	blti	r31, mod_too_small
+	/* move the r31 to mod since the result was positive */
+	or	r3, r0, r31
+	addik	r30, r30, 1
+mod_too_small:
+	addik	r29, r29, -1
+	beqi	r29, loop_end
+	add	r30, r30, r30 /* shift in the '1' into div */
+	bri	div2 /* div2 */
+loop_end:
+	bri	return_here
+div_by_zero:
+result_is_zero:
+	or	r3, r0, r0 /* set result to 0 */
+return_here:
+/* restore values of csrs and that of r3 and the divisor and the dividend */
+	lwi	r29, r1, 0
+	lwi	r30, r1, 4
+	lwi	r31, r1, 8
+	rtsd	r15, 8
+	addik	r1, r1, 12
+
+.size __umodsi3, . - __umodsi3
+.end __umodsi3

+ 2 - 19
arch/microblaze/pci/pci-common.c

@@ -60,21 +60,6 @@ struct dma_map_ops *get_pci_dma_ops(void)
 }
 }
 EXPORT_SYMBOL(get_pci_dma_ops);
 EXPORT_SYMBOL(get_pci_dma_ops);
 
 
-int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
-	return dma_set_mask(&dev->dev, mask);
-}
-
-int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
-	int rc;
-
-	rc = dma_set_mask(&dev->dev, mask);
-	dev->dev.coherent_dma_mask = dev->dma_mask;
-
-	return rc;
-}
-
 struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
 struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
 {
 {
 	struct pci_controller *phb;
 	struct pci_controller *phb;
@@ -1075,8 +1060,6 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
 		 bus->number, bus->self ? pci_name(bus->self) : "PHB");
 		 bus->number, bus->self ? pci_name(bus->self) : "PHB");
 
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 	list_for_each_entry(dev, &bus->devices, bus_list) {
-		struct dev_archdata *sd = &dev->dev.archdata;
-
 		/* Setup OF node pointer in archdata */
 		/* Setup OF node pointer in archdata */
 		dev->dev.of_node = pci_device_to_OF_node(dev);
 		dev->dev.of_node = pci_device_to_OF_node(dev);
 
 
@@ -1086,8 +1069,8 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
 		set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
 		set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
 
 
 		/* Hook up default DMA ops */
 		/* Hook up default DMA ops */
-		sd->dma_ops = pci_dma_ops;
-		sd->dma_data = (void *)PCI_DRAM_OFFSET;
+		set_dma_ops(&dev->dev, pci_dma_ops);
+		dev->dev.archdata.dma_data = (void *)PCI_DRAM_OFFSET;
 
 
 		/* Read default IRQs and fixup if necessary */
 		/* Read default IRQs and fixup if necessary */
 		pci_read_irq_line(dev);
 		pci_read_irq_line(dev);

+ 3 - 0
arch/microblaze/platform/generic/system.dts

@@ -85,6 +85,7 @@
 			xlnx,dynamic-bus-sizing = <0x1>;
 			xlnx,dynamic-bus-sizing = <0x1>;
 			xlnx,edge-is-positive = <0x1>;
 			xlnx,edge-is-positive = <0x1>;
 			xlnx,family = "virtex5";
 			xlnx,family = "virtex5";
+			xlnx,endianness = <0x1>;
 			xlnx,fpu-exception = <0x1>;
 			xlnx,fpu-exception = <0x1>;
 			xlnx,fsl-data-size = <0x20>;
 			xlnx,fsl-data-size = <0x20>;
 			xlnx,fsl-exception = <0x0>;
 			xlnx,fsl-exception = <0x0>;
@@ -218,6 +219,7 @@
 			#address-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			#size-cells = <1>;
 			compatible = "xlnx,compound";
 			compatible = "xlnx,compound";
+			ranges ;
 			ethernet@81c00000 {
 			ethernet@81c00000 {
 				compatible = "xlnx,xps-ll-temac-1.01.b", "xlnx,xps-ll-temac-1.00.a";
 				compatible = "xlnx,xps-ll-temac-1.01.b", "xlnx,xps-ll-temac-1.00.a";
 				device_type = "network";
 				device_type = "network";
@@ -332,6 +334,7 @@
 			#address-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			#size-cells = <1>;
 			compatible = "xlnx,mpmc-4.02.a";
 			compatible = "xlnx,mpmc-4.02.a";
+			ranges ;
 			PIM3: sdma@84600180 {
 			PIM3: sdma@84600180 {
 				compatible = "xlnx,ll-dma-1.00.a";
 				compatible = "xlnx,ll-dma-1.00.a";
 				interrupt-parent = <&xps_intc_0>;
 				interrupt-parent = <&xps_intc_0>;

+ 0 - 3
arch/microblaze/platform/platform.c

@@ -17,9 +17,6 @@
 
 
 static struct of_device_id xilinx_of_bus_ids[] __initdata = {
 static struct of_device_id xilinx_of_bus_ids[] __initdata = {
 	{ .compatible = "simple-bus", },
 	{ .compatible = "simple-bus", },
-	{ .compatible = "xlnx,plb-v46-1.00.a", },
-	{ .compatible = "xlnx,opb-v20-1.10.c", },
-	{ .compatible = "xlnx,opb-v20-1.10.b", },
 	{ .compatible = "xlnx,compound", },
 	{ .compatible = "xlnx,compound", },
 	{}
 	{}
 };
 };

+ 4 - 4
drivers/net/xilinx_emaclite.c

@@ -430,8 +430,8 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
 	}
 	}
 
 
 	/* Get the protocol type of the ethernet frame that arrived */
 	/* Get the protocol type of the ethernet frame that arrived */
-	proto_type = ((in_be32(addr + XEL_HEADER_OFFSET +
-			XEL_RXBUFF_OFFSET) >> XEL_HEADER_SHIFT) &
+	proto_type = ((ntohl(in_be32(addr + XEL_HEADER_OFFSET +
+			XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) &
 			XEL_RPLR_LENGTH_MASK);
 			XEL_RPLR_LENGTH_MASK);
 
 
 	/* Check if received ethernet frame is a raw ethernet frame
 	/* Check if received ethernet frame is a raw ethernet frame
@@ -439,9 +439,9 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
 	if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
 	if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
 
 
 		if (proto_type == ETH_P_IP) {
 		if (proto_type == ETH_P_IP) {
-			length = ((in_be32(addr +
+			length = ((ntohl(in_be32(addr +
 					XEL_HEADER_IP_LENGTH_OFFSET +
 					XEL_HEADER_IP_LENGTH_OFFSET +
-					XEL_RXBUFF_OFFSET) >>
+					XEL_RXBUFF_OFFSET)) >>
 					XEL_HEADER_SHIFT) &
 					XEL_HEADER_SHIFT) &
 					XEL_RPLR_LENGTH_MASK);
 					XEL_RPLR_LENGTH_MASK);
 			length += ETH_HLEN + ETH_FCS_LEN;
 			length += ETH_HLEN + ETH_FCS_LEN;

+ 18 - 6
drivers/video/xilinxfb.c

@@ -32,10 +32,14 @@
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
 #include <linux/of_platform.h>
+#include <linux/of_address.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/xilinxfb.h>
 #include <linux/xilinxfb.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
+
+#ifdef CONFIG_PPC_DCR
 #include <asm/dcr.h>
 #include <asm/dcr.h>
+#endif
 
 
 #define DRIVER_NAME		"xilinxfb"
 #define DRIVER_NAME		"xilinxfb"
 
 
@@ -123,10 +127,10 @@ struct xilinxfb_drvdata {
 						registers */
 						registers */
 	void __iomem	*regs;		/* virt. address of the control
 	void __iomem	*regs;		/* virt. address of the control
 						registers */
 						registers */
-
+#ifdef CONFIG_PPC_DCR
 	dcr_host_t      dcr_host;
 	dcr_host_t      dcr_host;
 	unsigned int    dcr_len;
 	unsigned int    dcr_len;
-
+#endif
 	void		*fb_virt;	/* virt. address of the frame buffer */
 	void		*fb_virt;	/* virt. address of the frame buffer */
 	dma_addr_t	fb_phys;	/* phys. address of the frame buffer */
 	dma_addr_t	fb_phys;	/* phys. address of the frame buffer */
 	int		fb_alloced;	/* Flag, was the fb memory alloced? */
 	int		fb_alloced;	/* Flag, was the fb memory alloced? */
@@ -152,9 +156,10 @@ static void xilinx_fb_out_be32(struct xilinxfb_drvdata *drvdata, u32 offset,
 {
 {
 	if (drvdata->flags & PLB_ACCESS_FLAG)
 	if (drvdata->flags & PLB_ACCESS_FLAG)
 		out_be32(drvdata->regs + (offset << 2), val);
 		out_be32(drvdata->regs + (offset << 2), val);
+#ifdef CONFIG_PPC_DCR
 	else
 	else
 		dcr_write(drvdata->dcr_host, offset, val);
 		dcr_write(drvdata->dcr_host, offset, val);
-
+#endif
 }
 }
 
 
 static int
 static int
@@ -383,8 +388,11 @@ static int xilinxfb_release(struct device *dev)
 	if (drvdata->flags & PLB_ACCESS_FLAG) {
 	if (drvdata->flags & PLB_ACCESS_FLAG) {
 		iounmap(drvdata->regs);
 		iounmap(drvdata->regs);
 		release_mem_region(drvdata->regs_phys, 8);
 		release_mem_region(drvdata->regs_phys, 8);
-	} else
+	}
+#ifdef CONFIG_PPC_DCR
+	else
 		dcr_unmap(drvdata->dcr_host, drvdata->dcr_len);
 		dcr_unmap(drvdata->dcr_host, drvdata->dcr_len);
+#endif
 
 
 	kfree(drvdata);
 	kfree(drvdata);
 	dev_set_drvdata(dev, NULL);
 	dev_set_drvdata(dev, NULL);
@@ -404,7 +412,7 @@ xilinxfb_of_probe(struct platform_device *op, const struct of_device_id *match)
 	u32 tft_access;
 	u32 tft_access;
 	struct xilinxfb_platform_data pdata;
 	struct xilinxfb_platform_data pdata;
 	struct resource res;
 	struct resource res;
-	int size, rc, start;
+	int size, rc;
 	struct xilinxfb_drvdata *drvdata;
 	struct xilinxfb_drvdata *drvdata;
 
 
 	/* Copy with the default pdata (not a ptr reference!) */
 	/* Copy with the default pdata (not a ptr reference!) */
@@ -437,7 +445,10 @@ xilinxfb_of_probe(struct platform_device *op, const struct of_device_id *match)
 			dev_err(&op->dev, "invalid address\n");
 			dev_err(&op->dev, "invalid address\n");
 			goto err;
 			goto err;
 		}
 		}
-	} else {
+	}
+#ifdef CONFIG_PPC_DCR
+	else {
+		int start;
 		res.start = 0;
 		res.start = 0;
 		start = dcr_resource_start(op->dev.of_node, 0);
 		start = dcr_resource_start(op->dev.of_node, 0);
 		drvdata->dcr_len = dcr_resource_len(op->dev.of_node, 0);
 		drvdata->dcr_len = dcr_resource_len(op->dev.of_node, 0);
@@ -447,6 +458,7 @@ xilinxfb_of_probe(struct platform_device *op, const struct of_device_id *match)
 			goto err;
 			goto err;
 		}
 		}
 	}
 	}
+#endif
 
 
 	prop = of_get_property(op->dev.of_node, "phys-size", &size);
 	prop = of_get_property(op->dev.of_node, "phys-size", &size);
 	if ((prop) && (size >= sizeof(u32)*2)) {
 	if ((prop) && (size >= sizeof(u32)*2)) {