require '_h2ph_pre.ph';

no warnings qw(redefine misc);

unless(defined(&_AARCH64_PMAP_H_)) {
    eval 'sub _AARCH64_PMAP_H_ () {1;}' unless defined(&_AARCH64_PMAP_H_);
    if(defined(&__aarch64__)) {
	if(defined(&_KERNEL)) {
	    if(defined(&_KERNEL_OPT)) {
		require './aarch64/opt_kasan.ph';
		require './aarch64/opt_pmap.ph';
	    }
	    require 'sys/types.ph';
	    require 'sys/pool.ph';
	    require 'sys/queue.ph';
	    require 'uvm/uvm_pglist.ph';
	    require 'aarch64/armreg.ph';
	    require 'aarch64/pte.ph';
	    eval 'sub PMAP_TLB_MAX () {1;}' unless defined(&PMAP_TLB_MAX);
	    if((defined(&PMAP_TLB_MAX) ? &PMAP_TLB_MAX : undef) > 1) {
		eval 'sub PMAP_TLB_NEED_SHOOTDOWN () {1;}' unless defined(&PMAP_TLB_NEED_SHOOTDOWN);
	    }
	    eval 'sub PMAP_TLB_FLUSH_ASID_ON_RESET () { &true;}' unless defined(&PMAP_TLB_FLUSH_ASID_ON_RESET);
	    eval 'sub PMAP_TLB_NUM_PIDS () {65536;}' unless defined(&PMAP_TLB_NUM_PIDS);
	    eval 'sub PMAP_TLB_BITMAP_LENGTH () { &PMAP_TLB_NUM_PIDS;}' unless defined(&PMAP_TLB_BITMAP_LENGTH);
	    eval 'sub cpu_set_tlb_info {
	        my($ci, $ti) = @_;
    		eval q((( &void)(($ci)-> &ci_tlb_info = ($ti))));
	    }' unless defined(&cpu_set_tlb_info);
	    if((defined(&PMAP_TLB_MAX) ? &PMAP_TLB_MAX : undef) > 1) {
		eval 'sub cpu_tlb_info {
		    my($ci) = @_;
    		    eval q((($ci)-> &ci_tlb_info));
		}' unless defined(&cpu_tlb_info);
	    } else {
		eval 'sub cpu_tlb_info {
		    my($ci) = @_;
    		    eval q(( &pmap_tlb0_info));
		}' unless defined(&cpu_tlb_info);
	    }
	    eval 'sub pmap_md_tlb_asid_max {
	        my($void) = @_;
    		eval q({  &switch ( &__SHIFTOUT( &reg_id_aa64mmfr0_el1_read(),  &ID_AA64MMFR0_EL1_ASIDBITS)) {  &case  &ID_AA64MMFR0_EL1_ASIDBITS_8BIT: (1 << 8) - 1;  &case  &ID_AA64MMFR0_EL1_ASIDBITS_16BIT: (1 << 16) - 1;  &default: 0; } });
	    }' unless defined(&pmap_md_tlb_asid_max);
	    require 'uvm/pmap/tlb.ph';
	    require 'uvm/pmap/pmap_tlb.ph';
	    eval 'sub KERNEL_PID () {0;}' unless defined(&KERNEL_PID);
	    eval 'sub LX_BLKPAG_ATTR_NORMAL_WB () { &__SHIFTIN(0,  &LX_BLKPAG_ATTR_INDX);}' unless defined(&LX_BLKPAG_ATTR_NORMAL_WB);
	    eval 'sub LX_BLKPAG_ATTR_NORMAL_NC () { &__SHIFTIN(1,  &LX_BLKPAG_ATTR_INDX);}' unless defined(&LX_BLKPAG_ATTR_NORMAL_NC);
	    eval 'sub LX_BLKPAG_ATTR_NORMAL_WT () { &__SHIFTIN(2,  &LX_BLKPAG_ATTR_INDX);}' unless defined(&LX_BLKPAG_ATTR_NORMAL_WT);
	    eval 'sub LX_BLKPAG_ATTR_DEVICE_MEM () { &__SHIFTIN(3,  &LX_BLKPAG_ATTR_INDX);}' unless defined(&LX_BLKPAG_ATTR_DEVICE_MEM);
	    eval 'sub LX_BLKPAG_ATTR_DEVICE_MEM_NP () { &__SHIFTIN(4,  &LX_BLKPAG_ATTR_INDX);}' unless defined(&LX_BLKPAG_ATTR_DEVICE_MEM_NP);
	    eval 'sub LX_BLKPAG_ATTR_MASK () { &LX_BLKPAG_ATTR_INDX;}' unless defined(&LX_BLKPAG_ATTR_MASK);
	    eval 'sub lxpde_pa {
	        my($pde) = @_;
    		eval q((( &paddr_t)(($pde) &  &LX_TBL_PA)));
	    }' unless defined(&lxpde_pa);
	    eval 'sub lxpde_valid {
	        my($pde) = @_;
    		eval q(((($pde) &  &LX_VALID) ==  &LX_VALID));
	    }' unless defined(&lxpde_valid);
	    eval 'sub l0pde_pa {
	        my($pde) = @_;
    		eval q( &lxpde_pa($pde));
	    }' unless defined(&l0pde_pa);
	    eval 'sub l0pde_index {
	        my($v) = @_;
    		eval q(((( &vaddr_t)($v) &  &L0_ADDR_BITS) >>  &L0_SHIFT));
	    }' unless defined(&l0pde_index);
	    eval 'sub l0pde_valid {
	        my($pde) = @_;
    		eval q( &lxpde_valid($pde));
	    }' unless defined(&l0pde_valid);
	    eval 'sub l1pde_pa {
	        my($pde) = @_;
    		eval q( &lxpde_pa($pde));
	    }' unless defined(&l1pde_pa);
	    eval 'sub l1pde_index {
	        my($v) = @_;
    		eval q(((( &vaddr_t)($v) &  &L1_ADDR_BITS) >>  &L1_SHIFT));
	    }' unless defined(&l1pde_index);
	    eval 'sub l1pde_valid {
	        my($pde) = @_;
    		eval q( &lxpde_valid($pde));
	    }' unless defined(&l1pde_valid);
	    eval 'sub l1pde_is_block {
	        my($pde) = @_;
    		eval q(((($pde) &  &LX_TYPE) ==  &LX_TYPE_BLK));
	    }' unless defined(&l1pde_is_block);
	    eval 'sub l1pde_is_table {
	        my($pde) = @_;
    		eval q(((($pde) &  &LX_TYPE) ==  &LX_TYPE_TBL));
	    }' unless defined(&l1pde_is_table);
	    eval 'sub l2pde_pa {
	        my($pde) = @_;
    		eval q( &lxpde_pa($pde));
	    }' unless defined(&l2pde_pa);
	    eval 'sub l2pde_index {
	        my($v) = @_;
    		eval q(((( &vaddr_t)($v) &  &L2_ADDR_BITS) >>  &L2_SHIFT));
	    }' unless defined(&l2pde_index);
	    eval 'sub l2pde_valid {
	        my($pde) = @_;
    		eval q( &lxpde_valid($pde));
	    }' unless defined(&l2pde_valid);
	    eval 'sub l2pde_is_block {
	        my($pde) = @_;
    		eval q(((($pde) &  &LX_TYPE) ==  &LX_TYPE_BLK));
	    }' unless defined(&l2pde_is_block);
	    eval 'sub l2pde_is_table {
	        my($pde) = @_;
    		eval q(((($pde) &  &LX_TYPE) ==  &LX_TYPE_TBL));
	    }' unless defined(&l2pde_is_table);
	    eval 'sub l3pte_pa {
	        my($pde) = @_;
    		eval q( &lxpde_pa($pde));
	    }' unless defined(&l3pte_pa);
	    eval 'sub l3pte_executable {
	        my($pde,$user) = @_;
    		eval q(((($pde) & (($user) ?  &LX_BLKPAG_UXN :  &LX_BLKPAG_PXN)) == 0));
	    }' unless defined(&l3pte_executable);
	    eval 'sub l3pte_readable {
	        my($pde) = @_;
    		eval q((($pde) &  &LX_BLKPAG_AF));
	    }' unless defined(&l3pte_readable);
	    eval 'sub l3pte_writable {
	        my($pde) = @_;
    		eval q(((($pde) & ( &LX_BLKPAG_AF |  &LX_BLKPAG_AP)) == ( &LX_BLKPAG_AF |  &LX_BLKPAG_AP_RW)));
	    }' unless defined(&l3pte_writable);
	    eval 'sub l3pte_index {
	        my($v) = @_;
    		eval q(((( &vaddr_t)($v) &  &L3_ADDR_BITS) >>  &L3_SHIFT));
	    }' unless defined(&l3pte_index);
	    eval 'sub l3pte_valid {
	        my($pde) = @_;
    		eval q( &lxpde_valid($pde));
	    }' unless defined(&l3pte_valid);
	    eval 'sub l3pte_is_page {
	        my($pde) = @_;
    		eval q(((($pde) &  &LX_TYPE) ==  &L3_TYPE_PAG));
	    }' unless defined(&l3pte_is_page);
	    eval 'sub L1_TRUNC_BLOCK {
	        my($x) = @_;
    		eval q((($x) &  &L1_FRAME));
	    }' unless defined(&L1_TRUNC_BLOCK);
	    eval 'sub L1_ROUND_BLOCK {
	        my($x) = @_;
    		eval q( &L1_TRUNC_BLOCK(($x) +  &L1_SIZE - 1));
	    }' unless defined(&L1_ROUND_BLOCK);
	    eval 'sub L2_TRUNC_BLOCK {
	        my($x) = @_;
    		eval q((($x) &  &L2_FRAME));
	    }' unless defined(&L2_TRUNC_BLOCK);
	    eval 'sub L2_ROUND_BLOCK {
	        my($x) = @_;
    		eval q( &L2_TRUNC_BLOCK(($x) +  &L2_SIZE - 1));
	    }' unless defined(&L2_ROUND_BLOCK);
	    eval 'sub L3_TRUNC_BLOCK {
	        my($x) = @_;
    		eval q((($x) &  &L3_FRAME));
	    }' unless defined(&L3_TRUNC_BLOCK);
	    eval 'sub L3_ROUND_BLOCK {
	        my($x) = @_;
    		eval q( &L3_TRUNC_BLOCK(($x) +  &L3_SIZE - 1));
	    }' unless defined(&L3_ROUND_BLOCK);
	    eval 'sub DEVMAP_ALIGN {
	        my($x) = @_;
    		eval q( &L3_TRUNC_BLOCK(($x)));
	    }' unless defined(&DEVMAP_ALIGN);
	    eval 'sub DEVMAP_SIZE {
	        my($x) = @_;
    		eval q( &L3_ROUND_BLOCK(($x)));
	    }' unless defined(&DEVMAP_SIZE);
	    eval 'sub DEVMAP_ENTRY {
	        my($va, $pa, $sz) = @_;
    		eval q({ . &pd_va =  &DEVMAP_ALIGN($va), . &pd_pa =  &DEVMAP_ALIGN($pa), . &pd_size =  &DEVMAP_SIZE($sz), . &pd_prot =  &VM_PROT_READ |  &VM_PROT_WRITE, . &pd_flags =  &PMAP_DEV });
	    }' unless defined(&DEVMAP_ENTRY);
	    eval 'sub DEVMAP_ENTRY_END () {{ 0};}' unless defined(&DEVMAP_ENTRY_END);
	    eval 'sub AARCH64_MMAP_FLAG_SHIFT () {(64-  &PGSHIFT);}' unless defined(&AARCH64_MMAP_FLAG_SHIFT);
	    eval 'sub AARCH64_MMAP_FLAG_MASK () {0xf;}' unless defined(&AARCH64_MMAP_FLAG_MASK);
	    eval 'sub AARCH64_MMAP_WRITEBACK () {0;}' unless defined(&AARCH64_MMAP_WRITEBACK);
	    eval 'sub AARCH64_MMAP_NOCACHE () {1;}' unless defined(&AARCH64_MMAP_NOCACHE);
	    eval 'sub AARCH64_MMAP_WRITECOMBINE () {2;}' unless defined(&AARCH64_MMAP_WRITECOMBINE);
	    eval 'sub AARCH64_MMAP_DEVICE () {3;}' unless defined(&AARCH64_MMAP_DEVICE);
	    eval 'sub ARM_MMAP_MASK () { &__BITS(63,  &AARCH64_MMAP_FLAG_SHIFT);}' unless defined(&ARM_MMAP_MASK);
	    eval 'sub ARM_MMAP_WRITECOMBINE () { &__SHIFTIN( &AARCH64_MMAP_WRITECOMBINE,  &ARM_MMAP_MASK);}' unless defined(&ARM_MMAP_WRITECOMBINE);
	    eval 'sub ARM_MMAP_WRITEBACK () { &__SHIFTIN( &AARCH64_MMAP_WRITEBACK,  &ARM_MMAP_MASK);}' unless defined(&ARM_MMAP_WRITEBACK);
	    eval 'sub ARM_MMAP_NOCACHE () { &__SHIFTIN( &AARCH64_MMAP_NOCACHE,  &ARM_MMAP_MASK);}' unless defined(&ARM_MMAP_NOCACHE);
	    eval 'sub ARM_MMAP_DEVICE () { &__SHIFTIN( &AARCH64_MMAP_DEVICE,  &ARM_MMAP_MASK);}' unless defined(&ARM_MMAP_DEVICE);
	    eval 'sub PMAP_PTE () {0x10000000;}' unless defined(&PMAP_PTE);
	    eval 'sub PMAP_DEV () {0x20000000;}' unless defined(&PMAP_DEV);
	    eval 'sub PMAP_DEV_NP () {0x40000000;}' unless defined(&PMAP_DEV_NP);
	    eval 'sub PMAP_DEV_MASK () {( &PMAP_DEV |  &PMAP_DEV_NP);}' unless defined(&PMAP_DEV_MASK);
	    eval 'sub aarch64_mmap_flags {
	        my($mdpgno) = @_;
    		eval q({ \'u_int\'  &nflag,  &pflag;  &nflag = ($mdpgno >>  &AARCH64_MMAP_FLAG_SHIFT) &  &AARCH64_MMAP_FLAG_MASK;  &switch ( &nflag) {  &case  &AARCH64_MMAP_DEVICE:  &pflag =  &PMAP_DEV;  &break;  &case  &AARCH64_MMAP_WRITECOMBINE:  &pflag =  &PMAP_WRITE_COMBINE;  &break;  &case  &AARCH64_MMAP_WRITEBACK:  &pflag =  &PMAP_WRITE_BACK;  &break;  &case  &AARCH64_MMAP_NOCACHE:  &default:  &pflag =  &PMAP_NOCACHE;  &break; }  &pflag; });
	    }' unless defined(&aarch64_mmap_flags);
	    eval 'sub pmap_phys_address {
	        my($pa) = @_;
    		eval q( &aarch64_ptob(($pa)));
	    }' unless defined(&pmap_phys_address);
	    eval 'sub pmap_mmap_flags {
	        my($ppn) = @_;
    		eval q( &aarch64_mmap_flags(($ppn)));
	    }' unless defined(&pmap_mmap_flags);
	    if(defined(&DDB)) {
	    }
	    eval 'sub LX_BLKPAG_OS_WIRED () { &LX_BLKPAG_OS_2;}' unless defined(&LX_BLKPAG_OS_WIRED);
	    eval 'sub LX_BLKPAG_OS_BOOT () { &LX_BLKPAG_OS_3;}' unless defined(&LX_BLKPAG_OS_BOOT);
	    eval 'sub PMAP_PTE_OS2 () {"wired";}' unless defined(&PMAP_PTE_OS2);
	    eval 'sub PMAP_PTE_OS3 () {"boot";}' unless defined(&PMAP_PTE_OS3);
	    if(defined(&PMAP_MI)) {
		require 'aarch64/pmap_machdep.ph';
	    } else {
		eval 'sub PMAP_NEED_PROCWR () {1;}' unless defined(&PMAP_NEED_PROCWR);
		eval 'sub PMAP_GROWKERNEL () {1;}' unless defined(&PMAP_GROWKERNEL);
		eval 'sub PMAP_STEAL_MEMORY () {1;}' unless defined(&PMAP_STEAL_MEMORY);
		eval 'sub __HAVE_VM_PAGE_MD () {1;}' unless defined(&__HAVE_VM_PAGE_MD);
		eval 'sub __HAVE_PMAP_PV_TRACK () {1;}' unless defined(&__HAVE_PMAP_PV_TRACK);
		eval 'sub pmap_l0pa {
		    my($pm) = @_;
    		    eval q({  ($pm->{pm_l0table_pa}); });
		}' unless defined(&pmap_l0pa);
		eval 'sub mdpg_ptep_parent () { ($mdpg_pp->{pp_pv}->{pv_ptep});}' unless defined(&mdpg_ptep_parent);
		eval 'sub VM_MDPAGE_INIT {
		    my($pg) = @_;
    		    eval q( &do {  &PMAP_PAGE_INIT(($pg)-> ($mdpage->{mdpg_pp})); }  &while ( 0));
		}' unless defined(&VM_MDPAGE_INIT);
		eval 'sub PMAP_PAGE_INIT {
		    my($pp) = @_;
    		    eval q( &do {  &mutex_init(($pp)-> &pp_pvlock,  &MUTEX_NODEBUG,  &IPL_NONE); ($pp)-> ($pp_pv->{pv_next}) =  &NULL; ($pp)-> ($pp_pv->{pv_pmap}) =  &NULL; ($pp)-> ($pp_pv->{pv_va}) = 0; ($pp)-> ($pp_pv->{pv_ptep}) =  &NULL; }  &while ( 0));
		}' unless defined(&PMAP_PAGE_INIT);
		eval 'sub LX_BLKPAG_OS_READ () { &LX_BLKPAG_OS_0;}' unless defined(&LX_BLKPAG_OS_READ);
		eval 'sub LX_BLKPAG_OS_WRITE () { &LX_BLKPAG_OS_1;}' unless defined(&LX_BLKPAG_OS_WRITE);
		eval 'sub LX_BLKPAG_OS_RWMASK () {( &LX_BLKPAG_OS_WRITE |  &LX_BLKPAG_OS_READ);}' unless defined(&LX_BLKPAG_OS_RWMASK);
		eval 'sub PMAP_PTE_OS0 () {"read";}' unless defined(&PMAP_PTE_OS0);
		eval 'sub PMAP_PTE_OS1 () {"write";}' unless defined(&PMAP_PTE_OS1);
		eval 'sub VTOPHYS_FAILED () {(( &paddr_t)-1);}' unless defined(&VTOPHYS_FAILED);
		eval 'sub POOL_VTOPHYS {
		    my($va) = @_;
    		    eval q( &vtophys(( &vaddr_t) ($va)));
		}' unless defined(&POOL_VTOPHYS);
		unless(defined(&KASAN)) {
		    eval 'sub PMAP_MAP_POOLPAGE {
		        my($pa) = @_;
    			eval q( &AARCH64_PA_TO_KVA($pa));
		    }' unless defined(&PMAP_MAP_POOLPAGE);
		    eval 'sub PMAP_UNMAP_POOLPAGE {
		        my($va) = @_;
    			eval q( &AARCH64_KVA_TO_PA($va));
		    }' unless defined(&PMAP_UNMAP_POOLPAGE);
		    eval 'sub PMAP_DIRECT () {1;}' unless defined(&PMAP_DIRECT);
		    eval 'sub pmap_direct_process () {
		        eval q(( &paddr_t  &pa,  &voff_t  &pgoff, \'size_t\'  &len,  &int (* &process)( &void *, \'size_t\',  &void *),  &void * &arg) {  &vaddr_t  &va =  &AARCH64_PA_TO_KVA( &pa);  &process(( &void *)( &va +  &pgoff),  &len,  &arg); });
		    }' unless defined(&pmap_direct_process);
		}
		eval 'sub pte_valid_p {
		    my($pte) = @_;
    		    eval q({  &l3pte_valid($pte); });
		}' unless defined(&pte_valid_p);
		eval 'sub pmap_update {
		    my($pmap) = @_;
    		    eval q((( &void)0));
		}' unless defined(&pmap_update);
		eval 'sub pmap_copy {
		    my($dp,$sp,$d,$l,$s) = @_;
    		    eval q((( &void)0));
		}' unless defined(&pmap_copy);
		eval 'sub pmap_wired_count {
		    my($pmap) = @_;
    		    eval q((($pmap)-> ($pm_stats->{wired_count})));
		}' unless defined(&pmap_wired_count);
		eval 'sub pmap_resident_count {
		    my($pmap) = @_;
    		    eval q((($pmap)-> ($pm_stats->{resident_count})));
		}' unless defined(&pmap_resident_count);
		eval 'sub PMAP_MAPSIZE1 () { &L2_SIZE;}' unless defined(&PMAP_MAPSIZE1);
	    }
	}
    }
 elsif(defined(&__arm__)) {
	require 'arm/pmap.ph';
    }
}
1;
