Merge branch 'next' of git://git.monstr.eu/linux-2.6-microblaze
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 25 Oct 2010 23:53:11 +0000 (16:53 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 25 Oct 2010 23:53:11 +0000 (16:53 -0700)
* '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
  ...

56 files changed:
arch/microblaze/Kconfig
arch/microblaze/Kconfig.debug
arch/microblaze/Makefile
arch/microblaze/include/asm/byteorder.h
arch/microblaze/include/asm/checksum.h
arch/microblaze/include/asm/cpuinfo.h
arch/microblaze/include/asm/elf.h
arch/microblaze/include/asm/gpio.h
arch/microblaze/include/asm/io.h
arch/microblaze/include/asm/page.h
arch/microblaze/include/asm/pci.h
arch/microblaze/include/asm/pgalloc.h
arch/microblaze/include/asm/pgtable.h
arch/microblaze/include/asm/prom.h
arch/microblaze/include/asm/pvr.h
arch/microblaze/include/asm/seccomp.h [new file with mode: 0644]
arch/microblaze/include/asm/setup.h
arch/microblaze/include/asm/thread_info.h
arch/microblaze/include/asm/unaligned.h
arch/microblaze/include/asm/unistd.h
arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
arch/microblaze/kernel/cpu/cpuinfo-static.c
arch/microblaze/kernel/cpu/cpuinfo.c
arch/microblaze/kernel/cpu/mb.c
arch/microblaze/kernel/cpu/pvr.c
arch/microblaze/kernel/early_printk.c
arch/microblaze/kernel/entry.S
arch/microblaze/kernel/exceptions.c
arch/microblaze/kernel/heartbeat.c
arch/microblaze/kernel/intc.c
arch/microblaze/kernel/kgdb.c
arch/microblaze/kernel/microblaze_ksyms.c
arch/microblaze/kernel/prom.c
arch/microblaze/kernel/setup.c
arch/microblaze/kernel/syscall_table.S
arch/microblaze/kernel/timer.c
arch/microblaze/kernel/vmlinux.lds.S
arch/microblaze/lib/Makefile
arch/microblaze/lib/ashldi3.c [new file with mode: 0644]
arch/microblaze/lib/ashrdi3.c [new file with mode: 0644]
arch/microblaze/lib/divsi3.S [new file with mode: 0644]
arch/microblaze/lib/libgcc.h [new file with mode: 0644]
arch/microblaze/lib/lshrdi3.c [new file with mode: 0644]
arch/microblaze/lib/memcpy.c
arch/microblaze/lib/memmove.c
arch/microblaze/lib/memset.c
arch/microblaze/lib/modsi3.S [new file with mode: 0644]
arch/microblaze/lib/muldi3.S [new file with mode: 0644]
arch/microblaze/lib/mulsi3.S [new file with mode: 0644]
arch/microblaze/lib/udivsi3.S [new file with mode: 0644]
arch/microblaze/lib/umodsi3.S [new file with mode: 0644]
arch/microblaze/pci/pci-common.c
arch/microblaze/platform/generic/system.dts
arch/microblaze/platform/platform.c
drivers/net/xilinx_emaclite.c
drivers/video/xilinxfb.c

index 692fdfc..dad40fc 100644 (file)
@@ -121,6 +121,23 @@ config CMDLINE_FORCE
          Set this to have arguments from the default kernel command string
          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
 
 menu "Advanced setup"
index e6e5e0d..e66e25c 100644 (file)
@@ -10,7 +10,7 @@ source "lib/Kconfig.debug"
 
 config EARLY_PRINTK
        bool "Early printk function for kernel"
-       depends on SERIAL_UARTLITE_CONSOLE
+       depends on SERIAL_UARTLITE_CONSOLE || SERIAL_8250_CONSOLE
        default n
        help
          This option turns on/off early printk messages to console.
index 592c707..15f1f1d 100644 (file)
@@ -42,11 +42,8 @@ KBUILD_CFLAGS += -ffixed-r31 $(CPUFLAGS-1) $(CPUFLAGS-2)
 LDFLAGS                :=
 LDFLAGS_vmlinux        :=
 
-LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
-
 head-y := arch/microblaze/kernel/head.o
 libs-y += arch/microblaze/lib/
-libs-y += $(LIBGCC)
 core-y += arch/microblaze/kernel/
 core-y += arch/microblaze/mm/
 core-y += arch/microblaze/platform/
@@ -72,12 +69,16 @@ export MMU DTB
 
 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:
        $(Q)$(MAKE) $(clean)=$(boot)
 
-$(BOOT_TARGETS): vmlinux
+$(BOOT_TARGETS1): vmlinux
+       $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+$(BOOT_TARGETS2): vmlinux
        $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 define archhelp
index ce9c587..3190276 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef _ASM_MICROBLAZE_BYTEORDER_H
 #define _ASM_MICROBLAZE_BYTEORDER_H
 
+#ifdef __MICROBLAZEEL__
+#include <linux/byteorder/little_endian.h>
+#else
 #include <linux/byteorder/big_endian.h>
+#endif
 
 #endif /* _ASM_MICROBLAZE_BYTEORDER_H */
index 128bf03..0185cbe 100644 (file)
@@ -24,8 +24,13 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
                "addc %0, %0, %3\n\t"
                "addc %0, %0, r0\n\t"
                : "+&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;
 }
 
