34,10 → 34,13 |
|
#include <arch/mm/tlb.h> |
#include <mm/tlb.h> |
#include <mm/as.h> |
#include <mm/asid.h> |
#include <arch/mm/frame.h> |
#include <arch/mm/page.h> |
#include <arch/mm/mmu.h> |
#include <mm/asid.h> |
#include <arch/interrupt.h> |
#include <arch.h> |
#include <print.h> |
#include <arch/types.h> |
#include <typedefs.h> |
47,6 → 50,9 |
#include <arch/asm.h> |
#include <symtab.h> |
|
static void dtlb_pte_copy(pte_t *t); |
static void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str); |
|
char *context_encoding[] = { |
"Primary", |
"Secondary", |
99,37 → 105,60 |
dtlb_data_in_write(data.value); |
} |
|
void dtlb_pte_copy(pte_t *t) |
{ |
} |
|
/** ITLB miss handler. */ |
void fast_instruction_access_mmu_miss(void) |
void fast_instruction_access_mmu_miss(int n, istate_t *istate) |
{ |
panic("%s\n", __FUNCTION__); |
} |
|
/** DTLB miss handler. */ |
void fast_data_access_mmu_miss(void) |
/** DTLB miss handler. |
* |
* Note that some faults (e.g. kernel faults) were already resolved |
* by the low-level, assembly language part of the fast_data_access_mmu_miss |
* handler. |
*/ |
void fast_data_access_mmu_miss(int n, istate_t *istate) |
{ |
tlb_tag_access_reg_t tag; |
uintptr_t tpc; |
char *tpc_str; |
uintptr_t va; |
pte_t *t; |
|
tag.value = dtlb_tag_access_read(); |
if (tag.context != ASID_KERNEL || tag.vpn == 0) { |
tpc = tpc_read(); |
tpc_str = get_symtab_entry(tpc); |
va = tag.vpn * PAGE_SIZE; |
if (tag.context == ASID_KERNEL) { |
if (!tag.vpn) { |
/* NULL access in kernel */ |
do_fast_data_access_mmu_miss_fault(istate, __FUNCTION__); |
} |
do_fast_data_access_mmu_miss_fault(istate, "Unexpected kernel page fault."); |
} |
|
printf("Faulting page: %p, ASID=%d\n", tag.vpn * PAGE_SIZE, tag.context); |
printf("TPC=%p, (%s)\n", tpc, tpc_str ? tpc_str : "?"); |
panic("%s\n", __FUNCTION__); |
page_table_lock(AS, true); |
t = page_mapping_find(AS, va); |
if (t) { |
/* |
* The mapping was found in the software page hash table. |
* Insert it into DTLB. |
*/ |
dtlb_pte_copy(t); |
page_table_unlock(AS, true); |
} else { |
/* |
* Forward the page fault to the address space page fault handler. |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { |
do_fast_data_access_mmu_miss_fault(istate, __FUNCTION__); |
} |
} |
|
/* |
* Identity map piece of faulting kernel address space. |
*/ |
dtlb_insert_mapping(tag.vpn * PAGE_SIZE, tag.vpn * FRAME_SIZE, PAGESIZE_8K, false, true); |
} |
|
/** DTLB protection fault handler. */ |
void fast_data_access_protection(void) |
void fast_data_access_protection(int n, istate_t *istate) |
{ |
panic("%s\n", __FUNCTION__); |
} |
161,6 → 190,20 |
|
} |
|
void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str) |
{ |
tlb_tag_access_reg_t tag; |
uintptr_t va; |
char *tpc_str = get_symtab_entry(istate->tpc); |
|
tag.value = dtlb_tag_access_read(); |
va = tag.vpn * PAGE_SIZE; |
|
printf("Faulting page: %p, ASID=%d\n", va, tag.context); |
printf("TPC=%p, (%s)\n", istate->tpc, tpc_str); |
panic("%s\n", str); |
} |
|
/** Invalidate all unlocked ITLB and DTLB entries. */ |
void tlb_invalidate_all(void) |
{ |