Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 1851 → Rev 1852

/trunk/kernel/arch/sparc64/src/mm/tlb.c
50,8 → 50,10
#include <arch/asm.h>
#include <symtab.h>
 
static void dtlb_pte_copy(pte_t *t);
static void dtlb_pte_copy(pte_t *t, bool ro);
static void itlb_pte_copy(pte_t *t);
static void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str);
static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const char *str);
 
char *context_encoding[] = {
"Primary",
105,14 → 107,96
dtlb_data_in_write(data.value);
}
 
void dtlb_pte_copy(pte_t *t)
/** Copy PTE to TLB.
*
* @param t Page Table Entry to be copied.
* @param ro If true, the entry will be created read-only, regardless of its w field.
*/
void dtlb_pte_copy(pte_t *t, bool ro)
{
tlb_tag_access_reg_t tag;
tlb_data_t data;
page_address_t pg;
frame_address_t fr;
 
pg.address = t->page;
fr.address = t->frame;
 
tag.value = 0;
tag.context = t->as->asid;
tag.vpn = pg.vpn;
dtlb_tag_access_write(tag.value);
data.value = 0;
data.v = true;
data.size = PAGESIZE_8K;
data.pfn = fr.pfn;
data.l = false;
data.cp = t->c;
data.cv = t->c;
data.p = t->p;
data.w = ro ? false : t->w;
data.g = t->g;
dtlb_data_in_write(data.value);
}
 
void itlb_pte_copy(pte_t *t)
{
tlb_tag_access_reg_t tag;
tlb_data_t data;
page_address_t pg;
frame_address_t fr;
 
pg.address = t->page;
fr.address = t->frame;
 
tag.value = 0;
tag.context = t->as->asid;
tag.vpn = pg.vpn;
itlb_tag_access_write(tag.value);
data.value = 0;
data.v = true;
data.size = PAGESIZE_8K;
data.pfn = fr.pfn;
data.l = false;
data.cp = t->c;
data.cv = t->c;
data.p = t->p;
data.w = false;
data.g = t->g;
itlb_data_in_write(data.value);
}
 
/** ITLB miss handler. */
void fast_instruction_access_mmu_miss(int n, istate_t *istate)
{
panic("%s\n", __FUNCTION__);
uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
pte_t *t;
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
if (t && PTE_EXECUTABLE(t)) {
/*
* The mapping was found in the software page hash table.
* Insert it into ITLB.
*/
t->a = true;
itlb_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_EXEC, istate) == AS_PF_FAULT) {
do_fast_instruction_access_mmu_miss_fault(istate, __FUNCTION__);
}
}
}
 
/** DTLB miss handler.
144,7 → 228,8
* The mapping was found in the software page hash table.
* Insert it into DTLB.
*/
dtlb_pte_copy(t);
t->a = true;
dtlb_pte_copy(t, true);
page_table_unlock(AS, true);
} else {
/*
190,6 → 275,14
 
}
 
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const char *str)
{
char *tpc_str = get_symtab_entry(istate->tpc);
 
printf("TPC=%p, (%s)\n", istate->tpc, tpc_str);
panic("%s\n", str);
}
 
void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str)
{
tlb_tag_access_reg_t tag;