index b4f5ca3..cd25753 100644 (file)
@@ -38,6 +38,7 @@ struct cpuinfo {
        u32 use_exc;
        u32 ver_code;
        u32 mmu;
+       u32 endian;
 
        /* CPU caches */
        u32 use_icache;
@@ -76,7 +77,6 @@ struct cpuinfo {
        u32 num_rd_brk;
        u32 num_wr_brk;
        u32 cpu_clock_freq; /* store real freq of cpu */
-       u32 freq_div_hz; /* store freq/HZ */
 
        /* FPGA family */
        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)
 {
        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 */
index 732caf1..098dfdd 100644 (file)
@@ -71,7 +71,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
 #define ELF_ET_DYN_BASE         (0x08000000)
 
-#ifdef __LITTLE_ENDIAN__
+#ifdef __MICROBLAZEEL__
 #define ELF_DATA       ELFDATA2LSB
 #else
 #define ELF_DATA       ELFDATA2MSB
index 2345ac3..2b2c18b 100644 (file)
@@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio)
        return __gpio_cansleep(gpio);
 }
 
-/*
- * Not implemented, yet.
- */
 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)
index 00b5398..eae3222 100644 (file)
@@ -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 in_8(a) __raw_readb(a)
 
+#define mmiowb()
+
 #define ioport_map(port, nr)   ((void __iomem *)(port))
 #define ioport_unmap(addr)
 
index cf377d9..ed9d0f6 100644 (file)
@@ -205,9 +205,6 @@ extern int page_is_ram(unsigned long pfn);
 #define TOPHYS(addr)  __virt_to_phys(addr)
 
 #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 | \
                                 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
index 5a388ee..2232ff9 100644 (file)
@@ -165,5 +165,7 @@ extern void __init xilinx_pci_init(void);
 static inline void __init xilinx_pci_init(void) { return; }
 #endif
 
+#include <asm-generic/pci-dma-compat.h>
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_MICROBLAZE_PCI_H */
index c614a89..ebd3579 100644 (file)
@@ -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 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) \
                (pmd_val(*(pmd)) = (unsigned long) (pte))
index ca2d928..d4f4216 100644 (file)
@@ -57,6 +57,13 @@ static inline int pte_file(pte_t pte) { return 0; }
 
 #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 */
 
 #include <asm-generic/4level-fixup.h>
index 101fa09..bdc3831 100644 (file)
@@ -27,6 +27,7 @@
 
 /* Other Prototypes */
 extern int early_uartlite_console(void);
+extern int early_uart16550_console(void);
 
 #ifdef CONFIG_PCI
 /*
index 9578666..37db96a 100644 (file)
@@ -30,7 +30,9 @@ struct pvr_s {
 #define PVR0_USE_EXC_MASK              0x04000000
 #define PVR0_USE_ICACHE_MASK           0x02000000
 #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_USER1_MASK                        0x000000FF
 
@@ -38,9 +40,9 @@ struct pvr_s {
 #define PVR1_USER2_MASK                        0xFFFFFFFF
 
 /* 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_I_OPB_MASK                        0x20000000
+#define PVR2_I_OPB_MASK                        0x20000000 /* or AXI */
 #define PVR2_I_LMB_MASK                        0x10000000
 #define PVR2_INTERRUPT_IS_EDGE_MASK    0x08000000
 #define PVR2_EDGE_IS_POSITIVE_MASK     0x04000000
