HP OpenVMS Systems Documentation

Content starts here

Porting Applications from HP OpenVMS Alpha to HP OpenVMS Industry Standard 64 for Integrity Servers


Previous Contents Index


Appendix B
Unsupported Layered Products

HP has not plans to port some layered products to OpenVMS I64. Table B-1 lists these layered products and the replacement products recommended by HP.

Table B-1 Layered Products Not Ported to OpenVMS I64
Product Suggested Replacement
BASEstar Classic BASEstar Open
HP Ada Compiler for OpenVMS Alpha Systems GNAT Ada for OpenVMS Integrity Servers---from Ada Core Technologies
Pathworks 32 Advanced Server


Appendix C
Porting Application-Specific Stack-Switching Code to I64

Many applications support small, private threading packages that switch stacks to perform multiple tasks within the context of a single process. Many of these packages use one or more small routines written in assembly language (Macro-32 on VAX or Macro-64 on Alpha) to manipulate the stack pointers and to cause, in effect, a context switch within a single process. Typically, the ability to stall and restart the tasks is also required. The replaced stack can be in any mode appropriate to the required task.

On I64, switching stacks is much more difficult.The I64 architecture includes two stacks, a memory stack and a register stack engine backing store (commonly called the RSE stack or simply the register stack.) The RSE stack is maintained by hardware and the architecture provides support for asynchronous manipulation of the stack. Also, the I64 architecture includes many specialized hardware registers (called control and application registers) that must be maintained across a context switch. In addition, the IAS assembler is not a supported part of the OpenVMS distribution.

To accommodate these types of applications, OpenVMS offers a set of system routines called KP services. Originally written to support device drivers written in higher-level languages, the KP services have been expanded to work in any mode and at any IPL. While the KP model may not match the needs of all private stack-switching code, HP strongly suggests moving to this model.

KP services are available on both Alpha and I64, allowing for common code. There are some differences in implementation; however, whenever possible, options valid on only one architecture are ignored on the other.

C.1 Overview of KP Services

The KP model is most accurately described as a co-routine model with voluntary stall and resumption. A code stream running in process or system context desires to start another stream (called the KP routine) in the same mode but without disturbing the existing stack context and allowing the KP routine to stall and resume as necessary while maintaining its own distinct context. Resumption of a KP routine can be asynchronous to the original code stream that started the KP routine.

The easiest view of a KP routine is that of a routine that operates on a private stack (or on I64, a pair of stacks.) The routine can be stalled and resumed. To a compiler, the routines to start, stall, and resume simply appear as outbound procedure calls which obey the OpenVMS calling standard. The saving of state and stack switch takes place entirely within the context of the KP routines. When a code stream gives up control, the resumption point is always as if the call that caused transfer of control completed.

The base support includes routines to assist in the allocation of necessary stacks and data structures and routines to start, stall, restart, and terminate a KP routine.

A KP routine can start another KP routine.

The basic KP support routines are:

  • EXE$KP_START---Start a KP routine.
  • EXE$KP_STALL_GENERAL---stall the current routine and return to the last caller of EXE$KP_START or EXE$KP_RESTART.
  • EXE$KP_RESTART---Restart a KP routine that has been stalled by a call to EXE$KP_STALL_GENERAL.
  • EXE$KP_END---Terminate the KP routine.

The routines and required data structures are described in Section C.2.2.

C.1.1 Terminology

The memory stack is the stack that is pointed to the stack pointer register. The memory stack is the only stack on Alpha systems.

The register stack is the informal name for the register stack engine (RSE) backing store. The I64 architecture includes 96 stacked registers that are used for argument passing between routines and that can be used for local storage within a routine as well. The hardware maintains the stacked register state and flushes registers to the backing store as needed.

A KP routine is a sequence of code that runs on a private stack or stacks. It is started via a call to EXE$KP_START and is terminated by an implicit or explicit call to EXE$KP_END.

A KPB is the data structure that describes the stack or stacks and that maintains state and context information for the KP routine.

A KPB is valid if it has been used to activate a KP routine via EXE$KP_START. EXE$KP_END marks the KPB as invalid. The initial state of a KPB is invalid.

A KPB is active when the KP routine has been started via EXE$KP_START or resumed via EXE$KP_RESTART. EXE$KP_STALL_GENERAL and EXE$KP_END mark the KPB as inactive. The initial state of a KPB is inactive.

C.1.2 Stacks and Data Structures

