/* Version X-3A1A3 */ /***************************************************************************** * Copyright 2002 Compaq Information Technologies Group, L.P. * * Compaq and the Compaq logo are trademarks of Compaq Information * Technologies Group, L.P. in the U.S. and/or other countries. * * Confidential computer software. Valid license from Compaq required for * possession, use or copying. Consistent with FAR 12.211 and 12.212, * Commercial Computer Software, Computer Software Documentation, and * Technical Data for Commercial Items are licensed to the U.S. Government * under vendor's standard commercial license. *****************************************************************************/ /* *++ * FACILITY: * * Open/VMS AXP (LIB) * * ABSTRACT: * * This header file will provide big page inline functions equivalent to * the LIB big page macros which exist for BLISS and Macro. * * AUTHOR: * * Karen Noel * * CREATION DATE: 12-Sep-1994 * * MODIFICATION HISTORY: * * X-3A1A3 KLN3058 Karen L. Noel 18-Apr-2002 * o Add more parens in $make_va macro so it works in conditional * statements and with complex arguments. * o Add $is_valid_address macro. * * X-3A1A2 KLN3037 Karen L. Noel 13-Mar-2002 * We don't trust the compiler anymore. Put the inlines * back in. It messes up initialization routines. * * X-3A1A1 KLN3025 Karen L. Noel 26-Feb-2002 * o Port PT space to IA64. * o Remove inline pragmas. We trust the compiler now. * * X-3A1 KLN2202 Karen L. Noel 27-Nov-2000 * Fix $make_va so it properly returns a VOID_PQ. * * X-3 KLN1396 Karen L. Noel 24-Feb-1995 * Add $is_shared_va and $is_private_va. * * X-2 KLN1322 Karen L. Noel 22-Sep-1994 * 64-bit project: Internal programming * Define roundup argument. * *-- */ #ifndef __LIB_BIGPAGE_LOADED #define __LIB_BIGPAGE_LOADED 1 /* * Included files: * * */ #include #include #include /* * * External data cells: * */ extern PTE_PQ const mmg$gq_shared_va_ptes; extern PTE_PQ const mmg$gq_pt_base[VA$C_VRNX_COUNT]; extern VOID_PQ const mmg$gq_system_virtual_base; extern const unsigned __int64 mmg$gq_non_va_mask, mmg$gq_level_width, mmg$gq_ptes_per_page; extern const int mmg$gl_bwp_width, mmg$gl_bwp_mask, mmg$gl_page_size; /* *++ * $sys_start_of_page - Calculate the starting address of the page. * * Inputs: * source_va - source address * * Returns: * The address of the first byte within the page specified by source_va. *-- */ #define $sys_start_of_page(source_va) \ (VOID_PQ)((unsigned __int64)source_va & ~(unsigned __int64)(mmg$gl_bwp_mask)) /* *++ * $sys_next_page - Calculate the address of the next page. * * Inputs: * source_va - source address * clearbwp - If 1, masks the bwp portion of the VA. * * Returns: * The address of one page after the source address. If clearbwp is 1, * the address will be rounded down to be the start of the next page. * *-- */ #define $sys_next_page(source_va, clearbwp) \ (VOID_PQ)(((unsigned __int64)source_va + \ (unsigned __int64)mmg$gl_page_size) & \ ~(clearbwp * ((unsigned __int64)mmg$gl_bwp_mask)) ) /* *++ * $sys_previous_page - Calculate the address of the previous page. * * Inputs: * source_va - source address * clearbwp - If 1, masks the bwp portion of the VA. * * Returns: * The address of one page before the source address. If clearbwp is 1, * the address will be rounded down to be the start of the previous page. * *-- */ #define $sys_previous_page(source_va, clearbwp) \ (VOID_PQ)(((unsigned __int64)source_va - \ (unsigned __int64)mmg$gl_page_size) & \ ~(clearbwp * ((unsigned __int64)mmg$gl_bwp_mask)) ) /* *++ * $sys_pages_to_bytes - Convert pages to bytes * * Inputs: * page_count - source page count * * Returns: * The number of bytes in page_count. * *-- */ #define $sys_pages_to_bytes(page_count) (page_count << mmg$gl_bwp_width) /* *++ * $bytes_to_pages - Convert bytes to pages * * Inputs: * byte_count - Byte count * roundup = 1 if byte_count is to be rounded up before converted to pages * = 0 if rounding is not required. * * Returns: * The number of pages in byte_count. * *-- */ #define $sys_bytes_to_pages(byte_count, roundup) \ ((byte_count + (roundup*mmg$gl_bwp_mask)) >> mmg$gl_bwp_width) /* *++ * $extract_vpn - Extract page table space vpn from va * * Inputs: * addr - source virtual address * * Extracts a VPN from a virtual address * *-- */ #define $extract_vpn(addr) \ (unsigned int)(((unsigned __int64)addr & ~mmg$gq_non_va_mask) \ >> mmg$gl_bwp_width) /* *++ * $extract_pte_offset - Extract page table space pte offset from va * * Inputs: * addr - source virtual address * * Extracts a PTE offset from a virtual address * *-- */ #define $extract_pte_offset(addr) \ ((((unsigned __int64)addr & ~mmg$gq_non_va_mask) \ >> mmg$gq_level_width) \ & ~(PTE$C_BYTES_PER_PTE-1)) /* *++ * $make_va - Make a virtual address from a virtual page number in page table * space * * Input: * vpn - source virtual page number * * Output: * va - virtual address (VOID_PQ) * * Makes a virtual address from virtual page number * *-- */ #define $$$non_sext_va(vpn) \ ((unsigned __int64)(vpn) << mmg$gq_bwp_width) #define $$$sext_bit \ ((unsigned __int64)1<<(mmg$gq_va_bits-1)) #define $make_va(vpn) \ ((($$$non_sext_va(vpn) & $$$sext_bit) == 0) ? \ (VOID_PQ)($$$non_sext_va(vpn)) : \ (VOID_PQ)($$$non_sext_va(vpn) | mmg$gq_non_va_mask)) /* *++ * $is_pt_space_va - Test if quadword is a PT space address * * Inputs: arg - 64-bit address * * Output: 1 if arg is PT space address * 0 if arg is not PT space address * *-- */ #pragma inline ($$$is_pt_space_va) static int $$$is_pt_space_va (unsigned __int64 arg) { int vrnx; unsigned __int64 p,size_of_pt_space; # ifdef __NEW_STARLET VA v; v.va$q_quad = arg; # else va v; v.va$q_quad[0] = arg; v.va$q_quad[1] = arg>>32; # endif /* Get VRNX from the VA */ vrnx = v.va$v_vrnx; /* If less that pt_base, it's not a PT space VA */ if (arg < (unsigned __int64)mmg$gq_pt_base[vrnx]) return 0; /* Get size of a PT space give 3 levels of page tables */ p = mmg$gq_ptes_per_page; size_of_pt_space = p*p*p*PTE$C_BYTES_PER_PTE; /* If greater than or equal to the top of PT space, it's not a PT space VA */ if (arg >= (unsigned __int64)mmg$gq_pt_base[vrnx] + size_of_pt_space) return 0; /* It's a PT space VA */ return 1; } #define $is_pt_space_va(arg) $$$is_pt_space_va((unsigned __int64)(arg)) /* *++ * $is_process_pte_va - Test if quadword is a process pte address * * Inputs: arg - 64-bit address * * Output: 1 if arg is process pte address * 0 if arg is not process pte address * *-- */ #pragma inline ($$$is_process_pte_va) static int $$$is_process_pte_va (unsigned __int64 arg) { int vrnx; unsigned __int64 size_of_pt_space; # ifdef __NEW_STARLET VA v; v.va$q_quad = arg; # else va v; v.va$q_quad[0] = arg; v.va$q_quad[1] = arg>>32; # endif /* Get VRNX from the VA */ vrnx = v.va$v_vrnx; /* If VRNX is system space, it's not a process PTE address */ if (vrnx == VA$C_VRNX_SYSTEM) return 0; /* Return the results from the PT space VA test */ return ($is_pt_space_va(arg)); } #define $is_process_pte_va(arg) $$$is_process_pte_va ((unsigned __int64)(arg)) /* *++ * $is_system_pte_va - Test if quadword is a system pte address * * Inputs: arg - 64-bit address * * Output: 1 if arg is system pte address * 0 if arg is not system pte address * *-- */ #define $is_system_pte_va(arg) \ (((unsigned __int64)(arg) >= (unsigned __int64)mmg$gq_shared_va_ptes) && \ ((unsigned __int64)(arg) < (unsigned __int64)mmg$gq_system_virtual_base)) /* *++ * $is_shared_va - Test if quadword is a shared va * * Inputs: arg - 64-bit address * * Output: 1 if arg is shared address * 0 if arg is not shared address * *-- */ #define $is_shared_va(arg) \ ((unsigned __int64)(arg) >= (unsigned __int64)mmg$gq_shared_va_ptes) /* *++ * $is_private_va - Test if quadword is a private va * * Inputs: arg - 64-bit address * * Output: 1 if arg is private address * 0 if arg is not private address * *-- */ #define $is_private_va(arg) \ ((unsigned __int64)(arg) < (unsigned __int64)mmg$gq_shared_va_ptes) /* *++ * $is_valid_address - Test if quadword is a valid 64-bit address * * Inputs: arg - 64-bit address * * Output: 1 if arg is valid address * 0 if arg is not valid address * *-- */ extern VOID_PQ const mmg$gq_gap_lo_va; extern VOID_PQ const mmg$gq_gap_hi_va; #define $is_valid_address(arg) \ (((unsigned __int64)(arg) < (unsigned __int64)mmg$gq_gap_lo_va) || \ ((unsigned __int64)(arg) >= (unsigned __int64)mmg$gq_gap_hi_va) ) #endif /* __LIB_BIGPAGE_LOADED */