@@ -63,8 +65,8 @@ struct pvr_s {
 #define PVR2_OPCODE_0x0_ILL_MASK       0x00000040
 #define PVR2_UNALIGNED_EXC_MASK                0x00000020
 #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_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_ZONES(pvr)     (pvr.pvr[11] & PVR11_MMU_ZONES)
 
+/* endian */
+#define PVR_ENDIAN(pvr)        (pvr.pvr[0] & PVR0_ENDI)
 
 int cpu_has_pvr(void);
 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 (file)
index 0000000..0d91275
--- /dev/null
@@ -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 */
index 782b5c8..8f39689 100644 (file)
@@ -25,6 +25,12 @@ void early_printk(const char *fmt, ...);
 int setup_early_printk(char *opt);
 void disable_early_printk(void);
 
+#if defined(CONFIG_EARLY_PRINTK)
+#define eprintk early_printk
+#else
+#define eprintk printk
+#endif
+
 void heartbeat(void);
 void setup_heartbeat(void);
 
index 8a8e9fc..b73da2a 100644 (file)
@@ -127,23 +127,19 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SECCOMP            10      /* secure computing */
 #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 */
 #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_SECCOMP           (1 << TIF_SECCOMP)
-#define _TIF_KERNEL_TRACE      (1 << TIF_KERNEL_TRACE)
 
 /* work to do in syscall trace */
 #define _TIF_WORK_SYSCALL_MASK  (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
index 3658d91..2b97cbe 100644 (file)
 
 # ifdef __KERNEL__
 
-# include <linux/unaligned/be_struct.h>
+# include <linux/unaligned/be_byteshift.h>
 # include <linux/unaligned/le_byteshift.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 /* _ASM_MICROBLAZE_UNALIGNED_H */
index 2b67e92..d770b00 100644 (file)
 #define __NR_rt_tgsigqueueinfo 365 /* new */
 #define __NR_perf_event_open   366 /* 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__
 #ifndef __ASSEMBLY__
index f72dbd6..f70a604 100644 (file)
@@ -72,6 +72,7 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
        CI(pvr_user2, USER2);
 
        CI(mmu, USE_MMU);
+       CI(endian, ENDIAN);
 
        CI(use_icache, USE_ICACHE);
        CI(icache_tagbits, ICACHE_ADDR_TAG_BITS);
index 6095aa6..b16b994 100644 (file)
@@ -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->mmu = fcpu(cpu, "xlnx,use-mmu");
+       ci->endian = fcpu(cpu, "xlnx,endianness");
 
        ci->ver_code = 0;
        ci->fpga_family_code = 0;
index 255ef88..87c79fa 100644 (file)
@@ -30,6 +30,8 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
        {"7.20.c", 0x0e},
        {"7.20.d", 0x0f},
        {"7.30.a", 0x10},
+       {"7.30.b", 0x11},
+       {"8.00.a", 0x12},
        {NULL, 0},
 };
 
index 7086e35..b4048af 100644 (file)
@@ -51,11 +51,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        count = seq_printf(m,
                        "CPU-Family:    MicroBlaze\n"
                        "FPGA-Arch:     %s\n"
-                       "CPU-Ver:       %s\n"
+                       "CPU-Ver:       %s, %s endian\n"
                        "CPU-MHz:       %d.%02d\n"
                        "BogoMips:      %lu.%02lu\n",
                        fpga_family,
                        cpu_ver,
+                       cpuinfo.endian ? "little" : "big",
                        cpuinfo.cpu_clock_freq /
                        1000000,
                        cpuinfo.cpu_clock_freq %
index 9bee938..e01afa6 100644 (file)
@@ -27,7 +27,7 @@
        register unsigned tmp __asm__("r3");                    \
        tmp = 0x0;      /* Prevent warning about unused */      \
        __asm__ __volatile__ (                                  \
-                       ".byte 0x94,0x60,0xa0, " #pvrid "\n\t"  \
+                       "mfs    %0, rpvr" #pvrid ";"    \
                        : "=r" (tmp) : : "memory");             \
        val = tmp;                                              \
 }
index 7de8492..c3616a0 100644 (file)
@@ -24,7 +24,8 @@
 static u32 early_console_initialized;
 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.
