aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common/entry.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/mach-common/entry.S')
-rw-r--r--arch/blackfin/mach-common/entry.S132
1 files changed, 66 insertions, 66 deletions
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index bde6dc4e2614..fae774651374 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -36,6 +36,7 @@
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/linkage.h> 37#include <linux/linkage.h>
38#include <linux/unistd.h> 38#include <linux/unistd.h>
39#include <linux/threads.h>
39#include <asm/blackfin.h> 40#include <asm/blackfin.h>
40#include <asm/errno.h> 41#include <asm/errno.h>
41#include <asm/fixed_code.h> 42#include <asm/fixed_code.h>
@@ -75,11 +76,11 @@ ENTRY(_ex_workaround_261)
75 * handle it. 76 * handle it.
76 */ 77 */
77 P4 = R7; /* Store EXCAUSE */ 78 P4 = R7; /* Store EXCAUSE */
78 p5.l = _last_cplb_fault_retx; 79
79 p5.h = _last_cplb_fault_retx; 80 GET_PDA(p5, r7);
80 r7 = [p5]; 81 r7 = [p5 + PDA_LFRETX];
81 r6 = retx; 82 r6 = retx;
82 [p5] = r6; 83 [p5 + PDA_LFRETX] = r6;
83 cc = r6 == r7; 84 cc = r6 == r7;
84 if !cc jump _bfin_return_from_exception; 85 if !cc jump _bfin_return_from_exception;
85 /* fall through */ 86 /* fall through */
@@ -111,24 +112,21 @@ ENTRY(_ex_dcplb_viol)
111ENTRY(_ex_dcplb_miss) 112ENTRY(_ex_dcplb_miss)
112ENTRY(_ex_icplb_miss) 113ENTRY(_ex_icplb_miss)
113 (R7:6,P5:4) = [sp++]; 114 (R7:6,P5:4) = [sp++];
114 ASTAT = [sp++]; 115 /* We leave the previously pushed ASTAT on the stack. */
115 SAVE_ALL_SYS 116 SAVE_CONTEXT_CPLB
116#ifdef CONFIG_MPU 117
117 /* We must load R1 here, _before_ DEBUG_HWTRACE_SAVE, since that 118 /* We must load R1 here, _before_ DEBUG_HWTRACE_SAVE, since that
118 * will change the stack pointer. */ 119 * will change the stack pointer. */
119 R0 = SEQSTAT; 120 R0 = SEQSTAT;
120 R1 = SP; 121 R1 = SP;
121#endif 122
122 DEBUG_HWTRACE_SAVE(p5, r7) 123 DEBUG_HWTRACE_SAVE(p5, r7)
123#ifdef CONFIG_MPU 124
124 sp += -12; 125 sp += -12;
125 call _cplb_hdr; 126 call _cplb_hdr;
126 sp += 12; 127 sp += 12;
127 CC = R0 == 0; 128 CC = R0 == 0;
128 IF !CC JUMP _handle_bad_cplb; 129 IF !CC JUMP _handle_bad_cplb;
129#else
130 call __cplb_hdr;
131#endif
132 130
133#ifdef CONFIG_DEBUG_DOUBLEFAULT 131#ifdef CONFIG_DEBUG_DOUBLEFAULT
134 /* While we were processing this, did we double fault? */ 132 /* While we were processing this, did we double fault? */
@@ -142,7 +140,8 @@ ENTRY(_ex_icplb_miss)
142#endif 140#endif
143 141
144 DEBUG_HWTRACE_RESTORE(p5, r7) 142 DEBUG_HWTRACE_RESTORE(p5, r7)
145 RESTORE_ALL_SYS 143 RESTORE_CONTEXT_CPLB
144 ASTAT = [SP++];
146 SP = EX_SCRATCH_REG; 145 SP = EX_SCRATCH_REG;
147 rtx; 146 rtx;
148ENDPROC(_ex_icplb_miss) 147ENDPROC(_ex_icplb_miss)
@@ -297,9 +296,8 @@ ENTRY(_handle_bad_cplb)
297 * the stack to get ready so, we can fall through - we 296 * the stack to get ready so, we can fall through - we
298 * need to make a CPLB exception look like a normal exception 297 * need to make a CPLB exception look like a normal exception
299 */ 298 */
300 299 RESTORE_CONTEXT_CPLB
301 RESTORE_ALL_SYS 300 /* ASTAT is still on the stack, where it is needed. */
302 [--sp] = ASTAT;
303 [--sp] = (R7:6,P5:4); 301 [--sp] = (R7:6,P5:4);
304 302
305ENTRY(_ex_replaceable) 303ENTRY(_ex_replaceable)
@@ -324,7 +322,9 @@ ENTRY(_ex_trap_c)
324 [p4] = p5; 322 [p4] = p5;
325 csync; 323 csync;
326 324
325 GET_PDA(p5, r6);
327#ifndef CONFIG_DEBUG_DOUBLEFAULT 326#ifndef CONFIG_DEBUG_DOUBLEFAULT
327
328 /* 328 /*
329 * Save these registers, as they are only valid in exception context 329 * Save these registers, as they are only valid in exception context
330 * (where we are now - as soon as we defer to IRQ5, they can change) 330 * (where we are now - as soon as we defer to IRQ5, they can change)
@@ -335,29 +335,25 @@ ENTRY(_ex_trap_c)
335 p4.l = lo(DCPLB_FAULT_ADDR); 335 p4.l = lo(DCPLB_FAULT_ADDR);
336 p4.h = hi(DCPLB_FAULT_ADDR); 336 p4.h = hi(DCPLB_FAULT_ADDR);
337 r7 = [p4]; 337 r7 = [p4];
338 p5.h = _saved_dcplb_fault_addr; 338 [p5 + PDA_DCPLB] = r7;
339 p5.l = _saved_dcplb_fault_addr;
340 [p5] = r7;
341 339
342 r7 = [p4 + (ICPLB_FAULT_ADDR - DCPLB_FAULT_ADDR)]; 340 p4.l = lo(ICPLB_FAULT_ADDR);
343 p5.h = _saved_icplb_fault_addr; 341 p4.h = hi(ICPLB_FAULT_ADDR);
344 p5.l = _saved_icplb_fault_addr; 342 r6 = [p4];
345 [p5] = r7; 343 [p5 + PDA_ICPLB] = r6;
346 344
347 r6 = retx; 345 r6 = retx;
348 p4.l = _saved_retx; 346 [p5 + PDA_RETX] = r6;
349 p4.h = _saved_retx;
350 [p4] = r6;
351#endif 347#endif
352 r6 = SYSCFG; 348 r6 = SYSCFG;
353 [p4 + 4] = r6; 349 [p5 + PDA_SYSCFG] = r6;
354 BITCLR(r6, 0); 350 BITCLR(r6, 0);
355 SYSCFG = r6; 351 SYSCFG = r6;
356 352
357 /* Disable all interrupts, but make sure level 5 is enabled so 353 /* Disable all interrupts, but make sure level 5 is enabled so
358 * we can switch to that level. Save the old mask. */ 354 * we can switch to that level. Save the old mask. */
359 cli r6; 355 cli r6;
360 [p4 + 8] = r6; 356 [p5 + PDA_EXIMASK] = r6;
361 357
362 p4.l = lo(SAFE_USER_INSTRUCTION); 358 p4.l = lo(SAFE_USER_INSTRUCTION);
363 p4.h = hi(SAFE_USER_INSTRUCTION); 359 p4.h = hi(SAFE_USER_INSTRUCTION);
@@ -371,9 +367,10 @@ ENTRY(_ex_trap_c)
371ENDPROC(_ex_trap_c) 367ENDPROC(_ex_trap_c)
372 368
373/* We just realized we got an exception, while we were processing a different 369/* We just realized we got an exception, while we were processing a different
374 * exception. This is a unrecoverable event, so crash 370 * exception. This is a unrecoverable event, so crash.
371 * Note: this cannot be ENTRY() as we jump here with "if cc jump" ...
375 */ 372 */
376ENTRY(_double_fault) 373_double_fault:
377 /* Turn caches & protection off, to ensure we don't get any more 374 /* Turn caches & protection off, to ensure we don't get any more
378 * double exceptions 375 * double exceptions
379 */ 376 */
@@ -424,17 +421,16 @@ ENDPROC(_double_fault)
424ENTRY(_exception_to_level5) 421ENTRY(_exception_to_level5)
425 SAVE_ALL_SYS 422 SAVE_ALL_SYS
426 423
427 p4.l = _saved_retx; 424 GET_PDA(p4, r7); /* Fetch current PDA */
428 p4.h = _saved_retx; 425 r6 = [p4 + PDA_RETX];
429 r6 = [p4];
430 [sp + PT_PC] = r6; 426 [sp + PT_PC] = r6;
431 427
432 r6 = [p4 + 4]; 428 r6 = [p4 + PDA_SYSCFG];
433 [sp + PT_SYSCFG] = r6; 429 [sp + PT_SYSCFG] = r6;
434 430
435 /* Restore interrupt mask. We haven't pushed RETI, so this 431 /* Restore interrupt mask. We haven't pushed RETI, so this
436 * doesn't enable interrupts until we return from this handler. */ 432 * doesn't enable interrupts until we return from this handler. */
437 r6 = [p4 + 8]; 433 r6 = [p4 + PDA_EXIMASK];
438 sti r6; 434 sti r6;
439 435
440 /* Restore the hardware error vector. */ 436 /* Restore the hardware error vector. */
@@ -478,8 +474,8 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
478 * scratch register (for want of a better option). 474 * scratch register (for want of a better option).
479 */ 475 */
480 EX_SCRATCH_REG = sp; 476 EX_SCRATCH_REG = sp;
481 sp.l = _exception_stack_top; 477 GET_PDA_SAFE(sp);
482 sp.h = _exception_stack_top; 478 sp = [sp + PDA_EXSTACK]
483 /* Try to deal with syscalls quickly. */ 479 /* Try to deal with syscalls quickly. */
484 [--sp] = ASTAT; 480 [--sp] = ASTAT;
485 [--sp] = (R7:6,P5:4); 481 [--sp] = (R7:6,P5:4);
@@ -501,27 +497,22 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
501 * but they are not very interesting, so don't save them 497 * but they are not very interesting, so don't save them
502 */ 498 */
503 499
500 GET_PDA(p5, r7);
504 p4.l = lo(DCPLB_FAULT_ADDR); 501 p4.l = lo(DCPLB_FAULT_ADDR);
505 p4.h = hi(DCPLB_FAULT_ADDR); 502 p4.h = hi(DCPLB_FAULT_ADDR);
506 r7 = [p4]; 503 r7 = [p4];
507 p5.h = _saved_dcplb_fault_addr; 504 [p5 + PDA_DCPLB] = r7;
508 p5.l = _saved_dcplb_fault_addr;
509 [p5] = r7;
510 505
511 r7 = [p4 + (ICPLB_FAULT_ADDR - DCPLB_FAULT_ADDR)]; 506 p4.l = lo(ICPLB_FAULT_ADDR);
512 p5.h = _saved_icplb_fault_addr; 507 p4.h = hi(ICPLB_FAULT_ADDR);
513 p5.l = _saved_icplb_fault_addr; 508 r7 = [p4];
514 [p5] = r7; 509 [p5 + PDA_ICPLB] = r7;
515 510
516 p4.l = _saved_retx;
517 p4.h = _saved_retx;
518 r6 = retx; 511 r6 = retx;
519 [p4] = r6; 512 [p5 + PDA_RETX] = r6;
520 513
521 r7 = SEQSTAT; /* reason code is in bit 5:0 */ 514 r7 = SEQSTAT; /* reason code is in bit 5:0 */
522 p4.l = _saved_seqstat; 515 [p5 + PDA_SEQSTAT] = r7;
523 p4.h = _saved_seqstat;
524 [p4] = r7;
525#else 516#else
526 r7 = SEQSTAT; /* reason code is in bit 5:0 */ 517 r7 = SEQSTAT; /* reason code is in bit 5:0 */
527#endif 518#endif
@@ -546,11 +537,11 @@ ENTRY(_kernel_execve)
546 p0 = sp; 537 p0 = sp;
547 r3 = SIZEOF_PTREGS / 4; 538 r3 = SIZEOF_PTREGS / 4;
548 r4 = 0(x); 539 r4 = 0(x);
5490: 540.Lclear_regs:
550 [p0++] = r4; 541 [p0++] = r4;
551 r3 += -1; 542 r3 += -1;
552 cc = r3 == 0; 543 cc = r3 == 0;
553 if !cc jump 0b (bp); 544 if !cc jump .Lclear_regs (bp);
554 545
555 p0 = sp; 546 p0 = sp;
556 sp += -16; 547 sp += -16;
@@ -558,7 +549,7 @@ ENTRY(_kernel_execve)
558 call _do_execve; 549 call _do_execve;
559 SP += 16; 550 SP += 16;
560 cc = r0 == 0; 551 cc = r0 == 0;
561 if ! cc jump 1f; 552 if ! cc jump .Lexecve_failed;
562 /* Success. Copy our temporary pt_regs to the top of the kernel 553 /* Success. Copy our temporary pt_regs to the top of the kernel
563 * stack and do a normal exception return. 554 * stack and do a normal exception return.
564 */ 555 */
@@ -574,12 +565,12 @@ ENTRY(_kernel_execve)
574 p0 = fp; 565 p0 = fp;
575 r4 = [p0--]; 566 r4 = [p0--];
576 r3 = SIZEOF_PTREGS / 4; 567 r3 = SIZEOF_PTREGS / 4;
5770: 568.Lcopy_regs:
578 r4 = [p0--]; 569 r4 = [p0--];
579 [p1--] = r4; 570 [p1--] = r4;
580 r3 += -1; 571 r3 += -1;
581 cc = r3 == 0; 572 cc = r3 == 0;
582 if ! cc jump 0b (bp); 573 if ! cc jump .Lcopy_regs (bp);
583 574
584 r0 = (KERNEL_STACK_SIZE - SIZEOF_PTREGS) (z); 575 r0 = (KERNEL_STACK_SIZE - SIZEOF_PTREGS) (z);
585 p1 = r0; 576 p1 = r0;
@@ -591,7 +582,7 @@ ENTRY(_kernel_execve)
591 582
592 RESTORE_CONTEXT; 583 RESTORE_CONTEXT;
593 rti; 584 rti;
5941: 585.Lexecve_failed:
595 unlink; 586 unlink;
596 rts; 587 rts;
597ENDPROC(_kernel_execve) 588ENDPROC(_kernel_execve)
@@ -925,9 +916,14 @@ _schedule_and_signal_from_int:
925 p1 = rets; 916 p1 = rets;
926 [sp + PT_RESERVED] = p1; 917 [sp + PT_RESERVED] = p1;
927 918
928 p0.l = _irq_flags; 919#ifdef CONFIG_SMP
929 p0.h = _irq_flags; 920 GET_PDA(p0, r0); /* Fetch current PDA (can't migrate to other CPU here) */
921 r0 = [p0 + PDA_IRQFLAGS];
922#else
923 p0.l = _bfin_irq_flags;
924 p0.h = _bfin_irq_flags;
930 r0 = [p0]; 925 r0 = [p0];
926#endif
931 sti r0; 927 sti r0;
932 928
933 r0 = sp; 929 r0 = sp;
@@ -1539,14 +1535,18 @@ ENTRY(_sys_call_table)
1539 .endr 1535 .endr
1540END(_sys_call_table) 1536END(_sys_call_table)
1541 1537
1542_exception_stack: 1538#ifdef CONFIG_EXCEPTION_L1_SCRATCH
1543 .rept 1024 1539/* .section .l1.bss.scratch */
1544 .long 0; 1540.set _exception_stack_top, L1_SCRATCH_START + L1_SCRATCH_LENGTH
1541#else
1542#ifdef CONFIG_SYSCALL_TAB_L1
1543.section .l1.bss
1544#else
1545.bss
1546#endif
1547ENTRY(_exception_stack)
1548 .rept 1024 * NR_CPUS
1549 .long 0
1545 .endr 1550 .endr
1546_exception_stack_top: 1551_exception_stack_top:
1547
1548#if ANOMALY_05000261
1549/* Used by the assembly entry point to work around an anomaly. */
1550_last_cplb_fault_retx:
1551 .long 0;
1552#endif 1552#endif