|
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 . . . }
|
|