@@ -45,25 +46,70 @@ static void early_printk_putc(char c)
                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)
 {
        while (*s && n-- > 0) {
-               early_printk_putc(*s);
+               early_printk_uartlite_putc(*s);
                if (*s == '\n')
-                       early_printk_putc('\r');
+                       early_printk_uartlite_putc('\r');
                s++;
        }
 }
 
-static struct console early_serial_console = {
+static struct console early_serial_uartlite_console = {
        .name = "earlyser",
-       .write = early_printk_write,
+       .write = early_printk_uartlite_write,
        .flags = CON_PRINTBUFFER,
        .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, ...)
 {
@@ -84,20 +130,43 @@ int __init setup_early_printk(char *opt)
        if (early_console_initialized)
                return 1;
 
+#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
        base_addr = early_uartlite_console();
        if (base_addr) {
                early_console_initialized = 1;
 #ifdef CONFIG_MMU
                early_console_reg_tlb_alloc(base_addr);
 #endif
+               early_console = &early_serial_uartlite_console;
                early_printk("early_printk_console is enabled at 0x%08x\n",
                                                        base_addr);
 
                /* register_console(early_console); */
 
                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)
index 304882e..819238b 100644 (file)
        swi     r13, r1, PTO+PT_R13;    /* Save SDA2 */                 \
        swi     r14, r1, PTO+PT_PC;     /* PC, before IRQ/trap */       \
        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     r19, r1, PTO+PT_R19;                                    \
        swi     r20, r1, PTO+PT_R20;                                    \
        lwi     r13, r1, PTO+PT_R13;    /* restore SDA2 */              \
        lwi     r14, r1, PTO+PT_PC;     /* RESTORE_LINK PC, before IRQ/trap */\
        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     r19, r1, PTO+PT_R19;                                    \
        lwi     r20, r1, PTO+PT_R20;                                    \
@@ -295,6 +299,8 @@ C_ENTRY(_user_exception):
        /* addik        r1, r1, -STATE_SAVE_SIZE; */
        addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE;
        SAVE_REGS
+       swi     r0, r1, PTO + PT_R3
+       swi     r0, r1, PTO + PT_R4
 
        lwi     r11, r0, TOPHYS(PER_CPU(ENTRY_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 */
 
 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 */
-       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
@@ -765,9 +765,7 @@ C_ENTRY(_debug_exception):
        /* save all regs to pt_reg structure */
        swi     r0, r1, PTO+PT_R0;      /* R0 must be saved too */
        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     r17, r1, PTO+PT_R17
        /* save special purpose registers to pt_regs */
        mfs     r11, rear;
        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.  */
        SAVE_REGS;
-       swi     r17, r1, PTO+PT_R17;
-       swi     r16, r1, PTO+PT_R16;
        swi     r16, r1, PTO+PT_PC;     /* Save LP */
        swi     r0, r1, PTO + PT_MODE; /* Was in user-mode.  */
        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);
        /* MS: Restore all 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 */
        lwi     r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
 DBTRAP_return_user: /* MS: Make global symbol for debugging */
@@ -863,7 +857,6 @@ DBTRAP_return_user: /* MS: Make global symbol for debugging */
        RESTORE_REGS
        lwi     r14, r1, PTO+PT_R14;
        lwi     r16, r1, PTO+PT_PC;
-       lwi     r17, r1, PTO+PT_R17;
        addik   r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */
        tovirt(r1,r1);
 DBTRAP_return_kernel: /* MS: Make global symbol for debugging */
index b98ee8d..478f294 100644 (file)
@@ -72,7 +72,6 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
                                                        int fsr, int addr)
 {
 #ifdef CONFIG_MMU
-       int code;
        addr = regs->pc;
 #endif
 
@@ -86,8 +85,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
        switch (type & 0x1F) {
        case MICROBLAZE_ILL_OPCODE_EXCEPTION:
                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);
                        return;
                }
@@ -97,8 +95,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
                break;
        case MICROBLAZE_IBUS_EXCEPTION:
                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);
                        return;
                }
@@ -108,8 +105,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
                break;
        case MICROBLAZE_DBUS_EXCEPTION:
                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);
                        return;
                }
@@ -119,8 +115,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
                break;
        case MICROBLAZE_DIV_ZERO_EXCEPTION:
                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);
                        return;
                }
@@ -129,7 +124,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
                die("Divide by zero exception", regs, SIGBUS);
                break;
        case MICROBLAZE_FPU_EXCEPTION:
