hp.com home products and services support and drivers solutions how to buy
cd-rom home
End of Jump to page title
HP OpenVMS systems
documentation

Jump to content


Upgrading Privileged-Code Applications on OpenVMS Alpha and OpenVMS I64 Systems

Upgrading Privileged-Code Applications on OpenVMS Alpha and OpenVMS I64 Systems


Previous Contents Index

Part II
Privileged-Code Changes for OpenVMS I64


Chapter 7
OpenVMS Infrastructure Changes for OpenVMS I64

There are two major changes necessary to the OpenVMS infrastructure to accommodate 50-bit physical addressing. These changes are for privileged applications on the I64 platform only. Alpha code does not require any change.

The following sections discuss how to change your code to accommodate these infrastructure differences. In most cases, you can change your I64 code so it is common code with Alpha.

To help you find which modules might require changing, we have created a command procedure that searches for all structure fields, data cells and routines mentioned in this document. Refer to Section 9 for more information.

7.1 C Programming

This section contains instructions for C programmers.

7.1.1 PTE Field References in C

The field PTE$V_PFN is defined in ptedef.h. This field is used to reference the PFN stored in a valid or transition PTE. The following are examples of good C programming:


    PTE local_pte; 
    local_pte.pte$v_pfn = pfn; 


    PTE_PQ va_pte; 
    pfn = va_pte->pte$v_pfn; 

These references work correctly as common code on Alpha and I64.

Some C code may assume that the PFN field is 32-bits at bit position 32. This is a bad example:


    unsigned __int64 pte; 
    pfn = pte >> 32;  

This code must be changed to use the PTE structure and the field pte$v_pfn as shown in the good programming examples above.

7.1.2 PFN References in C

PFNs are often stored as 32-bit integer variables in existing C code. These are sometimes signed and sometimes unsigned.

An example of an existing PFN:


    unsigned int new_pfn; 

A new type is defined in lib_types.h called PFN_T. This type is 32-bits on Alpha and 64-bits on I64.

When modifying your code for 64-bit PFNs, you can use unsigned __int64 or the PFN_T type. This is your choice.

New Code


    unsigned __int64 new_pfn; 

Alternate New Code


    #include <lib_types.h> 
    PFN_T new_pfn; 

When examining C code, look for casts of PFN fields and variables. Also look for assignment to and from other 32-bit ariables.

Example of Bad Code


    pfn = (int)foo; 

You can eliminate the need for a cast or change the cast to unsigned __int64 or PFN_T. This depends on the context of the code in question.

New Code


    pfn = (unsigned __int64)foo; 

Alternate New Code


    pfn = (PFN_T)foo; 

Using unsigned __int64 is sometimes preferable to PFN_T. This is because the PFN_T typedef includes conditionals for Alpha and IA64. In general, less conditional code is better because it insures that the same code is tested in both cases.

Example


    unsigned __int64 pfn; 
    unsigned __int64 pa; 
    int boff; 
    pfn = pte_contents.pte$v_pfn; 
    pa = (pfn << mmg$gl_bwp_width)| boff; 

Code that calculates a physical address from a PFN requires 64-bit arithmetic. The declaration of the pfn variable as unsigned __int64 insures this calculation is done correctly. In the above example, if the pfn variable were switched to type PFN_T, the line that computes the pa variable would execute differently on Alpha and I64 because the size of the pfn variable differs.

A good "rule of thumb" is this: if your code already uses unsigned __int64 as a PFN type, you should probably leave it alone.

7.2 Macro-32 Programming

This section contains instructions for Macro-32 programmers.

7.2.1 PTE Field References in Macro-32

The PTE$V_PFN field is used to reference the PFN stored in a valid or transition PTE. The symbols PTE$V_PFN, PTE$S_PFN and PTE$M_PFN are defined in $PTEDEF. This table shows the symbol values on Alpha and I64.
Symbol Name Alpha Value I64 Value
PTE$V_PFN 32 24
PTE$S_PFN 32 40
PTE$M_PFN ^XFFFFFFFF00000000 ^XFFFFFFFFFF000000

In Macro-32 PFNs can be shifted or extracted from PTEs. Also, PFNs can be shifted or inserted to PTEs.

Good Example 1


    ; R0 = PFN, R1 = PTE contents, R3 = PTE address 
    EVAX_SRL R1,#PTE$V_PFN,R0   ; Get PFN from PTE 
    EXTZV    R1,#PTE$V_PFN,#PTE$S_PFN,R0 

Good Example 2


    ; R0 = PFN, R1 = PTE contents, R3 = PTE address 
    EVAX_SLL R0,#PTE$V_PFN,R1   ; Put PFN into PTE position 
    INSV  R0,#PTE$V_PFN,#PTE$S_PFN,(R3) ; Store PFN into PTE 

These references work correctly as common code on Alpha and I64. Some Macro-32 code may assume that the PFN field is the upper longword of the PTE.

Bad Example


   ASSUME PTE$V_PFN EQ 32 
   MOVL R0,4(R3)    ; Store PFN into PTE 

This code must be changed to use the PTE structure symbols as shown above.

7.2.2 PFN References in Macro-32

PFNs are often treated as longwords in existing Macro-32 code. You must change your code to ensure that the high order 32-bits are not truncated or sign extended.

Existing Code


    TSTL R0             ; Is there a PFN? 
    BNEQ 10$            ; If neq, yes 

New Code


    EVAX_BNE R0,10$     ; Branch if we have a PFN 

Existing Code


    MOVL R0,R7          ; Copy PFN 

New Code


    EVAX_OR R0,R31,R7   ; Copy PFN 

Existing Code


    INCL R0             ; Next PFN 

New Code


    EVAX_ADDQ R0,#1,R0  ; Next PFN 

The above examples work correctly as common code on Alpha and I64. In other cases, you must conditionalize your code because the Alpha has 32-bit storage and I64 has 64-bit storage.

Existing Code


    MOVL     GSD$L_BASEPFN(R10),R0     ; Read the base PFN 

New Code


    .IF DF ALPHA 
    MOVL     GSD$I_BASEPFN(R10),R0     ; Read the base PFN 
    .ENDC 
 
    .IF DF IA64 
    EVAX_LDQ R0,GSD$I_BASEPFN(R10)     ; Read the base PFN 
    .ENDC 

Notice that the new Macro-32 code is awkward. This code could have been common between Alpha and I64 if it were written in C.

To help program conditional code referencing "I" fields in structures, several new macros have been added to lib.mlb.

MACRO-32 Macro Alpha Code I64 Code
CLEAR$I loc CLRL loc EVAX_STQ R31, loc
LOAD$I Rx, loc MOVL loc, Rx EVAX_LDQ Rx, loc
STORE$I Rx, loc MOVL Rx, loc EVAX_STQ Rx, loc
INCR$I loc INCL loc EVAX_ADDQ loc, #1, loc
DECR$I loc DECL loc EVAX_SUBQ loc, #1, loc

The above example can be programmed with the LOAD$I macro as follows:


    LOAD$I  R0, GSD$I_BASEPFN(R10) ; Read the base PFN 


Previous Next Contents Index