aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arc')
-rw-r--r--arch/arc/include/asm/arcregs.h4
-rw-r--r--arch/arc/include/asm/entry.h31
-rw-r--r--arch/arc/include/asm/ptrace.h36
-rw-r--r--arch/arc/kernel/asm-offsets.c2
-rw-r--r--arch/arc/kernel/entry.S21
-rw-r--r--arch/arc/kernel/kgdb.c2
-rw-r--r--arch/arc/kernel/process.c2
-rw-r--r--arch/arc/kernel/troubleshoot.c12
8 files changed, 53 insertions, 57 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 */
diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c
index 75f05b83d77d..6c3aa0edb9b5 100644
--- a/arch/arc/kernel/asm-offsets.c
+++ b/arch/arc/kernel/asm-offsets.c
@@ -46,7 +46,7 @@ int main(void)
46 BLANK(); 46 BLANK();
47 47
48 DEFINE(PT_status32, offsetof(struct pt_regs, status32)); 48 DEFINE(PT_status32, offsetof(struct pt_regs, status32));
49 DEFINE(PT_orig_r8, offsetof(struct pt_regs, orig_r8_word)); 49 DEFINE(PT_event, offsetof(struct pt_regs, event));
50 DEFINE(PT_sp, offsetof(struct pt_regs, sp)); 50 DEFINE(PT_sp, offsetof(struct pt_regs, sp));
51 DEFINE(PT_r0, offsetof(struct pt_regs, r0)); 51 DEFINE(PT_r0, offsetof(struct pt_regs, r0));
52 DEFINE(PT_r1, offsetof(struct pt_regs, r1)); 52 DEFINE(PT_r1, offsetof(struct pt_regs, r1));
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index fd5f9160bbd2..fb0fe3265637 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -142,7 +142,7 @@ VECTOR reserved ; Reserved Exceptions
142.endr 142.endr
143 143
144#include <linux/linkage.h> /* ARC_{EXTRY,EXIT} */ 144#include <linux/linkage.h> /* ARC_{EXTRY,EXIT} */
145#include <asm/entry.h> /* SAVE_ALL_{INT1,INT2,TRAP...} */ 145#include <asm/entry.h> /* SAVE_ALL_{INT1,INT2,SYS...} */
146#include <asm/errno.h> 146#include <asm/errno.h>
147#include <asm/arcregs.h> 147#include <asm/arcregs.h>
148#include <asm/irqflags.h> 148#include <asm/irqflags.h>
@@ -495,8 +495,6 @@ tracesys_exit:
495trap_with_param: 495trap_with_param:
496 496
497 ; stop_pc info by gdb needs this info 497 ; stop_pc info by gdb needs this info
498 stw orig_r8_IS_BRKPT, [sp, PT_orig_r8]
499
500 mov r0, r12 498 mov r0, r12
501 lr r1, [efa] 499 lr r1, [efa]
502 mov r2, sp 500 mov r2, sp
@@ -541,7 +539,7 @@ ARC_ENTRY EV_Trap
541 lr r9, [erstatus] 539 lr r9, [erstatus]
542 540
543 SWITCH_TO_KERNEL_STK 541 SWITCH_TO_KERNEL_STK
544 SAVE_ALL_TRAP 542 SAVE_ALL_SYS
545 543
546 ;------- (4) What caused the Trap -------------- 544 ;------- (4) What caused the Trap --------------
547 lr r12, [ecr] 545 lr r12, [ecr]
@@ -696,28 +694,33 @@ not_exception:
696 694
697#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS 695#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
698 696
697 ; Level 2 interrupt return Path - from hardware standpoint
699 bbit0 r10, STATUS_A2_BIT, not_level2_interrupt 698 bbit0 r10, STATUS_A2_BIT, not_level2_interrupt
700 699
701 ;------------------------------------------------------------------ 700 ;------------------------------------------------------------------
701 ; However the context returning might not have taken L2 intr itself
702 ; e.g. Task'A' user-code -> L2 intr -> schedule -> 'B' user-code ret
703 ; Special considerations needed for the context which took L2 intr
704
705 ld r9, [sp, PT_event] ; Ensure this is L2 intr context
706 brne r9, event_IRQ2, 149f
707
708 ;------------------------------------------------------------------
702 ; if L2 IRQ interrupted a L1 ISR, we'd disbaled preemption earlier 709 ; if L2 IRQ interrupted a L1 ISR, we'd disbaled preemption earlier
703 ; so that sched doesnt move to new task, causing L1 to be delayed 710 ; so that sched doesnt move to new task, causing L1 to be delayed
704 ; undeterministically. Now that we've achieved that, lets reset 711 ; undeterministically. Now that we've achieved that, lets reset
705 ; things to what they were, before returning from L2 context 712 ; things to what they were, before returning from L2 context
706 ;---------------------------------------------------------------- 713 ;----------------------------------------------------------------
707 714
708 ldw r9, [sp, PT_orig_r8] ; get orig_r8 to make sure it is
709 brne r9, orig_r8_IS_IRQ2, 149f ; infact a L2 ISR ret path
710
711 ld r9, [sp, PT_status32] ; get statu32_l2 (saved in pt_regs) 715 ld r9, [sp, PT_status32] ; get statu32_l2 (saved in pt_regs)
712 bbit0 r9, STATUS_A1_BIT, 149f ; L1 not active when L2 IRQ, so normal 716 bbit0 r9, STATUS_A1_BIT, 149f ; L1 not active when L2 IRQ, so normal
713 717
714 ; A1 is set in status32_l2
715 ; decrement thread_info->preempt_count (re-enable preemption) 718 ; decrement thread_info->preempt_count (re-enable preemption)
716 GET_CURR_THR_INFO_FROM_SP r10 719 GET_CURR_THR_INFO_FROM_SP r10
717 ld r9, [r10, THREAD_INFO_PREEMPT_COUNT] 720 ld r9, [r10, THREAD_INFO_PREEMPT_COUNT]
718 721
719 ; paranoid check, given A1 was active when A2 happened, preempt count 722 ; paranoid check, given A1 was active when A2 happened, preempt count
720 ; must not be 0 beccause we would have incremented it. 723 ; must not be 0 because we would have incremented it.
721 ; If this does happen we simply HALT as it means a BUG !!! 724 ; If this does happen we simply HALT as it means a BUG !!!
722 cmp r9, 0 725 cmp r9, 0
723 bnz 2f 726 bnz 2f
diff --git a/arch/arc/kernel/kgdb.c b/arch/arc/kernel/kgdb.c
index 52bdc83c1495..84f1bb8208b4 100644
--- a/arch/arc/kernel/kgdb.c
+++ b/arch/arc/kernel/kgdb.c
@@ -181,7 +181,7 @@ void kgdb_trap(struct pt_regs *regs, int param)
181 * with trap_s 4 (compiled) breakpoints, continuation needs to 181 * with trap_s 4 (compiled) breakpoints, continuation needs to
182 * start after the breakpoint. 182 * start after the breakpoint.
183 */ 183 */
184 if (param == 3) 184 if (regs->ecr_param == 3)
185 instruction_pointer(regs) -= BREAK_INSTR_SIZE; 185 instruction_pointer(regs) -= BREAK_INSTR_SIZE;
186 186
187 kgdb_handle_exception(1, SIGTRAP, 0, regs); 187 kgdb_handle_exception(1, SIGTRAP, 0, regs);
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c
index a3cc6a577039..07a3a968fe49 100644
--- a/arch/arc/kernel/process.c
+++ b/arch/arc/kernel/process.c
@@ -76,7 +76,7 @@ asmlinkage void ret_from_fork(void);
76 * ------------------ 76 * ------------------
77 * | SP | 77 * | SP |
78 * | orig_r0 | 78 * | orig_r0 |
79 * | orig_r8 | 79 * | event/ECR |
80 * | user_r25 | 80 * | user_r25 |
81 * ------------------ <===== END of PAGE 81 * ------------------ <===== END of PAGE
82 */ 82 */
diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c
index 31a5d8905e1a..977464126be9 100644
--- a/arch/arc/kernel/troubleshoot.c
+++ b/arch/arc/kernel/troubleshoot.c
@@ -117,17 +117,16 @@ static void show_faulting_vma(unsigned long address, char *buf)
117 117
118static void show_ecr_verbose(struct pt_regs *regs) 118static void show_ecr_verbose(struct pt_regs *regs)
119{ 119{
120 unsigned int vec, cause_code, cause_reg; 120 unsigned int vec, cause_code;
121 unsigned long address; 121 unsigned long address;
122 122
123 cause_reg = current->thread.cause_code; 123 pr_info("\n[ECR ]: 0x%08lx => ", regs->event);
124 pr_info("\n[ECR ]: 0x%08x => ", cause_reg);
125 124
126 /* For Data fault, this is data address not instruction addr */ 125 /* For Data fault, this is data address not instruction addr */
127 address = current->thread.fault_address; 126 address = current->thread.fault_address;
128 127
129 vec = cause_reg >> 16; 128 vec = regs->ecr_vec;
130 cause_code = (cause_reg >> 8) & 0xFF; 129 cause_code = regs->ecr_cause;
131 130
132 /* For DTLB Miss or ProtV, display the memory involved too */ 131 /* For DTLB Miss or ProtV, display the memory involved too */
133 if (vec == ECR_V_DTLB_MISS) { 132 if (vec == ECR_V_DTLB_MISS) {
@@ -174,8 +173,7 @@ void show_regs(struct pt_regs *regs)
174 print_task_path_n_nm(tsk, buf); 173 print_task_path_n_nm(tsk, buf);
175 show_regs_print_info(KERN_INFO); 174 show_regs_print_info(KERN_INFO);
176 175
177 if (current->thread.cause_code) 176 show_ecr_verbose(regs);
178 show_ecr_verbose(regs);
179 177
180 pr_info("[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n", 178 pr_info("[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n",
181 current->thread.fault_address, 179 current->thread.fault_address,