-               pr_debug(KERN_WARNING "FPU exception\n");
+               pr_debug("FPU exception\n");
                /* IEEE FP exception */
                /* I removed fsr variable and use code var for storing fsr */
                if (fsr & FSR_IO)
@@ -147,14 +142,8 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
 
 #ifdef CONFIG_MMU
        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;
 #endif
        default:
index 5227517..154756f 100644 (file)
@@ -47,11 +47,10 @@ void setup_heartbeat(void)
        struct device_node *gpio = NULL;
        int *prop;
        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++) {
                gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]);
@@ -60,7 +59,7 @@ void setup_heartbeat(void)
        }
 
        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);
                printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
 
index 03172c1..d61ea33 100644 (file)
@@ -126,11 +126,8 @@ void __init init_IRQ(void)
                                0
                        };
 #endif
-       static char *intc_list[] = {
+       const char * const intc_list[] = {
                                "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
                        };
 
@@ -141,12 +138,15 @@ void __init init_IRQ(void)
        }
        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);
-       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 =
-               *(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)))
                printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");
 
index bfc006b..09a5e82 100644 (file)
@@ -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)
 {
        if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0)
-               return 0;
+               return;
 
        /* Jump over the first arch_kgdb_breakpoint which is barrier to
         * 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;
        unsigned long address;
-       int cpu = smp_processor_id();
 
        switch (remcom_in_buffer[0]) {
        case 'c':
@@ -143,5 +142,9 @@ void kgdb_arch_exit(void)
  * Global data
  */
 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 */
+#endif
 };
index ff85f77..5cb0341 100644 (file)
 #include <linux/syscalls.h>
 
 #include <asm/checksum.h>
+#include <asm/cacheflush.h>
 #include <linux/io.h>
 #include <asm/page.h>
 #include <asm/system.h>
 #include <linux/ftrace.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;
 EXPORT_SYMBOL_GPL(_ebss);
 #ifdef CONFIG_FUNCTION_TRACER
@@ -63,3 +39,9 @@ EXPORT_SYMBOL(__strncpy_user);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memmove);
 #endif