On I64, three pieces of memory are associated with a KP routine---a memory stack, an RSE stack, and a KPB, which is the data structure that ties them all together. On Alpha, there is no RSE stack and all parameters and fields related to the RSE stack are ignored.

The KPB and stacks each must be allocated from an appropriate region, and at an appropriate mode, protection, and ownership to match the mode in which the KP routine will execute. When porting an existing application, it is expected that the application already allocates an appropriate memory stack. The existing memory stack allocation routine can be adapted to the KP API. As with previous architectures, the memory stack is accessed from the highest address (the base of the stack) to the lowest address.

RSE stacks are typically allocated from 64-bit space because the register stack engine is a new entity with no previous 32-bit dependencies. A number of allocation routines have been supplied that should cover most common application needs. The RSE stack is accessed from the lowest address to the highest address.

Table C-1 offers guidelines for allocation by mode and scope of the application.

Table C-1 Allocation Guidelines by Mode and Scope
Mode-Scope1 KPB Memory Stack Register Stack
Kernel---System
EXE$KP_ALLOC_KPB 2
Nonpaged pool
KW
EXE$ALONONPAGED
S0/S1
KW
EXE$KP_ALLOC_MEM_STACK
S2
KW
EXE$KP_ALLOC_RSE_STACK 3
Kernel---Process Nonpaged pool or P1
KW
EXE$ALONONPAGED or EXE$ALOP1PROC
P1---Permanent
KW
$CREATE_REGION/$CRETVA
P2---Permanent
KW
EXE$KP_ALLOC_RSE_STACK_P2
Kernel---Image
P1
KW
EXE$ALOP1IMAG
P1-Nonpermanent
KW
$CREATE_REGION/$CRETVA
P2---Nonpermanent
KW
$CREATE_REGION/$CRETVA
Exec---Process P1
EW
EXE$ALOP1PROC
P1---Permanent
EW
$CREATE_REGION/$CRETVA
P2---Permanent
EW
EXE$KP_ALLOC_RSE_STACK_P2
Exec---Image P1
EW
EXE$ALOP1IMAG
P1---Nonpermanent
EW
$CREATE_REGION/$CRETVA
P2---Nonpermanent
EW
$CREATE_REGION/$CRETVA
Super---Process P1
SW
EXE$ALOP1PROC
P1---Permanent
SW
$CREATE_REGION/$CRETVA
P2---Permanent
SW
EXE$KP_ALLOC_RSE_STACK_P2
Super---Image P1
SW
EXE$ALOP1IMAG
P1---Nonpermanent
SW
$CREATE_REGION/$CRETVA
P2---Nonpermanent
SW
$CREATE_REGION/$CRETVA
User---Image P0
UW
Heap/Malloc/LIB$GET_VM
P0---Nonpermanent 4
UW
EXE$KP_ALLOC_MEM_STACK_USER
P2---Nonpermanent
UW
EXE$KP_ALLOC_RSE_STACK_P2

1 Image scope terminates at image exit. Process scope terminates at process exit and will survive image rundown. System scope does not require process context.
2EXE$KP_ALLOC_KPB allocates kernel mode KPB and kernel mode stacks in a single call.
3 EXE$KP_ALLOC_RSE_STACK_P2 creates permanent regions.
4 Note that permanent memory regions may not be created in user mode.

C.1.3 KPBs

The KPB is a data structure that is used to maintain the necessary context between the initiating code stream and the KP routine. The KPB is semitransparent. Some fields are maintained by the application, some by the KP routines and some are shared. The KP routines assume the KPB was zeroed on allocation and, thus that any nonzero field contains legitimate data.

The structure definitions for a KPB are defined by the $KPBDEF macro for Macro-32 and KPBDEF.H for C. The KPB definitions are considered system-internal and thus supplied in LIB.MLB and SYS$LIB_C.TLB. For BLISS, LIB.REQ or LIB.L32/LIB.L64 contain the KPB definitions.

The KPB is a variable-length structure consisting of a number of areas or substructures. Not all areas are required. The areas are:

  • Base area
  • Scheduling area
  • VEST area
  • Spinlock area
  • Debug area
  • User parameter area

The base area is required. It contains a standard structure header, the stack sizes and base addresses, flags (including what other areas are present), the memory stack pointer for the nonactive code stream, pointers to the other areas, and additional fields required by the base KP routines.

The scheduling area includes pointers to stall, restart and end handling routines, a fork block and a pointer to an additional fork block. With the exception of the end routine, most are required by high-IPL driver-level code only. Callers of EXE$KP_USER_ALLOC_KPB must supply an end routine to perform necessary cleanup of the allocated memory.

