41,7 → 41,6 |
#include <arch.h> |
#include <interrupt.h> |
|
|
/** Returns value stored in fault status register. |
* |
* @return Value stored in CP15 fault status register (FSR). |
50,7 → 49,7 |
{ |
fault_status_union_t fsu; |
|
// fault status is stored in CP15 register 5 |
/* fault status is stored in CP15 register 5 */ |
asm volatile ( |
"mrc p15, 0, %0, c5, c0, 0" |
: "=r"(fsu.dummy) |
58,16 → 57,16 |
return fsu.fs; |
} |
|
|
/** Returns FAR (fault address register) content. |
* |
* @return FAR (fault address register) content (address that caused a page fault) |
* @return FAR (fault address register) content (address that caused a page |
* fault) |
*/ |
static inline uintptr_t read_fault_address_register(void) |
{ |
uintptr_t ret; |
|
// fault adress is stored in CP15 register 6 |
/* fault adress is stored in CP15 register 6 */ |
asm volatile ( |
"mrc p15, 0, %0, c6, c0, 0" |
: "=r"(ret) |
75,7 → 74,6 |
return ret; |
} |
|
|
/** Decides whether the instruction is load/store or not. |
* |
* @param instr Instruction |
84,22 → 82,22 |
*/ |
static inline bool is_load_store_instruction(instruction_t instr) |
{ |
// load store immediate offset |
/* load store immediate offset */ |
if (instr.type == 0x2) { |
return true; |
} |
|
// load store register offset |
/* load store register offset */ |
if (instr.type == 0x3 && instr.bit4 == 0) { |
return true; |
} |
|
// load store multiple |
/* load store multiple */ |
if (instr.type == 0x4) { |
return true; |
} |
|
// coprocessor load/store |
/* oprocessor load/store */ |
if (instr.type == 0x6) { |
return true; |
} |
107,8 → 105,7 |
return false; |
} |
|
|
/** Decides whether the instructions is swap or not. |
/** Decides whether the instruction is swap or not. |
* |
* @param instr Instruction |
* |
116,7 → 113,7 |
*/ |
static inline bool is_swap_instruction(instruction_t instr) |
{ |
// swap, swapb instruction |
/* swap, swapb instruction */ |
if (instr.type == 0x0 && |
(instr.opcode == 0x8 || instr.opcode == 0xa) && |
instr.access == 0x0 && instr.bits567 == 0x4 && instr.bit4 == 1) { |
126,15 → 123,16 |
return false; |
} |
|
|
/** Decides whether read or write into memory is requested. |
* |
* @param instr_addr Address of instruction which tries to access memory. |
* @param badvaddr Virtual address the instruction tries to access. |
* |
* @return Type of access into memory, PF_ACCESS_EXEC if no memory access is requested. |
* @return Type of access into memory, PF_ACCESS_EXEC if no memory access is |
* requested. |
*/ |
static pf_access_t get_memory_access_type(uint32_t instr_addr, uintptr_t badvaddr) |
static pf_access_t get_memory_access_type(uint32_t instr_addr, |
uintptr_t badvaddr) |
{ |
instruction_union_t instr_union; |
instr_union.pc = instr_addr; |
141,14 → 139,14 |
|
instruction_t instr = *(instr_union.instr); |
|
// undefined instructions |
/* undefined instructions */ |
if (instr.condition == 0xf) { |
panic("page_fault - instruction doesn't access memory (instr_code: %x, badvaddr:%x)", |
instr, badvaddr); |
panic("page_fault - instruction doesn't access memory " |
"(instr_code: %x, badvaddr:%x)", instr, badvaddr); |
return PF_ACCESS_EXEC; |
} |
|
// load store instructions |
/* load store instructions */ |
if (is_load_store_instruction(instr)) { |
if (instr.access == 1) { |
return PF_ACCESS_READ; |
157,13 → 155,13 |
} |
} |
|
// swap, swpb instruction |
/* swap, swpb instruction */ |
if (is_swap_instruction(instr)) { |
return PF_ACCESS_WRITE; |
} |
|
panic("page_fault - instruction doesn't access memory (instr_code: %x, badvaddr:%x)", |
instr, badvaddr); |
panic("page_fault - instruction doesn't access memory " |
"(instr_code: %x, badvaddr:%x)", instr, badvaddr); |
|
return PF_ACCESS_EXEC; |
} |
184,8 → 182,9 |
|
if (ret == AS_PF_FAULT) { |
print_istate(istate); |
dprintf("page fault - pc: %x, va: %x, status: %x(%x), access:%d\n", |
istate->pc, badvaddr, fsr.status, fsr, access); |
dprintf("page fault - pc: %x, va: %x, status: %x(%x), " |
"access:%d\n", istate->pc, badvaddr, fsr.status, fsr, |
access); |
|
fault_if_from_uspace(istate, "Page fault: %#x", badvaddr); |
panic("page fault\n"); |
204,10 → 203,10 |
if (ret == AS_PF_FAULT) { |
dprintf("prefetch_abort\n"); |
print_istate(istate); |
panic("page fault - prefetch_abort at address: %x\n", istate->pc); |
panic("page fault - prefetch_abort at address: %x\n", |
istate->pc); |
} |
} |
|
/** @} |
*/ |
|