54,10 → 54,10 |
#include <arch/mm/tsb.h> |
#endif |
|
static void dtlb_pte_copy(pte_t *t, bool ro); |
static void itlb_pte_copy(pte_t *t); |
static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const |
char *str); |
static void dtlb_pte_copy(pte_t *t, index_t index, bool ro); |
static void itlb_pte_copy(pte_t *t, index_t index); |
static void do_fast_instruction_access_mmu_miss_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, |
92,8 → 92,8 |
* @param locked True for permanent mappings, false otherwise. |
* @param cacheable True if the mapping is cacheable, false otherwise. |
*/ |
void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool |
locked, bool cacheable) |
void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, |
bool locked, bool cacheable) |
{ |
tlb_tag_access_reg_t tag; |
tlb_data_t data; |
127,10 → 127,11 |
/** 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. |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
* @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) |
void dtlb_pte_copy(pte_t *t, index_t index, bool ro) |
{ |
tlb_tag_access_reg_t tag; |
tlb_data_t data; |
137,8 → 138,8 |
page_address_t pg; |
frame_address_t fr; |
|
pg.address = t->page; |
fr.address = t->frame; |
pg.address = t->page + (index << MMU_PAGE_WIDTH); |
fr.address = t->frame + (index << MMU_PAGE_WIDTH); |
|
tag.value = 0; |
tag.context = t->as->asid; |
165,8 → 166,9 |
/** Copy PTE to ITLB. |
* |
* @param t Page Table Entry to be copied. |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
*/ |
void itlb_pte_copy(pte_t *t) |
void itlb_pte_copy(pte_t *t, index_t index) |
{ |
tlb_tag_access_reg_t tag; |
tlb_data_t data; |
173,8 → 175,8 |
page_address_t pg; |
frame_address_t fr; |
|
pg.address = t->page; |
fr.address = t->frame; |
pg.address = t->page + (index << MMU_PAGE_WIDTH); |
fr.address = t->frame + (index << MMU_PAGE_WIDTH); |
|
tag.value = 0; |
tag.context = t->as->asid; |
199,6 → 201,7 |
void fast_instruction_access_mmu_miss(int n, istate_t *istate) |
{ |
uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE); |
index_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE; |
pte_t *t; |
|
page_table_lock(AS, true); |
209,9 → 212,9 |
* Insert it into ITLB. |
*/ |
t->a = true; |
itlb_pte_copy(t); |
itlb_pte_copy(t, index); |
#ifdef CONFIG_TSB |
itsb_pte_copy(t); |
itsb_pte_copy(t, index); |
#endif |
page_table_unlock(AS, true); |
} else { |
236,10 → 239,12 |
{ |
tlb_tag_access_reg_t tag; |
uintptr_t va; |
index_t index; |
pte_t *t; |
|
tag.value = dtlb_tag_access_read(); |
va = tag.vpn << PAGE_WIDTH; |
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE); |
index = tag.vpn % MMU_PAGES_PER_PAGE; |
|
if (tag.context == ASID_KERNEL) { |
if (!tag.vpn) { |
259,14 → 264,15 |
* Insert it into DTLB. |
*/ |
t->a = true; |
dtlb_pte_copy(t, true); |
dtlb_pte_copy(t, index, true); |
#ifdef CONFIG_TSB |
dtsb_pte_copy(t, true); |
dtsb_pte_copy(t, index, true); |
#endif |
page_table_unlock(AS, true); |
} else { |
/* |
* Forward the page fault to the address space page fault handler. |
* 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) { |
281,10 → 287,12 |
{ |
tlb_tag_access_reg_t tag; |
uintptr_t va; |
index_t index; |
pte_t *t; |
|
tag.value = dtlb_tag_access_read(); |
va = tag.vpn << PAGE_WIDTH; |
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE); |
index = tag.vpn % MMU_PAGES_PER_PAGE; /* 16K-page emulation */ |
|
page_table_lock(AS, true); |
t = page_mapping_find(AS, va); |
296,10 → 304,11 |
*/ |
t->a = true; |
t->d = true; |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY, va); |
dtlb_pte_copy(t, false); |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY, |
va + index * MMU_PAGE_SIZE); |
dtlb_pte_copy(t, index, false); |
#ifdef CONFIG_TSB |
dtsb_pte_copy(t, false); |
dtsb_pte_copy(t, index, false); |
#endif |
page_table_unlock(AS, true); |
} else { |
348,8 → 357,8 |
|
} |
|
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const char |
*str) |
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, |
const char *str) |
{ |
fault_if_from_uspace(istate, "%s\n", str); |
dump_istate(istate); |
356,12 → 365,12 |
panic("%s\n", str); |
} |
|
void do_fast_data_access_mmu_miss_fault(istate_t *istate, tlb_tag_access_reg_t |
tag, const char *str) |
void do_fast_data_access_mmu_miss_fault(istate_t *istate, |
tlb_tag_access_reg_t tag, const char *str) |
{ |
uintptr_t va; |
|
va = tag.vpn << PAGE_WIDTH; |
va = tag.vpn << MMU_PAGE_WIDTH; |
|
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va, |
tag.context); |
370,12 → 379,12 |
panic("%s\n", str); |
} |
|
void do_fast_data_access_protection_fault(istate_t *istate, tlb_tag_access_reg_t |
tag, const char *str) |
void do_fast_data_access_protection_fault(istate_t *istate, |
tlb_tag_access_reg_t tag, const char *str) |
{ |
uintptr_t va; |
|
va = tag.vpn << PAGE_WIDTH; |
va = tag.vpn << MMU_PAGE_WIDTH; |
|
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va, |
tag.context); |
481,11 → 490,11 |
ctx.context = asid; |
mmu_primary_context_write(ctx.v); |
|
for (i = 0; i < cnt; i++) { |
for (i = 0; i < cnt * MMU_PAGES_PER_PAGE; i++) { |
itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY, |
page + i * PAGE_SIZE); |
page + i * MMU_PAGE_SIZE); |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY, |
page + i * PAGE_SIZE); |
page + i * MMU_PAGE_SIZE); |
} |
|
mmu_primary_context_write(pc_save.v); |