require '_h2ph_pre.ph';

no warnings 'redefine';

unless(defined(&_AMD64_PMAP_H_)) {
    eval 'sub _AMD64_PMAP_H_ () {1;}' unless defined(&_AMD64_PMAP_H_);
    unless(defined(&_LOCORE)) {
	require 'machine/cpufunc.ph';
	require 'machine/pte.ph';
	require 'machine/segments.ph';
	require 'uvm/uvm_object.ph';
    }
    eval 'sub VIRT_BITS () {48;}' unless defined(&VIRT_BITS);
    eval 'sub PHYS_BITS () {40;}' unless defined(&PHYS_BITS);
    eval 'sub VA_SIGN_MASK () {0xffff000000000000;}' unless defined(&VA_SIGN_MASK);
    eval 'sub VA_SIGN_NEG {
        my($va) = @_;
	    eval q((($va) |  &VA_SIGN_MASK));
    }' unless defined(&VA_SIGN_NEG);
    eval 'sub VA_SIGN_POS {
        my($va) = @_;
	    eval q((($va) & ~ &VA_SIGN_MASK));
    }' unless defined(&VA_SIGN_POS);
    eval 'sub L4_SLOT_PTE () {255;}' unless defined(&L4_SLOT_PTE);
    eval 'sub L4_SLOT_KERN () {256;}' unless defined(&L4_SLOT_KERN);
    eval 'sub L4_SLOT_KERNBASE () {511;}' unless defined(&L4_SLOT_KERNBASE);
    eval 'sub L4_SLOT_APTE () {510;}' unless defined(&L4_SLOT_APTE);
    eval 'sub L4_SLOT_DIRECT () {509;}' unless defined(&L4_SLOT_DIRECT);
    eval 'sub L4_SLOT_DIRECT_NC () {508;}' unless defined(&L4_SLOT_DIRECT_NC);
    eval 'sub PDIR_SLOT_KERN () { &L4_SLOT_KERN;}' unless defined(&PDIR_SLOT_KERN);
    eval 'sub PDIR_SLOT_PTE () { &L4_SLOT_PTE;}' unless defined(&PDIR_SLOT_PTE);
    eval 'sub PDIR_SLOT_APTE () { &L4_SLOT_APTE;}' unless defined(&PDIR_SLOT_APTE);
    eval 'sub PDIR_SLOT_DIRECT () { &L4_SLOT_DIRECT;}' unless defined(&PDIR_SLOT_DIRECT);
    eval 'sub PDIR_SLOT_DIRECT_NC () { &L4_SLOT_DIRECT_NC;}' unless defined(&PDIR_SLOT_DIRECT_NC);
    eval 'sub PTE_BASE () {(( &pt_entry_t *) ( &L4_SLOT_PTE *  &NBPD_L4));}' unless defined(&PTE_BASE);
    eval 'sub APTE_BASE () {(( &pt_entry_t *) ( &VA_SIGN_NEG(( &L4_SLOT_APTE *  &NBPD_L4))));}' unless defined(&APTE_BASE);
    eval 'sub PMAP_DIRECT_BASE () {( &VA_SIGN_NEG(( &L4_SLOT_DIRECT *  &NBPD_L4)));}' unless defined(&PMAP_DIRECT_BASE);
    eval 'sub PMAP_DIRECT_END () {( &VA_SIGN_NEG((( &L4_SLOT_DIRECT + 1) *  &NBPD_L4)));}' unless defined(&PMAP_DIRECT_END);
    eval 'sub PMAP_DIRECT_BASE_NC () {( &VA_SIGN_NEG(( &L4_SLOT_DIRECT_NC *  &NBPD_L4)));}' unless defined(&PMAP_DIRECT_BASE_NC);
    eval 'sub PMAP_DIRECT_END_NC () {( &VA_SIGN_NEG((( &L4_SLOT_DIRECT_NC + 1) *  &NBPD_L4)));}' unless defined(&PMAP_DIRECT_END_NC);
    eval 'sub L1_BASE () { &PTE_BASE;}' unless defined(&L1_BASE);
    eval 'sub AL1_BASE () { &APTE_BASE;}' unless defined(&AL1_BASE);
    eval 'sub L2_BASE () {(( &pd_entry_t *)( &L1_BASE +  &L4_SLOT_PTE *  &NBPD_L3));}' unless defined(&L2_BASE);
    eval 'sub L3_BASE () {(( &pd_entry_t *)( &L2_BASE +  &L4_SLOT_PTE *  &NBPD_L2));}' unless defined(&L3_BASE);
    eval 'sub L4_BASE () {(( &pd_entry_t *)( &L3_BASE +  &L4_SLOT_PTE *  &NBPD_L1));}' unless defined(&L4_BASE);
    eval 'sub AL2_BASE () {(( &pd_entry_t *)( &AL1_BASE +  &L4_SLOT_PTE *  &NBPD_L3));}' unless defined(&AL2_BASE);
    eval 'sub AL3_BASE () {(( &pd_entry_t *)( &AL2_BASE +  &L4_SLOT_PTE *  &NBPD_L2));}' unless defined(&AL3_BASE);
    eval 'sub AL4_BASE () {(( &pd_entry_t *)( &AL3_BASE +  &L4_SLOT_PTE *  &NBPD_L1));}' unless defined(&AL4_BASE);
    eval 'sub PDP_PDE () {( &L4_BASE +  &PDIR_SLOT_PTE);}' unless defined(&PDP_PDE);
    eval 'sub APDP_PDE () {( &L4_BASE +  &PDIR_SLOT_APTE);}' unless defined(&APDP_PDE);
    eval 'sub PDP_BASE () { &L4_BASE;}' unless defined(&PDP_BASE);
    eval 'sub APDP_BASE () { &AL4_BASE;}' unless defined(&APDP_BASE);
    eval 'sub NKL4_MAX_ENTRIES () {1;}' unless defined(&NKL4_MAX_ENTRIES);
    eval 'sub NKL3_MAX_ENTRIES () {( &NKL4_MAX_ENTRIES * 512);}' unless defined(&NKL3_MAX_ENTRIES);
    eval 'sub NKL2_MAX_ENTRIES () {( &NKL3_MAX_ENTRIES * 512);}' unless defined(&NKL2_MAX_ENTRIES);
    eval 'sub NKL1_MAX_ENTRIES () {( &NKL2_MAX_ENTRIES * 512);}' unless defined(&NKL1_MAX_ENTRIES);
    eval 'sub NKL4_KIMG_ENTRIES () {1;}' unless defined(&NKL4_KIMG_ENTRIES);
    eval 'sub NKL3_KIMG_ENTRIES () {1;}' unless defined(&NKL3_KIMG_ENTRIES);
    eval 'sub NKL2_KIMG_ENTRIES () {8;}' unless defined(&NKL2_KIMG_ENTRIES);
    eval 'sub NDML4_ENTRIES () {1;}' unless defined(&NDML4_ENTRIES);
    eval 'sub NDML3_ENTRIES () {1;}' unless defined(&NDML3_ENTRIES);
    eval 'sub NDML2_ENTRIES () {4;}' unless defined(&NDML2_ENTRIES);
    eval 'sub NKL4_START_ENTRIES () {0;}' unless defined(&NKL4_START_ENTRIES);
    eval 'sub NKL3_START_ENTRIES () {0;}' unless defined(&NKL3_START_ENTRIES);
    eval 'sub NKL2_START_ENTRIES () {0;}' unless defined(&NKL2_START_ENTRIES);
    eval 'sub NKL1_START_ENTRIES () {0;}' unless defined(&NKL1_START_ENTRIES);
    eval 'sub NTOPLEVEL_PDES () {( &PAGE_SIZE / ($sizeof{ &pd_entry_t}));}' unless defined(&NTOPLEVEL_PDES);
    eval 'sub KERNSPACE () {( &NKL4_ENTRIES *  &NBPD_L4);}' unless defined(&KERNSPACE);
    eval 'sub NPDPG () {( &PAGE_SIZE / $sizeof{ &pd_entry_t});}' unless defined(&NPDPG);
    eval 'sub ptei {
        my($VA) = @_;
	    eval q(((( &VA_SIGN_POS($VA)) &  &L1_MASK) >>  &L1_SHIFT));
    }' unless defined(&ptei);
    eval 'sub pl1_pi {
        my($VA) = @_;
	    eval q(((( &VA_SIGN_POS($VA)) &  &L1_MASK) >>  &L1_SHIFT));
    }' unless defined(&pl1_pi);
    eval 'sub pl2_pi {
        my($VA) = @_;
	    eval q(((( &VA_SIGN_POS($VA)) &  &L2_MASK) >>  &L2_SHIFT));
    }' unless defined(&pl2_pi);
    eval 'sub pl3_pi {
        my($VA) = @_;
	    eval q(((( &VA_SIGN_POS($VA)) &  &L3_MASK) >>  &L3_SHIFT));
    }' unless defined(&pl3_pi);
    eval 'sub pl4_pi {
        my($VA) = @_;
	    eval q(((( &VA_SIGN_POS($VA)) &  &L4_MASK) >>  &L4_SHIFT));
    }' unless defined(&pl4_pi);
    eval 'sub pl1_i {
        my($VA) = @_;
	    eval q(((( &VA_SIGN_POS($VA)) &  &L1_FRAME) >>  &L1_SHIFT));
    }' unless defined(&pl1_i);
    eval 'sub pl2_i {
        my($VA) = @_;
	    eval q(((( &VA_SIGN_POS($VA)) &  &L2_FRAME) >>  &L2_SHIFT));
    }' unless defined(&pl2_i);
    eval 'sub pl3_i {
        my($VA) = @_;
	    eval q(((( &VA_SIGN_POS($VA)) &  &L3_FRAME) >>  &L3_SHIFT));
    }' unless defined(&pl3_i);
    eval 'sub pl4_i {
        my($VA) = @_;
	    eval q(((( &VA_SIGN_POS($VA)) &  &L4_FRAME) >>  &L4_SHIFT));
    }' unless defined(&pl4_i);
    eval 'sub pl_i {
        my($va, $lvl) = @_;
	    eval q(((( &VA_SIGN_POS($va)) &  $ptp_masks[($lvl)-1]) >>  $ptp_shifts[($lvl)-1]));
    }' unless defined(&pl_i);
    eval 'sub PTP_MASK_INITIALIZER () {{  &L1_FRAME,  &L2_FRAME,  &L3_FRAME,  &L4_FRAME };}' unless defined(&PTP_MASK_INITIALIZER);
    eval 'sub PTP_SHIFT_INITIALIZER () {{  &L1_SHIFT,  &L2_SHIFT,  &L3_SHIFT,  &L4_SHIFT };}' unless defined(&PTP_SHIFT_INITIALIZER);
    eval 'sub NKPTP_INITIALIZER () {{  &NKL1_START_ENTRIES,  &NKL2_START_ENTRIES,  &NKL3_START_ENTRIES,  &NKL4_START_ENTRIES };}' unless defined(&NKPTP_INITIALIZER);
    eval 'sub NKPTPMAX_INITIALIZER () {{  &NKL1_MAX_ENTRIES,  &NKL2_MAX_ENTRIES,  &NKL3_MAX_ENTRIES,  &NKL4_MAX_ENTRIES };}' unless defined(&NKPTPMAX_INITIALIZER);
    eval 'sub NBPD_INITIALIZER () {{  &NBPD_L1,  &NBPD_L2,  &NBPD_L3,  &NBPD_L4 };}' unless defined(&NBPD_INITIALIZER);
    eval 'sub PDES_INITIALIZER () {{  &L2_BASE,  &L3_BASE,  &L4_BASE };}' unless defined(&PDES_INITIALIZER);
    eval 'sub APDES_INITIALIZER () {{  &AL2_BASE,  &AL3_BASE,  &AL4_BASE };}' unless defined(&APDES_INITIALIZER);
    eval 'sub ptp_va2o {
        my($va, $lvl) = @_;
	    eval q(( &pl_i($va, ($lvl)+1) *  &PAGE_SIZE));
    }' unless defined(&ptp_va2o);
    eval 'sub PTP_LEVELS () {4;}' unless defined(&PTP_LEVELS);
    eval 'sub PG_W () { &PG_AVAIL1;}' unless defined(&PG_W);
    eval 'sub PG_PVLIST () { &PG_AVAIL2;}' unless defined(&PG_PVLIST);
    eval 'sub NPTECL () {8;}' unless defined(&NPTECL);
    if(defined( &_KERNEL)  && !defined( &_LOCORE)) {
	eval 'sub pm_lock () { ($pm_obj[0]->{vmobjlock});}' unless defined(&pm_lock);
	eval 'sub pm_obj_l1 () { $pm_obj[0];}' unless defined(&pm_obj_l1);
	eval 'sub pm_obj_l2 () { $pm_obj[1];}' unless defined(&pm_obj_l2);
	eval 'sub pm_obj_l3 () { $pm_obj[2];}' unless defined(&pm_obj_l3);
	eval 'sub PG_PMAP_MOD () { &PG_PMAP0;}' unless defined(&PG_PMAP_MOD);
	eval 'sub PG_PMAP_REF () { &PG_PMAP1;}' unless defined(&PG_PMAP_REF);
	eval 'sub PMAP_RR_MAX () {16;}' unless defined(&PMAP_RR_MAX);
	eval 'sub pmap_kernel () {
	    eval q(( &kernel_pmap_store));
	}' unless defined(&pmap_kernel);
	eval 'sub pmap_resident_count {
	    my($pmap) = @_;
    	    eval q((($pmap)-> ($pm_stats->{resident_count})));
	}' unless defined(&pmap_resident_count);
	eval 'sub pmap_wired_count {
	    my($pmap) = @_;
    	    eval q((($pmap)-> ($pm_stats->{wired_count})));
	}' unless defined(&pmap_wired_count);
	eval 'sub pmap_update {
	    my($pmap) = @_;
    	    eval q();
	}' unless defined(&pmap_update);
	eval 'sub pmap_clear_modify {
	    my($pg) = @_;
    	    eval q( &pmap_clear_attrs($pg,  &PG_M));
	}' unless defined(&pmap_clear_modify);
	eval 'sub pmap_clear_reference {
	    my($pg) = @_;
    	    eval q( &pmap_clear_attrs($pg,  &PG_U));
	}' unless defined(&pmap_clear_reference);
	eval 'sub pmap_copy {
	    my($DP,$SP,$D,$L,$S) = @_;
    	    eval q();
	}' unless defined(&pmap_copy);
	eval 'sub pmap_is_modified {
	    my($pg) = @_;
    	    eval q( &pmap_test_attrs($pg,  &PG_M));
	}' unless defined(&pmap_is_modified);
	eval 'sub pmap_is_referenced {
	    my($pg) = @_;
    	    eval q( &pmap_test_attrs($pg,  &PG_U));
	}' unless defined(&pmap_is_referenced);
	eval 'sub pmap_move {
	    my($DP,$SP,$D,$L,$S) = @_;
    	    eval q();
	}' unless defined(&pmap_move);
	eval 'sub pmap_phys_address {
	    my($ppn) = @_;
    	    eval q( &ptoa($ppn));
	}' unless defined(&pmap_phys_address);
	eval 'sub pmap_valid_entry {
	    my($E) = @_;
    	    eval q((($E) &  &PG_V));
	}' unless defined(&pmap_valid_entry);
	eval 'sub pmap_proc_iflush {
	    my($p,$va,$len) = @_;
    	    eval q();
	}' unless defined(&pmap_proc_iflush);
	eval 'sub pmap_unuse_final {
	    my($p) = @_;
    	    eval q();
	}' unless defined(&pmap_unuse_final);
	eval 'sub pmap_remove_holes {
	    my($map) = @_;
    	    eval q( &do { }  &while (0));
	}' unless defined(&pmap_remove_holes);
	if(defined(&MULTIPROCESSOR)) {
	} else {
	    eval 'sub pmap_tlb_shootwait () {
	        eval q();
	    }' unless defined(&pmap_tlb_shootwait);
	}
	eval 'sub PMAP_STEAL_MEMORY () {1;}' unless defined(&PMAP_STEAL_MEMORY);
	eval 'sub PMAP_GROWKERNEL () {1;}' unless defined(&PMAP_GROWKERNEL);
	eval 'sub PMAP_PAGEIDLEZERO {
	    my($pg) = @_;
    	    eval q( &pmap_pageidlezero(($pg)));
	}' unless defined(&PMAP_PAGEIDLEZERO);