+
+#ifdef CONFIG_MMU
+EXPORT_SYMBOL(empty_zero_page);
+#endif
+
+EXPORT_SYMBOL(mbc);
index bacbd3d..a105301 100644 (file)
@@ -72,11 +72,12 @@ static int __init early_init_dt_scan_serial(unsigned long node,
 /* find compatible node with uartlite */
        p = of_get_flat_dt_prop(node, "compatible", &l);
        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;
 
        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 */
@@ -84,6 +85,40 @@ int __init early_uartlite_console(void)
 {
        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
 
 void __init early_init_devtree(void *params)
index f5f7688..bb1558e 100644 (file)
@@ -92,12 +92,6 @@ inline unsigned get_romfs_len(unsigned *addr)
 }
 #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,
                unsigned int fdt, unsigned int msr)
 {
index 03376dc..e88a930 100644 (file)
@@ -372,3 +372,6 @@ ENTRY(sys_call_table)
        .long sys_rt_tgsigqueueinfo     /* 365 */
        .long sys_perf_event_open
        .long sys_recvmmsg
+       .long sys_fanotify_init
+       .long sys_fanotify_mark
+       .long sys_prlimit64     /* 370 */
index b1380ae..a5aa33d 100644 (file)
@@ -38,6 +38,9 @@ static unsigned int timer_baseaddr;
 #define TIMER_BASE     timer_baseaddr
 #endif
 
+unsigned int freq_div_hz;
+unsigned int timer_clock_freq;
+
 #define TCSR0  (0x00)
 #define TLR0   (0x04)
 #define TCR0   (0x08)
@@ -115,7 +118,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode,
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
                printk(KERN_INFO "%s: periodic\n", __func__);
-               microblaze_timer0_start_periodic(cpuinfo.freq_div_hz);
+               microblaze_timer0_start_periodic(freq_div_hz);
                break;
        case CLOCK_EVT_MODE_ONESHOT:
                printk(KERN_INFO "%s: oneshot\n", __func__);
@@ -168,7 +171,7 @@ static struct irqaction timer_irqaction = {
 static __init void microblaze_clockevent_init(void)
 {
        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.max_delta_ns =
                clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
@@ -201,7 +204,7 @@ static struct cyclecounter microblaze_cc = {
 
 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);
 
        timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock());
@@ -221,7 +224,7 @@ static struct clocksource clocksource_microblaze = {
 static int __init microblaze_clocksource_init(void)
 {
        clocksource_microblaze.mult =
-                       clocksource_hz2mult(cpuinfo.cpu_clock_freq,
+                       clocksource_hz2mult(timer_clock_freq,
                                                clocksource_microblaze.shift);
        if (clocksource_register(&clocksource_microblaze))
                panic("failed to register clocksource");
@@ -247,6 +250,7 @@ void __init time_init(void)
        u32 irq, i = 0;
        u32 timer_num = 1;
        struct device_node *timer = NULL;
+       const void *prop;
 #ifdef CONFIG_SELFMOD_TIMER
        unsigned int timer_baseaddr = 0;
        int arr_func[] = {
@@ -258,12 +262,10 @@ void __init time_init(void)
                                0
                        };
 #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++) {
                timer = of_find_compatible_node(NULL, NULL, timer_list[i]);
@@ -272,13 +274,13 @@ void __init time_init(void)
        }
        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);
-       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) {
-               printk(KERN_EMERG "Please enable two timers in HW\n");
+               eprintk(KERN_EMERG "Please enable two timers in HW\n");
                BUG();
        }
 
@@ -288,7 +290,14 @@ void __init time_init(void)
        printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
                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);
 #ifdef CONFIG_HEART_BEAT
index a09f296..96a88c3 100644 (file)
@@ -8,7 +8,6 @@
  * for more details.
  */
 
-OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
 OUTPUT_ARCH(microblaze)
 ENTRY(microblaze_start)
 
@@ -16,7 +15,11 @@ ENTRY(microblaze_start)
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/thread_info.h>
 
+#ifdef __MICROBLAZEEL__
+jiffies = jiffies_64;
+#else
 jiffies = jiffies_64 + 4;
+#endif
 
 SECTIONS {
        . = CONFIG_KERNEL_START;
index 4dfe47d..f1fcbff 100644 (file)
@@ -11,3 +11,13 @@ lib-y += memcpy.o memmove.o
 endif
 
 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
diff --git a/arch/microblaze/lib/ashldi3.c b/arch/microblaze/lib/ashldi3.c
new file mode 100644 (file)
index 0000000..beb80f3
--- /dev/null
@@ -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);
diff --git a/arch/microblaze/lib/ashrdi3.c b/arch/microblaze/lib/ashrdi3.c
new file mode 100644 (file)
index 0000000..c884a91
--- /dev/null
@@ -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);
diff --git a/arch/microblaze/lib/divsi3.S b/arch/microblaze/lib/divsi3.S
new file mode 100644 (file)
index 0000000..595b02d
--- /dev/null
@@ -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
diff --git a/arch/microblaze/lib/libgcc.h b/arch/microblaze/lib/libgcc.h
new file mode 100644 (file)
index 0000000..05909d5
--- /dev/null
@@ -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 */
diff --git a/arch/microblaze/lib/lshrdi3.c b/arch/microblaze/lib/lshrdi3.c
new file mode 100644 (file)
index 0000000..dcf8d68
--- /dev/null
@@ -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);
index 014bac9..cc495d7 100644 (file)
 #include <asm/system.h>
 
 #ifdef __HAVE_ARCH_MEMCPY
+#ifndef 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;
-#ifndef CONFIG_OPT_LIB_FUNCTION
+
        /* Simple, byte oriented memcpy. */
        while (c--)
                *dst++ = *src++;
 
        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
         * alignment. This will work fine if both source and destination are
         * 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 */
                        /* Word align the source */
                        i_src = (const void *) ((unsigned)src & ~3);
-
+#ifndef __MICROBLAZEEL__
                        /* Load the holding buffer */
                        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;
                                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 */
                        src = (const void *)i_src;
                        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 */
                        /* Word align the source */
                        i_src = (const void *) ((unsigned)src & ~3);
-
+#ifndef __MICROBLAZEEL__
                        /* Load the holding buffer */
                        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;
                                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 */
                        src = (const void *)i_src;
                        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 */
                        /* Word align the source */
                        i_src = (const void *) ((unsigned)src & ~3);
-
+#ifndef __MICROBLAZEEL__
                        /* Load the holding buffer */
                        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;
                                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 */
                        src = (const void *)i_src;
                        src -= 1;
