#define ECR_V_ITLB_MISS 0x21
#define ECR_V_DTLB_MISS 0x22
#define ECR_V_PROTV 0x23
+#define ECR_V_TRAP 0x25
/* Protection Violation Exception Cause Code Values */
#define ECR_C_PROTV_INST_FETCH 0x00
#define ECR_C_BIT_DTLB_LD_MISS 8
#define ECR_C_BIT_DTLB_ST_MISS 9
+/* Dummy ECR values for Interrupts */
+#define event_IRQ1 0x00310000
+#define event_IRQ2 0x00320000
/* Auxiliary registers */
#define AUX_IDENTITY 4
* Note that syscalls are implemented via TRAP which is also a exception
* from CPU's point of view
*-------------------------------------------------------------*/
-.macro SAVE_ALL_EXCEPTION marker
+.macro SAVE_ALL_SYS
- st \marker, [sp, 8] /* event */
+ lr r9, [ecr]
+ st r9, [sp, 8] /* event */
st r0, [sp, 4] /* orig_r0, needed only for sys calls */
/* Restore r9 used to code the early prologue */
PUSHAX erbta
.endm
-/*--------------------------------------------------------------
- * Save scratch regs for exceptions
- *-------------------------------------------------------------*/
-.macro SAVE_ALL_SYS
- SAVE_ALL_EXCEPTION event_EXCPN
-.endm
-
-/*--------------------------------------------------------------
- * Save scratch regs for sys calls
- *-------------------------------------------------------------*/
-.macro SAVE_ALL_TRAP
- SAVE_ALL_EXCEPTION event_SCALL
-.endm
-
/*--------------------------------------------------------------
* Restore all registers used by system call or Exceptions
* SP should always be pointing to the next free stack element
long sp; /* user/kernel sp depending on where we came from */
long orig_r0;
- /*to distinguish bet excp, syscall, irq */
- unsigned long event;
+ /*
+ * To distinguish bet excp, syscall, irq
+ * For traps and exceptions, Exception Cause Register.
+ * ECR: <00> <VV> <CC> <PP>
+ * Last word used by Linux for extra state mgmt (syscall-restart)
+ * For interrupts, use artificial ECR values to note current prio-level
+ */
+ union {
+ struct {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ unsigned long state:8, ecr_vec:8,
+ ecr_cause:8, ecr_param:8;
+#else
+ unsigned long ecr_param:8, ecr_cause:8,
+ ecr_vec:8, state:8;
+#endif
+ };
+ unsigned long event;
+ };
long user_r25;
};
/* return 1 if PC in delay slot */
#define delay_mode(regs) ((regs->status32 & STATUS_DE_MASK) == STATUS_DE_MASK)
-#define in_syscall(regs) (regs->event & event_SCALL)
-#define in_brkpt_trap(regs) (regs->event & event_BRKPT)
+#define in_syscall(regs) ((regs->ecr_vec == ECR_V_TRAP) && !regs->ecr_param)
+#define in_brkpt_trap(regs) ((regs->ecr_vec == ECR_V_TRAP) && regs->ecr_param)
-#define syscall_wont_restart(regs) (regs->event |= event_SCALL_RESTARTED)
-#define syscall_restartable(regs) !(regs->event & event_SCALL_RESTARTED)
+#define STATE_SCALL_RESTARTED 0x01
+
+#define syscall_wont_restart(reg) (reg->state |= STATE_SCALL_RESTARTED)
+#define syscall_restartable(reg) !(reg->state & STATE_SCALL_RESTARTED)
#define current_pt_regs() \
({ \
#endif /* !__ASSEMBLY__ */
-#define event_SCALL 0x0001
-#define event_SCALL_RESTARTED 0x0002
-#define event_BRKPT 0x0004
-#define event_EXCPN 0x0008
-#define event_IRQ1 0x0010
-#define event_IRQ2 0x0020
-
#endif /* __ASM_PTRACE_H */
.endr
#include <linux/linkage.h> /* ARC_{EXTRY,EXIT} */
-#include <asm/entry.h> /* SAVE_ALL_{INT1,INT2,TRAP...} */
+#include <asm/entry.h> /* SAVE_ALL_{INT1,INT2,SYS...} */
#include <asm/errno.h>
#include <asm/arcregs.h>
#include <asm/irqflags.h>
trap_with_param:
; stop_pc info by gdb needs this info
- st event_BRKPT, [sp, PT_event]
-
mov r0, r12
lr r1, [efa]
mov r2, sp
lr r9, [erstatus]
SWITCH_TO_KERNEL_STK
- SAVE_ALL_TRAP
+ SAVE_ALL_SYS
;------- (4) What caused the Trap --------------
lr r12, [ecr]
* with trap_s 4 (compiled) breakpoints, continuation needs to
* start after the breakpoint.
*/
- if (param == 3)
+ if (regs->ecr_param == 3)
instruction_pointer(regs) -= BREAK_INSTR_SIZE;
kgdb_handle_exception(1, SIGTRAP, 0, regs);
* ------------------
* | SP |
* | orig_r0 |
- * | event |
+ * | event/ECR |
* | user_r25 |
* ------------------ <===== END of PAGE
*/
static void show_ecr_verbose(struct pt_regs *regs)
{
- unsigned int vec, cause_code, cause_reg;
+ unsigned int vec, cause_code;
unsigned long address;
- cause_reg = current->thread.cause_code;
- pr_info("\n[ECR ]: 0x%08x => ", cause_reg);
+ pr_info("\n[ECR ]: 0x%08lx => ", regs->event);
/* For Data fault, this is data address not instruction addr */
address = current->thread.fault_address;
- vec = cause_reg >> 16;
- cause_code = (cause_reg >> 8) & 0xFF;
+ vec = regs->ecr_vec;
+ cause_code = regs->ecr_cause;
/* For DTLB Miss or ProtV, display the memory involved too */
if (vec == ECR_V_DTLB_MISS) {
print_task_path_n_nm(tsk, buf);
show_regs_print_info(KERN_INFO);
- if (current->thread.cause_code)
- show_ecr_verbose(regs);
+ show_ecr_verbose(regs);
pr_info("[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n",
current->thread.fault_address,