diff options
-rw-r--r-- | arch/arc/include/asm/entry.h | 29 | ||||
-rw-r--r-- | arch/arc/include/asm/ptrace.h | 24 | ||||
-rw-r--r-- | arch/arc/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/arc/kernel/entry.S | 4 |
4 files changed, 40 insertions, 19 deletions
diff --git a/arch/arc/include/asm/entry.h b/arch/arc/include/asm/entry.h index 6b42bf5..9eada5b 100644 --- a/arch/arc/include/asm/entry.h +++ b/arch/arc/include/asm/entry.h @@ -343,18 +343,12 @@ *-------------------------------------------------------------*/ .macro SAVE_ALL_EXCEPTION marker + st \marker, [sp, 8] + st r0, [sp, 4] /* orig_r0, needed only for sys calls */ + /* Restore r9 used to code the early prologue */ EXCPN_PROLOG_RESTORE_REG r9 - /* Save the complete regfile now */ - - /* orig_r8 marker: - * syscalls -> 1 to NR_SYSCALLS - * Exceptions -> NR_SYSCALLS + 1 - * Break-point-> NR_SYSCALLS + 2 - */ - st \marker, [sp, 8] - st r0, [sp, 4] /* orig_r0, needed only for sys calls */ SAVE_CALLER_SAVED st.a r26, [sp, -4] /* gp */ st.a fp, [sp, -4] @@ -384,14 +378,25 @@ * Save scratch regs for exceptions *-------------------------------------------------------------*/ .macro SAVE_ALL_SYS - SAVE_ALL_EXCEPTION (NR_syscalls + 1) + SAVE_ALL_EXCEPTION orig_r8_IS_EXCPN .endm /*-------------------------------------------------------------- * Save scratch regs for sys calls *-------------------------------------------------------------*/ .macro SAVE_ALL_TRAP - SAVE_ALL_EXCEPTION r8 + /* + * Setup pt_regs->orig_r8. + * Encode syscall number (r8) in upper short word of event type (r9) + * N.B. #1: This is already endian safe (see ptrace.h) + * #2: Only r9 can be used as scratch as it is already clobbered + * and it's contents are no longer needed by the latter part + * of exception prologue + */ + lsl r9, r8, 16 + or r9, r9, orig_r8_IS_SCALL + + SAVE_ALL_EXCEPTION r9 .endm /*-------------------------------------------------------------- @@ -442,7 +447,7 @@ ld r9, [@int1_saved_reg] /* now we are ready to save the remaining context :) */ - st -1, [sp, 8] /* orig_r8, -1 for interuppt level one */ + st orig_r8_IS_IRQ1, [sp, 8] /* Event Type */ st 0, [sp, 4] /* orig_r0 , N/A for IRQ */ SAVE_CALLER_SAVED st.a r26, [sp, -4] /* gp */ diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index 3afadef..3ec89f4 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h @@ -50,7 +50,17 @@ struct pt_regs { long r0; long sp; /* user/kernel sp depending on where we came from */ long orig_r0; - long orig_r8; /*to distinguish bet excp, sys call, int1 or int2 */ + + /*to distinguish bet excp, syscall, irq */ + union { +#ifdef CONFIG_CPU_BIG_ENDIAN + /* so that assembly code is same for LE/BE */ + unsigned long orig_r8:16, event:16; +#else + unsigned long event:16, orig_r8:16; +#endif + long orig_r8_word; + }; }; /* Callee saved registers - need to be saved only when you are scheduled out */ @@ -87,9 +97,8 @@ struct callee_regs { sp; \ }) -/* return 1 if in syscall, 0 if Intr or Exception */ -#define in_syscall(regs) (((regs->orig_r8) >= 0 && \ - (regs->orig_r8 <= NR_syscalls)) ? 1 : 0) +#define in_syscall(regs) (regs->event & orig_r8_IS_SCALL) +#define in_brkpt_trap(regs) (regs->event & orig_r8_IS_BRKPT) #define current_pt_regs() \ ({ \ @@ -101,6 +110,13 @@ struct callee_regs { #endif /* !__ASSEMBLY__ */ +#define orig_r8_IS_SCALL 0x0001 +#define orig_r8_IS_SCALL_RESTARTED 0x0002 +#define orig_r8_IS_BRKPT 0x0004 +#define orig_r8_IS_EXCPN 0x0004 +#define orig_r8_IS_IRQ1 0x0010 +#define orig_r8_IS_IRQ2 0x0020 + #endif /* __KERNEL__ */ #ifndef __ASSEMBLY__ diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c index 64b2c2f..d7770cc 100644 --- a/arch/arc/kernel/asm-offsets.c +++ b/arch/arc/kernel/asm-offsets.c @@ -46,7 +46,7 @@ int main(void) BLANK(); DEFINE(PT_status32, offsetof(struct pt_regs, status32)); - DEFINE(PT_orig_r8, offsetof(struct pt_regs, orig_r8)); + DEFINE(PT_orig_r8, offsetof(struct pt_regs, orig_r8_word)); DEFINE(PT_sp, offsetof(struct pt_regs, sp)); DEFINE(PT_r0, offsetof(struct pt_regs, r0)); DEFINE(PT_r1, offsetof(struct pt_regs, r1)); diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index d625b77..ce8670d 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S @@ -350,8 +350,8 @@ ARC_EXIT EV_Extension trap_with_param: - ;make sure orig_r8 is a positive value - st NR_syscalls + 2, [sp, PT_orig_r8] + ; stop_pc info by gdb needs this info + st orig_r8_IS_BRKPT, [sp, PT_orig_r8] mov r0, r12 lr r1, [efa] |