Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 1864 → Rev 1865

/trunk/kernel/arch/sparc64/src/mm/tlb.c
52,9 → 52,9
 
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);
static void do_fast_data_access_protection_fault(istate_t *istate, const char *str);
static void do_fast_data_access_mmu_miss_fault(istate_t *istate, tlb_tag_access_reg_t tag, const char *str);
static void do_fast_data_access_protection_fault(istate_t *istate, tlb_tag_access_reg_t tag, const char *str);
 
char *context_encoding[] = {
"Primary",
213,13 → 213,14
pte_t *t;
 
tag.value = dtlb_tag_access_read();
va = tag.vpn * PAGE_SIZE;
va = tag.vpn << PAGE_WIDTH;
 
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, tag, __FUNCTION__);
}
do_fast_data_access_mmu_miss_fault(istate, "Unexpected kernel page fault.");
do_fast_data_access_mmu_miss_fault(istate, tag, "Unexpected kernel page fault.");
}
 
page_table_lock(AS, true);
238,7 → 239,7
*/
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__);
do_fast_data_access_mmu_miss_fault(istate, tag, __FUNCTION__);
}
}
}
251,7 → 252,7
pte_t *t;
 
tag.value = dtlb_tag_access_read();
va = tag.vpn * PAGE_SIZE;
va = tag.vpn << PAGE_WIDTH;
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
271,7 → 272,7
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
do_fast_data_access_protection_fault(istate, __FUNCTION__);
do_fast_data_access_protection_fault(istate, tag, __FUNCTION__);
}
}
}
311,14 → 312,12
panic("%s\n", str);
}
 
void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str)
void do_fast_data_access_mmu_miss_fault(istate_t *istate, tlb_tag_access_reg_t tag, 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;
va = tag.vpn << PAGE_WIDTH;
 
printf("Faulting page: %p, ASID=%d\n", va, tag.context);
printf("TPC=%p, (%s)\n", istate->tpc, tpc_str);
325,14 → 324,12
panic("%s\n", str);
}
 
void do_fast_data_access_protection_fault(istate_t *istate, const char *str)
void do_fast_data_access_protection_fault(istate_t *istate, tlb_tag_access_reg_t tag, 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;
va = tag.vpn << PAGE_WIDTH;
 
printf("Faulting page: %p, ASID=%d\n", va, tag.context);
printf("TPC=%p, (%s)\n", istate->tpc, tpc_str);
374,16 → 371,21
*/
void tlb_invalidate_asid(asid_t asid)
{
tlb_context_reg_t sc_save, ctx;
tlb_context_reg_t pc_save, ctx;
ctx.v = sc_save.v = mmu_secondary_context_read();
/* switch to nucleus because we are mapped by the primary context */
nucleus_enter();
ctx.v = pc_save.v = mmu_primary_context_read();
ctx.context = asid;
mmu_secondary_context_write(ctx.v);
mmu_primary_context_write(ctx.v);
itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_SECONDARY, 0);
dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_SECONDARY, 0);
itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0);
dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0);
mmu_secondary_context_write(sc_save.v);
mmu_primary_context_write(pc_save.v);
nucleus_leave();
}
 
/** Invalidate all ITLB and DTLB entries for specified page range in specified address space.
395,18 → 397,23
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
{
int i;
tlb_context_reg_t sc_save, ctx;
tlb_context_reg_t pc_save, ctx;
ctx.v = sc_save.v = mmu_secondary_context_read();
/* switch to nucleus because we are mapped by the primary context */
nucleus_enter();
ctx.v = pc_save.v = mmu_primary_context_read();
ctx.context = asid;
mmu_secondary_context_write(ctx.v);
mmu_primary_context_write(ctx.v);
for (i = 0; i < cnt; i++) {
itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY, page + i * PAGE_SIZE);
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY, page + i * PAGE_SIZE);
itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY, page + i * PAGE_SIZE);
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY, page + i * PAGE_SIZE);
}
mmu_secondary_context_write(sc_save.v);
mmu_primary_context_write(pc_save.v);
nucleus_leave();
}
 
/** @}