  | 
		
Upgrading Privileged-Code Applications on OpenVMS Alpha and
  OpenVMS I64 Systems
 
 
7.7.3 PFN Allocation and Mapping Routines
If your code calls either of the following routines, you must modify your
  code on I64:
 
 
  
    | Alpha Routine  | 
    New Alpha and I64 Routine  | 
   
  
     status = mmg$alloc_sva_map (  
      proto_pte,  
      page_count,  
      refcnt,  
&ret_svapte,  
&ret_sva,  
&ret_pfn);  | 
     status = mmg$allocate_sva_and_pfns (  
      page_count,  
      0, // flags  
      MMG$K_NO_RAD,  
      0, // system_region  
      proto_pte,  
      refcnt,  
&ret_sva);  
      ret_svapte = va_pte_to_svapte (pte_va (ret_sva));  | 
   
  
    |    | 
       | 
   
  
     status = mmg_std$alloc_system_va_map (  
      proto_pte,  
      page_count,  
      refcnt,  
      system_region,  
&ret_sva,  
&ret_pfn,  
      rad,  
      rad_flags);  | 
     status = mmg$allocate_sva_and_pfns (  
      page_count,  
      rad_flags,  
      rad,  
      system_region,  
      proto_pte,  
      refcnt,  
&ret_sva);  | 
   
 
Prototype 
 
 
  
      
      
           int mmg$allocate_sva_and_pfns (                                     unsigned __int64 page_count,                                     unsigned int flags,                                     int color,                                     int system_region,                                     int proto_pte,                                     int refcnt,                                     VOID_PPQ ret_sva);  
      
 |   
Page_count: Number of pages to allocate
 The following table lists the MMG flags:
 
  
    | MMG Flag  | 
    Meaning  | 
   
  
    |  MMG$M_COLOR_MUST  | 
     Return PFN must be of color (RAD) specified  | 
   
  
    |  MMG$M_COLOR_RANDOM  | 
     Return PFN should be a random color (RAD)  | 
   
 
Color: RAD on systems with NUMA support enabled
 System_region: 0 or 1 = 32-bit S0S1address space, 2 = 64-bit S2 address space
 Proto_pte: prototype PTE with low PTE bits, such as page protection, set for
  mapping
 Refcnt: Reference count for PFNs allocated
 Ret_sva: System virtual address of memory mapped
 If your code calls any of the following routines, you must modify your code
  to call the new routine.
 
  
    | Alpha Routine  | 
    New Alpha and I64 Routine  | 
   
  
     status = mmg$alloc_pfn_map_sva (  
      proto_pte,  
      page_count,  
      refcnt,  
      svapte,  
&ret_sva,  
&ret_pfn);  | 
     sva = va_pte_to_va (svapte_to_va_pte (svapte));  
      status = mmg$allocate_pfn_map (  
      page_count,  
      0, // flags  
      MMG$K_NO_RAD, // color  
      0, // low_pfn  
      0, // high_pfn  
      sva,  
      proto_pte,  
      refcnt);  
      ret_pfn = svapte->pte$v_pfn;  | 
   
  
    |    | 
       | 
   
  
     status = mmg$alloc_pfn_map_system_va (  
      proto_pte,  
      page_count,  
      refcnt,  
      sva,  
&ret_pfn,  
      color,  
      flags);  | 
     status = mmg$allocate_pfn_map (  
      page_count,  
      flags,  
      color,  
      0, // low_pfn  
      0, // high_pfn  
      sva,  
      proto_pte,  
      refcnt);  
      ret_pfn = pte_va (sva)->svapte>pte$v_pfn;  | 
   
  
    |    | 
       | 
   
  
     status = mmg$alloc_ctg_pfn_map_sva (  
      proto_pte,  
      page_count,  
      refcnt,  
      sva,  
      high_pfn,  
&ret_pfn):  | 
     status = mmg$allocate_pfn_map (  
      page_count,  
      MMG$M_CONTIG,  
      MMG$K_NO_RAD, //color,  
      0, // low_pfn  
      high_pfn,  
      sva,  
      proto_pte,  
      refcnt);  
      ret_pfn = pte_va (sva)->svapte>pte$v_pfn;  | 
   
 
