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:
David Karoly 2022-09-04 19:09:26 +02:00
parent 67406e5145
commit 17569c02ff
5 changed files with 48 additions and 31 deletions

View File

@ -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);

View File

@ -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

View File

@ -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); */

View File

@ -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... */

View File

@ -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);