#include <types.h>
#include <synch.h>
#include <kern/errno.h>
#include <lib.h>
#include <thread.h>
#include <cpu.h>
#include <spl.h>
#include <wchan.h>
#include <current.h>
#include <machine/coremap.h>
#include <vm.h>
#include <vm/swap.h>
#include <vm/page.h>
#include <addrspace.h>
#include <machine/tlb.h>
struct spinlock slk_steal = SPINLOCK_INITIALIZER;
void
vm_bootstrap( void ) {
coremap_bootstrap();
swap_bootstrap();
}
int
vm_fault( int fault_type, vaddr_t fault_addr ) {
struct addrspace *as;
int res;
fault_addr &= PAGE_FRAME;
as = curthread->t_addrspace;
if( as == NULL )
return EFAULT;
res = as_fault( as, fault_type, fault_addr );
KASSERT( !lock_do_i_hold( giant_paging_lock ) );
return res;
}
void
vm_map( vaddr_t vaddr, paddr_t paddr, int writeable ) {
int ix;
int ix_tlb;
uint32_t tlb_hi;
uint32_t tlb_lo;
KASSERT( (paddr & PAGE_FRAME) == paddr );
KASSERT( paddr != INVALID_PADDR );
LOCK_COREMAP();
ix = PADDR_TO_COREMAP( paddr );
KASSERT( coremap_is_wired( paddr ) );
ix_tlb = tlb_probe( vaddr, 0 );
if( ix_tlb < 0 ) {
ix_tlb = tlb_get_free_slot();
KASSERT( ix_tlb >= 0 && ix_tlb < NUM_TLB );
coremap[ix].cme_tlb_ix = ix_tlb;
coremap[ix].cme_cpu = curcpu->c_number;
}
else {
KASSERT( coremap[ix].cme_tlb_ix == ix_tlb );
KASSERT( coremap[ix].cme_cpu == curcpu->c_number );
}
tlb_hi = vaddr & TLBHI_VPAGE;
tlb_lo = (paddr & TLBLO_PPAGE) | TLBLO_VALID;
if( writeable )
tlb_lo |= TLBLO_DIRTY;
tlb_write( tlb_hi, tlb_lo, ix_tlb );
UNLOCK_COREMAP();
}
void
vm_unmap( vaddr_t vaddr ) {
LOCK_COREMAP();
tlb_unmap( vaddr );
UNLOCK_COREMAP();
}