void _optimsoc_itlb_miss(void) { optimsoc_page_dir_t dir; // Get current thread's page directory dir = _optimsoc_thread_get_pagedir_current(); VERIFY_DIR_ADDR(dir); // Load vaddr from EEAR uint32_t vaddr = or1k_mfspr(OR1K_SPR_SYS_EEAR_ADDR(0)); // Trace debug runtime_trace_itlb_miss(vaddr); // Lookup page optimsoc_pte_t pte = _optimsoc_vmm_lookup(dir, vaddr); if (pte) { // Update TLB _optimsoc_set_itlb(vaddr, pte); } else { // Raise page fault assert(_optimsoc_vmm_ifault_handler); _optimsoc_vmm_ifault_handler(vaddr); } }
void _optimsoc_ipage_fault(void) { // Load address from EEAR uint32_t vaddr = or1k_mfspr(OR1K_SPR_SYS_EEAR_ADDR(0)); // Call handler assert(_optimsoc_vmm_ifault_handler); _optimsoc_vmm_ifault_handler(vaddr); }
void itlb_miss() { struct optimsoc_scheduler_core *core_ctx; core_ctx = &optimsoc_scheduler_core[optimsoc_get_relcoreid()]; void *vaddr = (void*) or1k_mfspr(OR1K_SPR_SYS_EEAR_ADDR(0)); runtime_trace_itlb_miss(vaddr); /* Look up virtual address in the page table */ struct page_table_entry_t* entry; entry = find_page_entry(core_ctx->active_thread->task->page_table, vaddr); assert(entry != NULL); /* Write address back to ITLB */ arch_set_itlb(entry->vaddr_base, entry->paddr_base); }
void dtlb_miss() { struct optimsoc_scheduler_core *core_ctx; core_ctx = &optimsoc_scheduler_core[optimsoc_get_relcoreid()]; void *vaddr = (void*) or1k_mfspr(OR1K_SPR_SYS_EEAR_ADDR(0)); runtime_trace_dtlb_miss(vaddr); /* Look up virtual address in the page table */ struct page_table_entry_t* entry; entry = find_page_entry(core_ctx->active_thread->task->page_table, vaddr); if(entry != NULL) { /* Write address back to DTLB */ arch_set_dtlb(entry->vaddr_base, entry->paddr_base); } else { void *page = vmm_alloc_page(); assert(page != NULL); entry = malloc(sizeof(struct page_table_entry_t)); entry->vaddr_base = PAGE_BASE(vaddr); entry->paddr_base = page; printf("Allocated new data page %p and mapped to %p\n", entry->paddr_base, entry->vaddr_base); list_add_tail(core_ctx->active_thread->task->page_table, (void*)entry); runtime_trace_dtlb_allocate_page(page); arch_set_dtlb(entry->vaddr_base, entry->paddr_base); } }