aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze/kernel')
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c1
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-static.c1
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo.c2
-rw-r--r--arch/microblaze/kernel/cpu/mb.c3
-rw-r--r--arch/microblaze/kernel/cpu/pvr.c2
-rw-r--r--arch/microblaze/kernel/early_printk.c87
-rw-r--r--arch/microblaze/kernel/entry.S21
-rw-r--r--arch/microblaze/kernel/exceptions.c25
-rw-r--r--arch/microblaze/kernel/heartbeat.c11
-rw-r--r--arch/microblaze/kernel/intc.c14
-rw-r--r--arch/microblaze/kernel/kgdb.c7
-rw-r--r--arch/microblaze/kernel/microblaze_ksyms.c32
-rw-r--r--arch/microblaze/kernel/prom.c39
-rw-r--r--arch/microblaze/kernel/setup.c6
-rw-r--r--arch/microblaze/kernel/syscall_table.S3
-rw-r--r--arch/microblaze/kernel/timer.c41
-rw-r--r--arch/microblaze/kernel/vmlinux.lds.S5
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 f72dbd66c844..f70a6047f08e 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
@@ -72,6 +72,7 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
72 CI(pvr_user2, USER2); 72 CI(pvr_user2, USER2);
73 73
74 CI(mmu, USE_MMU); 74 CI(mmu, USE_MMU);
75 CI(endian, ENDIAN);
75 76
76 CI(use_icache, USE_ICACHE); 77 CI(use_icache, USE_ICACHE);
77 CI(icache_tagbits, ICACHE_ADDR_TAG_BITS); 78 CI(icache_tagbits, ICACHE_ADDR_TAG_BITS);
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c
index 6095aa6b5c88..b16b994ca3d2 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo-static.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c
@@ -119,6 +119,7 @@ void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
119 ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2"); 119 ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2");
120 120
121 ci->mmu = fcpu(cpu, "xlnx,use-mmu"); 121 ci->mmu = fcpu(cpu, "xlnx,use-mmu");
122 ci->endian = fcpu(cpu, "xlnx,endianness");
122 123
123 ci->ver_code = 0; 124 ci->ver_code = 0;
124 ci->fpga_family_code = 0; 125 ci->fpga_family_code = 0;
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
index 255ef880351e..87c79fa275c3 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -30,6 +30,8 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
30 {"7.20.c", 0x0e}, 30 {"7.20.c", 0x0e},
31 {"7.20.d", 0x0f}, 31 {"7.20.d", 0x0f},
32 {"7.30.a", 0x10}, 32 {"7.30.a", 0x10},
33 {"7.30.b", 0x11},
34 {"8.00.a", 0x12},
33 {NULL, 0}, 35 {NULL, 0},
34}; 36};
35 37
diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c
index 7086e3564281..b4048af02615 100644
--- a/arch/microblaze/kernel/cpu/mb.c
+++ b/arch/microblaze/kernel/cpu/mb.c
@@ -51,11 +51,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
51 count = seq_printf(m, 51 count = seq_printf(m,
52 "CPU-Family: MicroBlaze\n" 52 "CPU-Family: MicroBlaze\n"
53 "FPGA-Arch: %s\n" 53 "FPGA-Arch: %s\n"
54 "CPU-Ver: %s\n" 54 "CPU-Ver: %s, %s endian\n"
55 "CPU-MHz: %d.%02d\n" 55 "CPU-MHz: %d.%02d\n"
56 "BogoMips: %lu.%02lu\n", 56 "BogoMips: %lu.%02lu\n",
57 fpga_family, 57 fpga_family,
58 cpu_ver, 58 cpu_ver,
59 cpuinfo.endian ? "little" : "big",
59 cpuinfo.cpu_clock_freq / 60 cpuinfo.cpu_clock_freq /
60 1000000, 61 1000000,
61 cpuinfo.cpu_clock_freq % 62 cpuinfo.cpu_clock_freq %
diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c
index 9bee9382bf74..e01afa68273e 100644
--- a/arch/microblaze/kernel/cpu/pvr.c
+++ b/arch/microblaze/kernel/cpu/pvr.c
@@ -27,7 +27,7 @@
27 register unsigned tmp __asm__("r3"); \ 27 register unsigned tmp __asm__("r3"); \
28 tmp = 0x0; /* Prevent warning about unused */ \ 28 tmp = 0x0; /* Prevent warning about unused */ \
29 __asm__ __volatile__ ( \ 29 __asm__ __volatile__ ( \
30 ".byte 0x94,0x60,0xa0, " #pvrid "\n\t" \ 30 "mfs %0, rpvr" #pvrid ";" \
31 : "=r" (tmp) : : "memory"); \ 31 : "=r" (tmp) : : "memory"); \
32 val = tmp; \ 32 val = tmp; \
33} 33}
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c
index 7de84923ba07..c3616a080ebf 100644
--- a/arch/microblaze/kernel/early_printk.c
+++ b/arch/microblaze/kernel/early_printk.c
@@ -24,7 +24,8 @@
24static u32 early_console_initialized; 24static u32 early_console_initialized;
25static u32 base_addr; 25static u32 base_addr;
26 26
27static void early_printk_putc(char c) 27#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
28static void early_printk_uartlite_putc(char c)
28{ 29{
29 /* 30 /*
30 * Limit how many times we'll spin waiting for TX FIFO status. 31 * Limit how many times we'll spin waiting for TX FIFO status.
@@ -45,25 +46,70 @@ static void early_printk_putc(char c)
45 out_be32(base_addr + 4, c & 0xff); 46 out_be32(base_addr + 4, c & 0xff);
46} 47}
47 48
48static void early_printk_write(struct console *unused, 49static void early_printk_uartlite_write(struct console *unused,
49 const char *s, unsigned n) 50 const char *s, unsigned n)
50{ 51{
51 while (*s && n-- > 0) { 52 while (*s && n-- > 0) {
52 early_printk_putc(*s); 53 early_printk_uartlite_putc(*s);
53 if (*s == '\n') 54 if (*s == '\n')
54 early_printk_putc('\r'); 55 early_printk_uartlite_putc('\r');
55 s++; 56 s++;
56 } 57 }
57} 58}
58 59
59static struct console early_serial_console = { 60static struct console early_serial_uartlite_console = {
60 .name = "earlyser", 61 .name = "earlyser",
61 .write = early_printk_write, 62 .write = early_printk_uartlite_write,
62 .flags = CON_PRINTBUFFER, 63 .flags = CON_PRINTBUFFER,
63 .index = -1, 64 .index = -1,
64}; 65};
66#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
65 67
66static struct console *early_console = &early_serial_console; 68#ifdef CONFIG_SERIAL_8250_CONSOLE
69static void early_printk_uart16550_putc(char c)
70{
71 /*
72 * Limit how many times we'll spin waiting for TX FIFO status.
73 * This will prevent lockups if the base address is incorrectly
74 * set, or any other issue on the UARTLITE.
75 * This limit is pretty arbitrary, unless we are at about 10 baud
76 * we'll never timeout on a working UART.
77 */
78
79 #define UART_LSR_TEMT 0x40 /* Transmitter empty */
80 #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
81 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
82
83 unsigned retries = 10000;
84
85 while (--retries &&
86 !((in_be32(base_addr + 0x14) & BOTH_EMPTY) == BOTH_EMPTY))
87 ;
88
89 if (retries)
90 out_be32(base_addr, c & 0xff);
91}
92
93static void early_printk_uart16550_write(struct console *unused,
94 const char *s, unsigned n)
95{
96 while (*s && n-- > 0) {
97 early_printk_uart16550_putc(*s);
98 if (*s == '\n')
99 early_printk_uart16550_putc('\r');
100 s++;
101 }
102}
103
104static struct console early_serial_uart16550_console = {
105 .name = "earlyser",
106 .write = early_printk_uart16550_write,
107 .flags = CON_PRINTBUFFER,
108 .index = -1,
109};
110#endif /* CONFIG_SERIAL_8250_CONSOLE */
111
112static struct console *early_console;
67 113
68void early_printk(const char *fmt, ...) 114void early_printk(const char *fmt, ...)
69{ 115{
@@ -84,20 +130,43 @@ int __init setup_early_printk(char *opt)
84 if (early_console_initialized) 130 if (early_console_initialized)
85 return 1; 131 return 1;
86 132
133#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
87 base_addr = early_uartlite_console(); 134 base_addr = early_uartlite_console();
88 if (base_addr) { 135 if (base_addr) {
89 early_console_initialized = 1; 136 early_console_initialized = 1;
90#ifdef CONFIG_MMU 137#ifdef CONFIG_MMU
91 early_console_reg_tlb_alloc(base_addr); 138 early_console_reg_tlb_alloc(base_addr);
92#endif 139#endif
140 early_console = &early_serial_uartlite_console;
93 early_printk("early_printk_console is enabled at 0x%08x\n", 141 early_printk("early_printk_console is enabled at 0x%08x\n",
94 base_addr); 142 base_addr);
95 143
96 /* register_console(early_console); */ 144 /* register_console(early_console); */
97 145
98 return 0; 146 return 0;
99 } else 147 }
100 return 1; 148#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
149
150#ifdef CONFIG_SERIAL_8250_CONSOLE
151 base_addr = early_uart16550_console();
152 base_addr &= ~3; /* clear register offset */
153 if (base_addr) {
154 early_console_initialized = 1;
155#ifdef CONFIG_MMU
156 early_console_reg_tlb_alloc(base_addr);
157#endif
158 early_console = &early_serial_uart16550_console;
159
160 early_printk("early_printk_console is enabled at 0x%08x\n",
161 base_addr);
162
163 /* register_console(early_console); */
164
165 return 0;
166 }
167#endif /* CONFIG_SERIAL_8250_CONSOLE */
168
169 return 1;
101} 170}
102 171
103void __init disable_early_printk(void) 172void __init disable_early_printk(void)
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 304882e56459..819238b8a429 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -186,6 +186,8 @@
186 swi r13, r1, PTO+PT_R13; /* Save SDA2 */ \ 186 swi r13, r1, PTO+PT_R13; /* Save SDA2 */ \
187 swi r14, r1, PTO+PT_PC; /* PC, before IRQ/trap */ \ 187 swi r14, r1, PTO+PT_PC; /* PC, before IRQ/trap */ \
188 swi r15, r1, PTO+PT_R15; /* Save LP */ \ 188 swi r15, r1, PTO+PT_R15; /* Save LP */ \
189 swi r16, r1, PTO+PT_R16; \
190 swi r17, r1, PTO+PT_R17; \
189 swi r18, r1, PTO+PT_R18; /* Save asm scratch reg */ \ 191 swi r18, r1, PTO+PT_R18; /* Save asm scratch reg */ \
190 swi r19, r1, PTO+PT_R19; \ 192 swi r19, r1, PTO+PT_R19; \
191 swi r20, r1, PTO+PT_R20; \ 193 swi r20, r1, PTO+PT_R20; \
@@ -220,6 +222,8 @@
220 lwi r13, r1, PTO+PT_R13; /* restore SDA2 */ \ 222 lwi r13, r1, PTO+PT_R13; /* restore SDA2 */ \
221 lwi r14, r1, PTO+PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\ 223 lwi r14, r1, PTO+PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\
222 lwi r15, r1, PTO+PT_R15; /* restore LP */ \ 224 lwi r15, r1, PTO+PT_R15; /* restore LP */ \
225 lwi r16, r1, PTO+PT_R16; \
226 lwi r17, r1, PTO+PT_R17; \
223 lwi r18, r1, PTO+PT_R18; /* restore asm scratch reg */ \ 227 lwi r18, r1, PTO+PT_R18; /* restore asm scratch reg */ \
224 lwi r19, r1, PTO+PT_R19; \ 228 lwi r19, r1, PTO+PT_R19; \
225 lwi r20, r1, PTO+PT_R20; \ 229 lwi r20, r1, PTO+PT_R20; \
@@ -295,6 +299,8 @@ C_ENTRY(_user_exception):
295 /* addik r1, r1, -STATE_SAVE_SIZE; */ 299 /* addik r1, r1, -STATE_SAVE_SIZE; */
296 addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; 300 addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE;
297 SAVE_REGS 301 SAVE_REGS
302 swi r0, r1, PTO + PT_R3
303 swi r0, r1, PTO + PT_R4
298 304
299 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 305 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
300 swi r11, r1, PTO+PT_R1; /* Store user SP. */ 306 swi r11, r1, PTO+PT_R1; /* Store user SP. */
@@ -458,14 +464,8 @@ C_ENTRY(sys_execve):
458 addik r8, r1, PTO; /* add user context as 4th arg */ 464 addik r8, r1, PTO; /* add user context as 4th arg */
459 465
460C_ENTRY(sys_rt_sigreturn_wrapper): 466C_ENTRY(sys_rt_sigreturn_wrapper):
461 swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ 467 brid sys_rt_sigreturn /* Do real work */
462 swi r4, r1, PTO+PT_R4;
463 brlid r15, sys_rt_sigreturn /* Do real work */
464 addik r5, r1, PTO; /* add user context as 1st arg */ 468 addik r5, r1, PTO; /* add user context as 1st arg */
465 lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
466 lwi r4, r1, PTO+PT_R4;
467 bri ret_from_trap /* fall through will not work here due to align */
468 nop;
469 469
470/* 470/*
471 * HW EXCEPTION rutine start 471 * HW EXCEPTION rutine start
@@ -765,9 +765,7 @@ C_ENTRY(_debug_exception):
765 /* save all regs to pt_reg structure */ 765 /* save all regs to pt_reg structure */
766 swi r0, r1, PTO+PT_R0; /* R0 must be saved too */ 766 swi r0, r1, PTO+PT_R0; /* R0 must be saved too */
767 swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */ 767 swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */
768 swi r16, r1, PTO+PT_R16
769 swi r16, r1, PTO+PT_PC; /* PC and r16 are the same */ 768 swi r16, r1, PTO+PT_PC; /* PC and r16 are the same */
770 swi r17, r1, PTO+PT_R17
771 /* save special purpose registers to pt_regs */ 769 /* save special purpose registers to pt_regs */
772 mfs r11, rear; 770 mfs r11, rear;
773 swi r11, r1, PTO+PT_EAR; 771 swi r11, r1, PTO+PT_EAR;
@@ -801,8 +799,6 @@ C_ENTRY(_debug_exception):
801 799
802 addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ 800 addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */
803 SAVE_REGS; 801 SAVE_REGS;
804 swi r17, r1, PTO+PT_R17;
805 swi r16, r1, PTO+PT_R16;
806 swi r16, r1, PTO+PT_PC; /* Save LP */ 802 swi r16, r1, PTO+PT_PC; /* Save LP */
807 swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */ 803 swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */
808 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 804 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
@@ -848,8 +844,6 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
848 tophys(r1,r1); 844 tophys(r1,r1);
849 /* MS: Restore all regs */ 845 /* MS: Restore all regs */
850 RESTORE_REGS 846 RESTORE_REGS
851 lwi r17, r1, PTO+PT_R17;
852 lwi r16, r1, PTO+PT_R16;
853 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */ 847 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */
854 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */ 848 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
855DBTRAP_return_user: /* MS: Make global symbol for debugging */ 849DBTRAP_return_user: /* MS: Make global symbol for debugging */
@@ -863,7 +857,6 @@ DBTRAP_return_user: /* MS: Make global symbol for debugging */
863 RESTORE_REGS 857 RESTORE_REGS
864 lwi r14, r1, PTO+PT_R14; 858 lwi r14, r1, PTO+PT_R14;
865 lwi r16, r1, PTO+PT_PC; 859 lwi r16, r1, PTO+PT_PC;
866 lwi r17, r1, PTO+PT_R17;
867 addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */ 860 addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */
868 tovirt(r1,r1); 861 tovirt(r1,r1);
869DBTRAP_return_kernel: /* MS: Make global symbol for debugging */ 862DBTRAP_return_kernel: /* MS: Make global symbol for debugging */
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
index b98ee8d0c1cd..478f2943ede7 100644
--- a/arch/microblaze/kernel/exceptions.c
+++ b/arch/microblaze/kernel/exceptions.c
@@ -72,7 +72,6 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
72 int fsr, int addr) 72 int fsr, int addr)
73{ 73{
74#ifdef CONFIG_MMU 74#ifdef CONFIG_MMU
75 int code;
76 addr = regs->pc; 75 addr = regs->pc;
77#endif 76#endif
78 77
@@ -86,8 +85,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
86 switch (type & 0x1F) { 85 switch (type & 0x1F) {
87 case MICROBLAZE_ILL_OPCODE_EXCEPTION: 86 case MICROBLAZE_ILL_OPCODE_EXCEPTION:
88 if (user_mode(regs)) { 87 if (user_mode(regs)) {
89 pr_debug(KERN_WARNING "Illegal opcode exception " \ 88 pr_debug("Illegal opcode exception in user mode\n");
90 "in user mode.\n");
91 _exception(SIGILL, regs, ILL_ILLOPC, addr); 89 _exception(SIGILL, regs, ILL_ILLOPC, addr);
92 return; 90 return;
93 } 91 }
@@ -97,8 +95,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
97 break; 95 break;
98 case MICROBLAZE_IBUS_EXCEPTION: 96 case MICROBLAZE_IBUS_EXCEPTION:
99 if (user_mode(regs)) { 97 if (user_mode(regs)) {
100 pr_debug(KERN_WARNING "Instruction bus error " \ 98 pr_debug("Instruction bus error exception in user mode\n");
101 "exception in user mode.\n");
102 _exception(SIGBUS, regs, BUS_ADRERR, addr); 99 _exception(SIGBUS, regs, BUS_ADRERR, addr);
103 return; 100 return;
104 } 101 }
@@ -108,8 +105,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
108 break; 105 break;
109 case MICROBLAZE_DBUS_EXCEPTION: 106 case MICROBLAZE_DBUS_EXCEPTION:
110 if (user_mode(regs)) { 107 if (user_mode(regs)) {
111 pr_debug(KERN_WARNING "Data bus error exception " \ 108 pr_debug("Data bus error exception in user mode\n");
112 "in user mode.\n");
113 _exception(SIGBUS, regs, BUS_ADRERR, addr); 109 _exception(SIGBUS, regs, BUS_ADRERR, addr);
114 return; 110 return;
115 } 111 }
@@ -119,8 +115,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
119 break; 115 break;
120 case MICROBLAZE_DIV_ZERO_EXCEPTION: 116 case MICROBLAZE_DIV_ZERO_EXCEPTION:
121 if (user_mode(regs)) { 117 if (user_mode(regs)) {
122 pr_debug(KERN_WARNING "Divide by zero exception " \ 118 pr_debug("Divide by zero exception in user mode\n");
123 "in user mode\n");
124 _exception(SIGILL, regs, FPE_INTDIV, addr); 119 _exception(SIGILL, regs, FPE_INTDIV, addr);
125 return; 120 return;
126 } 121 }
@@ -129,7 +124,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
129 die("Divide by zero exception", regs, SIGBUS); 124 die("Divide by zero exception", regs, SIGBUS);
130 break; 125 break;
131 case MICROBLAZE_FPU_EXCEPTION: 126 case MICROBLAZE_FPU_EXCEPTION:
132 pr_debug(KERN_WARNING "FPU exception\n"); 127 pr_debug("FPU exception\n");
133 /* IEEE FP exception */ 128 /* IEEE FP exception */
134 /* I removed fsr variable and use code var for storing fsr */ 129 /* I removed fsr variable and use code var for storing fsr */
135 if (fsr & FSR_IO) 130 if (fsr & FSR_IO)
@@ -147,14 +142,8 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
147 142
148#ifdef CONFIG_MMU 143#ifdef CONFIG_MMU
149 case MICROBLAZE_PRIVILEGED_EXCEPTION: 144 case MICROBLAZE_PRIVILEGED_EXCEPTION:
150 pr_debug(KERN_WARNING "Privileged exception\n"); 145 pr_debug("Privileged exception\n");
151 /* "brk r0,r0" - used as debug breakpoint - old toolchain */ 146 _exception(SIGILL, regs, ILL_PRVOPC, addr);
152 if (get_user(code, (unsigned long *)regs->pc) == 0
153 && code == 0x980c0000) {
154 _exception(SIGTRAP, regs, TRAP_BRKPT, addr);
155 } else {
156 _exception(SIGILL, regs, ILL_PRVOPC, addr);
157 }
158 break; 147 break;
159#endif 148#endif
160 default: 149 default:
diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c
index 522751737cfa..154756f3c694 100644
--- a/arch/microblaze/kernel/heartbeat.c
+++ b/arch/microblaze/kernel/heartbeat.c
@@ -47,11 +47,10 @@ void setup_heartbeat(void)
47 struct device_node *gpio = NULL; 47 struct device_node *gpio = NULL;
48 int *prop; 48 int *prop;
49 int j; 49 int j;
50 char *gpio_list[] = { 50 const char * const gpio_list[] = {
51 "xlnx,xps-gpio-1.00.a", 51 "xlnx,xps-gpio-1.00.a",
52 "xlnx,opb-gpio-1.00.a", 52 NULL
53 NULL 53 };
54 };
55 54
56 for (j = 0; gpio_list[j] != NULL; j++) { 55 for (j = 0; gpio_list[j] != NULL; j++) {
57 gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]); 56 gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]);
@@ -60,7 +59,7 @@ void setup_heartbeat(void)
60 } 59 }
61 60
62 if (gpio) { 61 if (gpio) {
63 base_addr = *(int *) of_get_property(gpio, "reg", NULL); 62 base_addr = be32_to_cpup(of_get_property(gpio, "reg", NULL));
64 base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE); 63 base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
65 printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr); 64 printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
66 65
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index 03172c1da770..d61ea33aff7c 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -126,11 +126,8 @@ void __init init_IRQ(void)
126 0 126 0
127 }; 127 };
128#endif 128#endif
129 static char *intc_list[] = { 129 const char * const intc_list[] = {
130 "xlnx,xps-intc-1.00.a", 130 "xlnx,xps-intc-1.00.a",
131 "xlnx,opb-intc-1.00.c",
132 "xlnx,opb-intc-1.00.b",
133 "xlnx,opb-intc-1.00.a",
134 NULL 131 NULL
135 }; 132 };
136 133
@@ -141,12 +138,15 @@ void __init init_IRQ(void)
141 } 138 }
142 BUG_ON(!intc); 139 BUG_ON(!intc);
143 140
144 intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL); 141 intc_baseaddr = be32_to_cpup(of_get_property(intc,
142 "reg", NULL));
145 intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE); 143 intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
146 nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL); 144 nr_irq = be32_to_cpup(of_get_property(intc,
145 "xlnx,num-intr-inputs", NULL));
147 146
148 intr_type = 147 intr_type =
149 *(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL); 148 be32_to_cpup(of_get_property(intc,
149 "xlnx,kind-of-intr", NULL));
150 if (intr_type >= (1 << (nr_irq + 1))) 150 if (intr_type >= (1 << (nr_irq + 1)))
151 printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n"); 151 printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");
152 152
diff --git a/arch/microblaze/kernel/kgdb.c b/arch/microblaze/kernel/kgdb.c
index bfc006b7f2d8..09a5e8286137 100644
--- a/arch/microblaze/kernel/kgdb.c
+++ b/arch/microblaze/kernel/kgdb.c
@@ -80,7 +80,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
80void microblaze_kgdb_break(struct pt_regs *regs) 80void microblaze_kgdb_break(struct pt_regs *regs)
81{ 81{
82 if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0) 82 if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0)
83 return 0; 83 return;
84 84
85 /* Jump over the first arch_kgdb_breakpoint which is barrier to 85 /* Jump over the first arch_kgdb_breakpoint which is barrier to
86 * get kgdb work. The same solution is used for powerpc */ 86 * get kgdb work. The same solution is used for powerpc */
@@ -114,7 +114,6 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
114{ 114{
115 char *ptr; 115 char *ptr;
116 unsigned long address; 116 unsigned long address;
117 int cpu = smp_processor_id();
118 117
119 switch (remcom_in_buffer[0]) { 118 switch (remcom_in_buffer[0]) {
120 case 'c': 119 case 'c':
@@ -143,5 +142,9 @@ void kgdb_arch_exit(void)
143 * Global data 142 * Global data
144 */ 143 */
145struct kgdb_arch arch_kgdb_ops = { 144struct kgdb_arch arch_kgdb_ops = {
145#ifdef __MICROBLAZEEL__
146 .gdb_bpt_instr = {0x18, 0x00, 0x0c, 0xba}, /* brki r16, 0x18 */
147#else
146 .gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */ 148 .gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */
149#endif
147}; 150};
diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c
index ff85f7718035..5cb034174005 100644
--- a/arch/microblaze/kernel/microblaze_ksyms.c
+++ b/arch/microblaze/kernel/microblaze_ksyms.c
@@ -15,37 +15,13 @@
15#include <linux/syscalls.h> 15#include <linux/syscalls.h>
16 16
17#include <asm/checksum.h> 17#include <asm/checksum.h>
18#include <asm/cacheflush.h>
18#include <linux/io.h> 19#include <linux/io.h>
19#include <asm/page.h> 20#include <asm/page.h>
20#include <asm/system.h> 21#include <asm/system.h>
21#include <linux/ftrace.h> 22#include <linux/ftrace.h>
22#include <linux/uaccess.h> 23#include <linux/uaccess.h>
23 24
24/*
25 * libgcc functions - functions that are used internally by the
26 * compiler... (prototypes are not correct though, but that
27 * doesn't really matter since they're not versioned).
28 */
29extern void __ashldi3(void);
30EXPORT_SYMBOL(__ashldi3);
31extern void __ashrdi3(void);
32EXPORT_SYMBOL(__ashrdi3);
33extern void __divsi3(void);
34EXPORT_SYMBOL(__divsi3);
35extern void __lshrdi3(void);
36EXPORT_SYMBOL(__lshrdi3);
37extern void __modsi3(void);
38EXPORT_SYMBOL(__modsi3);
39extern void __mulsi3(void);
40EXPORT_SYMBOL(__mulsi3);
41extern void __muldi3(void);
42EXPORT_SYMBOL(__muldi3);
43extern void __ucmpdi2(void);
44EXPORT_SYMBOL(__ucmpdi2);
45extern void __udivsi3(void);
46EXPORT_SYMBOL(__udivsi3);
47extern void __umodsi3(void);
48EXPORT_SYMBOL(__umodsi3);
49extern char *_ebss; 25extern char *_ebss;
50EXPORT_SYMBOL_GPL(_ebss); 26EXPORT_SYMBOL_GPL(_ebss);
51#ifdef CONFIG_FUNCTION_TRACER 27#ifdef CONFIG_FUNCTION_TRACER
@@ -63,3 +39,9 @@ EXPORT_SYMBOL(__strncpy_user);
63EXPORT_SYMBOL(memcpy); 39EXPORT_SYMBOL(memcpy);
64EXPORT_SYMBOL(memmove); 40EXPORT_SYMBOL(memmove);
65#endif 41#endif
42
43#ifdef CONFIG_MMU
44EXPORT_SYMBOL(empty_zero_page);
45#endif
46
47EXPORT_SYMBOL(mbc);
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index bacbd3d41ec7..a105301e2b7f 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -72,11 +72,12 @@ static int __init early_init_dt_scan_serial(unsigned long node,
72/* find compatible node with uartlite */ 72/* find compatible node with uartlite */
73 p = of_get_flat_dt_prop(node, "compatible", &l); 73 p = of_get_flat_dt_prop(node, "compatible", &l);
74 if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) && 74 if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
75 (strncmp(p, "xlnx,opb-uartlite", 17) != 0)) 75 (strncmp(p, "xlnx,opb-uartlite", 17) != 0) &&
76 (strncmp(p, "xlnx,axi-uartlite", 17) != 0))
76 return 0; 77 return 0;
77 78
78 addr = of_get_flat_dt_prop(node, "reg", &l); 79 addr = of_get_flat_dt_prop(node, "reg", &l);
79 return *addr; /* return address */ 80 return be32_to_cpup(addr); /* return address */
80} 81}
81 82
82/* this function is looking for early uartlite console - Microblaze specific */ 83/* this function is looking for early uartlite console - Microblaze specific */
@@ -84,6 +85,40 @@ int __init early_uartlite_console(void)
84{ 85{
85 return of_scan_flat_dt(early_init_dt_scan_serial, NULL); 86 return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
86} 87}
88
89/* MS this is Microblaze specifig function */
90static int __init early_init_dt_scan_serial_full(unsigned long node,
91 const char *uname, int depth, void *data)
92{
93 unsigned long l;
94 char *p;
95 unsigned int addr;
96
97 pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
98
99/* find all serial nodes */
100 if (strncmp(uname, "serial", 6) != 0)
101 return 0;
102
103 early_init_dt_check_for_initrd(node);
104
105/* find compatible node with uartlite */
106 p = of_get_flat_dt_prop(node, "compatible", &l);
107
108 if ((strncmp(p, "xlnx,xps-uart16550", 18) != 0) &&
109 (strncmp(p, "xlnx,axi-uart16550", 18) != 0))
110 return 0;
111
112 addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l);
113 addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l);
114 return be32_to_cpu(addr); /* return address */
115}
116
117/* this function is looking for early uartlite console - Microblaze specific */
118int __init early_uart16550_console(void)
119{
120 return of_scan_flat_dt(early_init_dt_scan_serial_full, NULL);
121}
87#endif 122#endif
88 123
89void __init early_init_devtree(void *params) 124void __init early_init_devtree(void *params)
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index f5f768842354..bb1558e4b283 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -92,12 +92,6 @@ inline unsigned get_romfs_len(unsigned *addr)
92} 92}
93#endif /* CONFIG_MTD_UCLINUX_EBSS */ 93#endif /* CONFIG_MTD_UCLINUX_EBSS */
94 94
95#if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE)
96#define eprintk early_printk
97#else
98#define eprintk printk
99#endif
100
101void __init machine_early_init(const char *cmdline, unsigned int ram, 95void __init machine_early_init(const char *cmdline, unsigned int ram,
102 unsigned int fdt, unsigned int msr) 96 unsigned int fdt, unsigned int msr)
103{ 97{
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index 03376dc814c9..e88a930fd1e3 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -372,3 +372,6 @@ ENTRY(sys_call_table)
372 .long sys_rt_tgsigqueueinfo /* 365 */ 372 .long sys_rt_tgsigqueueinfo /* 365 */
373 .long sys_perf_event_open 373 .long sys_perf_event_open
374 .long sys_recvmmsg 374 .long sys_recvmmsg
375 .long sys_fanotify_init
376 .long sys_fanotify_mark
377 .long sys_prlimit64 /* 370 */
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index b1380ae93ae1..a5aa33db1df3 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -38,6 +38,9 @@ static unsigned int timer_baseaddr;
38#define TIMER_BASE timer_baseaddr 38#define TIMER_BASE timer_baseaddr
39#endif 39#endif
40 40
41unsigned int freq_div_hz;
42unsigned int timer_clock_freq;
43
41#define TCSR0 (0x00) 44#define TCSR0 (0x00)
42#define TLR0 (0x04) 45#define TLR0 (0x04)
43#define TCR0 (0x08) 46#define TCR0 (0x08)
@@ -115,7 +118,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode,
115 switch (mode) { 118 switch (mode) {
116 case CLOCK_EVT_MODE_PERIODIC: 119 case CLOCK_EVT_MODE_PERIODIC:
117 printk(KERN_INFO "%s: periodic\n", __func__); 120 printk(KERN_INFO "%s: periodic\n", __func__);
118 microblaze_timer0_start_periodic(cpuinfo.freq_div_hz); 121 microblaze_timer0_start_periodic(freq_div_hz);
119 break; 122 break;
120 case CLOCK_EVT_MODE_ONESHOT: 123 case CLOCK_EVT_MODE_ONESHOT:
121 printk(KERN_INFO "%s: oneshot\n", __func__); 124 printk(KERN_INFO "%s: oneshot\n", __func__);
@@ -168,7 +171,7 @@ static struct irqaction timer_irqaction = {
168static __init void microblaze_clockevent_init(void) 171static __init void microblaze_clockevent_init(void)
169{ 172{
170 clockevent_microblaze_timer.mult = 173 clockevent_microblaze_timer.mult =
171 div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, 174 div_sc(timer_clock_freq, NSEC_PER_SEC,
172 clockevent_microblaze_timer.shift); 175 clockevent_microblaze_timer.shift);
173 clockevent_microblaze_timer.max_delta_ns = 176 clockevent_microblaze_timer.max_delta_ns =
174 clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer); 177 clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
@@ -201,7 +204,7 @@ static struct cyclecounter microblaze_cc = {
201 204
202int __init init_microblaze_timecounter(void) 205int __init init_microblaze_timecounter(void)
203{ 206{
204 microblaze_cc.mult = div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, 207 microblaze_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
205 microblaze_cc.shift); 208 microblaze_cc.shift);
206 209
207 timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock()); 210 timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock());
@@ -221,7 +224,7 @@ static struct clocksource clocksource_microblaze = {
221static int __init microblaze_clocksource_init(void) 224static int __init microblaze_clocksource_init(void)
222{ 225{
223 clocksource_microblaze.mult = 226 clocksource_microblaze.mult =
224 clocksource_hz2mult(cpuinfo.cpu_clock_freq, 227 clocksource_hz2mult(timer_clock_freq,
225 clocksource_microblaze.shift); 228 clocksource_microblaze.shift);
226 if (clocksource_register(&clocksource_microblaze)) 229 if (clocksource_register(&clocksource_microblaze))
227 panic("failed to register clocksource"); 230 panic("failed to register clocksource");
@@ -247,6 +250,7 @@ void __init time_init(void)
247 u32 irq, i = 0; 250 u32 irq, i = 0;
248 u32 timer_num = 1; 251 u32 timer_num = 1;
249 struct device_node *timer = NULL; 252 struct device_node *timer = NULL;
253 const void *prop;
250#ifdef CONFIG_SELFMOD_TIMER 254#ifdef CONFIG_SELFMOD_TIMER
251 unsigned int timer_baseaddr = 0; 255 unsigned int timer_baseaddr = 0;
252 int arr_func[] = { 256 int arr_func[] = {
@@ -258,12 +262,10 @@ void __init time_init(void)
258 0 262 0
259 }; 263 };
260#endif 264#endif
261 char *timer_list[] = { 265 const char * const timer_list[] = {
262 "xlnx,xps-timer-1.00.a", 266 "xlnx,xps-timer-1.00.a",
263 "xlnx,opb-timer-1.00.b", 267 NULL
264 "xlnx,opb-timer-1.00.a", 268 };
265 NULL
266 };
267 269
268 for (i = 0; timer_list[i] != NULL; i++) { 270 for (i = 0; timer_list[i] != NULL; i++) {
269 timer = of_find_compatible_node(NULL, NULL, timer_list[i]); 271 timer = of_find_compatible_node(NULL, NULL, timer_list[i]);
@@ -272,13 +274,13 @@ void __init time_init(void)
272 } 274 }
273 BUG_ON(!timer); 275 BUG_ON(!timer);
274 276
275 timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL); 277 timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL));
276 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); 278 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
277 irq = *(int *) of_get_property(timer, "interrupts", NULL); 279 irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL));
278 timer_num = 280 timer_num = be32_to_cpup(of_get_property(timer,
279 *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL); 281 "xlnx,one-timer-only", NULL));
280 if (timer_num) { 282 if (timer_num) {
281 printk(KERN_EMERG "Please enable two timers in HW\n"); 283 eprintk(KERN_EMERG "Please enable two timers in HW\n");
282 BUG(); 284 BUG();
283 } 285 }
284 286
@@ -288,7 +290,14 @@ void __init time_init(void)
288 printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", 290 printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
289 timer_list[i], timer_baseaddr, irq); 291 timer_list[i], timer_baseaddr, irq);
290 292
291 cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ; 293 /* If there is clock-frequency property than use it */
294 prop = of_get_property(timer, "clock-frequency", NULL);
295 if (prop)
296 timer_clock_freq = be32_to_cpup(prop);
297 else
298 timer_clock_freq = cpuinfo.cpu_clock_freq;
299
300 freq_div_hz = timer_clock_freq / HZ;
292 301
293 setup_irq(irq, &timer_irqaction); 302 setup_irq(irq, &timer_irqaction);
294#ifdef CONFIG_HEART_BEAT 303#ifdef CONFIG_HEART_BEAT
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
index a09f2962fbec..96a88c31fe48 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -8,7 +8,6 @@
8 * for more details. 8 * for more details.
9 */ 9 */
10 10
11OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
12OUTPUT_ARCH(microblaze) 11OUTPUT_ARCH(microblaze)
13ENTRY(microblaze_start) 12ENTRY(microblaze_start)
14 13
@@ -16,7 +15,11 @@ ENTRY(microblaze_start)
16#include <asm-generic/vmlinux.lds.h> 15#include <asm-generic/vmlinux.lds.h>
17#include <asm/thread_info.h> 16#include <asm/thread_info.h>
18 17
18#ifdef __MICROBLAZEEL__
19jiffies = jiffies_64;
20#else
19jiffies = jiffies_64 + 4; 21jiffies = jiffies_64 + 4;
22#endif
20 23
21SECTIONS { 24SECTIONS {
22 . = CONFIG_KERNEL_START; 25 . = CONFIG_KERNEL_START;