diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-06-11 09:26:54 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-06-26 04:34:48 -0400 |
commit | 502a0c775c7f0a01065e0d078e06c0440b86a11a (patch) | |
tree | df280c7ba4533c0d6fddcd3985f4da3cd6a68dd8 /arch/arc/include | |
parent | 352c1d95e3220d0ea33cefac5c1f0deb2c4470c6 (diff) |
ARC: pt_regs update #5: Use real ECR for pt_regs->event vs. synth values
pt_regs->event was set with artificial values to identify the low level
system event (syscall trap / breakpoint trap / exceptions / interrupts)
With r8 saving out of the way, the full word can be used to save real
ECR (Exception Cause Register) which helps idenify the event naturally,
including additional info such as cause code, param.
Only for Interrupts, where ECR is not applicable, do we resort to
synthetic non ECR values.
SAVE_ALL_TRAP/EXCEPTIONS can now be merged as they both use ECR with
different runtime values.
The ptrace helpers now use the sub-fields of ECR to distinguish the
events (e.g. vector 0x25 is trap, param 0 is syscall...)
The following benefits will follow:
(1) This centralizes the location of where ECR is saved and will allow
the cleanup of task->thread.cause_code ECR placeholder which is set
in non-uniform way. Then ARC VM code can safely rely on it being
there for purpose of finer grained VM_EXEC dcache flush (based on
exec fault: I-TLB Miss)
(2) Further, ECR being passed around from low level handlers as arg can
be eliminated as it is part of standard reg-file in pt_regs
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc/include')
-rw-r--r-- | arch/arc/include/asm/arcregs.h | 4 | ||||
-rw-r--r-- | arch/arc/include/asm/entry.h | 31 | ||||
-rw-r--r-- | arch/arc/include/asm/ptrace.h | 36 |
3 files changed, 33 insertions, 38 deletions
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index 122e9af46824..355cb470c2a4 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h | |||
@@ -60,6 +60,7 @@ | |||
60 | #define ECR_V_ITLB_MISS 0x21 | 60 | #define ECR_V_ITLB_MISS 0x21 |
61 | #define ECR_V_DTLB_MISS 0x22 | 61 | #define ECR_V_DTLB_MISS 0x22 |
62 | #define ECR_V_PROTV 0x23 | 62 | #define ECR_V_PROTV 0x23 |
63 | #define ECR_V_TRAP 0x25 | ||
63 | 64 | ||
64 | /* Protection Violation Exception Cause Code Values */ | 65 | /* Protection Violation Exception Cause Code Values */ |
65 | #define ECR_C_PROTV_INST_FETCH 0x00 | 66 | #define ECR_C_PROTV_INST_FETCH 0x00 |
@@ -77,6 +78,9 @@ | |||
77 | #define ECR_C_BIT_DTLB_LD_MISS 8 | 78 | #define ECR_C_BIT_DTLB_LD_MISS 8 |
78 | #define ECR_C_BIT_DTLB_ST_MISS 9 | 79 | #define ECR_C_BIT_DTLB_ST_MISS 9 |
79 | 80 | ||
81 | /* Dummy ECR values for Interrupts */ | ||
82 | #define event_IRQ1 0x0031abcd | ||
83 | #define event_IRQ2 0x0032abcd | ||
80 | 84 | ||
81 | /* Auxiliary registers */ | 85 | /* Auxiliary registers */ |
82 | #define AUX_IDENTITY 4 | 86 | #define AUX_IDENTITY 4 |
diff --git a/arch/arc/include/asm/entry.h b/arch/arc/include/asm/entry.h index de01bc842a9a..8943c028d4bb 100644 --- a/arch/arc/include/asm/entry.h +++ b/arch/arc/include/asm/entry.h | |||
@@ -309,7 +309,7 @@ | |||
309 | #endif | 309 | #endif |
310 | 310 | ||
311 | /* Save Pre Intr/Exception User SP on kernel stack */ | 311 | /* Save Pre Intr/Exception User SP on kernel stack */ |
312 | st.a sp, [r9, -16] ; Make room for orig_r0, orig_r8, user_r25 | 312 | st.a sp, [r9, -16] ; Make room for orig_r0, ECR, user_r25 |
313 | 313 | ||
314 | /* CAUTION: | 314 | /* CAUTION: |
315 | * SP should be set at the very end when we are done with everything | 315 | * SP should be set at the very end when we are done with everything |
@@ -391,9 +391,10 @@ | |||
391 | * Note that syscalls are implemented via TRAP which is also a exception | 391 | * Note that syscalls are implemented via TRAP which is also a exception |
392 | * from CPU's point of view | 392 | * from CPU's point of view |
393 | *-------------------------------------------------------------*/ | 393 | *-------------------------------------------------------------*/ |
394 | .macro SAVE_ALL_EXCEPTION marker | 394 | .macro SAVE_ALL_SYS |
395 | 395 | ||
396 | st \marker, [sp, 8] /* orig_r8 */ | 396 | lr r9, [ecr] |
397 | st r9, [sp, 8] /* ECR */ | ||
397 | st r0, [sp, 4] /* orig_r0, needed only for sys calls */ | 398 | st r0, [sp, 4] /* orig_r0, needed only for sys calls */ |
398 | 399 | ||
399 | /* Restore r9 used to code the early prologue */ | 400 | /* Restore r9 used to code the early prologue */ |
@@ -412,20 +413,6 @@ | |||
412 | .endm | 413 | .endm |
413 | 414 | ||
414 | /*-------------------------------------------------------------- | 415 | /*-------------------------------------------------------------- |
415 | * Save scratch regs for exceptions | ||
416 | *-------------------------------------------------------------*/ | ||
417 | .macro SAVE_ALL_SYS | ||
418 | SAVE_ALL_EXCEPTION orig_r8_IS_EXCPN | ||
419 | .endm | ||
420 | |||
421 | /*-------------------------------------------------------------- | ||
422 | * Save scratch regs for sys calls | ||
423 | *-------------------------------------------------------------*/ | ||
424 | .macro SAVE_ALL_TRAP | ||
425 | SAVE_ALL_EXCEPTION orig_r8_IS_SCALL | ||
426 | .endm | ||
427 | |||
428 | /*-------------------------------------------------------------- | ||
429 | * Restore all registers used by system call or Exceptions | 416 | * Restore all registers used by system call or Exceptions |
430 | * SP should always be pointing to the next free stack element | 417 | * SP should always be pointing to the next free stack element |
431 | * when entering this macro. | 418 | * when entering this macro. |
@@ -452,7 +439,7 @@ | |||
452 | RESTORE_R12_TO_R0 | 439 | RESTORE_R12_TO_R0 |
453 | 440 | ||
454 | ld sp, [sp] /* restore original sp */ | 441 | ld sp, [sp] /* restore original sp */ |
455 | /* orig_r0, orig_r8, user_r25 skipped automatically */ | 442 | /* orig_r0, ECR, user_r25 skipped automatically */ |
456 | .endm | 443 | .endm |
457 | 444 | ||
458 | 445 | ||
@@ -469,7 +456,7 @@ | |||
469 | #endif | 456 | #endif |
470 | 457 | ||
471 | /* now we are ready to save the remaining context :) */ | 458 | /* now we are ready to save the remaining context :) */ |
472 | st orig_r8_IS_IRQ1, [sp, 8] /* Event Type */ | 459 | st event_IRQ1, [sp, 8] /* Dummy ECR */ |
473 | st 0, [sp, 4] /* orig_r0 , N/A for IRQ */ | 460 | st 0, [sp, 4] /* orig_r0 , N/A for IRQ */ |
474 | 461 | ||
475 | SAVE_R0_TO_R12 | 462 | SAVE_R0_TO_R12 |
@@ -494,7 +481,7 @@ | |||
494 | ld r9, [@int2_saved_reg] | 481 | ld r9, [@int2_saved_reg] |
495 | 482 | ||
496 | /* now we are ready to save the remaining context :) */ | 483 | /* now we are ready to save the remaining context :) */ |
497 | st orig_r8_IS_IRQ2, [sp, 8] /* Event Type */ | 484 | st event_IRQ2, [sp, 8] /* Dummy ECR */ |
498 | st 0, [sp, 4] /* orig_r0 , N/A for IRQ */ | 485 | st 0, [sp, 4] /* orig_r0 , N/A for IRQ */ |
499 | 486 | ||
500 | SAVE_R0_TO_R12 | 487 | SAVE_R0_TO_R12 |
@@ -535,7 +522,7 @@ | |||
535 | RESTORE_R12_TO_R0 | 522 | RESTORE_R12_TO_R0 |
536 | 523 | ||
537 | ld sp, [sp] /* restore original sp */ | 524 | ld sp, [sp] /* restore original sp */ |
538 | /* orig_r0, orig_r8, user_r25 skipped automatically */ | 525 | /* orig_r0, ECR, user_r25 skipped automatically */ |
539 | .endm | 526 | .endm |
540 | 527 | ||
541 | .macro RESTORE_ALL_INT2 | 528 | .macro RESTORE_ALL_INT2 |
@@ -554,7 +541,7 @@ | |||
554 | RESTORE_R12_TO_R0 | 541 | RESTORE_R12_TO_R0 |
555 | 542 | ||
556 | ld sp, [sp] /* restore original sp */ | 543 | ld sp, [sp] /* restore original sp */ |
557 | /* orig_r0, orig_r8, user_r25 skipped automatically */ | 544 | /* orig_r0, ECR, user_r25 skipped automatically */ |
558 | .endm | 545 | .endm |
559 | 546 | ||
560 | 547 | ||
diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index 7b2de6f7025a..c9938e7a7dbd 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h | |||
@@ -44,15 +44,24 @@ struct pt_regs { | |||
44 | long sp; /* user/kernel sp depending on where we came from */ | 44 | long sp; /* user/kernel sp depending on where we came from */ |
45 | long orig_r0; | 45 | long orig_r0; |
46 | 46 | ||
47 | /*to distinguish bet excp, syscall, irq */ | 47 | /* |
48 | * To distinguish bet excp, syscall, irq | ||
49 | * For traps and exceptions, Exception Cause Register. | ||
50 | * ECR: <00> <VV> <CC> <PP> | ||
51 | * Last word used by Linux for extra state mgmt (syscall-restart) | ||
52 | * For interrupts, use artificial ECR values to note current prio-level | ||
53 | */ | ||
48 | union { | 54 | union { |
55 | struct { | ||
49 | #ifdef CONFIG_CPU_BIG_ENDIAN | 56 | #ifdef CONFIG_CPU_BIG_ENDIAN |
50 | /* so that assembly code is same for LE/BE */ | 57 | unsigned long state:8, ecr_vec:8, |
51 | unsigned long orig_r8:16, event:16; | 58 | ecr_cause:8, ecr_param:8; |
52 | #else | 59 | #else |
53 | unsigned long event:16, orig_r8:16; | 60 | unsigned long ecr_param:8, ecr_cause:8, |
61 | ecr_vec:8, state:8; | ||
54 | #endif | 62 | #endif |
55 | long orig_r8_word; | 63 | }; |
64 | unsigned long event; | ||
56 | }; | 65 | }; |
57 | 66 | ||
58 | long user_r25; | 67 | long user_r25; |
@@ -94,11 +103,13 @@ struct callee_regs { | |||
94 | /* return 1 if PC in delay slot */ | 103 | /* return 1 if PC in delay slot */ |
95 | #define delay_mode(regs) ((regs->status32 & STATUS_DE_MASK) == STATUS_DE_MASK) | 104 | #define delay_mode(regs) ((regs->status32 & STATUS_DE_MASK) == STATUS_DE_MASK) |
96 | 105 | ||
97 | #define in_syscall(regs) (regs->event & orig_r8_IS_SCALL) | 106 | #define in_syscall(regs) ((regs->ecr_vec == ECR_V_TRAP) && !regs->ecr_param) |
98 | #define in_brkpt_trap(regs) (regs->event & orig_r8_IS_BRKPT) | 107 | #define in_brkpt_trap(regs) ((regs->ecr_vec == ECR_V_TRAP) && regs->ecr_param) |
99 | 108 | ||
100 | #define syscall_wont_restart(regs) (regs->event |= orig_r8_IS_SCALL_RESTARTED) | 109 | #define STATE_SCALL_RESTARTED 0x01 |
101 | #define syscall_restartable(regs) !(regs->event & orig_r8_IS_SCALL_RESTARTED) | 110 | |
111 | #define syscall_wont_restart(reg) (reg->state |= STATE_SCALL_RESTARTED) | ||
112 | #define syscall_restartable(reg) !(reg->state & STATE_SCALL_RESTARTED) | ||
102 | 113 | ||
103 | #define current_pt_regs() \ | 114 | #define current_pt_regs() \ |
104 | ({ \ | 115 | ({ \ |
@@ -115,11 +126,4 @@ static inline long regs_return_value(struct pt_regs *regs) | |||
115 | 126 | ||
116 | #endif /* !__ASSEMBLY__ */ | 127 | #endif /* !__ASSEMBLY__ */ |
117 | 128 | ||
118 | #define orig_r8_IS_SCALL 0x0001 | ||
119 | #define orig_r8_IS_SCALL_RESTARTED 0x0002 | ||
120 | #define orig_r8_IS_BRKPT 0x0004 | ||
121 | #define orig_r8_IS_EXCPN 0x0008 | ||
122 | #define orig_r8_IS_IRQ1 0x0010 | ||
123 | #define orig_r8_IS_IRQ2 0x0020 | ||
124 | |||
125 | #endif /* __ASM_PTRACE_H */ | 129 | #endif /* __ASM_PTRACE_H */ |