@@ -150,7 +184,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
        }
 
        return v_dst;
-#endif
 }
+#endif /* CONFIG_OPT_LIB_FUNCTION */
 EXPORT_SYMBOL(memcpy);
 #endif /* __HAVE_ARCH_MEMCPY */
index 0929198..123e361 100644 (file)
 #include <linux/string.h>
 
 #ifdef __HAVE_ARCH_MEMMOVE
+#ifndef 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;
 
-#ifdef CONFIG_OPT_LIB_FUNCTION
-       const uint32_t *i_src;
-       uint32_t *i_dst;
-#endif
-
        if (!c)
                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)
                return memcpy(v_dst, v_src, c);
 
-#ifndef CONFIG_OPT_LIB_FUNCTION
        /* copy backwards, from end to beginning */
        src += c;
        dst += c;
@@ -58,7 +53,22 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
                *--dst = *--src;
 
        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
         * alignment. This will work fine if both source and destination are
         * 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 */
                        /* Word align the source */
                        i_src = (const void *) (((unsigned)src + 4) & ~3);
-
+#ifndef __MICROBLAZEEL__
                        /* Load the holding buffer */
                        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;
                                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 */
                        src = (const void *)i_src;
                        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 */
                        /* Word align the source */
                        i_src = (const void *) (((unsigned)src + 4) & ~3);
-
+#ifndef __MICROBLAZEEL__
                        /* Load the holding buffer */
                        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;
                                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 */
                        src = (const void *)i_src;
                        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 */
                        /* Word align the source */
                        i_src = (const void *) (((unsigned)src + 4) & ~3);
-
+#ifndef __MICROBLAZEEL__
                        /* Load the holding buffer */
                        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;
                                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 */
                        src = (const void *)i_src;
                        src += 3;
@@ -169,7 +206,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
                *--dst = *--src;
        }
        return v_dst;
-#endif
 }
+#endif /* CONFIG_OPT_LIB_FUNCTION */
 EXPORT_SYMBOL(memmove);
 #endif /* __HAVE_ARCH_MEMMOVE */
index ecfb663..834565d 100644 (file)
 #include <linux/string.h>
 
 #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)
 {
        char *src = v_src;
-#ifdef CONFIG_OPT_LIB_FUNCTION
        uint32_t *i_src;
        uint32_t w32 = 0;
-#endif
+
        /* Truncate c to 8 bits */
        c = (c & 0xFF);
 
-#ifdef CONFIG_OPT_LIB_FUNCTION
        if (unlikely(c)) {
                /* Make a repeating word out of it */
                w32 = c;
@@ -72,12 +85,13 @@ void *memset(void *v_src, int c, __kernel_size_t n)
 
                src  = (void *)i_src;
        }
-#endif
+
        /* Simple, byte oriented memset or the rest of count. */
        while (n--)
                *src++ = c;
 
        return v_src;
 }
+#endif /* CONFIG_OPT_LIB_FUNCTION */
 EXPORT_SYMBOL(memset);
 #endif /* __HAVE_ARCH_MEMSET */
diff --git a/arch/microblaze/lib/modsi3.S b/arch/microblaze/lib/modsi3.S
new file mode 100644 (file)
index 0000000..84e0bee
--- /dev/null
@@ -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
diff --git a/arch/microblaze/lib/muldi3.S b/arch/microblaze/lib/muldi3.S
new file mode 100644 (file)
index 0000000..ceeaa8c
--- /dev/null
@@ -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
diff --git a/arch/microblaze/lib/mulsi3.S b/arch/microblaze/lib/mulsi3.S
new file mode 100644 (file)
index 0000000..90bd7b9
--- /dev/null
@@ -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
diff --git a/arch/microblaze/lib/udivsi3.S b/arch/microblaze/lib/udivsi3.S
new file mode 100644 (file)
index 0000000..64cf57e
--- /dev/null
@@ -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
diff --git a/arch/microblaze/lib/umodsi3.S b/arch/microblaze/lib/umodsi3.S
new file mode 100644 (file)
index 0000000..17d16ba
--- /dev/null
@@ -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
index 55ef532..e363615 100644 (file)
@@ -60,21 +60,6 @@ struct dma_map_ops *get_pci_dma_ops(void)
 }
 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 *phb;