Prototype 
 
 
  
      
      
           int mmg$allocate_pfn_map (                               unsigned __int64 page_count,                               unsigned int flags,                               int color,                               PFN_T low_pfn,                               PFN_T high_pfn,                               VOID_PQ sva,                               int proto_pte,                               int refcnt);  
      
 |   
Page_count: Number of pages to allocate
 The following table lists the MMG flags.
 
  
    | MMG Flag  | 
    Meaning  | 
   
  
    |  MMG$M_COLOR_MUST  | 
     Return PFN must be of color (RAD) specified  | 
   
  
    |  MMG$M_COLOR_RANDOM  | 
     Return PFN should be a random color (RAD)  | 
   
  
    |  MMG$M_CONTIG  | 
     Allocate contiguous pages  | 
   
 
Color: RAD on systems with NUMA support enabled
 Low_pfn: lowest PFN to allocate
 High_pfn: highest PFN to allocate (0, if no range)
 Sva: System virtual address to map pages (sva was already allocated by the
  caller)
 Proto_pte: prototype PTE with low PTE bits, such as page protection, set for
  mapping
 Refcnt: Reference count for PFNs allocated
7.8 PTE Format Changes
 The PFN field in the PTE is 32-bits wide on Alpha and 40-bits wide on I64.
  The PFN field happens to exactly overlay other fields in the PTE such as GPTX,
  BAKX and the combination of PGFLPAG and PGFLX.
 The following table shows the field definitions for the upper PTE fields:
 
  
    | Field Name  | 
    Alpha Bit Position  | 
    Alpha Field Length  | 
    I64 Bit Position  | 
   
  
    |  PFN 32  | 
     32  | 
     24 1  | 
     40 1  | 
   
  
    |  BAKX 32  | 
     32  | 
     24 1  | 
     40 1  | 
   
  
    |  GPTX 32  | 
     32  | 
     32  | 
     32  | 
   
  
    |  PGFLPAG 32  | 
     24  | 
     32  | 
     24  | 
   
  
    |  PGFLX 56  | 
     8  | 
     56  | 
     8  | 
   
 
 
1The two fields that are different between Alpha and I64 are PFN and
BAKX. The BAKX field is used to refer to the PFN, GPTX, or PGFLPAG/PGFLX field
when the code does not care which format the PTE is in. The BAKX mask typically
used to isolate the lower PTE bits. 
 
Good Example 
 
 
  
      
      
          EVAX_LDQ   R0,(R3)          ; Read the PTE     EVAX_BIC   R0,#PTE$M_BAKX,R1 ; Isolate the lower PTE bits  
      
 |   
Sometimes existing code uses the PFN field from the PTE when it should use
  the GPTX field. This code needs to be changed.
 Existing Code 
 
 
  
      
      
          pfn = pte_contents.pte$v_pfn;     if (pte_contents.pte$v_typ0 && !pte_contents.pte$v_typ1) {         pte_contents = mmg$gq_gpt_base[pfn]; // Read global PTE         if (pte_contents.pte$v_valid)             pfn = pte_contents.pte$v_pfn;  // Read pfn from valid GPTE         .         .         .     } 
      
 |   
New Code 
 
 
  
      
      
          pfn = pte_contents.pte$v_pfn;     if (pte_contents.pte$v_typ0 && !pte_contents.pte$v_typ1) {         gptx = pte_contents.pte$v_gptx;         pte_contents = mmg$gq_gpt_base[gptx]; // Read global PTE         if (pte_contents.pte$v_valid)             pfn = pte_contents.pte$v_pfn;  // Read pfn from global PTE         .         .         .     } 
      
 |   
  
  
		 |