diff options
Diffstat (limited to 'arch/microblaze/kernel')
-rw-r--r-- | arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c | 1 | ||||
-rw-r--r-- | arch/microblaze/kernel/cpu/cpuinfo-static.c | 1 | ||||
-rw-r--r-- | arch/microblaze/kernel/cpu/cpuinfo.c | 2 | ||||
-rw-r--r-- | arch/microblaze/kernel/cpu/mb.c | 3 | ||||
-rw-r--r-- | arch/microblaze/kernel/cpu/pvr.c | 2 | ||||
-rw-r--r-- | arch/microblaze/kernel/early_printk.c | 87 | ||||
-rw-r--r-- | arch/microblaze/kernel/entry.S | 21 | ||||
-rw-r--r-- | arch/microblaze/kernel/exceptions.c | 25 | ||||
-rw-r--r-- | arch/microblaze/kernel/heartbeat.c | 11 | ||||
-rw-r--r-- | arch/microblaze/kernel/intc.c | 14 | ||||
-rw-r--r-- | arch/microblaze/kernel/kgdb.c | 7 | ||||
-rw-r--r-- | arch/microblaze/kernel/microblaze_ksyms.c | 32 | ||||
-rw-r--r-- | arch/microblaze/kernel/prom.c | 39 | ||||
-rw-r--r-- | arch/microblaze/kernel/setup.c | 6 | ||||
-rw-r--r-- | arch/microblaze/kernel/syscall_table.S | 3 | ||||
-rw-r--r-- | arch/microblaze/kernel/timer.c | 41 | ||||
-rw-r--r-- | arch/microblaze/kernel/vmlinux.lds.S | 5 |
17 files changed, 192 insertions, 108 deletions
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c index f72dbd6..f70a604 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 6095aa6..b16b994 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/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c index 255ef88..87c79fa 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}, }; diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c index 7086e35..b4048af 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/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c index 9bee938..e01afa6 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; \ } diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c index 7de8492..c3616a0 100644 --- a/arch/microblaze/kernel/early_printk.c +++ b/arch/microblaze/kernel/early_printk.c @@ -24,7 +24,8 @@ static u32 early_console_initialized; static u32 base_addr; -static void early_printk_putc(char c) +#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE +static void early_printk_uartlite_putc(char c) { /* * Limit how many times we'll spin waiting for TX FIFO status. @@ -45,25 +46,70 @@ static void early_printk_putc(char c) out_be32(base_addr + 4, c & 0xff); } -static void early_printk_write(struct console *unused, +static void early_printk_uartlite_write(struct console *unused, const char *s, unsigned n) { while (*s && n-- > 0) { - early_printk_putc(*s); + early_printk_uartlite_putc(*s); if (*s == '\n') - early_printk_putc('\r'); + early_printk_uartlite_putc('\r'); s++; } } -static struct console early_serial_console = { +static struct console early_serial_uartlite_console = { .name = "earlyser", - .write = early_printk_write, + .write = early_printk_uartlite_write, .flags = CON_PRINTBUFFER, .index = -1, }; +#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */ -static struct console *early_console = &early_serial_console; +#ifdef CONFIG_SERIAL_8250_CONSOLE +static void early_printk_uart16550_putc(char c) +{ + /* + * Limit how many times we'll spin waiting for TX FIFO status. + * This will prevent lockups if the base address is incorrectly + * set, or any other issue on the UARTLITE. + * This limit is pretty arbitrary, unless we are at about 10 baud + * we'll never timeout on a working UART. + */ + + #define UART_LSR_TEMT 0x40 /* Transmitter empty */ + #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ + #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) + + unsigned retries = 10000; + + while (--retries && + !((in_be32(base_addr + 0x14) & BOTH_EMPTY) == BOTH_EMPTY)) + ; + + if (retries) + out_be32(base_addr, c & 0xff); +} + +static void early_printk_uart16550_write(struct console *unused, + const char *s, unsigned n) +{ + while (*s && n-- > 0) { + early_printk_uart16550_putc(*s); + if (*s == '\n') + early_printk_uart16550_putc('\r'); + s++; + } +} + +static struct console early_serial_uart16550_console = { + .name = "earlyser", + .write = early_printk_uart16550_write, + .flags = CON_PRINTBUFFER, + .index = -1, +}; +#endif /* CONFIG_SERIAL_8250_CONSOLE */ + +static struct console *early_console; void early_printk(const char *fmt, ...) { @@ -84,20 +130,43 @@ int __init setup_early_printk(char *opt) if (early_console_initialized) return 1; +#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE base_addr = early_uartlite_console(); if (base_addr) { early_console_initialized = 1; #ifdef CONFIG_MMU early_console_reg_tlb_alloc(base_addr); #endif + early_console = &early_serial_uartlite_console; early_printk("early_printk_console is enabled at 0x%08x\n", base_addr); /* register_console(early_console); */ return 0; - } else - return 1; + } +#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */ + +#ifdef CONFIG_SERIAL_8250_CONSOLE + base_addr = early_uart16550_console(); + base_addr &= ~3; /* clear register offset */ + if (base_addr) { + early_console_initialized = 1; +#ifdef CONFIG_MMU + early_console_reg_tlb_alloc(base_addr); +#endif + early_console = &early_serial_uart16550_console; + + early_printk("early_printk_console is enabled at 0x%08x\n", + base_addr); + + /* register_console(early_console); */ + + return 0; + } +#endif /* CONFIG_SERIAL_8250_CONSOLE */ + + return 1; } void __init disable_early_printk(void) diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index 304882e..819238b 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; \ @@ -295,6 +299,8 @@ C_ENTRY(_user_exception): /* addik r1, r1, -STATE_SAVE_SIZE; */ addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; SAVE_REGS + swi r0, r1, PTO + PT_R3 + swi r0, r1, PTO + PT_R4 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); swi r11, r1, PTO+PT_R1; /* Store user SP. */ @@ -458,14 +464,8 @@ C_ENTRY(sys_execve): addik r8, r1, PTO; /* add user context as 4th arg */ C_ENTRY(sys_rt_sigreturn_wrapper): - swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ - swi r4, r1, PTO+PT_R4; - brlid r15, sys_rt_sigreturn /* Do real work */ + brid sys_rt_sigreturn /* Do real work */ addik r5, r1, PTO; /* add user context as 1st arg */ - lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ - lwi r4, r1, PTO+PT_R4; - bri ret_from_trap /* fall through will not work here due to align */ - nop; /* * HW EXCEPTION rutine start @@ -765,9 +765,7 @@ C_ENTRY(_debug_exception): /* save all regs to pt_reg structure */ swi r0, r1, PTO+PT_R0; /* R0 must be saved too */ swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */ - swi r16, r1, PTO+PT_R16 swi r16, r1, PTO+PT_PC; /* PC and r16 are the same */ - swi r17, r1, PTO+PT_R17 /* save special purpose registers to pt_regs */ mfs r11, rear; swi r11, r1, PTO+PT_EAR; @@ -801,8 +799,6 @@ C_ENTRY(_debug_exception): addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ SAVE_REGS; - swi r17, r1, PTO+PT_R17; - swi r16, r1, PTO+PT_R16; swi r16, r1, PTO+PT_PC; /* Save LP */ swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */ lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); @@ -848,8 +844,6 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */ tophys(r1,r1); /* MS: Restore all regs */ RESTORE_REGS - lwi r17, r1, PTO+PT_R17; - lwi r16, r1, PTO+PT_R16; addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */ lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */ DBTRAP_return_user: /* MS: Make global symbol for debugging */ @@ -863,7 +857,6 @@ DBTRAP_return_user: /* MS: Make global symbol for debugging */ RESTORE_REGS lwi r14, r1, PTO+PT_R14; lwi r16, r1, PTO+PT_PC; - lwi r17, r1, PTO+PT_R17; addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */ tovirt(r1,r1); DBTRAP_return_kernel: /* MS: Make global symbol for debugging */ diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c index b98ee8d..478f294 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 @@ -86,8 +85,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, switch (type & 0x1F) { case MICROBLAZE_ILL_OPCODE_EXCEPTION: if (user_mode(regs)) { - pr_debug(KERN_WARNING "Illegal opcode exception " \ - "in user mode.\n"); + pr_debug("Illegal opcode exception in user mode\n"); _exception(SIGILL, regs, ILL_ILLOPC, addr); return; } @@ -97,8 +95,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, break; case MICROBLAZE_IBUS_EXCEPTION: if (user_mode(regs)) { - pr_debug(KERN_WARNING "Instruction bus error " \ - "exception in user mode.\n"); + pr_debug("Instruction bus error exception in user mode\n"); _exception(SIGBUS, regs, BUS_ADRERR, addr); return; } @@ -108,8 +105,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, break; case MICROBLAZE_DBUS_EXCEPTION: if (user_mode(regs)) { - pr_debug(KERN_WARNING "Data bus error exception " \ - "in user mode.\n"); + pr_debug("Data bus error exception in user mode\n"); _exception(SIGBUS, regs, BUS_ADRERR, addr); return; } @@ -119,8 +115,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, break; case MICROBLAZE_DIV_ZERO_EXCEPTION: if (user_mode(regs)) { - pr_debug(KERN_WARNING "Divide by zero exception " \ - "in user mode\n"); + pr_debug("Divide by zero exception in user mode\n"); _exception(SIGILL, regs, FPE_INTDIV, addr); return; } @@ -129,7 +124,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, die("Divide by zero exception", regs, SIGBUS); break; case MICROBLAZE_FPU_EXCEPTION: - pr_debug(KERN_WARNING "FPU exception\n"); + pr_debug("FPU exception\n"); /* IEEE FP exception */ /* I removed fsr variable and use code var for storing fsr */ if (fsr & FSR_IO) @@ -147,14 +142,8 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, #ifdef CONFIG_MMU case MICROBLAZE_PRIVILEGED_EXCEPTION: - pr_debug(KERN_WARNING "Privileged exception\n"); - /* "brk r0,r0" - used as debug breakpoint - old toolchain */ - if (get_user(code, (unsigned long *)regs->pc) == 0 - && code == 0x980c0000) { - _exception(SIGTRAP, regs, TRAP_BRKPT, addr); - } else { - _exception(SIGILL, regs, ILL_PRVOPC, addr); - } + pr_debug("Privileged exception\n"); + _exception(SIGILL, regs, ILL_PRVOPC, addr); break; #endif default: diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c index 5227517..154756f 100644 --- a/arch/microblaze/kernel/heartbeat.c +++ b/arch/microblaze/kernel/heartbeat.c @@ -47,11 +47,10 @@ void setup_heartbeat(void) struct device_node *gpio = NULL; int *prop; int j; - char *gpio_list[] = { - "xlnx,xps-gpio-1.00.a", - "xlnx,opb-gpio-1.00.a", - NULL - }; + const char * const gpio_list[] = { + "xlnx,xps-gpio-1.00.a", + NULL + }; for (j = 0; gpio_list[j] != NULL; j++) { gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]); @@ -60,7 +59,7 @@ void setup_heartbeat(void) } if (gpio) { - base_addr = *(int *) of_get_property(gpio, "reg", NULL); + base_addr = be32_to_cpup(of_get_property(gpio, "reg", NULL)); base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE); printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr); diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c index 03172c1..d61ea33 100644 --- a/arch/microblaze/kernel/intc.c +++ b/arch/microblaze/kernel/intc.c @@ -126,11 +126,8 @@ void __init init_IRQ(void) 0 }; #endif - static char *intc_list[] = { + const char * const intc_list[] = { "xlnx,xps-intc-1.00.a", - "xlnx,opb-intc-1.00.c", - "xlnx,opb-intc-1.00.b", - "xlnx,opb-intc-1.00.a", NULL }; @@ -141,12 +138,15 @@ void __init init_IRQ(void) } BUG_ON(!intc); - intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL); + intc_baseaddr = be32_to_cpup(of_get_property(intc, + "reg", NULL)); intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE); - nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL); + nr_irq = be32_to_cpup(of_get_property(intc, + "xlnx,num-intr-inputs", NULL)); intr_type = - *(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL); + be32_to_cpup(of_get_property(intc, + "xlnx,kind-of-intr", NULL)); if (intr_type >= (1 << (nr_irq + 1))) printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n"); diff --git a/arch/microblaze/kernel/kgdb.c b/arch/microblaze/kernel/kgdb.c index bfc006b..09a5e82 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': @@ -143,5 +142,9 @@ void kgdb_arch_exit(void) * Global data */ struct kgdb_arch arch_kgdb_ops = { +#ifdef __MICROBLAZEEL__ + .gdb_bpt_instr = {0x18, 0x00, 0x0c, 0xba}, /* brki r16, 0x18 */ +#else .gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */ +#endif }; diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c index ff85f77..5cb0341 100644 --- a/arch/microblaze/kernel/microblaze_ksyms.c +++ b/arch/microblaze/kernel/microblaze_ksyms.c @@ -15,37 +15,13 @@ #include <linux/syscalls.h> #include <asm/checksum.h> +#include <asm/cacheflush.h> #include <linux/io.h> #include <asm/page.h> #include <asm/system.h> #include <linux/ftrace.h> #include <linux/uaccess.h> -/* - * libgcc functions - functions that are used internally by the - * compiler... (prototypes are not correct though, but that - * doesn't really matter since they're not versioned). - */ -extern void __ashldi3(void); -EXPORT_SYMBOL(__ashldi3); -extern void __ashrdi3(void); -EXPORT_SYMBOL(__ashrdi3); -extern void __divsi3(void); -EXPORT_SYMBOL(__divsi3); -extern void __lshrdi3(void); -EXPORT_SYMBOL(__lshrdi3); -extern void __modsi3(void); -EXPORT_SYMBOL(__modsi3); -extern void __mulsi3(void); -EXPORT_SYMBOL(__mulsi3); -extern void __muldi3(void); -EXPORT_SYMBOL(__muldi3); -extern void __ucmpdi2(void); -EXPORT_SYMBOL(__ucmpdi2); -extern void __udivsi3(void); -EXPORT_SYMBOL(__udivsi3); -extern void __umodsi3(void); -EXPORT_SYMBOL(__umodsi3); extern char *_ebss; EXPORT_SYMBOL_GPL(_ebss); #ifdef CONFIG_FUNCTION_TRACER @@ -63,3 +39,9 @@ EXPORT_SYMBOL(__strncpy_user); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memmove); #endif + +#ifdef CONFIG_MMU +EXPORT_SYMBOL(empty_zero_page); +#endif + +EXPORT_SYMBOL(mbc); diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c index bacbd3d..a105301 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c @@ -72,11 +72,12 @@ static int __init early_init_dt_scan_serial(unsigned long node, /* find compatible node with uartlite */ p = of_get_flat_dt_prop(node, "compatible", &l); if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) && - (strncmp(p, "xlnx,opb-uartlite", 17) != 0)) + (strncmp(p, "xlnx,opb-uartlite", 17) != 0) && + (strncmp(p, "xlnx,axi-uartlite", 17) != 0)) return 0; addr = of_get_flat_dt_prop(node, "reg", &l); - return *addr; /* return address */ + return be32_to_cpup(addr); /* return address */ } /* this function is looking for early uartlite console - Microblaze specific */ @@ -84,6 +85,40 @@ int __init early_uartlite_console(void) { return of_scan_flat_dt(early_init_dt_scan_serial, NULL); } + +/* MS this is Microblaze specifig function */ +static int __init early_init_dt_scan_serial_full(unsigned long node, + const char *uname, int depth, void *data) +{ + unsigned long l; + char *p; + unsigned int addr; + + pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); + +/* find all serial nodes */ + if (strncmp(uname, "serial", 6) != 0) + return 0; + + early_init_dt_check_for_initrd(node); + +/* find compatible node with uartlite */ + p = of_get_flat_dt_prop(node, "compatible", &l); + + if ((strncmp(p, "xlnx,xps-uart16550", 18) != 0) && + (strncmp(p, "xlnx,axi-uart16550", 18) != 0)) + return 0; + + addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l); + addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l); + return be32_to_cpu(addr); /* return address */ +} + +/* this function is looking for early uartlite console - Microblaze specific */ +int __init early_uart16550_console(void) +{ + return of_scan_flat_dt(early_init_dt_scan_serial_full, NULL); +} #endif void __init early_init_devtree(void *params) diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index f5f7688..bb1558e 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/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index 03376dc..e88a930 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 */ diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index b1380ae..a5aa33d 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[] = { @@ -258,12 +262,10 @@ void __init time_init(void) 0 }; #endif - char *timer_list[] = { - "xlnx,xps-timer-1.00.a", - "xlnx,opb-timer-1.00.b", - "xlnx,opb-timer-1.00.a", - NULL - }; + const char * const timer_list[] = { + "xlnx,xps-timer-1.00.a", + NULL + }; for (i = 0; timer_list[i] != NULL; i++) { timer = of_find_compatible_node(NULL, NULL, timer_list[i]); @@ -272,13 +274,13 @@ void __init time_init(void) } BUG_ON(!timer); - timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL); + timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL)); timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); - irq = *(int *) of_get_property(timer, "interrupts", NULL); - timer_num = - *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL); + irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL)); + timer_num = be32_to_cpup(of_get_property(timer, + "xlnx,one-timer-only", NULL)); if (timer_num) { - printk(KERN_EMERG "Please enable two timers in HW\n"); + eprintk(KERN_EMERG "Please enable two timers in HW\n"); BUG(); } @@ -288,7 +290,14 @@ void __init time_init(void) printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", timer_list[i], timer_baseaddr, irq); - cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ; + /* If there is clock-frequency property than use it */ + prop = of_get_property(timer, "clock-frequency", NULL); + if (prop) + timer_clock_freq = be32_to_cpup(prop); + else + timer_clock_freq = cpuinfo.cpu_clock_freq; + + freq_div_hz = timer_clock_freq / HZ; setup_irq(irq, &timer_irqaction); #ifdef CONFIG_HEART_BEAT diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S index a09f296..96a88c3 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) @@ -16,7 +15,11 @@ ENTRY(microblaze_start) #include <asm-generic/vmlinux.lds.h> #include <asm/thread_info.h> +#ifdef __MICROBLAZEEL__ +jiffies = jiffies_64; +#else jiffies = jiffies_64 + 4; +#endif SECTIONS { . = CONFIG_KERNEL_START; |