The VEST and spinlock areas are used primarily by the driver code.

The debug area offers limited tracing capability implemented in the driver support routines.

The user parameter area is simply undefined storage allocated contiguously to the other areas. The application is free to use this memory for its own needs.

C.1.4 Supplied KPB Allocation Routines

The operating system supplies two standard allocation routines for KPBs with associated stacks. The original kernel-mode, driver level interface has been retained unchanged from Alpha so that device drivers using the KP interface do not require source changes in this area. In addition, a mode-independent routine is available. The mode-independent routine calls application-specified routines to allocate the KPB and each of the stacks. Most new applications and applications porting to the KP API will use the latter routine.

Both the kernel and mode-independent routines initialize the KPB. C prototypes for all the supplied routines can be found in the head file EXE_ROUTINES.H.

C.1.5 Kernel Mode Allocation

The format for kernel mode allocation is as follows.


EXE$KP_ALLOCATE_KPB kpb, stack_size, flags, param_size

C prototype


status = EXE$KP_ALLOCATE_KPB( KPB_PPS kpb,
    int stack_size,
    int flags,
    int param_size)

For kernel mode use only. This routine has the same prototype as the original Alpha routine.

On I64, RSE stack size = memory stack size.

Note

The stack size is in bytes.

Parameters

  • KPB---Address of a longword to receive the address of the allocated data structure. By convention within OpenVMS APIs, 32-bit pointers are passed by 32-bit address (short pointer to short pointer to struct KPB).
  • STACK_SIZE---A 32-bit value denoting the size of the stacks to be allocated in bytes. Passed by value. The supplied value is rounded up to a multiple of the hardware page size. In any case, the minimum number of pages allocated will be no smaller than the SYSGEN parameter KSTACKPAGES. The stack is allocated on page boundaries with unmapped guard pages on both ends. The memory stack is allocated in 32-bit S0/S1 address space.
    On I64 systems, the RSE stack is sized identically to the memory stack and is allocated from 64-bit S2 address space.
  • FLAGS---Longword bitmask of flags. Passed by value. Table C-2 describes the flags that are defined for this parameter.

    Table C-2 Kernel Mode Allocation Flags
    Flag Description
    KP$M_VEST OpenVMS system KPB. In general, this flag should be set.
    KP$M_SPLOCK Allocate a spinlock area within the KPB.
    KP$M_DEBUG Allocate a debug area within the KPB.
    KP$M_DEALLOC_AT_END KPB should be automatically deallocated when the kernel process routine terminates.
    KP$M_SAVE_FP
    (IA64 only)
    Save floating-point context as well as the general registers. Certain operations, such as integer multiplication and division on IA64, can be implemented using floating-point operations. These operations use the minimal floating-point register set, which is by definition not part of the preserved register set. If the application uses only the minimal floating-point register set, this bit need not be set. If the application uses floating-point data, this bit must be set to preserve the correct floating point context across the stack switch.
    KP$M_SET_STACK_LIMITS Call $SETSTK_64 at every stack switch. Process-scope applications should always set this flag because condition handling requires accurate stack limit values.
  • PARAM_SIZE---Longword by value. Size, in bytes, of the user parameter area in the KPB. Pass zero if no parameter area is required.
    Return value (status):
    SS$_NORMAL
    SS$_INSFMEM
    SS$_INSFARG
    SS$_INSFRPGS

C.1.6 Mode-Independent Allocation

The syntax for mode-independent allocation is as follows.


EXE$KP_USER_ALLOC_KPB kpb, flags, param_size, *kpb_alloc, mem_stack_bytes,
*memstk_alloc, rse_stack_bytes, *rsestk_alloc, *end_rtn

C prototype


status = EXE$KP_USER_ALLOC_KPB(  KPB_PPS kpb, int flags,
     int param_size,
     int (*kpb_alloc)(),
     int mem_stack_bytes,
     int(*memstk_alloc)(),
     int rse_stack_bytes,
     int(*rsestk_alloc)(),
     void(*end_rtn)())

