diff options
Diffstat (limited to 'arch/microblaze/kernel')
-rw-r--r-- | arch/microblaze/kernel/cpu/cpuinfo.c | 3 | ||||
-rw-r--r-- | arch/microblaze/kernel/entry.S | 72 | ||||
-rw-r--r-- | arch/microblaze/kernel/exceptions.c | 33 | ||||
-rw-r--r-- | arch/microblaze/kernel/head.S | 14 | ||||
-rw-r--r-- | arch/microblaze/kernel/hw_exception_handler.S | 10 | ||||
-rw-r--r-- | arch/microblaze/kernel/init_task.c | 5 | ||||
-rw-r--r-- | arch/microblaze/kernel/process.c | 1 | ||||
-rw-r--r-- | arch/microblaze/kernel/ptrace.c | 62 | ||||
-rw-r--r-- | arch/microblaze/kernel/setup.c | 12 | ||||
-rw-r--r-- | arch/microblaze/kernel/sys_microblaze.c | 1 | ||||
-rw-r--r-- | arch/microblaze/kernel/syscall_table.S | 2 | ||||
-rw-r--r-- | arch/microblaze/kernel/vmlinux.lds.S | 72 |
12 files changed, 208 insertions, 79 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 | ||
322 | 3: | ||
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; | ||
342 | 4: | ||
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. */ |
336 | 1: VM_ON; /* RETURN() expects virtual mode*/ | 367 | 5: |
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 */ |
344 | C_ENTRY(ret_from_trap): | 375 | C_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 | ||
396 | 1: | ||
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/init_task.c b/arch/microblaze/kernel/init_task.c index 67da22579b62..b5d711f94ff8 100644 --- a/arch/microblaze/kernel/init_task.c +++ b/arch/microblaze/kernel/init_task.c | |||
@@ -19,9 +19,8 @@ | |||
19 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 19 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
20 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 20 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
21 | 21 | ||
22 | union thread_union init_thread_union | 22 | union thread_union init_thread_union __init_task_data = |
23 | __attribute__((__section__(".data.init_task"))) = | 23 | { INIT_THREAD_INFO(init_task) }; |
24 | { INIT_THREAD_INFO(init_task) }; | ||
25 | 24 | ||
26 | struct task_struct init_task = INIT_TASK(init_task); | 25 | struct task_struct init_task = INIT_TASK(init_task); |
27 | EXPORT_SYMBOL(init_task); | 26 | EXPORT_SYMBOL(init_task); |
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 | ||
181 | asmlinkage 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 | |||
204 | asmlinkage 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 | ||
217 | static 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 | |||
177 | void ptrace_disable(struct task_struct *child) | 239 | void 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 | ||
96 | void __init machine_early_init(const char *cmdline, unsigned int ram, | 96 | void __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/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c index b96f1682bb24..07cabed4b947 100644 --- a/arch/microblaze/kernel/sys_microblaze.c +++ b/arch/microblaze/kernel/sys_microblaze.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/mman.h> | 23 | #include <linux/mman.h> |
24 | #include <linux/sys.h> | 24 | #include <linux/sys.h> |
25 | #include <linux/ipc.h> | 25 | #include <linux/ipc.h> |
26 | #include <linux/utsname.h> | ||
27 | #include <linux/file.h> | 26 | #include <linux/file.h> |
28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
29 | #include <linux/err.h> | 28 | #include <linux/err.h> |
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index 457216097dfd..ecec19155135 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S | |||
@@ -370,4 +370,4 @@ ENTRY(sys_call_table) | |||
370 | .long sys_ni_syscall | 370 | .long sys_ni_syscall |
371 | .long sys_ni_syscall | 371 | .long sys_ni_syscall |
372 | .long sys_rt_tgsigqueueinfo /* 365 */ | 372 | .long sys_rt_tgsigqueueinfo /* 365 */ |
373 | .long sys_perf_counter_open | 373 | .long sys_perf_event_open |
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") | |||
12 | OUTPUT_ARCH(microblaze) | 12 | OUTPUT_ARCH(microblaze) |
13 | ENTRY(_start) | 13 | ENTRY(_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 | ||
17 | jiffies = jiffies_64 + 4; | 19 | jiffies = jiffies_64 + 4; |
18 | 20 | ||
19 | SECTIONS { | 21 | SECTIONS { |
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) |