kernel/arm: clean up arch-specific defines
* align fault syndrome and fault address register naming with ARM Architecture Reference Manual (i.e. IFSR, DFSR, IFAR, DFAR) * move PSR bitfield defines to arch_cpu_defs.h Change-Id: I813045eec335ffbdd75270ad5a1afb2f222f73c8 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5618 Reviewed-by: Fredrik Holmqvist <fredrik.holmqvist@gmail.com> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
parent
67406e5145
commit
17569c02ff
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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); */
|
||||
|
@ -7,15 +7,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asm_defs.h>
|
||||
#include <arch/arm/arch_cpu_defs.h>
|
||||
|
||||
#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 <asm_defs.h>
|
||||
|
||||
/* The following two macros are taken from FreeBSD... */
|
||||
|
||||
|
@ -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<uintptr_t>(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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user