Parameters

  • KPB---Address of a longword to receive the address of the allocated data structure. By convention within OpenVMS APIs, 32-bit pointers are passed by 32-bit address (short pointer to short pointer to struct KPB).
  • FLAGS---Longword bitmask of flags. Passed by value. Table C-3 describes the flags that are defined for this parameter.

    Table C-3 Mode-Independent Allocation Flags
    Flag Description
    KP$M_VEST OpenVMS system KPB. In general, this flag should be set.
    KP$M_SPLOCK Allocate a spinlock area within the KPB.
    KP$M_DEBUG Allocate a debug area within the KPB.
    KP$M_DEALLOC_AT_END KPB should be automatically deallocated when the kernel process routine terminates.
    KP$M_SAVE_FP (I64 only; ignored on Alpha) Save floating-point context as well as the general registers. Certain operations such as integer multiplication and division on I64 systems can be implemented using floating-point operations. These operations use the minimal floating-point register set, which is by definition not part of the preserved register set. If the application uses only the minimal floating-point register set, this bit need not be set. If the application uses floating-point data, this bit must be set to preserve the correct floating-point context across the stack switch.
    KP$M_SET_STACK_LIMITS Call $SETSTK_64 at every stack switch. Process-scope applications should always set this flag because condition handling requires accurate stack limit values.
  • PARAM_SIZE -- Longword by value. Size, in bytes, of the user parameter area in the KPB. Pass zero if no parameter area is required.
  • KPB_ALLOC -- Address of a procedure descriptor for the routine to allocate the KPB. The allocation routine will be called with two parameters, a length and a longword to receive the address of the allocated KPB. The length parameter is in bytes and is passed by reference. The allocation routine must allocate at least the required number of bytes out of 32-bit space appropriate for the mode in which the KP routine will run. The address is expected to be at least quadword aligned and the actual allocation size must be written back into the length argument.
  • MEM_STACK_BYTES -- 32-bit value denoting the size of the memory stack to be allocated in bytes. Passed by value. The supplied value is rounded up to a multiple of the hardware page size.
  • MEMSTK_ALLOC -- Address of a procedure descriptor for a routine to allocate the memory stack. Section C.1.7 describes the format and required actions of this routine.
  • RSE_STACK_BYTES -- 32-bit value that denotes the size, in bytes, of the memory stack to be allocated. Passed by value. The supplied value is rounded up to a multiple of the hardware page size.
  • RSESTK_ALLOC -- Address of a procedure descriptor for a routine to allocate the memory stack. Section C.1.7 describes the format and required actions of this routine.
  • END_RTN -- Address of a procedure descriptor for the end routine. The end routine is called when the KP routine terminates, either by calling EXE$KP_END or by returning. An end routine is required to either cache or deallocate the stacks and KPB.

C.1.7 Stack Allocation APIs

The stack allocation routines have identical APIs for both memory and RSE stack allocation. The routine is called with a 64-bit address of the allocated KPB and an integral number of hardware-specific pages (not pagelets) to allocate.

The syntax for specifying stack allocation routines is as follows:


status = alloc-routine (KPB_PQ kpb, const int stack_pages)

  • KPB---64-bit address of a previously allocated KPB. Passed by 64-bit reference.
  • STACK_PAGES---Integral number of whole pages to allocate. Passed by 32-bit value.

The allocation routine is expected to allocate page-aligned address space. While not strictly necessary, it is strongly suggested that the stack be protected by no-access guard pages on both ends. HP also recommends that the minimum stack size be at least the value of the SYSGEN parameter KSTACKPAGES (global cell SGN$GL_KSTACKPAG). This allows a certain measure of control of the stack size without necessitating recompilation of the application. Also, stack usage on I64 is significantly different than on previous architectures, and the previously allocated stack size might not be adequate.

The memory stack allocation routine must set the following KPB fields as follows:

  • KPB$IS_STACK_SIZE---The size of the stack in bytes, not including guard pages.
  • KPB$PQ_STACK_BASE---The address of the stack base. For the memory stack, this is the address of the byte past the end of the allocated stack. In other words, this is the sum of the allocated address plus the size of the allocation in bytes.

The memory stack allocation routine can set the following KPB field as follows:

  • KPB$Q_MEM_REGION_ID---The region ID returned by the $CREATE_REGION system service. This information is required to deallocate the stack.

The RSE stack allocation routine must set the following KPB fields as follows:

  • KPB$IS_STACK_SIZE---The size of the stack in bytes, not including guard pages.
  • KPB$PQ_STACK_BASE-- The address of the stack base. For the RSE stack, this is the lowest allocated address.

The RSE stack allocation routine can set the following KPB field as follows:

  • KPB$Q_REGION_ID---The region ID returned by the $CREATE_REGION system service. This information is required to deallocate the stack.

Both routines must return status to the calling routine.


Previous Next Contents Index