@@ -1075,8 +1060,6 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
                 bus->number, bus->self ? pci_name(bus->self) : "PHB");
 
        list_for_each_entry(dev, &bus->devices, bus_list) {
-               struct dev_archdata *sd = &dev->dev.archdata;
-
                /* Setup OF node pointer in archdata */
                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));
 
                /* 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 */
                pci_read_irq_line(dev);
index 2d5c417..3f85df2 100644 (file)
@@ -85,6 +85,7 @@
                        xlnx,dynamic-bus-sizing = <0x1>;
                        xlnx,edge-is-positive = <0x1>;
                        xlnx,family = "virtex5";
+                       xlnx,endianness = <0x1>;
                        xlnx,fpu-exception = <0x1>;
                        xlnx,fsl-data-size = <0x20>;
                        xlnx,fsl-exception = <0x0>;
                        #address-cells = <1>;
                        #size-cells = <1>;
                        compatible = "xlnx,compound";
+                       ranges ;
                        ethernet@81c00000 {
                                compatible = "xlnx,xps-ll-temac-1.01.b", "xlnx,xps-ll-temac-1.00.a";
                                device_type = "network";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        compatible = "xlnx,mpmc-4.02.a";
+                       ranges ;
                        PIM3: sdma@84600180 {
                                compatible = "xlnx,ll-dma-1.00.a";
                                interrupt-parent = <&xps_intc_0>;
index 5b89b58..b9529ca 100644 (file)
@@ -17,9 +17,6 @@
 
 static struct of_device_id xilinx_of_bus_ids[] __initdata = {
        { .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", },
        {}
 };
index f3f8be5..14f0955 100644 (file)
@@ -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 */
-       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);
 
        /* 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_P_IP) {
-                       length = ((in_be32(addr +
+                       length = ((ntohl(in_be32(addr +
                                        XEL_HEADER_IP_LENGTH_OFFSET +
-                                       XEL_RXBUFF_OFFSET) >>
+                                       XEL_RXBUFF_OFFSET)) >>
                                        XEL_HEADER_SHIFT) &
                                        XEL_RPLR_LENGTH_MASK);
                        length += ETH_HLEN + ETH_FCS_LEN;
index 0c9ce88..68bd234 100644 (file)
 #include <linux/dma-mapping.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
+#include <linux/of_address.h>
 #include <linux/io.h>
 #include <linux/xilinxfb.h>
 #include <linux/slab.h>
+
+#ifdef CONFIG_PPC_DCR
 #include <asm/dcr.h>
+#endif
 
 #define DRIVER_NAME            "xilinxfb"
 
@@ -123,10 +127,10 @@ struct xilinxfb_drvdata {
                                                registers */
        void __iomem    *regs;          /* virt. address of the control
                                                registers */
-
+#ifdef CONFIG_PPC_DCR
        dcr_host_t      dcr_host;
        unsigned int    dcr_len;
-
+#endif
        void            *fb_virt;       /* virt. 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? */
@@ -152,9 +156,10 @@ static void xilinx_fb_out_be32(struct xilinxfb_drvdata *drvdata, u32 offset,
 {
        if (drvdata->flags & PLB_ACCESS_FLAG)
                out_be32(drvdata->regs + (offset << 2), val);
+#ifdef CONFIG_PPC_DCR
        else
                dcr_write(drvdata->dcr_host, offset, val);
-
+#endif
 }
 
 static int
@@ -383,8 +388,11 @@ static int xilinxfb_release(struct device *dev)
        if (drvdata->flags & PLB_ACCESS_FLAG) {
                iounmap(drvdata->regs);
                release_mem_region(drvdata->regs_phys, 8);
-       } else
+       }
+#ifdef CONFIG_PPC_DCR
+       else
                dcr_unmap(drvdata->dcr_host, drvdata->dcr_len);
+#endif
 
        kfree(drvdata);
        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;
        struct xilinxfb_platform_data pdata;
        struct resource res;
-       int size, rc, start;
+       int size, rc;
        struct xilinxfb_drvdata *drvdata;
 
        /* 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");
                        goto err;
                }
-       } else {
+       }
+#ifdef CONFIG_PPC_DCR
+       else {
+               int start;
                res.start = 0;
                start = dcr_resource_start(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;
                }
        }
+#endif
 
        prop = of_get_property(op->dev.of_node, "phys-size", &size);
        if ((prop) && (size >= sizeof(u32)*2)) {