ARC: Remove explicit passing around of ECR
With ECR now part of pt_regs * No need to propagate from lowest asm handlers as arg * No need to save it in tsk->thread.cause_code * Avoid bit chopping to access the bit-fields More code consolidation, cleanup Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
This commit is contained in:
parent
502a0c775c
commit
38a9ff6d24
@ -18,9 +18,8 @@ struct task_struct;
|
|||||||
void show_regs(struct pt_regs *regs);
|
void show_regs(struct pt_regs *regs);
|
||||||
void show_stacktrace(struct task_struct *tsk, struct pt_regs *regs);
|
void show_stacktrace(struct task_struct *tsk, struct pt_regs *regs);
|
||||||
void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
|
void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
|
||||||
unsigned long address, unsigned long cause_reg);
|
unsigned long address);
|
||||||
void die(const char *str, struct pt_regs *regs, unsigned long address,
|
void die(const char *str, struct pt_regs *regs, unsigned long address);
|
||||||
unsigned long cause_reg);
|
|
||||||
|
|
||||||
#define BUG() do { \
|
#define BUG() do { \
|
||||||
dump_stack(); \
|
dump_stack(); \
|
||||||
|
@ -31,7 +31,7 @@ static inline void arch_kgdb_breakpoint(void)
|
|||||||
__asm__ __volatile__ ("trap_s 0x4\n");
|
__asm__ __volatile__ ("trap_s 0x4\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void kgdb_trap(struct pt_regs *regs, int param);
|
extern void kgdb_trap(struct pt_regs *regs);
|
||||||
|
|
||||||
enum arc700_linux_regnums {
|
enum arc700_linux_regnums {
|
||||||
_R0 = 0,
|
_R0 = 0,
|
||||||
@ -53,7 +53,7 @@ enum arc700_linux_regnums {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define kgdb_trap(regs, param)
|
#define kgdb_trap(regs)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __ARC_KGDB_H__ */
|
#endif /* __ARC_KGDB_H__ */
|
||||||
|
@ -50,11 +50,9 @@ struct kprobe_ctlblk {
|
|||||||
|
|
||||||
int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause);
|
int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause);
|
||||||
void kretprobe_trampoline(void);
|
void kretprobe_trampoline(void);
|
||||||
void trap_is_kprobe(unsigned long cause, unsigned long address,
|
void trap_is_kprobe(unsigned long address, struct pt_regs *regs);
|
||||||
struct pt_regs *regs);
|
|
||||||
#else
|
#else
|
||||||
static void trap_is_kprobe(unsigned long cause, unsigned long address,
|
static void trap_is_kprobe(unsigned long address, struct pt_regs *regs)
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -29,7 +29,6 @@ struct thread_struct {
|
|||||||
unsigned long ksp; /* kernel mode stack pointer */
|
unsigned long ksp; /* kernel mode stack pointer */
|
||||||
unsigned long callee_reg; /* pointer to callee regs */
|
unsigned long callee_reg; /* pointer to callee regs */
|
||||||
unsigned long fault_address; /* dbls as brkpt holder as well */
|
unsigned long fault_address; /* dbls as brkpt holder as well */
|
||||||
unsigned long cause_code; /* Exception Cause Code (ECR) */
|
|
||||||
#ifdef CONFIG_ARC_FPU_SAVE_RESTORE
|
#ifdef CONFIG_ARC_FPU_SAVE_RESTORE
|
||||||
struct arc_fpu fpu;
|
struct arc_fpu fpu;
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_ARC_MISALIGN_ACCESS
|
#ifdef CONFIG_ARC_MISALIGN_ACCESS
|
||||||
int misaligned_fixup(unsigned long address, struct pt_regs *regs,
|
int misaligned_fixup(unsigned long address, struct pt_regs *regs,
|
||||||
unsigned long cause, struct callee_regs *cregs);
|
struct callee_regs *cregs);
|
||||||
#else
|
#else
|
||||||
static inline int
|
static inline int
|
||||||
misaligned_fixup(unsigned long address, struct pt_regs *regs,
|
misaligned_fixup(unsigned long address, struct pt_regs *regs,
|
||||||
unsigned long cause, struct callee_regs *cregs)
|
struct callee_regs *cregs)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -274,10 +274,8 @@ ARC_ENTRY instr_service
|
|||||||
SWITCH_TO_KERNEL_STK
|
SWITCH_TO_KERNEL_STK
|
||||||
SAVE_ALL_SYS
|
SAVE_ALL_SYS
|
||||||
|
|
||||||
lr r0, [ecr]
|
lr r0, [efa]
|
||||||
lr r1, [efa]
|
mov r1, sp
|
||||||
|
|
||||||
mov r2, sp
|
|
||||||
|
|
||||||
FAKE_RET_FROM_EXCPN r9
|
FAKE_RET_FROM_EXCPN r9
|
||||||
|
|
||||||
@ -298,9 +296,8 @@ ARC_ENTRY mem_service
|
|||||||
SWITCH_TO_KERNEL_STK
|
SWITCH_TO_KERNEL_STK
|
||||||
SAVE_ALL_SYS
|
SAVE_ALL_SYS
|
||||||
|
|
||||||
lr r0, [ecr]
|
lr r0, [efa]
|
||||||
lr r1, [efa]
|
mov r1, sp
|
||||||
mov r2, sp
|
|
||||||
bl do_memory_error
|
bl do_memory_error
|
||||||
b ret_from_exception
|
b ret_from_exception
|
||||||
ARC_EXIT mem_service
|
ARC_EXIT mem_service
|
||||||
@ -317,11 +314,11 @@ ARC_ENTRY EV_MachineCheck
|
|||||||
SWITCH_TO_KERNEL_STK
|
SWITCH_TO_KERNEL_STK
|
||||||
SAVE_ALL_SYS
|
SAVE_ALL_SYS
|
||||||
|
|
||||||
lr r0, [ecr]
|
lr r2, [ecr]
|
||||||
lr r1, [efa]
|
lr r0, [efa]
|
||||||
mov r2, sp
|
mov r1, sp
|
||||||
|
|
||||||
lsr r3, r0, 8
|
lsr r3, r2, 8
|
||||||
bmsk r3, r3, 7
|
bmsk r3, r3, 7
|
||||||
brne r3, ECR_C_MCHK_DUP_TLB, 1f
|
brne r3, ECR_C_MCHK_DUP_TLB, 1f
|
||||||
|
|
||||||
@ -384,12 +381,12 @@ ARC_ENTRY EV_TLBProtV
|
|||||||
|
|
||||||
;========== (6b) Non aligned access ============
|
;========== (6b) Non aligned access ============
|
||||||
4:
|
4:
|
||||||
mov r0, r2 ; cause code
|
mov r0, r1
|
||||||
mov r2, sp ; pt_regs
|
mov r1, sp ; pt_regs
|
||||||
|
|
||||||
#ifdef CONFIG_ARC_MISALIGN_ACCESS
|
#ifdef CONFIG_ARC_MISALIGN_ACCESS
|
||||||
SAVE_CALLEE_SAVED_USER
|
SAVE_CALLEE_SAVED_USER
|
||||||
mov r3, sp ; callee_regs
|
mov r2, sp ; callee_regs
|
||||||
|
|
||||||
bl do_misaligned_access
|
bl do_misaligned_access
|
||||||
|
|
||||||
@ -416,9 +413,8 @@ ARC_ENTRY EV_PrivilegeV
|
|||||||
SWITCH_TO_KERNEL_STK
|
SWITCH_TO_KERNEL_STK
|
||||||
SAVE_ALL_SYS
|
SAVE_ALL_SYS
|
||||||
|
|
||||||
lr r0, [ecr]
|
lr r0, [efa]
|
||||||
lr r1, [efa]
|
mov r1, sp
|
||||||
mov r2, sp
|
|
||||||
|
|
||||||
FAKE_RET_FROM_EXCPN r9
|
FAKE_RET_FROM_EXCPN r9
|
||||||
|
|
||||||
@ -437,9 +433,8 @@ ARC_ENTRY EV_Extension
|
|||||||
SWITCH_TO_KERNEL_STK
|
SWITCH_TO_KERNEL_STK
|
||||||
SAVE_ALL_SYS
|
SAVE_ALL_SYS
|
||||||
|
|
||||||
lr r0, [ecr]
|
lr r0, [efa]
|
||||||
lr r1, [efa]
|
mov r1, sp
|
||||||
mov r2, sp
|
|
||||||
bl do_extension_fault
|
bl do_extension_fault
|
||||||
b ret_from_exception
|
b ret_from_exception
|
||||||
ARC_EXIT EV_Extension
|
ARC_EXIT EV_Extension
|
||||||
@ -495,9 +490,8 @@ tracesys_exit:
|
|||||||
trap_with_param:
|
trap_with_param:
|
||||||
|
|
||||||
; stop_pc info by gdb needs this info
|
; stop_pc info by gdb needs this info
|
||||||
mov r0, r12
|
lr r0, [efa]
|
||||||
lr r1, [efa]
|
mov r1, sp
|
||||||
mov r2, sp
|
|
||||||
|
|
||||||
; Now that we have read EFA, its safe to do "fake" rtie
|
; Now that we have read EFA, its safe to do "fake" rtie
|
||||||
; and get out of CPU exception mode
|
; and get out of CPU exception mode
|
||||||
|
@ -169,7 +169,7 @@ int kgdb_arch_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kgdb_trap(struct pt_regs *regs, int param)
|
void kgdb_trap(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
/* trap_s 3 is used for breakpoints that overwrite existing
|
/* trap_s 3 is used for breakpoints that overwrite existing
|
||||||
* instructions, while trap_s 4 is used for compiled breakpoints.
|
* instructions, while trap_s 4 is used for compiled breakpoints.
|
||||||
|
@ -517,8 +517,7 @@ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void trap_is_kprobe(unsigned long cause, unsigned long address,
|
void trap_is_kprobe(unsigned long address, struct pt_regs *regs)
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
{
|
||||||
notify_die(DIE_TRAP, "kprobe_trap", regs, address, cause, SIGTRAP);
|
notify_die(DIE_TRAP, "kprobe_trap", regs, address, 0, SIGTRAP);
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,9 @@ void __init trap_init(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void die(const char *str, struct pt_regs *regs, unsigned long address,
|
void die(const char *str, struct pt_regs *regs, unsigned long address)
|
||||||
unsigned long cause_reg)
|
|
||||||
{
|
{
|
||||||
show_kernel_fault_diag(str, regs, address, cause_reg);
|
show_kernel_fault_diag(str, regs, address);
|
||||||
|
|
||||||
/* DEAD END */
|
/* DEAD END */
|
||||||
__asm__("flag 1");
|
__asm__("flag 1");
|
||||||
@ -42,14 +41,13 @@ void die(const char *str, struct pt_regs *regs, unsigned long address,
|
|||||||
* -for user faults enqueues requested signal
|
* -for user faults enqueues requested signal
|
||||||
* -for kernel, chk if due to copy_(to|from)_user, otherwise die()
|
* -for kernel, chk if due to copy_(to|from)_user, otherwise die()
|
||||||
*/
|
*/
|
||||||
static noinline int handle_exception(unsigned long cause, char *str,
|
static noinline int
|
||||||
struct pt_regs *regs, siginfo_t *info)
|
handle_exception(const char *str, struct pt_regs *regs, siginfo_t *info)
|
||||||
{
|
{
|
||||||
if (user_mode(regs)) {
|
if (user_mode(regs)) {
|
||||||
struct task_struct *tsk = current;
|
struct task_struct *tsk = current;
|
||||||
|
|
||||||
tsk->thread.fault_address = (__force unsigned int)info->si_addr;
|
tsk->thread.fault_address = (__force unsigned int)info->si_addr;
|
||||||
tsk->thread.cause_code = cause;
|
|
||||||
|
|
||||||
force_sig_info(info->si_signo, info, tsk);
|
force_sig_info(info->si_signo, info, tsk);
|
||||||
|
|
||||||
@ -58,14 +56,14 @@ static noinline int handle_exception(unsigned long cause, char *str,
|
|||||||
if (fixup_exception(regs))
|
if (fixup_exception(regs))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
die(str, regs, (unsigned long)info->si_addr, cause);
|
die(str, regs, (unsigned long)info->si_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DO_ERROR_INFO(signr, str, name, sicode) \
|
#define DO_ERROR_INFO(signr, str, name, sicode) \
|
||||||
int name(unsigned long cause, unsigned long address, struct pt_regs *regs) \
|
int name(unsigned long address, struct pt_regs *regs) \
|
||||||
{ \
|
{ \
|
||||||
siginfo_t info = { \
|
siginfo_t info = { \
|
||||||
.si_signo = signr, \
|
.si_signo = signr, \
|
||||||
@ -73,7 +71,7 @@ int name(unsigned long cause, unsigned long address, struct pt_regs *regs) \
|
|||||||
.si_code = sicode, \
|
.si_code = sicode, \
|
||||||
.si_addr = (void __user *)address, \
|
.si_addr = (void __user *)address, \
|
||||||
}; \
|
}; \
|
||||||
return handle_exception(cause, str, regs, &info);\
|
return handle_exception(str, regs, &info);\
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -90,11 +88,11 @@ DO_ERROR_INFO(SIGBUS, "Misaligned Access", do_misaligned_error, BUS_ADRALN)
|
|||||||
/*
|
/*
|
||||||
* Entry Point for Misaligned Data access Exception, for emulating in software
|
* Entry Point for Misaligned Data access Exception, for emulating in software
|
||||||
*/
|
*/
|
||||||
int do_misaligned_access(unsigned long cause, unsigned long address,
|
int do_misaligned_access(unsigned long address, struct pt_regs *regs,
|
||||||
struct pt_regs *regs, struct callee_regs *cregs)
|
struct callee_regs *cregs)
|
||||||
{
|
{
|
||||||
if (misaligned_fixup(address, regs, cause, cregs) != 0)
|
if (misaligned_fixup(address, regs, cregs) != 0)
|
||||||
return do_misaligned_error(cause, address, regs);
|
return do_misaligned_error(address, regs);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -104,10 +102,9 @@ int do_misaligned_access(unsigned long cause, unsigned long address,
|
|||||||
* Entry point for miscll errors such as Nested Exceptions
|
* Entry point for miscll errors such as Nested Exceptions
|
||||||
* -Duplicate TLB entry is handled seperately though
|
* -Duplicate TLB entry is handled seperately though
|
||||||
*/
|
*/
|
||||||
void do_machine_check_fault(unsigned long cause, unsigned long address,
|
void do_machine_check_fault(unsigned long address, struct pt_regs *regs)
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
{
|
||||||
die("Machine Check Exception", regs, address, cause);
|
die("Machine Check Exception", regs, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -120,23 +117,22 @@ void do_machine_check_fault(unsigned long cause, unsigned long address,
|
|||||||
* -1 used for software breakpointing (gdb)
|
* -1 used for software breakpointing (gdb)
|
||||||
* -2 used by kprobes
|
* -2 used by kprobes
|
||||||
*/
|
*/
|
||||||
void do_non_swi_trap(unsigned long cause, unsigned long address,
|
void do_non_swi_trap(unsigned long address, struct pt_regs *regs)
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
{
|
||||||
unsigned int param = cause & 0xff;
|
unsigned int param = regs->ecr_param;
|
||||||
|
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 1:
|
case 1:
|
||||||
trap_is_brkpt(cause, address, regs);
|
trap_is_brkpt(address, regs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
trap_is_kprobe(param, address, regs);
|
trap_is_kprobe(address, regs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
kgdb_trap(regs, param);
|
kgdb_trap(regs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -149,14 +145,14 @@ void do_non_swi_trap(unsigned long cause, unsigned long address,
|
|||||||
* -For a corner case, ARC kprobes implementation resorts to using
|
* -For a corner case, ARC kprobes implementation resorts to using
|
||||||
* this exception, hence the check
|
* this exception, hence the check
|
||||||
*/
|
*/
|
||||||
void do_insterror_or_kprobe(unsigned long cause,
|
void do_insterror_or_kprobe(unsigned long address, struct pt_regs *regs)
|
||||||
unsigned long address,
|
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
/* Check if this exception is caused by kprobes */
|
/* Check if this exception is caused by kprobes */
|
||||||
if (notify_die(DIE_IERR, "kprobe_ierr", regs, address,
|
rc = notify_die(DIE_IERR, "kprobe_ierr", regs, address, 0, SIGILL);
|
||||||
cause, SIGILL) == NOTIFY_STOP)
|
if (rc == NOTIFY_STOP)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
insterror_is_error(cause, address, regs);
|
insterror_is_error(address, regs);
|
||||||
}
|
}
|
||||||
|
@ -209,10 +209,9 @@ void show_regs(struct pt_regs *regs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
|
void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
|
||||||
unsigned long address, unsigned long cause_reg)
|
unsigned long address)
|
||||||
{
|
{
|
||||||
current->thread.fault_address = address;
|
current->thread.fault_address = address;
|
||||||
current->thread.cause_code = cause_reg;
|
|
||||||
|
|
||||||
/* Caller and Callee regs */
|
/* Caller and Callee regs */
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
|
@ -187,7 +187,7 @@ fault: state->fault = 1;
|
|||||||
* Returns 0 if successfully handled, 1 if some error happened
|
* Returns 0 if successfully handled, 1 if some error happened
|
||||||
*/
|
*/
|
||||||
int misaligned_fixup(unsigned long address, struct pt_regs *regs,
|
int misaligned_fixup(unsigned long address, struct pt_regs *regs,
|
||||||
unsigned long cause, struct callee_regs *cregs)
|
struct callee_regs *cregs)
|
||||||
{
|
{
|
||||||
struct disasm_state state;
|
struct disasm_state state;
|
||||||
char buf[TASK_COMM_LEN];
|
char buf[TASK_COMM_LEN];
|
||||||
|
@ -52,15 +52,14 @@ bad_area:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_page_fault(struct pt_regs *regs, unsigned long address,
|
void do_page_fault(struct pt_regs *regs, unsigned long address)
|
||||||
unsigned long cause_code)
|
|
||||||
{
|
{
|
||||||
struct vm_area_struct *vma = NULL;
|
struct vm_area_struct *vma = NULL;
|
||||||
struct task_struct *tsk = current;
|
struct task_struct *tsk = current;
|
||||||
struct mm_struct *mm = tsk->mm;
|
struct mm_struct *mm = tsk->mm;
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
int fault, ret;
|
int fault, ret;
|
||||||
int write = cause_code & (1 << ECR_C_BIT_DTLB_ST_MISS); /* ST/EX */
|
int write = regs->ecr_cause & ECR_C_PROTV_STORE; /* ST/EX */
|
||||||
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
|
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
|
||||||
(write ? FAULT_FLAG_WRITE : 0);
|
(write ? FAULT_FLAG_WRITE : 0);
|
||||||
|
|
||||||
@ -111,7 +110,8 @@ good_area:
|
|||||||
|
|
||||||
/* Handle protection violation, execute on heap or stack */
|
/* Handle protection violation, execute on heap or stack */
|
||||||
|
|
||||||
if (cause_code == ((ECR_V_PROTV << 16) | ECR_C_PROTV_INST_FETCH))
|
if ((regs->ecr_vec == ECR_V_PROTV) &&
|
||||||
|
(regs->ecr_cause == ECR_C_PROTV_INST_FETCH))
|
||||||
goto bad_area;
|
goto bad_area;
|
||||||
|
|
||||||
if (write) {
|
if (write) {
|
||||||
@ -178,7 +178,6 @@ bad_area_nosemaphore:
|
|||||||
/* User mode accesses just cause a SIGSEGV */
|
/* User mode accesses just cause a SIGSEGV */
|
||||||
if (user_mode(regs)) {
|
if (user_mode(regs)) {
|
||||||
tsk->thread.fault_address = address;
|
tsk->thread.fault_address = address;
|
||||||
tsk->thread.cause_code = cause_code;
|
|
||||||
info.si_signo = SIGSEGV;
|
info.si_signo = SIGSEGV;
|
||||||
info.si_errno = 0;
|
info.si_errno = 0;
|
||||||
/* info.si_code has been set above */
|
/* info.si_code has been set above */
|
||||||
@ -199,7 +198,7 @@ no_context:
|
|||||||
if (fixup_exception(regs))
|
if (fixup_exception(regs))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
die("Oops", regs, address, cause_code);
|
die("Oops", regs, address);
|
||||||
|
|
||||||
out_of_memory:
|
out_of_memory:
|
||||||
if (is_global_init(tsk)) {
|
if (is_global_init(tsk)) {
|
||||||
@ -220,7 +219,6 @@ do_sigbus:
|
|||||||
goto no_context;
|
goto no_context;
|
||||||
|
|
||||||
tsk->thread.fault_address = address;
|
tsk->thread.fault_address = address;
|
||||||
tsk->thread.cause_code = cause_code;
|
|
||||||
info.si_signo = SIGBUS;
|
info.si_signo = SIGBUS;
|
||||||
info.si_errno = 0;
|
info.si_errno = 0;
|
||||||
info.si_code = BUS_ADRERR;
|
info.si_code = BUS_ADRERR;
|
||||||
|
@ -382,7 +382,6 @@ do_slow_path_pf:
|
|||||||
; ------- setup args for Linux Page fault Hanlder ---------
|
; ------- setup args for Linux Page fault Hanlder ---------
|
||||||
mov_s r0, sp
|
mov_s r0, sp
|
||||||
lr r1, [efa]
|
lr r1, [efa]
|
||||||
lr r2, [ecr]
|
|
||||||
|
|
||||||
; We don't want exceptions to be disabled while the fault is handled.
|
; We don't want exceptions to be disabled while the fault is handled.
|
||||||
; Now that we have saved the context we return from exception hence
|
; Now that we have saved the context we return from exception hence
|
||||||
|
Loading…
Reference in New Issue
Block a user