diff --git a/headers/private/kernel/arch/arm/arch_cpu.h b/headers/private/kernel/arch/arm/arch_cpu.h index b77af08024..d749c55cd4 100644 --- a/headers/private/kernel/arch/arm/arch_cpu.h +++ b/headers/private/kernel/arch/arm/arch_cpu.h @@ -77,8 +77,11 @@ typedef struct arch_cpu_info { extern "C" { #endif -extern addr_t arm_get_far(void); -extern int32 arm_get_fsr(void); +extern uint32 arm_get_dfsr(void); +extern uint32 arm_get_ifsr(void); +extern addr_t arm_get_dfar(void); +extern addr_t arm_get_ifar(void); + extern addr_t arm_get_fp(void); extern int mmu_read_c1(void); diff --git a/headers/private/system/arch/arm/arch_cpu_defs.h b/headers/private/system/arch/arm/arch_cpu_defs.h index e34eeeec73..631373bc4a 100644 --- a/headers/private/system/arch/arm/arch_cpu_defs.h +++ b/headers/private/system/arch/arm/arch_cpu_defs.h @@ -13,7 +13,11 @@ #define CPSR_MODE_MASK 0x1f #define CPSR_MODE_USR 0x10 +#define CPSR_MODE_FIQ 0x11 +#define CPSR_MODE_IRQ 0x12 #define CPSR_MODE_SVC 0x13 +#define CPSR_MODE_ABT 0x17 +#define CPSR_MODE_UND 0x1b #define CPSR_MODE_SYS 0x1f #define CPSR_T 0x20 diff --git a/src/system/kernel/arch/arm/arch_asm.S b/src/system/kernel/arch/arm/arch_asm.S index 46ce6429a8..efe0f8681f 100644 --- a/src/system/kernel/arch/arm/arch_asm.S +++ b/src/system/kernel/arch/arm/arch_asm.S @@ -108,18 +108,32 @@ FUNCTION(arm_restore_fpu): FUNCTION_END(arm_restore_fpu) -/* addr_t arm_get_fsr(void); */ -FUNCTION(arm_get_fsr): - mrc p15, 0, r0, c5, c0, 0 @ get FSR +/* uint32 arm_get_dfsr(void); */ +FUNCTION(arm_get_dfsr): + mrc p15, 0, r0, c5, c0, 0 @ get DFSR bx lr -FUNCTION_END(arm_get_fsr) +FUNCTION_END(arm_get_dfsr) -/* addr_t arm_get_far(void); */ -FUNCTION(arm_get_far): - mrc p15, 0, r0, c6, c0, 0 @ get FAR +/* uint32 arm_get_ifsr(void) */ +FUNCTION(arm_get_ifsr): + mrc p15, 0, r0, c5, c0, 1 @ get IFSR bx lr -FUNCTION_END(arm_get_far) +FUNCTION_END(arm_get_ifsr) + + +/* addr_t arm_get_dfar(void); */ +FUNCTION(arm_get_dfar): + mrc p15, 0, r0, c6, c0, 0 @ get DFAR + bx lr +FUNCTION_END(arm_get_dfar) + + +/* addr_t arm_get_ifar(void) */ +FUNCTION(arm_get_ifar): + MRC p15, 0, r0, c6, c0, 2 @ get IFAR + bx lr +FUNCTION_END(arm_get_ifar) /* addr_t arm_get_fp(void); */ diff --git a/src/system/kernel/arch/arm/arch_exceptions.S b/src/system/kernel/arch/arm/arch_exceptions.S index 3402da29f3..c19de53b60 100644 --- a/src/system/kernel/arch/arm/arch_exceptions.S +++ b/src/system/kernel/arch/arm/arch_exceptions.S @@ -7,15 +7,9 @@ * */ -#include +#include -#define CPSR_MODE_MASK 0x1f -#define CPSR_MODE_USR 0x10 -#define CPSR_MODE_FIQ 0x11 -#define CPSR_MODE_IRQ 0x12 -#define CPSR_MODE_SVC 0x13 -#define CPSR_MODE_ABT 0x17 -#define CPSR_MODE_UND 0x1b +#include /* The following two macros are taken from FreeBSD... */ diff --git a/src/system/kernel/arch/arm/arch_int.cpp b/src/system/kernel/arch/arm/arch_int.cpp index 6eeac52ea1..88f7ee27f8 100644 --- a/src/system/kernel/arch/arm/arch_int.cpp +++ b/src/system/kernel/arch/arm/arch_int.cpp @@ -144,7 +144,7 @@ arch_int_init_post_vm(kernel_args *args) B_READ_AREA | B_EXECUTE_AREA, sVectorPageArea); if (sUserVectorPageArea < 0) - panic("user vector page @ %p could not be created (%lx)!", + panic("user vector page @ %p could not be created (%x)!", sVectorPageAddress, sUserVectorPageArea); // copy vectors into the newly created area @@ -290,15 +290,15 @@ extern "C" void arch_arm_data_abort(struct iframe *frame) { Thread *thread = thread_get_current_thread(); + addr_t dfar = arm_get_dfar(); + uint32 dfsr = arm_get_dfsr(); bool isUser = (frame->spsr & CPSR_MODE_MASK) == CPSR_MODE_USR; - int32 fsr = arm_get_fsr(); - addr_t far = arm_get_far(); - bool isWrite = (fsr & FSR_WNR) == FSR_WNR; + bool isWrite = (dfsr & FSR_WNR) == FSR_WNR; addr_t newip = 0; #ifdef TRACE_ARCH_INT print_iframe("Data Abort", frame); - dprintf("FAR: %08lx, isWrite: %d, thread: %s\n", far, isWrite, thread->name); + dprintf("DFAR: %08lx, DFSR: %08x, isUser: %d, isWrite: %d, thread: %s\n", dfar, dfsr, isUser, isWrite, thread->name); #endif IFrameScope scope(frame); @@ -310,7 +310,7 @@ arch_arm_data_abort(struct iframe *frame) cpu_ent* cpu = &gCPU[smp_get_current_cpu()]; if (cpu->fault_handler != 0) { - debug_set_page_fault_info(far, frame->pc, + debug_set_page_fault_info(dfar, frame->pc, isWrite ? DEBUG_PAGE_FAULT_WRITE : 0); frame->svc_sp = cpu->fault_handler_stack_pointer; frame->pc = cpu->fault_handler; @@ -320,7 +320,7 @@ arch_arm_data_abort(struct iframe *frame) if (thread->fault_handler != 0) { kprintf("ERROR: thread::fault_handler used in kernel " "debugger!\n"); - debug_set_page_fault_info(far, frame->pc, + debug_set_page_fault_info(dfar, frame->pc, isWrite ? DEBUG_PAGE_FAULT_WRITE : 0); frame->pc = reinterpret_cast(thread->fault_handler); return; @@ -329,7 +329,7 @@ arch_arm_data_abort(struct iframe *frame) // otherwise, not really panic("page fault in debugger without fault handler! Touching " - "address %p from pc %p\n", (void *)far, (void *)frame->pc); + "address %p from pc %p\n", (void *)dfar, (void *)frame->pc); return; } else if ((frame->spsr & (1 << 7)) != 0) { // interrupts disabled @@ -348,24 +348,24 @@ arch_arm_data_abort(struct iframe *frame) // The fault happened at the fault handler address. This is a // certain infinite loop. panic("page fault, interrupts disabled, fault handler loop. " - "Touching address %p from pc %p\n", (void*)far, + "Touching address %p from pc %p\n", (void*)dfar, (void*)frame->pc); } // If we are not running the kernel startup the page fault was not // allowed to happen and we must panic. panic("page fault, but interrupts were disabled. Touching address " - "%p from pc %p\n", (void *)far, (void *)frame->pc); + "%p from pc %p\n", (void *)dfar, (void *)frame->pc); return; } else if (thread != NULL && thread->page_faults_allowed < 1) { panic("page fault not allowed at this place. Touching address " - "%p from pc %p\n", (void *)far, (void *)frame->pc); + "%p from pc %p\n", (void *)dfar, (void *)frame->pc); return; } enable_interrupts(); - vm_page_fault(far, frame->pc, isWrite, false, isUser, &newip); + vm_page_fault(dfar, frame->pc, isWrite, false, isUser, &newip); if (newip != 0) { // the page fault handler wants us to modify the iframe to set the @@ -379,12 +379,14 @@ extern "C" void arch_arm_prefetch_abort(struct iframe *frame) { Thread *thread = thread_get_current_thread(); + addr_t ifar = arm_get_ifar(); + uint32 ifsr = arm_get_ifsr(); bool isUser = (frame->spsr & CPSR_MODE_MASK) == CPSR_MODE_USR; addr_t newip = 0; #ifdef TRACE_ARCH_INT print_iframe("Prefetch Abort", frame); - dprintf("thread: %s\n", thread->name); + dprintf("IFAR: %08lx, IFSR: %08x, isUser: %d, thread: %s\n", ifar, ifsr, isUser, thread->name); #endif IFrameScope scope(frame);