From c4554c32a7a6f81e9226084c43a3b8e17853c535 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 11 Sep 2010 22:10:51 -0700 Subject: microblaze: Remove pr_ uses of KERN_ Signed-off-by: Joe Perches Signed-off-by: Michal Simek --- arch/microblaze/kernel/exceptions.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c index b98ee8d0c1cd..7dd4d127fce8 100644 --- a/arch/microblaze/kernel/exceptions.c +++ b/arch/microblaze/kernel/exceptions.c @@ -86,8 +86,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 +96,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 +106,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 +116,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 +125,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,7 +143,7 @@ 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"); + pr_debug("Privileged exception\n"); /* "brk r0,r0" - used as debug breakpoint - old toolchain */ if (get_user(code, (unsigned long *)regs->pc) == 0 && code == 0x980c0000) { -- cgit v1.2.3 From 4bdfd9ebc3bb6e111309b711a601bce7a8ae6857 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 10 Aug 2010 08:57:45 +0200 Subject: microblaze: Fix generic DTS to ensure OF requirements LL Temac dts nodes should contain ranges property. It is sufficient to use empty ranges property. Signed-off-by: Michal Simek --- arch/microblaze/platform/generic/system.dts | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/microblaze/platform/generic/system.dts b/arch/microblaze/platform/generic/system.dts index 2d5c41767cd0..ef667d125ce0 100644 --- a/arch/microblaze/platform/generic/system.dts +++ b/arch/microblaze/platform/generic/system.dts @@ -218,6 +218,7 @@ #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"; @@ -332,6 +333,7 @@ #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>; -- cgit v1.2.3 From f859f0a235d4d9e7eae49bf10bab6b0967d328f6 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 10 Aug 2010 08:19:03 +0200 Subject: microblaze: kgdb: Remove unused variable and fix return value I forget to remove unused variable from kgdb_arch_handle_exception. Fix return value in microblaze_kgdb_break function. Error log: arch/microblaze/kernel/kgdb.c: In function 'microblaze_kgdb_break': arch/microblaze/kernel/kgdb.c:83: warning: 'return' with a value, in function returning void arch/microblaze/kernel/kgdb.c: In function 'kgdb_arch_handle_exception': arch/microblaze/kernel/kgdb.c:119: warning: unused variable 'cpu' Signed-off-by: Michal Simek --- arch/microblaze/kernel/kgdb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/kgdb.c b/arch/microblaze/kernel/kgdb.c index bfc006b7f2d8..9b5a817605ec 100644 --- a/arch/microblaze/kernel/kgdb.c +++ b/arch/microblaze/kernel/kgdb.c @@ -80,7 +80,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) 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': -- cgit v1.2.3 From 5f0cb3e01ec41b35b8452856f2ddd7a9f36fb80b Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 16 Aug 2010 11:02:18 +0200 Subject: microblaze: Fix pmd_populate macro Compilation warning: mm/memory.c: In function '__pte_alloc': mm/memory.c:421: warning: assignment makes integer from pointer without a cast Signed-off-by: Michal Simek --- arch/microblaze/include/asm/pgalloc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h index c614a893f8a3..ebd35792482c 100644 --- a/arch/microblaze/include/asm/pgalloc.h +++ b/arch/microblaze/include/asm/pgalloc.h @@ -165,7 +165,8 @@ extern inline void pte_free(struct mm_struct *mm, struct page *ptepage) #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)) -- cgit v1.2.3 From 95d3a8cd1596b7d34b873d1fa5a70bbc656f5410 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 6 Aug 2010 08:49:13 +0200 Subject: microblaze: trivial: thread_info cleanup Coding style cleanup. Signed-off-by: Michal Simek --- arch/microblaze/include/asm/thread_info.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h index 8a8e9fc6e0c0..21e7997d08be 100644 --- a/arch/microblaze/include/asm/thread_info.h +++ b/arch/microblaze/include/asm/thread_info.h @@ -133,14 +133,14 @@ static inline struct thread_info *current_thread_info(void) /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_POLLING_NRFLAG 16 -#define _TIF_SYSCALL_TRACE (1< Date: Tue, 3 Aug 2010 11:32:20 +0200 Subject: microblaze: Remove old user debugging gdb stub Old gdb uses priviledged exception handler to handle gdb exception. New gdb uses brki r16, 0x18 that's why we can remove old gdb support. Signed-off-by: Michal Simek --- arch/microblaze/kernel/exceptions.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c index 7dd4d127fce8..478f2943ede7 100644 --- a/arch/microblaze/kernel/exceptions.c +++ b/arch/microblaze/kernel/exceptions.c @@ -72,7 +72,6 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, int fsr, int addr) { #ifdef CONFIG_MMU - int code; addr = regs->pc; #endif @@ -144,13 +143,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, #ifdef CONFIG_MMU case MICROBLAZE_PRIVILEGED_EXCEPTION: pr_debug("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); - } + _exception(SIGILL, regs, ILL_PRVOPC, addr); break; #endif default: -- cgit v1.2.3 From 68c6ac3366764730c6cc6bcc7003b233bd6b6571 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 6 Aug 2010 08:50:35 +0200 Subject: microblaze: Add seccomp support Add seccomp support. Signed-off-by: Michal Simek --- arch/microblaze/Kconfig | 17 +++++++++++++++++ arch/microblaze/include/asm/seccomp.h | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 arch/microblaze/include/asm/seccomp.h (limited to 'arch') diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 692fdfce2a23..dad40fc2bef8 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -121,6 +121,23 @@ config CMDLINE_FORCE 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//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" diff --git a/arch/microblaze/include/asm/seccomp.h b/arch/microblaze/include/asm/seccomp.h new file mode 100644 index 000000000000..0d912758a0d7 --- /dev/null +++ b/arch/microblaze/include/asm/seccomp.h @@ -0,0 +1,16 @@ +#ifndef _ASM_MICROBLAZE_SECCOMP_H +#define _ASM_MICROBLAZE_SECCOMP_H + +#include + +#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 */ -- cgit v1.2.3 From 06d1973490199d38a65029101199e04004fbe8f3 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 6 Aug 2010 08:51:54 +0200 Subject: microblaze: remove unused TIF_KERNEL_TRACE TIF_KERNEL_TRACE is not used anywhere. Signed-off-by: Michal Simek --- arch/microblaze/include/asm/thread_info.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h index 21e7997d08be..b73da2ac21b3 100644 --- a/arch/microblaze/include/asm/thread_info.h +++ b/arch/microblaze/include/asm/thread_info.h @@ -127,9 +127,6 @@ 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 @@ -143,7 +140,6 @@ static inline struct thread_info *current_thread_info(void) #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 | \ -- cgit v1.2.3 From 791d0a169b912220d58e0ce4564d7bf1e68146a8 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 6 Aug 2010 10:36:02 +0200 Subject: microblaze: Fix sys_rt_sigreturn_wrapper Do not save return registers before rt_sigreturn is called. _user_exception(syscall handler) already setup return address that's why it is removed from rt_sigreturn_wrapper. Signed-off-by: Michal Simek --- arch/microblaze/kernel/entry.S | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index 304882e56459..ab4f1e159308 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S @@ -458,14 +458,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 -- cgit v1.2.3 From 7d4320956f0f8aa2c36c23f209acc3e4c3ae52d6 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 6 Aug 2010 10:42:30 +0200 Subject: microblaze: Clear return value in pt_regs Signal code uses r3 value which saved in restore_sigcontext to rt_sigframe but it require to be zeroed. If is not zero rt_sigframe contains wrong values. Signed-off-by: Michal Simek --- arch/microblaze/kernel/entry.S | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index ab4f1e159308..8539c6c0e741 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S @@ -295,6 +295,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. */ -- cgit v1.2.3 From 69717607f028d7d4f4b355afb86556f3dd9363fc Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 6 Aug 2010 14:13:13 +0200 Subject: microblaze: Report if only one timer is used Kernel needs two timers because of clocksource and clockevent. It is better to show warning message directly on early console if available. If it isn't available kernel log buffer contains it. Signed-off-by: Michal Simek --- arch/microblaze/include/asm/setup.h | 6 ++++++ arch/microblaze/kernel/setup.c | 6 ------ arch/microblaze/kernel/timer.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h index 782b5c89248e..5f910ebe0325 100644 --- a/arch/microblaze/include/asm/setup.h +++ b/arch/microblaze/include/asm/setup.h @@ -25,6 +25,12 @@ void early_printk(const char *fmt, ...); int setup_early_printk(char *opt); void disable_early_printk(void); +#if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE) +#define eprintk early_printk +#else +#define eprintk printk +#endif + void heartbeat(void); void setup_heartbeat(void); diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index f5f768842354..bb1558e4b283 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -92,12 +92,6 @@ inline unsigned get_romfs_len(unsigned *addr) } #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) { diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index b1380ae93ae1..ec7df67006ba 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -278,7 +278,7 @@ void __init time_init(void) timer_num = *(int *) 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(); } -- cgit v1.2.3 From 36cf089dc648f542622eb43daaa35b3a90f510a6 Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Tue, 10 Aug 2010 14:00:52 +0200 Subject: microblaze: Removing dead CONTIGUOUS_PAGE_ALLOC config option CONFIG_CONTIGUOUS_PAGE_ALLOC doesn't exist in Kconfig, therefore removing all references to it from the source. Signed-off-by: Christian Dietrich Signed-off-by: Michal Simek --- arch/microblaze/include/asm/page.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h index cf377d91da71..ed9d0f6e2cdb 100644 --- a/arch/microblaze/include/asm/page.h +++ b/arch/microblaze/include/asm/page.h @@ -205,9 +205,6 @@ extern int page_is_ram(unsigned long pfn); #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) -- cgit v1.2.3 From 600eb6110a3f15aedffc3cce31b6065a09e7cb31 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 9 Aug 2010 14:37:42 +0200 Subject: microblaze: Fix r16 and r17 reg saving r16 and r17 should be saved across interrupt and exception handling. Signed-off-by: Michal Simek --- arch/microblaze/kernel/entry.S | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index 8539c6c0e741..819238b8a429 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S @@ -186,6 +186,8 @@ 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; \ @@ -220,6 +222,8 @@ 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; \ @@ -761,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; @@ -797,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)); @@ -844,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 */ @@ -859,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 */ -- cgit v1.2.3 From b3ea83809347a6f717daa01854677582a7e47a62 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 12 Aug 2010 14:27:28 +0200 Subject: microblaze: remove OUTPUT_FORMAT from linker script OUTPUT_FORMAT setup bigendian platform. Microblaze Linux port is becoming bi endian that's why it is removed. Signed-off-by: Michal Simek --- arch/microblaze/kernel/vmlinux.lds.S | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S index a09f2962fbec..20b0552391d1 100644 --- a/arch/microblaze/kernel/vmlinux.lds.S +++ b/arch/microblaze/kernel/vmlinux.lds.S @@ -8,7 +8,6 @@ * for more details. */ -OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze") OUTPUT_ARCH(microblaze) ENTRY(microblaze_start) -- cgit v1.2.3 From f66efecad0b468214f574b295f4152aa95d74d4e Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 13 Aug 2010 12:44:17 +0200 Subject: microblaze: Add new microblaze versions PVR for 7.30.b, 8.00.a versions. Signed-off-by: Michal Simek --- arch/microblaze/kernel/cpu/cpuinfo.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c index 255ef880351e..87c79fa275c3 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo.c +++ b/arch/microblaze/kernel/cpu/cpuinfo.c @@ -30,6 +30,8 @@ const struct cpu_ver_key cpu_ver_lookup[] = { {"7.20.c", 0x0e}, {"7.20.d", 0x0f}, {"7.30.a", 0x10}, + {"7.30.b", 0x11}, + {"8.00.a", 0x12}, {NULL, 0}, }; -- cgit v1.2.3 From 6d5f2f6d4114578e2504ed3f675d450cbde5a161 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 13 Aug 2010 12:47:18 +0200 Subject: microblaze: Add PVR for BTC Signed-off-by: Michal Simek --- arch/microblaze/include/asm/pvr.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h index 9578666e98ba..cf59ef55c3b6 100644 --- a/arch/microblaze/include/asm/pvr.h +++ b/arch/microblaze/include/asm/pvr.h @@ -30,7 +30,8 @@ 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_VERSION_MASK 0x0000FF00 #define PVR0_USER1_MASK 0x000000FF -- cgit v1.2.3 From b9b12fd147553676c6b9483bdc9e3eae0b449aa0 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sat, 14 Aug 2010 16:18:26 +0900 Subject: microblaze: use asm-generic/pci-dma-compat.h Use asm-generic/pci-dma-compat.h instead of the homegrown pci_set_dma_mask and pci_set_consistent_dma_mask. Signed-off-by: FUJITA Tomonori --- arch/microblaze/include/asm/pci.h | 2 ++ arch/microblaze/pci/pci-common.c | 15 --------------- 2 files changed, 2 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index 5a388eeeb28f..2232ff942ba9 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h @@ -165,5 +165,7 @@ extern void __init xilinx_pci_init(void); static inline void __init xilinx_pci_init(void) { return; } #endif +#include + #endif /* __KERNEL__ */ #endif /* __ASM_MICROBLAZE_PCI_H */ diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 55ef532f32be..2bc57a836d71 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -60,21 +60,6 @@ struct dma_map_ops *get_pci_dma_ops(void) } 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; -- cgit v1.2.3 From 4d24d7f7aeca897bada4936a2bd10c33c4f23308 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 16 Aug 2010 10:52:20 +0200 Subject: microblaze: wire up prlimit64 and fanotify* syscalls Signed-off-by: Michal Simek --- arch/microblaze/include/asm/unistd.h | 5 ++++- arch/microblaze/kernel/syscall_table.S | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h index 2b67e92a773c..d770b00ec6b1 100644 --- a/arch/microblaze/include/asm/unistd.h +++ b/arch/microblaze/include/asm/unistd.h @@ -383,8 +383,11 @@ #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__ diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index 03376dc814c9..e88a930fd1e3 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S @@ -372,3 +372,6 @@ ENTRY(sys_call_table) .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 */ -- cgit v1.2.3 From ac2e7c92ee071d398b72a7848a298664b80f9712 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 17 Aug 2010 11:48:36 +0200 Subject: microblaze: Define empty mmiowb mmiowb is required by any driver. Signed-off-by: Michal Simek --- arch/microblaze/include/asm/io.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h index 00b5398d08c7..eae32220f447 100644 --- a/arch/microblaze/include/asm/io.h +++ b/arch/microblaze/include/asm/io.h @@ -243,6 +243,8 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size, #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) -- cgit v1.2.3 From cec051671dc2bb72cc2870aa149d7101ea494b8b Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 17 Aug 2010 11:49:24 +0200 Subject: microblaze: support gpio_to_irq() gpiolib returns -ENXIO if struct gpio_chip::to_irq isn't set, so it's safe to always call. Based on PPC patch "powerpc/gpio: support gpio_to_irq()" 78331aded913d76c7ff996a1a0747d54b057460b Signed-off-by: Michal Simek --- arch/microblaze/include/asm/gpio.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/gpio.h b/arch/microblaze/include/asm/gpio.h index 2345ac354d9b..2b2c18be71c6 100644 --- a/arch/microblaze/include/asm/gpio.h +++ b/arch/microblaze/include/asm/gpio.h @@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio) 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) -- cgit v1.2.3 From 4e07dba7cb8c9c76a52d0e32b69f13bb583a9674 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 12 Aug 2010 14:28:53 +0200 Subject: microblaze: Add libgcc function directly to kernel Replaced libgcc functions with asm optimized implementation. Signed-off-by: Michal Simek --- arch/microblaze/Makefile | 3 - arch/microblaze/kernel/microblaze_ksyms.c | 25 ------ arch/microblaze/lib/Makefile | 10 +++ arch/microblaze/lib/ashldi3.c | 29 +++++++ arch/microblaze/lib/ashrdi3.c | 31 ++++++++ arch/microblaze/lib/divsi3.S | 73 ++++++++++++++++++ arch/microblaze/lib/libgcc.h | 25 ++++++ arch/microblaze/lib/lshrdi3.c | 29 +++++++ arch/microblaze/lib/modsi3.S | 73 ++++++++++++++++++ arch/microblaze/lib/muldi3.S | 121 ++++++++++++++++++++++++++++++ arch/microblaze/lib/mulsi3.S | 46 ++++++++++++ arch/microblaze/lib/udivsi3.S | 84 +++++++++++++++++++++ arch/microblaze/lib/umodsi3.S | 86 +++++++++++++++++++++ 13 files changed, 607 insertions(+), 28 deletions(-) create mode 100644 arch/microblaze/lib/ashldi3.c create mode 100644 arch/microblaze/lib/ashrdi3.c create mode 100644 arch/microblaze/lib/divsi3.S create mode 100644 arch/microblaze/lib/libgcc.h create mode 100644 arch/microblaze/lib/lshrdi3.c create mode 100644 arch/microblaze/lib/modsi3.S create mode 100644 arch/microblaze/lib/muldi3.S create mode 100644 arch/microblaze/lib/mulsi3.S create mode 100644 arch/microblaze/lib/udivsi3.S create mode 100644 arch/microblaze/lib/umodsi3.S (limited to 'arch') diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index 592c7079de88..70a3837c9ba8 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile @@ -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/ diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c index ff85f7718035..ef0ab9bb15c1 100644 --- a/arch/microblaze/kernel/microblaze_ksyms.c +++ b/arch/microblaze/kernel/microblaze_ksyms.c @@ -21,31 +21,6 @@ #include #include -/* - * 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 diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile index 4dfe47d3cd91..f1fcbff3da25 100644 --- a/arch/microblaze/lib/Makefile +++ b/arch/microblaze/lib/Makefile @@ -11,3 +11,13 @@ lib-y += memcpy.o memmove.o 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 index 000000000000..beb80f316095 --- /dev/null +++ b/arch/microblaze/lib/ashldi3.c @@ -0,0 +1,29 @@ +#include + +#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 index 000000000000..c884a912b660 --- /dev/null +++ b/arch/microblaze/lib/ashrdi3.c @@ -0,0 +1,31 @@ +#include + +#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 index 000000000000..595b02d6e86b --- /dev/null +++ b/arch/microblaze/lib/divsi3.S @@ -0,0 +1,73 @@ +#include + +/* +* 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 index 000000000000..05909d58e2fe --- /dev/null +++ b/arch/microblaze/lib/libgcc.h @@ -0,0 +1,25 @@ +#ifndef __ASM_LIBGCC_H +#define __ASM_LIBGCC_H + +#include + +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 index 000000000000..dcf8d6810b7c --- /dev/null +++ b/arch/microblaze/lib/lshrdi3.c @@ -0,0 +1,29 @@ +#include + +#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); diff --git a/arch/microblaze/lib/modsi3.S b/arch/microblaze/lib/modsi3.S new file mode 100644 index 000000000000..84e0bee6e8c7 --- /dev/null +++ b/arch/microblaze/lib/modsi3.S @@ -0,0 +1,73 @@ +#include + +/* +* 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 index 000000000000..ceeaa8c407f2 --- /dev/null +++ b/arch/microblaze/lib/muldi3.S @@ -0,0 +1,121 @@ +#include + +/* + * 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 index 000000000000..90bd7b93afe6 --- /dev/null +++ b/arch/microblaze/lib/mulsi3.S @@ -0,0 +1,46 @@ +#include + +/* + * 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 index 000000000000..64cf57e4bb85 --- /dev/null +++ b/arch/microblaze/lib/udivsi3.S @@ -0,0 +1,84 @@ +#include + +/* +* 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 index 000000000000..17d16bafae58 --- /dev/null +++ b/arch/microblaze/lib/umodsi3.S @@ -0,0 +1,86 @@ +#include + +/* + * 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 -- cgit v1.2.3 From bd3b492a29a5221fef1c24ecfd00bb335945dce9 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 12 Aug 2010 13:06:59 +0200 Subject: microblaze: Export missing symbols for modules Several kernel modules requires empty_zero_page and mbc to be exported. Signed-off-by: Michal Simek --- arch/microblaze/kernel/microblaze_ksyms.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c index ef0ab9bb15c1..5cb034174005 100644 --- a/arch/microblaze/kernel/microblaze_ksyms.c +++ b/arch/microblaze/kernel/microblaze_ksyms.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -38,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); -- cgit v1.2.3 From 099a2f4284eba5da2708d0e8fe0797dc095d47ca Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 10 Sep 2010 12:43:42 +0200 Subject: microblaze: Define VMALLOC_START/END per cpu changes requires VMALLOC_START/END to be define even for noMMU systems. Signed-off-by: Michal Simek --- arch/microblaze/include/asm/pgtable.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h index ca2d92871545..d4f421672d3b 100644 --- a/arch/microblaze/include/asm/pgtable.h +++ b/arch/microblaze/include/asm/pgtable.h @@ -57,6 +57,13 @@ static inline int pte_file(pte_t pte) { return 0; } #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 -- cgit v1.2.3 From 92ee8bd468b43938319d6ff51afb071b6e9ef758 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Sep 2010 21:23:49 -0700 Subject: microblaze: Use static const char * const where possible Signed-off-by: Joe Perches Signed-off-by: Michal Simek --- arch/microblaze/kernel/heartbeat.c | 10 +++++----- arch/microblaze/kernel/intc.c | 2 +- arch/microblaze/kernel/timer.c | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c index 522751737cfa..f8bc2d79ee35 100644 --- a/arch/microblaze/kernel/heartbeat.c +++ b/arch/microblaze/kernel/heartbeat.c @@ -47,11 +47,11 @@ 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", + "xlnx,opb-gpio-1.00.a", + NULL + }; for (j = 0; gpio_list[j] != NULL; j++) { gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]); diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c index 03172c1da770..e1cf0819d753 100644 --- a/arch/microblaze/kernel/intc.c +++ b/arch/microblaze/kernel/intc.c @@ -126,7 +126,7 @@ 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", diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index ec7df67006ba..da9d1e56108b 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -258,12 +258,12 @@ 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", + "xlnx,opb-timer-1.00.b", + "xlnx,opb-timer-1.00.a", + NULL + }; for (i = 0; timer_list[i] != NULL; i++) { timer = of_find_compatible_node(NULL, NULL, timer_list[i]); -- cgit v1.2.3 From a7d8355008e4f6bbdcb8f998328afa685cec959c Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 28 Sep 2010 15:43:59 +1000 Subject: microblaze: Remove hardcoded asm instraction for PVR loading It comes from past where pvr wasn't supported in msr instruction. Signed-off-by: Michal Simek --- arch/microblaze/kernel/cpu/pvr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c index 9bee9382bf74..e01afa68273e 100644 --- a/arch/microblaze/kernel/cpu/pvr.c +++ b/arch/microblaze/kernel/cpu/pvr.c @@ -27,7 +27,7 @@ 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; \ } -- cgit v1.2.3 From e65f1e2843d31d9ed74c7cce273adc0d97b5140f Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 14 Sep 2010 08:09:37 +0200 Subject: microblaze: Remove additional compatible properties Device-tree BSP generates longer compatible properties that's why we can remove extra/old one. Signed-off-by: Michal Simek --- arch/microblaze/kernel/heartbeat.c | 1 - arch/microblaze/kernel/intc.c | 3 --- arch/microblaze/kernel/timer.c | 2 -- arch/microblaze/platform/platform.c | 3 --- 4 files changed, 9 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c index f8bc2d79ee35..5c24eb8219f1 100644 --- a/arch/microblaze/kernel/heartbeat.c +++ b/arch/microblaze/kernel/heartbeat.c @@ -49,7 +49,6 @@ void setup_heartbeat(void) int j; const char * const gpio_list[] = { "xlnx,xps-gpio-1.00.a", - "xlnx,opb-gpio-1.00.a", NULL }; diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c index e1cf0819d753..e85bbea1c62b 100644 --- a/arch/microblaze/kernel/intc.c +++ b/arch/microblaze/kernel/intc.c @@ -128,9 +128,6 @@ void __init init_IRQ(void) #endif 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 }; diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index da9d1e56108b..64ca14dbac6e 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -260,8 +260,6 @@ void __init time_init(void) #endif const char * const timer_list[] = { "xlnx,xps-timer-1.00.a", - "xlnx,opb-timer-1.00.b", - "xlnx,opb-timer-1.00.a", NULL }; diff --git a/arch/microblaze/platform/platform.c b/arch/microblaze/platform/platform.c index 5b89b58c5aed..b9529caa507a 100644 --- a/arch/microblaze/platform/platform.c +++ b/arch/microblaze/platform/platform.c @@ -17,9 +17,6 @@ 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", }, {} }; -- cgit v1.2.3 From 96a5ff42298d0ea44d5aa321a56aeba280b52645 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 28 Sep 2010 16:27:49 +1000 Subject: microblaze: remove early printk uarlite console dependency from header This dependency is resolved in menuconfig. Signed-off-by: Michal Simek --- arch/microblaze/include/asm/setup.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h index 5f910ebe0325..8f3968971e4e 100644 --- a/arch/microblaze/include/asm/setup.h +++ b/arch/microblaze/include/asm/setup.h @@ -25,7 +25,7 @@ void early_printk(const char *fmt, ...); int setup_early_printk(char *opt); void disable_early_printk(void); -#if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE) +#if defined(CONFIG_EARLY_PRINTK) #define eprintk early_printk #else #define eprintk printk -- cgit v1.2.3 From 2af9ebe951bb12434e9f10cd1f0f83943ef3f54b Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 28 Sep 2010 16:33:53 +1000 Subject: microblaze: Rename all uartlite early printk functions This is done because of uart16550 early printk support Signed-off-by: Michal Simek --- arch/microblaze/kernel/early_printk.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c index 7de84923ba07..fa07d211adec 100644 --- a/arch/microblaze/kernel/early_printk.c +++ b/arch/microblaze/kernel/early_printk.c @@ -24,7 +24,7 @@ static u32 early_console_initialized; static u32 base_addr; -static void early_printk_putc(char c) +static void early_printk_uartlite_putc(char c) { /* * Limit how many times we'll spin waiting for TX FIFO status. @@ -45,25 +45,25 @@ 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, }; -static struct console *early_console = &early_serial_console; +static struct console *early_console = &early_serial_uartlite_console; void early_printk(const char *fmt, ...) { -- cgit v1.2.3 From 9a7e8d805ea042a7f37c8d3cef8350db63df9d57 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 28 Sep 2010 16:38:28 +1000 Subject: microblaze: Setup early console dynamically Just setup pointer early console in run time. Signed-off-by: Michal Simek --- arch/microblaze/kernel/early_printk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c index fa07d211adec..41e285c354b6 100644 --- a/arch/microblaze/kernel/early_printk.c +++ b/arch/microblaze/kernel/early_printk.c @@ -63,7 +63,7 @@ static struct console early_serial_uartlite_console = { .index = -1, }; -static struct console *early_console = &early_serial_uartlite_console; +static struct console *early_console; void early_printk(const char *fmt, ...) { @@ -90,6 +90,7 @@ int __init setup_early_printk(char *opt) #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); -- cgit v1.2.3 From 51f5fa50942ab013aa2e321bdfdba1c34ebf3256 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 28 Sep 2010 16:40:00 +1000 Subject: microblaze: Do not compile early console support for uartlite if is disabled Kconfig blocks to select any other early console support that's why this patch has no real impact on current kernel version. But it is done because of uart16550. Signed-off-by: Michal Simek --- arch/microblaze/kernel/early_printk.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c index 41e285c354b6..685a64e93ede 100644 --- a/arch/microblaze/kernel/early_printk.c +++ b/arch/microblaze/kernel/early_printk.c @@ -24,6 +24,7 @@ static u32 early_console_initialized; static u32 base_addr; +#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE static void early_printk_uartlite_putc(char c) { /* @@ -62,6 +63,7 @@ static struct console early_serial_uartlite_console = { .flags = CON_PRINTBUFFER, .index = -1, }; +#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */ static struct console *early_console; @@ -84,6 +86,7 @@ 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; @@ -97,8 +100,10 @@ int __init setup_early_printk(char *opt) /* register_console(early_console); */ return 0; - } else - return 1; + } +#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */ + + return 1; } void __init disable_early_printk(void) -- cgit v1.2.3 From 67f4aaa21cf8cf09726cd26b506f3407ad7f11f9 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 28 Sep 2010 16:17:03 +1000 Subject: microblaze: Support early console on uart16550 Early console support reuse setting from U-BOOT that's why it is not necessary to setup baudrates, etc. Signed-off-by: Michal Simek --- arch/microblaze/Kconfig.debug | 2 +- arch/microblaze/include/asm/prom.h | 1 + arch/microblaze/kernel/early_printk.c | 63 +++++++++++++++++++++++++++++++++++ arch/microblaze/kernel/prom.c | 34 +++++++++++++++++++ 4 files changed, 99 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/microblaze/Kconfig.debug b/arch/microblaze/Kconfig.debug index e6e5e0da28c3..e66e25c4b0b2 100644 --- a/arch/microblaze/Kconfig.debug +++ b/arch/microblaze/Kconfig.debug @@ -10,7 +10,7 @@ source "lib/Kconfig.debug" 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. diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 101fa098f62a..bdc38312ae4a 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -27,6 +27,7 @@ /* Other Prototypes */ extern int early_uartlite_console(void); +extern int early_uart16550_console(void); #ifdef CONFIG_PCI /* diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c index 685a64e93ede..c3616a080ebf 100644 --- a/arch/microblaze/kernel/early_printk.c +++ b/arch/microblaze/kernel/early_printk.c @@ -65,6 +65,50 @@ static struct console early_serial_uartlite_console = { }; #endif /* CONFIG_SERIAL_UARTLITE_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, ...) @@ -103,6 +147,25 @@ int __init setup_early_printk(char *opt) } #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; } diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c index 427b13b4740f..608e5cf2e10a 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c @@ -89,6 +89,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 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) -- cgit v1.2.3 From 6c3bbdd6609aefa6494ee3020f80108dbdccf755 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Wed, 15 Sep 2010 11:05:51 -0700 Subject: microblaze: pci-common cleanup Use set_dma_ops and remove now used-once oddly named temp pointer sd. Signed-off-by: Milton Miller Signed-off-by: Nishanth Aravamudan Signed-off-by: Michal Simek --- arch/microblaze/pci/pci-common.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 2bc57a836d71..e363615d6798 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -1060,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); @@ -1071,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); -- cgit v1.2.3 From b4dcaee50a3859bc3c7e6bace5daeec1d903e239 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 10 Sep 2010 12:58:37 +0200 Subject: microblaze: trivial: Add comment for AXI pvr AXI and OPB share some PVR macros. Signed-off-by: Michal Simek --- arch/microblaze/include/asm/pvr.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h index cf59ef55c3b6..316105531d55 100644 --- a/arch/microblaze/include/asm/pvr.h +++ b/arch/microblaze/include/asm/pvr.h @@ -39,9 +39,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 @@ -64,8 +64,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 -- cgit v1.2.3 From 8e2ad016b20f98790d5995aae1d157d1613ab9e6 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 13 Aug 2010 12:47:42 +0200 Subject: microblaze: Add PVR for endians plus detection Upcomming microblaze version will support little-endian. Signed-off-by: Michal Simek Acked-by: Grant Likely --- arch/microblaze/include/asm/cpuinfo.h | 1 + arch/microblaze/include/asm/pvr.h | 3 +++ arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c | 1 + arch/microblaze/kernel/cpu/cpuinfo-static.c | 1 + arch/microblaze/kernel/cpu/mb.c | 3 ++- arch/microblaze/platform/generic/system.dts | 1 + 6 files changed, 9 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h index b4f5ca33aebf..0d4f0ce3ff7c 100644 --- a/arch/microblaze/include/asm/cpuinfo.h +++ b/arch/microblaze/include/asm/cpuinfo.h @@ -38,6 +38,7 @@ struct cpuinfo { u32 use_exc; u32 ver_code; u32 mmu; + u32 endian; /* CPU caches */ u32 use_icache; diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h index 316105531d55..37db96a15b45 100644 --- a/arch/microblaze/include/asm/pvr.h +++ b/arch/microblaze/include/asm/pvr.h @@ -32,6 +32,7 @@ struct pvr_s { #define PVR0_USE_DCACHE_MASK 0x01000000 #define PVR0_USE_MMU 0x00800000 #define PVR0_USE_BTC 0x00400000 +#define PVR0_ENDI 0x00200000 #define PVR0_VERSION_MASK 0x0000FF00 #define PVR0_USER1_MASK 0x000000FF @@ -209,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/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c index f72dbd66c844..f70a6047f08e 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c +++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c @@ -72,6 +72,7 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu) CI(pvr_user2, USER2); CI(mmu, USE_MMU); + CI(endian, ENDIAN); CI(use_icache, USE_ICACHE); CI(icache_tagbits, ICACHE_ADDR_TAG_BITS); diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c index 6095aa6b5c88..b16b994ca3d2 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo-static.c +++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c @@ -119,6 +119,7 @@ void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu) 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; diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c index 7086e3564281..b4048af02615 100644 --- a/arch/microblaze/kernel/cpu/mb.c +++ b/arch/microblaze/kernel/cpu/mb.c @@ -51,11 +51,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) 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 % diff --git a/arch/microblaze/platform/generic/system.dts b/arch/microblaze/platform/generic/system.dts index ef667d125ce0..3f85df2b73b3 100644 --- a/arch/microblaze/platform/generic/system.dts +++ b/arch/microblaze/platform/generic/system.dts @@ -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>; -- cgit v1.2.3 From e4f29092272ee91a34d3660c31f15ed103057aa0 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 28 Sep 2010 15:49:17 +1000 Subject: microblaze: KGDB little endian support Just need to use little-endian opcode for brki r16, 0x18 Signed-off-by: Michal Simek CC: Jason Wessel --- arch/microblaze/kernel/kgdb.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/microblaze/kernel/kgdb.c b/arch/microblaze/kernel/kgdb.c index 9b5a817605ec..09a5e8286137 100644 --- a/arch/microblaze/kernel/kgdb.c +++ b/arch/microblaze/kernel/kgdb.c @@ -142,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 }; -- cgit v1.2.3 From 02b08045a0306c38131c6d7155c4034a775d40b1 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 28 Sep 2010 16:04:14 +1000 Subject: microblaze: Add support for little-endian Microblaze Microblaze little-endian toolchain exports __MICROBLAZEEL__ which is used in the kernel to identify little/big endian. The most of the changes are in loading values from DTB which is always big endian. Little endian platforms are based on new AXI bus which has impact to early uartlite initialization. Signed-off-by: Michal Simek --- arch/microblaze/include/asm/byteorder.h | 4 ++++ arch/microblaze/include/asm/checksum.h | 9 +++++++-- arch/microblaze/include/asm/cpuinfo.h | 3 ++- arch/microblaze/include/asm/elf.h | 2 +- arch/microblaze/include/asm/unaligned.h | 12 +++++++++--- arch/microblaze/kernel/heartbeat.c | 2 +- arch/microblaze/kernel/intc.c | 9 ++++++--- arch/microblaze/kernel/prom.c | 7 ++++--- arch/microblaze/kernel/timer.c | 8 ++++---- arch/microblaze/kernel/vmlinux.lds.S | 4 ++++ 10 files changed, 42 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/byteorder.h b/arch/microblaze/include/asm/byteorder.h index ce9c58732ffc..31902762a426 100644 --- a/arch/microblaze/include/asm/byteorder.h +++ b/arch/microblaze/include/asm/byteorder.h @@ -1,6 +1,10 @@ #ifndef _ASM_MICROBLAZE_BYTEORDER_H #define _ASM_MICROBLAZE_BYTEORDER_H +#ifdef __MICROBLAZEEL__ +#include +#else #include +#endif #endif /* _ASM_MICROBLAZE_BYTEORDER_H */ diff --git a/arch/microblaze/include/asm/checksum.h b/arch/microblaze/include/asm/checksum.h index 128bf03b54b7..0185cbefdda4 100644 --- a/arch/microblaze/include/asm/checksum.h +++ b/arch/microblaze/include/asm/checksum.h @@ -24,8 +24,13 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, "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; } diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h index 0d4f0ce3ff7c..7fab800496ae 100644 --- a/arch/microblaze/include/asm/cpuinfo.h +++ b/arch/microblaze/include/asm/cpuinfo.h @@ -98,7 +98,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 */ diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h index 732caf1be741..098dfdde4b06 100644 --- a/arch/microblaze/include/asm/elf.h +++ b/arch/microblaze/include/asm/elf.h @@ -71,7 +71,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #define ELF_ET_DYN_BASE (0x08000000) -#ifdef __LITTLE_ENDIAN__ +#ifdef __MICROBLAZEEL__ #define ELF_DATA ELFDATA2LSB #else #define ELF_DATA ELFDATA2MSB diff --git a/arch/microblaze/include/asm/unaligned.h b/arch/microblaze/include/asm/unaligned.h index 3658d91ac0fb..2b97cbe500e9 100644 --- a/arch/microblaze/include/asm/unaligned.h +++ b/arch/microblaze/include/asm/unaligned.h @@ -12,12 +12,18 @@ # ifdef __KERNEL__ -# include +# include # include # include -# 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 */ diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c index 5c24eb8219f1..154756f3c694 100644 --- a/arch/microblaze/kernel/heartbeat.c +++ b/arch/microblaze/kernel/heartbeat.c @@ -59,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); diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c index e85bbea1c62b..d61ea33aff7c 100644 --- a/arch/microblaze/kernel/intc.c +++ b/arch/microblaze/kernel/intc.c @@ -138,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"); diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c index 608e5cf2e10a..04d3325039d9 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c @@ -77,11 +77,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 */ @@ -115,7 +116,7 @@ static int __init early_init_dt_scan_serial_full(unsigned long node, addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l); addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l); - return addr; /* return address */ + return be32_to_cpu(addr); /* return address */ } /* this function is looking for early uartlite console - Microblaze specific */ diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 64ca14dbac6e..fcb97e86003d 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -270,11 +270,11 @@ 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) { eprintk(KERN_EMERG "Please enable two timers in HW\n"); BUG(); diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S index 20b0552391d1..96a88c31fe48 100644 --- a/arch/microblaze/kernel/vmlinux.lds.S +++ b/arch/microblaze/kernel/vmlinux.lds.S @@ -15,7 +15,11 @@ ENTRY(microblaze_start) #include #include +#ifdef __MICROBLAZEEL__ +jiffies = jiffies_64; +#else jiffies = jiffies_64 + 4; +#endif SECTIONS { . = CONFIG_KERNEL_START; -- cgit v1.2.3 From ccea0e6e49e4db8ee7968c183ecddb3e399c5f54 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Oct 2010 17:39:21 +1000 Subject: microblaze: Support timer on AXI lite New microblaze systems uses two buses. One for memories and flashes and the second for low-speed peripherals which can run on different CLK. This is the reason why the kernel is trying to read clock-frequency directly from node. If there is then the kernel will work with it. If not then cpu CLK is used. Signed-off-by: Michal Simek --- arch/microblaze/include/asm/cpuinfo.h | 1 - arch/microblaze/kernel/timer.c | 21 ++++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h index 7fab800496ae..cd257537ae54 100644 --- a/arch/microblaze/include/asm/cpuinfo.h +++ b/arch/microblaze/include/asm/cpuinfo.h @@ -77,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; diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index fcb97e86003d..a5aa33db1df3 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -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(µblaze_tc, µblaze_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[] = { @@ -286,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 -- cgit v1.2.3 From 93e2e85139509338c68279c7260ebb68177b23a9 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Sat, 9 Oct 2010 13:58:24 +1000 Subject: microblaze: Separate library optimized functions memcpy/memmove/memset Signed-off-by: Michal Simek --- arch/microblaze/lib/memcpy.c | 13 ++++++++++--- arch/microblaze/lib/memmove.c | 26 ++++++++++++++++++-------- arch/microblaze/lib/memset.c | 22 ++++++++++++++++++---- 3 files changed, 46 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c index 014bac92bdff..ab2d115f9ee5 100644 --- a/arch/microblaze/lib/memcpy.c +++ b/arch/microblaze/lib/memcpy.c @@ -33,17 +33,24 @@ #include #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 @@ -150,7 +157,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 */ diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c index 0929198c5e68..1d3c0e7990e5 100644 --- a/arch/microblaze/lib/memmove.c +++ b/arch/microblaze/lib/memmove.c @@ -31,16 +31,12 @@ #include #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 @@ -169,7 +179,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 */ diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c index ecfb663e1fc1..834565d1607e 100644 --- a/arch/microblaze/lib/memset.c +++ b/arch/microblaze/lib/memset.c @@ -31,17 +31,30 @@ #include #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 */ -- cgit v1.2.3 From 1180b28ca82c529972bfd438467d5cd71cca5372 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Sat, 9 Oct 2010 14:05:58 +1000 Subject: microblaze: Support C optimized lib functions for little-endian Optimized C library functions can rapidly speedup the kernel. memset doesn't need to be optimized because there is no difference in behavior on little/big endian cpu. Signed-off-by: Michal Simek --- arch/microblaze/lib/memcpy.c | 33 ++++++++++++++++++++++++++++++--- arch/microblaze/lib/memmove.c | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c index ab2d115f9ee5..cc495d7d99cc 100644 --- a/arch/microblaze/lib/memcpy.c +++ b/arch/microblaze/lib/memcpy.c @@ -93,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; @@ -102,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; @@ -110,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; @@ -119,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; @@ -127,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; @@ -136,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; diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c index 1d3c0e7990e5..123e3616f2dd 100644 --- a/arch/microblaze/lib/memmove.c +++ b/arch/microblaze/lib/memmove.c @@ -114,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; @@ -123,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; @@ -131,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; @@ -140,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; @@ -148,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; @@ -157,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; -- cgit v1.2.3 From b843e4ec01991a386a9e0e9030703524446e03da Mon Sep 17 00:00:00 2001 From: Thomas Backlund Date: Thu, 21 Oct 2010 13:19:10 +0300 Subject: microblaze: Fix build with make 3.82 When running make headers_install_all on x86_64 and make 3.82 I hit this: arch/microblaze/Makefile:80: *** mixed implicit and normal rules. Stop. make: *** [headers_install_all] Error 2 So split the rules to satisfy make 3.82. Signed-off-by: Thomas Backlund Cc: Stable Signed-off-by: Michal Simek --- arch/microblaze/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index 70a3837c9ba8..15f1f1d1840d 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile @@ -69,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 -- cgit v1.2.3