# some #ifdef were dropped here -- fill in the blanks
	eval 'sub kvtopte {
	    my($va) = @_;
    	    eval q({ ( &PTE_BASE +  &pl1_i($va)); });
	}' unless defined(&kvtopte);
	eval 'sub pmap_pte_set {
	    my($p, $n) = @_;
    	    eval q( &x86_atomic_testset_u64($p, $n));
	}' unless defined(&pmap_pte_set);
	eval 'sub pmap_pte_clearbits {
	    my($p, $b) = @_;
    	    eval q( &x86_atomic_clearbits_u64($p, $b));
	}' unless defined(&pmap_pte_clearbits);
	eval 'sub pmap_pte_setbits {
	    my($p, $b) = @_;
    	    eval q( &x86_atomic_setbits_u64($p, $b));
	}' unless defined(&pmap_pte_setbits);
	eval 'sub pmap_cpu_has_pg_n () {
	    eval q((1));
	}' unless defined(&pmap_cpu_has_pg_n);
	eval 'sub pmap_cpu_has_invlpg () {(1);}' unless defined(&pmap_cpu_has_invlpg);
	eval 'sub PMAP_DIRECT_MAP {
	    my($pa) = @_;
    	    eval q((( &vaddr_t) &PMAP_DIRECT_BASE + $pa));
	}' unless defined(&PMAP_DIRECT_MAP);
	eval 'sub PMAP_DIRECT_UNMAP {
	    my($va) = @_;
    	    eval q((( &paddr_t)$va -  &PMAP_DIRECT_BASE));
	}' unless defined(&PMAP_DIRECT_UNMAP);
	eval 'sub pmap_map_direct {
	    my($pg) = @_;
    	    eval q( &PMAP_DIRECT_MAP( &VM_PAGE_TO_PHYS($pg)));
	}' unless defined(&pmap_map_direct);
	eval 'sub pmap_unmap_direct {
	    my($va) = @_;
    	    eval q( &PHYS_TO_VM_PAGE( &PMAP_DIRECT_UNMAP($va)));
	}' unless defined(&pmap_unmap_direct);
	eval 'sub PMAP_DIRECT_NC_MAP {
	    my($pa) = @_;
    	    eval q((( &vaddr_t) &PMAP_DIRECT_BASE_NC + $pa));
	}' unless defined(&PMAP_DIRECT_NC_MAP);
	eval 'sub PMAP_DIRECT_NC_UNMAP {
	    my($va) = @_;
    	    eval q((( &paddr_t)$va -  &PMAP_DIRECT_BASE_NC));
	}' unless defined(&PMAP_DIRECT_NC_UNMAP);
	eval 'sub pmap_map_nc_direct {
	    my($pg) = @_;
    	    eval q( &PMAP_DIRECT_NC_MAP( &VM_PAGE_TO_PHYS($pg)));
	}' unless defined(&pmap_map_nc_direct);
	eval 'sub pmap_unmap_nc_direct {
	    my($va) = @_;
    	    eval q( &PHYS_TO_VM_PAGE( &PMAP_DIRECT_NC_UNMAP($va)));
	}' unless defined(&pmap_unmap_nc_direct);
	eval 'sub __HAVE_PMAP_DIRECT () {1;}' unless defined(&__HAVE_PMAP_DIRECT);
    }
}
1;
