aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-24 12:01:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-24 12:01:44 -0400
commita6b49cb210f878709bdc0bddc16a853f18790d02 (patch)
tree6147078ef0ce584cb6a8dae7468f060ef5838d12 /arch/microblaze/kernel
parent2c9871de0ae89a0e2c365ea6e277135fe031d8b4 (diff)
parentbfc8125858d777bd5bdba03a091c07cc2e0e17c0 (diff)
Merge branch 'for-linus' of git://git.monstr.eu/linux-2.6-microblaze
* 'for-linus' of git://git.monstr.eu/linux-2.6-microblaze: (24 commits) microblaze: Disable heartbeat/enable emaclite in defconfigs microblaze: Support simpleImage.dts make target microblaze: Fix _start symbol to physical address microblaze: Use LOAD_OFFSET macro to get correct LMA for all sections microblaze: Create the LOAD_OFFSET macro used to compute VMA vs LMA offsets microblaze: Copy ppc asm-compat.h for clean handling of constants in asm and C microblaze: Actually show KiB rather than pages in "Freeing initrd memory:" microblaze: Support ptrace syscall tracing. microblaze: Updated CPU version and FPGA family codes in PVR microblaze: Generate correct signal and siginfo for integer div-by-zero microblaze: Don't be noisy when userspace causes hardware exceptions microblaze: Remove ipc.h file which points to non-existing asm-generic file microblaze: Clear sticky FSR register after generating exception signals microblaze: Ensure CPU usermode is set on new userspace processes microblaze: Use correct kbuild variable KBUILD_CFLAGS microblaze: Save and restore msr in hw exception microblaze: Add architectural support for USB EHCI host controllers microblaze: Implement include/asm/syscall.h. microblaze: Improve checking mechanism for MSR instruction microblaze: Add checking mechanism for MSR instruction ...
Diffstat (limited to 'arch/microblaze/kernel')
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo.c3
-rw-r--r--arch/microblaze/kernel/entry.S72
-rw-r--r--arch/microblaze/kernel/exceptions.c33
-rw-r--r--arch/microblaze/kernel/head.S14
-rw-r--r--arch/microblaze/kernel/hw_exception_handler.S10
-rw-r--r--arch/microblaze/kernel/process.c1
-rw-r--r--arch/microblaze/kernel/ptrace.c62
-rw-r--r--arch/microblaze/kernel/setup.c12
-rw-r--r--arch/microblaze/kernel/vmlinux.lds.S72
9 files changed, 205 insertions, 74 deletions
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
index c411c6757deb..3539babc1c18 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -28,6 +28,7 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
28 {"7.10.d", 0x0b}, 28 {"7.10.d", 0x0b},
29 {"7.20.a", 0x0c}, 29 {"7.20.a", 0x0c},
30 {"7.20.b", 0x0d}, 30 {"7.20.b", 0x0d},
31 {"7.20.c", 0x0e},
31 /* FIXME There is no keycode defined in MBV for these versions */ 32 /* FIXME There is no keycode defined in MBV for these versions */
32 {"2.10.a", 0x10}, 33 {"2.10.a", 0x10},
33 {"3.00.a", 0x20}, 34 {"3.00.a", 0x20},
@@ -49,6 +50,8 @@ const struct family_string_key family_string_lookup[] = {
49 {"spartan3a", 0xa}, 50 {"spartan3a", 0xa},
50 {"spartan3an", 0xb}, 51 {"spartan3an", 0xb},
51 {"spartan3adsp", 0xc}, 52 {"spartan3adsp", 0xc},
53 {"spartan6", 0xd},
54 {"virtex6", 0xe},
52 /* FIXME There is no key code defined for spartan2 */ 55 /* FIXME There is no key code defined for spartan2 */
53 {"spartan2", 0xf0}, 56 {"spartan2", 0xf0},
54 {NULL, 0}, 57 {NULL, 0},
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index c7353e79f4a2..acc1f05d1e2c 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -308,38 +308,69 @@ C_ENTRY(_user_exception):
308 swi r12, r1, PTO+PT_R0; 308 swi r12, r1, PTO+PT_R0;
309 tovirt(r1,r1) 309 tovirt(r1,r1)
310 310
311 la r15, r0, ret_from_trap-8
312/* where the trap should return need -8 to adjust for rtsd r15, 8*/ 311/* where the trap should return need -8 to adjust for rtsd r15, 8*/
313/* Jump to the appropriate function for the system call number in r12 312/* Jump to the appropriate function for the system call number in r12
314 * (r12 is not preserved), or return an error if r12 is not valid. The LP 313 * (r12 is not preserved), or return an error if r12 is not valid. The LP
315 * register should point to the location where 314 * register should point to the location where
316 * the called function should return. [note that MAKE_SYS_CALL uses label 1] */ 315 * the called function should return. [note that MAKE_SYS_CALL uses label 1] */
317 /* See if the system call number is valid. */ 316
317 # Step into virtual mode.
318 set_vms;
319 addik r11, r0, 3f
320 rtid r11, 0
321 nop
3223:
323 add r11, r0, CURRENT_TASK /* Get current task ptr into r11 */
324 lwi r11, r11, TS_THREAD_INFO /* get thread info */
325 lwi r11, r11, TI_FLAGS /* get flags in thread info */
326 andi r11, r11, _TIF_WORK_SYSCALL_MASK
327 beqi r11, 4f
328
329 addik r3, r0, -ENOSYS
330 swi r3, r1, PTO + PT_R3
331 brlid r15, do_syscall_trace_enter
332 addik r5, r1, PTO + PT_R0
333
334 # do_syscall_trace_enter returns the new syscall nr.
335 addk r12, r0, r3
336 lwi r5, r1, PTO+PT_R5;
337 lwi r6, r1, PTO+PT_R6;
338 lwi r7, r1, PTO+PT_R7;
339 lwi r8, r1, PTO+PT_R8;
340 lwi r9, r1, PTO+PT_R9;
341 lwi r10, r1, PTO+PT_R10;
3424:
343/* Jump to the appropriate function for the system call number in r12
344 * (r12 is not preserved), or return an error if r12 is not valid.
345 * The LP register should point to the location where the called function
346 * should return. [note that MAKE_SYS_CALL uses label 1] */
347 /* See if the system call number is valid */
318 addi r11, r12, -__NR_syscalls; 348 addi r11, r12, -__NR_syscalls;
319 bgei r11,1f; 349 bgei r11,5f;
320 /* Figure out which function to use for this system call. */ 350 /* Figure out which function to use for this system call. */
321 /* Note Microblaze barrel shift is optional, so don't rely on it */ 351 /* Note Microblaze barrel shift is optional, so don't rely on it */
322 add r12, r12, r12; /* convert num -> ptr */ 352 add r12, r12, r12; /* convert num -> ptr */
323 add r12, r12, r12; 353 add r12, r12, r12;
324 354
325 /* Trac syscalls and stored them to r0_ram */ 355 /* Trac syscalls and stored them to r0_ram */
326 lwi r3, r12, 0x400 + TOPHYS(r0_ram) 356 lwi r3, r12, 0x400 + r0_ram
327 addi r3, r3, 1 357 addi r3, r3, 1
328 swi r3, r12, 0x400 + TOPHYS(r0_ram) 358 swi r3, r12, 0x400 + r0_ram
359
360 # Find and jump into the syscall handler.
361 lwi r12, r12, sys_call_table
362 /* where the trap should return need -8 to adjust for rtsd r15, 8 */
363 la r15, r0, ret_from_trap-8
364 bra r12
329 365
330 lwi r12, r12, TOPHYS(sys_call_table); /* Function ptr */
331 /* Make the system call. to r12*/
332 set_vms;
333 rtid r12, 0;
334 nop;
335 /* The syscall number is invalid, return an error. */ 366 /* The syscall number is invalid, return an error. */
3361: VM_ON; /* RETURN() expects virtual mode*/ 3675:
337 addi r3, r0, -ENOSYS; 368 addi r3, r0, -ENOSYS;
338 rtsd r15,8; /* looks like a normal subroutine return */ 369 rtsd r15,8; /* looks like a normal subroutine return */
339 or r0, r0, r0 370 or r0, r0, r0
340 371
341 372
342/* Entry point used to return from a syscall/trap. */ 373/* Entry point used to return from a syscall/trap */
343/* We re-enable BIP bit before state restore */ 374/* We re-enable BIP bit before state restore */
344C_ENTRY(ret_from_trap): 375C_ENTRY(ret_from_trap):
345 set_bip; /* Ints masked for state restore*/ 376 set_bip; /* Ints masked for state restore*/
@@ -349,6 +380,23 @@ C_ENTRY(ret_from_trap):
349 380
350 /* We're returning to user mode, so check for various conditions that 381 /* We're returning to user mode, so check for various conditions that
351 * trigger rescheduling. */ 382 * trigger rescheduling. */
383 # FIXME: Restructure all these flag checks.
384 add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
385 lwi r11, r11, TS_THREAD_INFO; /* get thread info */
386 lwi r11, r11, TI_FLAGS; /* get flags in thread info */
387 andi r11, r11, _TIF_WORK_SYSCALL_MASK
388 beqi r11, 1f
389
390 swi r3, r1, PTO + PT_R3
391 swi r4, r1, PTO + PT_R4
392 brlid r15, do_syscall_trace_leave
393 addik r5, r1, PTO + PT_R0
394 lwi r3, r1, PTO + PT_R3
395 lwi r4, r1, PTO + PT_R4
3961:
397
398 /* We're returning to user mode, so check for various conditions that
399 * trigger rescheduling. */
352 /* Get current task ptr into r11 */ 400 /* Get current task ptr into r11 */
353 add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ 401 add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
354 lwi r11, r11, TS_THREAD_INFO; /* get thread info */ 402 lwi r11, r11, TS_THREAD_INFO; /* get thread info */
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
index 0cb64a31e89a..d9f70f83097f 100644
--- a/arch/microblaze/kernel/exceptions.c
+++ b/arch/microblaze/kernel/exceptions.c
@@ -72,7 +72,8 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
72#endif 72#endif
73 73
74#if 0 74#if 0
75 printk(KERN_WARNING "Exception %02x in %s mode, FSR=%08x PC=%08x ESR=%08x\n", 75 printk(KERN_WARNING "Exception %02x in %s mode, FSR=%08x PC=%08x " \
76 "ESR=%08x\n",
76 type, user_mode(regs) ? "user" : "kernel", fsr, 77 type, user_mode(regs) ? "user" : "kernel", fsr,
77 (unsigned int) regs->pc, (unsigned int) regs->esr); 78 (unsigned int) regs->pc, (unsigned int) regs->esr);
78#endif 79#endif
@@ -80,42 +81,50 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
80 switch (type & 0x1F) { 81 switch (type & 0x1F) {
81 case MICROBLAZE_ILL_OPCODE_EXCEPTION: 82 case MICROBLAZE_ILL_OPCODE_EXCEPTION:
82 if (user_mode(regs)) { 83 if (user_mode(regs)) {
83 printk(KERN_WARNING "Illegal opcode exception in user mode.\n"); 84 pr_debug(KERN_WARNING "Illegal opcode exception " \
85 "in user mode.\n");
84 _exception(SIGILL, regs, ILL_ILLOPC, addr); 86 _exception(SIGILL, regs, ILL_ILLOPC, addr);
85 return; 87 return;
86 } 88 }
87 printk(KERN_WARNING "Illegal opcode exception in kernel mode.\n"); 89 printk(KERN_WARNING "Illegal opcode exception " \
90 "in kernel mode.\n");
88 die("opcode exception", regs, SIGBUS); 91 die("opcode exception", regs, SIGBUS);
89 break; 92 break;
90 case MICROBLAZE_IBUS_EXCEPTION: 93 case MICROBLAZE_IBUS_EXCEPTION:
91 if (user_mode(regs)) { 94 if (user_mode(regs)) {
92 printk(KERN_WARNING "Instruction bus error exception in user mode.\n"); 95 pr_debug(KERN_WARNING "Instruction bus error " \
96 "exception in user mode.\n");
93 _exception(SIGBUS, regs, BUS_ADRERR, addr); 97 _exception(SIGBUS, regs, BUS_ADRERR, addr);
94 return; 98 return;
95 } 99 }
96 printk(KERN_WARNING "Instruction bus error exception in kernel mode.\n"); 100 printk(KERN_WARNING "Instruction bus error exception " \
101 "in kernel mode.\n");
97 die("bus exception", regs, SIGBUS); 102 die("bus exception", regs, SIGBUS);
98 break; 103 break;
99 case MICROBLAZE_DBUS_EXCEPTION: 104 case MICROBLAZE_DBUS_EXCEPTION:
100 if (user_mode(regs)) { 105 if (user_mode(regs)) {
101 printk(KERN_WARNING "Data bus error exception in user mode.\n"); 106 pr_debug(KERN_WARNING "Data bus error exception " \
107 "in user mode.\n");
102 _exception(SIGBUS, regs, BUS_ADRERR, addr); 108 _exception(SIGBUS, regs, BUS_ADRERR, addr);
103 return; 109 return;
104 } 110 }
105 printk(KERN_WARNING "Data bus error exception in kernel mode.\n"); 111 printk(KERN_WARNING "Data bus error exception " \
112 "in kernel mode.\n");
106 die("bus exception", regs, SIGBUS); 113 die("bus exception", regs, SIGBUS);
107 break; 114 break;
108 case MICROBLAZE_DIV_ZERO_EXCEPTION: 115 case MICROBLAZE_DIV_ZERO_EXCEPTION:
109 if (user_mode(regs)) { 116 if (user_mode(regs)) {
110 printk(KERN_WARNING "Divide by zero exception in user mode\n"); 117 pr_debug(KERN_WARNING "Divide by zero exception " \
111 _exception(SIGILL, regs, ILL_ILLOPC, addr); 118 "in user mode\n");
119 _exception(SIGILL, regs, FPE_INTDIV, addr);
112 return; 120 return;
113 } 121 }
114 printk(KERN_WARNING "Divide by zero exception in kernel mode.\n"); 122 printk(KERN_WARNING "Divide by zero exception " \
123 "in kernel mode.\n");
115 die("Divide by exception", regs, SIGBUS); 124 die("Divide by exception", regs, SIGBUS);
116 break; 125 break;
117 case MICROBLAZE_FPU_EXCEPTION: 126 case MICROBLAZE_FPU_EXCEPTION:
118 printk(KERN_WARNING "FPU exception\n"); 127 pr_debug(KERN_WARNING "FPU exception\n");
119 /* IEEE FP exception */ 128 /* IEEE FP exception */
120 /* I removed fsr variable and use code var for storing fsr */ 129 /* I removed fsr variable and use code var for storing fsr */
121 if (fsr & FSR_IO) 130 if (fsr & FSR_IO)
@@ -133,7 +142,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
133 142
134#ifdef CONFIG_MMU 143#ifdef CONFIG_MMU
135 case MICROBLAZE_PRIVILEGED_EXCEPTION: 144 case MICROBLAZE_PRIVILEGED_EXCEPTION:
136 printk(KERN_WARNING "Privileged exception\n"); 145 pr_debug(KERN_WARNING "Privileged exception\n");
137 /* "brk r0,r0" - used as debug breakpoint */ 146 /* "brk r0,r0" - used as debug breakpoint */
138 if (get_user(code, (unsigned long *)regs->pc) == 0 147 if (get_user(code, (unsigned long *)regs->pc) == 0
139 && code == 0x980c0000) { 148 && code == 0x980c0000) {
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S
index e41c6ce2a7be..697ce3007f30 100644
--- a/arch/microblaze/kernel/head.S
+++ b/arch/microblaze/kernel/head.S
@@ -54,6 +54,16 @@ ENTRY(_start)
54 mfs r1, rmsr 54 mfs r1, rmsr
55 andi r1, r1, ~2 55 andi r1, r1, ~2
56 mts rmsr, r1 56 mts rmsr, r1
57/*
58 * Here is checking mechanism which check if Microblaze has msr instructions
59 * We load msr and compare it with previous r1 value - if is the same,
60 * msr instructions works if not - cpu don't have them.
61 */
62 /* r8=0 - I have msr instr, 1 - I don't have them */
63 rsubi r0, r0, 1 /* set the carry bit */
64 msrclr r0, 0x4 /* try to clear it */
65 /* read the carry bit, r8 will be '0' if msrclr exists */
66 addik r8, r0, 0
57 67
58/* r7 may point to an FDT, or there may be one linked in. 68/* r7 may point to an FDT, or there may be one linked in.
59 if it's in r7, we've got to save it away ASAP. 69 if it's in r7, we've got to save it away ASAP.
@@ -209,8 +219,8 @@ start_here:
209 * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for 219 * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for
210 * the function. 220 * the function.
211 */ 221 */
212 la r8, r0, machine_early_init 222 la r9, r0, machine_early_init
213 brald r15, r8 223 brald r15, r9
214 nop 224 nop
215 225
216#ifndef CONFIG_MMU 226#ifndef CONFIG_MMU
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
index 3288c9737671..6b0288ebccd6 100644
--- a/arch/microblaze/kernel/hw_exception_handler.S
+++ b/arch/microblaze/kernel/hw_exception_handler.S
@@ -84,9 +84,10 @@
84#define NUM_TO_REG(num) r ## num 84#define NUM_TO_REG(num) r ## num
85 85
86#ifdef CONFIG_MMU 86#ifdef CONFIG_MMU
87/* FIXME you can't change first load of MSR because there is
88 * hardcoded jump bri 4 */
89 #define RESTORE_STATE \ 87 #define RESTORE_STATE \
88 lwi r5, r1, 0; \
89 mts rmsr, r5; \
90 nop; \
90 lwi r3, r1, PT_R3; \ 91 lwi r3, r1, PT_R3; \
91 lwi r4, r1, PT_R4; \ 92 lwi r4, r1, PT_R4; \
92 lwi r5, r1, PT_R5; \ 93 lwi r5, r1, PT_R5; \
@@ -309,6 +310,9 @@ _hw_exception_handler:
309 lwi r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)) /* get saved current */ 310 lwi r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)) /* get saved current */
310#endif 311#endif
311 312
313 mfs r5, rmsr;
314 nop
315 swi r5, r1, 0;
312 mfs r3, resr 316 mfs r3, resr
313 nop 317 nop
314 mfs r4, rear; 318 mfs r4, rear;
@@ -380,6 +384,8 @@ handle_other_ex: /* Handle Other exceptions here */
380 addk r8, r17, r0; /* Load exception address */ 384 addk r8, r17, r0; /* Load exception address */
381 bralid r15, full_exception; /* Branch to the handler */ 385 bralid r15, full_exception; /* Branch to the handler */
382 nop; 386 nop;
387 mts r0, rfsr; /* Clear sticky fsr */
388 nop
383 389
384 /* 390 /*
385 * Trigger execution of the signal handler by enabling 391 * Trigger execution of the signal handler by enabling
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 00b12c6d5326..4201c743cc9f 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -235,6 +235,7 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp)
235 regs->pc = pc; 235 regs->pc = pc;
236 regs->r1 = usp; 236 regs->r1 = usp;
237 regs->pt_mode = 0; 237 regs->pt_mode = 0;
238 regs->msr |= MSR_UMS;
238} 239}
239 240
240#ifdef CONFIG_MMU 241#ifdef CONFIG_MMU
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c
index 53ff39af6a5c..4b3ac32754de 100644
--- a/arch/microblaze/kernel/ptrace.c
+++ b/arch/microblaze/kernel/ptrace.c
@@ -29,6 +29,10 @@
29#include <linux/sched.h> 29#include <linux/sched.h>
30#include <linux/ptrace.h> 30#include <linux/ptrace.h>
31#include <linux/signal.h> 31#include <linux/signal.h>
32#include <linux/elf.h>
33#include <linux/audit.h>
34#include <linux/seccomp.h>
35#include <linux/tracehook.h>
32 36
33#include <linux/errno.h> 37#include <linux/errno.h>
34#include <asm/processor.h> 38#include <asm/processor.h>
@@ -174,6 +178,64 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
174 return rval; 178 return rval;
175} 179}
176 180
181asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
182{
183 long ret = 0;
184
185 secure_computing(regs->r12);
186
187 if (test_thread_flag(TIF_SYSCALL_TRACE) &&
188 tracehook_report_syscall_entry(regs))
189 /*
190 * Tracing decided this syscall should not happen.
191 * We'll return a bogus call number to get an ENOSYS
192 * error, but leave the original number in regs->regs[0].
193 */
194 ret = -1L;
195
196 if (unlikely(current->audit_context))
197 audit_syscall_entry(EM_XILINX_MICROBLAZE, regs->r12,
198 regs->r5, regs->r6,
199 regs->r7, regs->r8);
200
201 return ret ?: regs->r12;
202}
203
204asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
205{
206 int step;
207
208 if (unlikely(current->audit_context))
209 audit_syscall_exit(AUDITSC_RESULT(regs->r3), regs->r3);
210
211 step = test_thread_flag(TIF_SINGLESTEP);
212 if (step || test_thread_flag(TIF_SYSCALL_TRACE))
213 tracehook_report_syscall_exit(regs, step);
214}
215
216#if 0
217static asmlinkage void syscall_trace(void)
218{
219 if (!test_thread_flag(TIF_SYSCALL_TRACE))
220 return;
221 if (!(current->ptrace & PT_PTRACED))
222 return;
223 /* The 0x80 provides a way for the tracing parent to distinguish
224 between a syscall stop and SIGTRAP delivery */
225 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
226 ? 0x80 : 0));
227 /*
228 * this isn't the same as continuing with a signal, but it will do
229 * for normal use. strace only continues with a signal if the
230 * stopping signal is not SIGTRAP. -brl
231 */
232 if (current->exit_code) {
233 send_sig(current->exit_code, current, 1);
234 current->exit_code = 0;
235 }
236}
237#endif
238
177void ptrace_disable(struct task_struct *child) 239void ptrace_disable(struct task_struct *child)
178{ 240{
179 /* nothing to do */ 241 /* nothing to do */
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index 2a97bf513b64..8c1e0f4dcf18 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -94,7 +94,7 @@ inline unsigned get_romfs_len(unsigned *addr)
94#endif /* CONFIG_MTD_UCLINUX_EBSS */ 94#endif /* CONFIG_MTD_UCLINUX_EBSS */
95 95
96void __init machine_early_init(const char *cmdline, unsigned int ram, 96void __init machine_early_init(const char *cmdline, unsigned int ram,
97 unsigned int fdt) 97 unsigned int fdt, unsigned int msr)
98{ 98{
99 unsigned long *src, *dst = (unsigned long *)0x0; 99 unsigned long *src, *dst = (unsigned long *)0x0;
100 100
@@ -157,6 +157,16 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
157 early_printk("New klimit: 0x%08x\n", (unsigned)klimit); 157 early_printk("New klimit: 0x%08x\n", (unsigned)klimit);
158#endif 158#endif
159 159
160#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
161 if (msr)
162 early_printk("!!!Your kernel has setup MSR instruction but "
163 "CPU don't have it %d\n", msr);
164#else
165 if (!msr)
166 early_printk("!!!Your kernel not setup MSR instruction but "
167 "CPU have it %d\n", msr);
168#endif
169
160 for (src = __ivt_start; src < __ivt_end; src++, dst++) 170 for (src = __ivt_start; src < __ivt_end; src++, dst++)
161 *dst = *src; 171 *dst = *src;
162 172
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
index ec5fa91a48d8..e704188d7855 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -12,13 +12,16 @@ OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
12OUTPUT_ARCH(microblaze) 12OUTPUT_ARCH(microblaze)
13ENTRY(_start) 13ENTRY(_start)
14 14
15#include <asm/page.h>
15#include <asm-generic/vmlinux.lds.h> 16#include <asm-generic/vmlinux.lds.h>
17#include <asm/thread_info.h>
16 18
17jiffies = jiffies_64 + 4; 19jiffies = jiffies_64 + 4;
18 20
19SECTIONS { 21SECTIONS {
20 . = CONFIG_KERNEL_START; 22 . = CONFIG_KERNEL_START;
21 .text : { 23 _start = CONFIG_KERNEL_BASE_ADDR;
24 .text : AT(ADDR(.text) - LOAD_OFFSET) {
22 _text = . ; 25 _text = . ;
23 _stext = . ; 26 _stext = . ;
24 *(.text .text.*) 27 *(.text .text.*)
@@ -33,24 +36,22 @@ SECTIONS {
33 } 36 }
34 37
35 . = ALIGN (4) ; 38 . = ALIGN (4) ;
36 _fdt_start = . ; /* place for fdt blob */ 39 __fdt_blob : AT(ADDR(__fdt_blob) - LOAD_OFFSET) {
37 . = . + 0x4000; 40 _fdt_start = . ; /* place for fdt blob */
38 _fdt_end = . ; 41 *(__fdt_blob) ; /* Any link-placed DTB */
42 . = _fdt_start + 0x4000; /* Pad up to 16kbyte */
43 _fdt_end = . ;
44 }
39 45
40 . = ALIGN(16); 46 . = ALIGN(16);
41 RODATA 47 RODATA
42 . = ALIGN(16); 48 EXCEPTION_TABLE(16)
43 __ex_table : {
44 __start___ex_table = .;
45 *(__ex_table)
46 __stop___ex_table = .;
47 }
48 49
49 /* 50 /*
50 * sdata2 section can go anywhere, but must be word aligned 51 * sdata2 section can go anywhere, but must be word aligned
51 * and SDA2_BASE must point to the middle of it 52 * and SDA2_BASE must point to the middle of it
52 */ 53 */
53 .sdata2 : { 54 .sdata2 : AT(ADDR(.sdata2) - LOAD_OFFSET) {
54 _ssrw = .; 55 _ssrw = .;
55 . = ALIGN(4096); /* page aligned when MMU used - origin 0x8 */ 56 . = ALIGN(4096); /* page aligned when MMU used - origin 0x8 */
56 *(.sdata2) 57 *(.sdata2)
@@ -61,12 +62,7 @@ SECTIONS {
61 } 62 }
62 63
63 _sdata = . ; 64 _sdata = . ;
64 .data ALIGN (4096) : { /* page aligned when MMU used - origin 0x4 */ 65 RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
65 DATA_DATA
66 CONSTRUCTORS
67 }
68 . = ALIGN(32);
69 .data.cacheline_aligned : { *(.data.cacheline_aligned) }
70 _edata = . ; 66 _edata = . ;
71 67
72 /* Reserve some low RAM for r0 based memory references */ 68 /* Reserve some low RAM for r0 based memory references */
@@ -74,18 +70,14 @@ SECTIONS {
74 r0_ram = . ; 70 r0_ram = . ;
75 . = . + 4096; /* a page should be enough */ 71 . = . + 4096; /* a page should be enough */
76 72
77 /* The initial task */
78 . = ALIGN(8192);
79 .data.init_task : { *(.data.init_task) }
80
81 /* Under the microblaze ABI, .sdata and .sbss must be contiguous */ 73 /* Under the microblaze ABI, .sdata and .sbss must be contiguous */
82 . = ALIGN(8); 74 . = ALIGN(8);
83 .sdata : { 75 .sdata : AT(ADDR(.sdata) - LOAD_OFFSET) {
84 _ssro = .; 76 _ssro = .;
85 *(.sdata) 77 *(.sdata)
86 } 78 }
87 79
88 .sbss : { 80 .sbss : AT(ADDR(.sbss) - LOAD_OFFSET) {
89 _ssbss = .; 81 _ssbss = .;
90 *(.sbss) 82 *(.sbss)
91 _esbss = .; 83 _esbss = .;
@@ -96,47 +88,36 @@ SECTIONS {
96 88
97 __init_begin = .; 89 __init_begin = .;
98 90
99 . = ALIGN(4096); 91 INIT_TEXT_SECTION(PAGE_SIZE)
100 .init.text : {
101 _sinittext = . ;
102 INIT_TEXT
103 _einittext = .;
104 }
105 92
106 .init.data : { 93 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
107 INIT_DATA 94 INIT_DATA
108 } 95 }
109 96
110 . = ALIGN(4); 97 . = ALIGN(4);
111 .init.ivt : { 98 .init.ivt : AT(ADDR(.init.ivt) - LOAD_OFFSET) {
112 __ivt_start = .; 99 __ivt_start = .;
113 *(.init.ivt) 100 *(.init.ivt)
114 __ivt_end = .; 101 __ivt_end = .;
115 } 102 }
116 103
117 .init.setup : { 104 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
118 __setup_start = .; 105 INIT_SETUP(0)
119 *(.init.setup)
120 __setup_end = .;
121 } 106 }
122 107
123 .initcall.init : { 108 .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET ) {
124 __initcall_start = .; 109 INIT_CALLS
125 INITCALLS
126 __initcall_end = .;
127 } 110 }
128 111
129 .con_initcall.init : { 112 .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
130 __con_initcall_start = .; 113 CON_INITCALL
131 *(.con_initcall.init)
132 __con_initcall_end = .;
133 } 114 }
134 115
135 SECURITY_INIT 116 SECURITY_INIT
136 117
137 __init_end_before_initramfs = .; 118 __init_end_before_initramfs = .;
138 119
139 .init.ramfs ALIGN(4096) : { 120 .init.ramfs ALIGN(4096) : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
140 __initramfs_start = .; 121 __initramfs_start = .;
141 *(.init.ramfs) 122 *(.init.ramfs)
142 __initramfs_end = .; 123 __initramfs_end = .;
@@ -152,7 +133,8 @@ SECTIONS {
152 } 133 }
153 __init_end = .; 134 __init_end = .;
154 135
155 .bss ALIGN (4096) : { /* page aligned when MMU used */ 136 .bss ALIGN (4096) : AT(ADDR(.bss) - LOAD_OFFSET) {
137 /* page aligned when MMU used */
156 __bss_start = . ; 138 __bss_start = . ;
157 *(.bss*) 139 *(.bss*)
158 *(COMMON) 140 *(COMMON)