Document revision date: 19 July 1999
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

OpenVMS Alpha Guide to Upgrading Privileged-Code Applications


Previous Contents Index

B.9 IOC_STD$CREATE_DIOBM

Routine IOC_STD$CREATE_DIOBM is a new routine that is used to derive a 32-bit system virtual address for a specific number of PTEs that are pointed to by a 64-bit process virtual address. This routine allocates a "primary" DIOBM structure of sufficient size for its needs and returns a pointer to it. When the derived 32-bit system virtual address is no longer required the DIOBM must be released by calling the IOC_STD$RELEASE_DIOBM routine.

The algorithm used by this routine is very similar to one used by IOC_STD$FILL_DIOBM as described in Section B.10. The significant difference is that IOC_STD$CREATE_DIOBM allocates a sufficiently sized primary DIOBM structure for its needs and does not depend on a preallocated fixed-size DIOBM. This routine is designed for previous users of the MMG$IOLOCK routine that do not have an embedded DIOBM to work with, but can maintain a single pointer to the external DIOBM structure that is returned by IOC_STD$CREATE_DIOBM.

The interface for IOC_STD$CREATE_DIOBM is:


int ioc_std$create_diobm (const PTE_PQ va_pte, const uint32 pte_count, 
                          const uint32 flags, 
                          PTE **svapte_p, DIOBM **diobm_p) 

Table B-7 summarizes the use of the arguments.

Table B-7 IOC_STD$CREATE_DIOBM Arguments
Argument Type Access Description
va_pte PTE_PQ Input A 64-bit pointer to the first PTE that maps the user buffer.
pte_count uint32 Input Number of PTEs that are required to map the entire buffer.
svapte_p PTE ** Output Pointer to a 32-bit PTE address that is returned. The returned address is always a 32-bit system virtual address.
flags uint32 Input Option flags. The following bit mask values can be set:

DIOBM$M_NORESWAIT - Disable resource wait.

All other option bits must be zero.

diobm_p DIOBM ** Output Pointer to DIOBM address that is returned.

This routine requires system resources, nonpaged pool and possibly SPTEs. If there are insufficient resources this routine will, by default, place the process (kernel thread) in a kernel mode wait state for nonpaged pool and try again until it succeeds. In this case, the return value of this routine is always SS$_NORMAL because it will not return until it can do so successfully.

However, the caller can inhibit this resource wait by setting the DIOBM$M_NORESWAIT option in the flags parameter. When this is done an error status is returned to the caller if there are insufficient system resources. This capability is intended to be used in contexts where a resource wait in kernel mode is not acceptable or if the caller can readily put the process into a wait state in the requestor's mode.

This routine must be called in process context and assumes that it was called at IPL 2, or minimally that it can lower IPL to 2.

The use of the DIOBM structure by this routine is described in detail in Appendix A.

This routine is coded in C and is contained in the new DIOBM.C module.

B.10 IOC_STD$FILL_DIOBM

Routine IOC_STD$FILL_DIOBM is a new routine that is used to derive a 32-bit system virtual address for a specific number of PTEs that are pointed to by a 64-bit process virtual address. This routine employs a previously allocated or embedded "primary" DIOBM structure that must be supplied as one of its inputs. When the derived 32-bit system virtual address is no longer required the DIOBM must be released by calling the IOC_STD$RELEASE_DIOBM routine.

This routine derives a 32-bit system virtual address for the PTEs using one of the following methods:

  1. If the PTEs are in the region of page table space that maps S0/S1 space, a 32-bit PTE address using the SPT window is returned.
  2. If less than or equal to DIOBM$K_PTECNT_FIX PTEs are required, the PTEs are copied into the PTE vector in the DIOBM and the 32-bit system virtual address of the PTE vector in the DIOBM is returned.
  3. If more than DIOBM$K_PTECNT_FIX and less than or equal to ioc$gl_diobm_ptecnt_max PTEs are required, a secondary DIOBM is allocated, the PTEs are copied into the PTE vector in the secondary DIOBM, and the 32-bit system virtual address of the PTE vector in the secondary DIOBM is returned.
  4. If more than ioc$gl_diobm_ptecnt_max PTEs are required, a temporary PTE window in S0/S1 space is created that maps the neccessary process level-3 page table pages. These level-3 page table pages are locked into memory and the 32-bit S0/S1 address of the PTEs through the PTE window is returned.

The interface for IOC_STD$FILL_DIOBM is:


int ioc_std$fill_diobm (DIOBM *const diobm, const PTE_PQ va_pte, 
                        const uint32 pte_count, const uint32 flags, 
                        PTE **svapte_p) 

Table B-8 summarizes the use of the arguments.

Table B-8 IOC_STD$FILL_DIOBM Arguments
Argument Type Access Description
diobm DIOBM * Input Pointer to a previously allocated but unused or uninitialized DIOBM structure.
va_pte PTE_PQ Input A 64-bit pointer to the first PTE that maps the user buffer.
pte_count uint32 Input Number of PTEs that are required to map the entire buffer.
flags uint32 Input Option flags. The following bit mask values can be set:

DIOBM$M_NORESWAIT - Disable resource wait.

All other option bits must be zero.

svapte_p PTE ** Output Pointer to a 32-bit PTE address that is returned. The returned address is always a 32-bit system virtual address.

This routine may require system resources, either nonpaged pool or SPTEs, depending on the number of PTEs that are required to map the buffer. If there are insufficient resources this routine will, by default, place the process (kernel thread) in a kernel mode wait state for nonpaged pool and try again until it succeeds. In this case, the return value of this routine is always SS$_NORMAL because it will not return until it can do so successfully.

However, the caller can inhibit this resource wait by setting the DIOBM$M_NORESWAIT option in the flags parameter. When this is done an error status is returned to the caller if there are insufficient system resources. This capability is intended to be used in contexts where a resource wait in kernel mode is not acceptable or if the caller can readily put the process into a wait state in the requestor's mode.

This routine must be called in process context and assumes that it was called at IPL 2, or minimally that it can lower IPL to 2.

The use of the DIOBM structure by this routine is described in detail in Appendix A. The normal version of the IOC_STD$FILL_DIOBM routine makes no assumptions about the contents of the input DIOBM structure. In contrast, the full checking version of this routine in the IO_ROUTINES_MON.EXE execlet performs some initial validation and declares an INCONSTATE bugcheck should these check fail.

B.11 IOC_STD$PTETOPFN

The routine IOC_STD$PTETOPFN allows drivers or other components to obtain the PFN for a page that has been previously locked into memory but the valid bit in its PTE is currently clear. This routine handles transition PTEs and PTEs that have reverted into GPTX format.

In releases prior to OpenVMS Alpha Version 7.0, the interface for this routine was:


int ioc_std$ptetopfn (PTE *pte); 

The new interface for this routine is:


int ioc_std$ptetopfn (PTE_PQ pte); 

The first interface difference is that IOC_STD$PTETOPFN uses the full 64-bits of the caller's PTE address that is passed by value. The second interface difference is not apparent from the above function prototype. The IOC_STD$PTETOPFN routine has been enhanced to handle the case where the pte$v_valid bit is set in the PTE. Therefore, drivers can use this routine without first checking the valid bit.

Both of these are upwardly compatible changes to the interface.

B.12 IOC_STD$RELEASE_DIOBM

Routine IOC_STD$RELEASE_DIOBM is a new routine that is used to release the PTE mapping resources that were setup by a prior call to either the IOC_STD$CREATE_DIOBM or IOC_STD$FILL_DIOBM routines.

The interface for IOC_STD$RELEASE_DIOBM is:


int ioc_std$release_diobm (DIOBM *const diobm) 

Table B-9 summarizes the use of the arguments.

Table B-9 IOC_STD$RELEASE_DIOBM Arguments
Argument Type Access Description
diobm DIOBM * Input Pointer to an active primary DIOBM.

This routine deallocates any secondary DIOBM that is connected to the primary DIOBM. If this primary DIOBM has a PTE window the resources used for the window are deallocated. If the primary DIOBM was allocated by IOC_STD$CREATE_DIOBM, the primary DIOBM is deallocate as well. The use of the DIOBM structure by this routine is described in detail in Appendix A.

The returned value of this routine is always SS$_NORMAL.

This routine does not depend on process context. However, the IPL and spinlocks of the caller must allow this routine to acquire and restore the MMG spinlock.

This routine is coded in C and is contained in the new DIOBM.C module.

B.13 IOC_STD$SIMREQCOM, IOC$SIMREQCOM

The routine IOC_STD$SIMREQCOM allows drivers or other components to complete an I/O that does not have a normal IRP associated with it. Because this routine does not have an IRP, the necessary information to signal an I/O completion is passed directly in separate parameters. For example, the user's IOSB address, the event flag value, a pointer to an ACB, and the caller's access mode are among the parameters.

In releases prior to OpenVMS Alpha Version 7.0, the interface for this routine was:


int ioc_std$simreqcom (int32 iosb[2], int pri, int efn, int32 iost[2], 
                       ACB *acb, int acmode); 

The new interface for this routine is:


int ioc_std$simreqcom (VOID_PQ iosb_p, int pri, int efn, int32 iost[2], 
                       ACB *acb, int acmode); 

The first interface difference is that IOC_STD$SIMREQCOM uses the full 64-bits of the caller's IOSB address iosb_p that is passed by value. The second interface difference is not apparent from the above function prototype. The IOC_STD$SIMREQCOM routine has been enhanced to accept either a pointer to an ACB64 or ACB structure.

Both of these are upwardly compatible changes to the interface.

B.13.1 CALL_SIMREQCOM macro

The CALL_SIMREQCOM MACRO-32 macro facilitates the use of the IOC_STD$SIMREQCOM routine by code that was originally written to use the JSB-interface counterpart IOC$SIMREQCOM. The CALL_SIMREQCOM macro has implicit register inputs that correspond to the register inputs of the JSB-interface for the IOC$SIMREQCOM routine.

Because this macro uses registers for its inputs, it can be altered to use the full 64-bit value of the caller's IOSB address which is passed in register R1.

B.13.2 IOC$SIMREQCOM

The IOC$SIMREQCOM routine is simply a JSB-to-CALL jacket routine around IOC_STD$SIMREQCOM. Because it is implemented through the use of the CALL_SIMREQCOM macro, IOC$SIMREQCOM transparently supports a 64-bit caller's IOSB address in the R1 parameter. Similarly, this routine allows R5 to point to either an ACB or ACB64 structure.

B.14 IOC_STD$SVAPTE_IN_BUF

Routine IOC_STD$SVAPTE_IN_BUF is a new routine that is used to calculate a 32-bit PTE address for a virtual address within a buffer that has been previously locked for this IRP and for which a 32-bit PTE address has been derived.

It is the caller's responsibility to assure that the virtual address is a legal address within a buffer that has been locked into memory prior to calling this routine and that a 32-bit PTE address has been derived for this buffer. The IOC_STD$SVAPTE_IN_BUF routine may declare a bugcheck if either of these conditions have not been met.

The interface for IOC_STD$SVAPTE_IN_BUF is:


int ioc_std$svapte_in_buf (IRP *irp, VOID_PQ va, PTE **svapte_p) 

Table B-10 summarizes the use of the arguments.

Table B-10 IOC_STD$SVAPTE_IN_BUF Arguments
Argument Type Access Description
irp IRP * Input Pointer to the current IRP.
va VOID_PQ Input Virtual address within the buffer that was locked for this IRP.
svapte_p PTE ** Output Pointer to a 32-bit PTE address that is returned. The returned address is a 32-bit system virtual address that is derived based on the values in irp$l_svapte and irp$q_qio_p1.

Table B-11 lists all the implicit inputs that are used by this routine.

Table B-11 IOC_STD$SVAPTE_IN_BUF Implicit Inputs
Field Use
irp$q_qio_p1 Virtual address of the start of the buffer that has been previously locked into memory for this IRP.
irp$l_svapte 32-bit PTE address for the PTEs that map the buffer.

The returned value of this routine is always SS$_NORMAL.

This routine is coded in C and is contained in the new SVAPTE2.C module.

B.15 IOC_STD$VA_TO_PA

Routine IOC_STD$VA_TO_PA is a new routine that is used to derive a 64-bit physical memory address for a 64-bit virtual address. The virtual address is interpreted in the context of the current process and may be in either process-private or system space.

It is the caller's responsibility to assure that the virtual address is a legal address and that the memory page containing the specified virtual address is locked into memory prior to calling this routine. The IOC_STD$VA_TO_PA routine may declare a bugcheck if either of these conditions have not been met.

The interface for IOC_STD$VA_TO_PA is:


VOID_PQ ioc_std$va_to_pa (VOID_PQ va, VOID_PPQ pa_p) 

The returned value of this routine is the 64-bit physical address. Table B-12 summarizes the use of the arguments.

Table B-12 IOC_STD$VA_TO_PA Arguments
Argument Type Access Description
va VOID_PQ Input A 64-bit virtual address.
pa_p VOID_PPQ Output Pointer to a 64-bit physical address that is returned. This parameter is optional and may either be omitted entirely or specified as 0. The physical address is also returned as the value of the routine.

Currently, the physical address for a process virtual address can be derived by calling MMG_STD$SVAPTECHK followed by IOC$SVAPTE_TO_PA. However, as described in Section 2.2.3, the MMG_STD$SVAPTECHK routine no longer accepts a P0/P1 address. The new IOC_STD$VA_TO_PA routine provides a direct way of computing the physical address from a process virtual address.

B.16 MMG_STD$GET_PTE_FOR_VA

Routine MMG_STD$GET_PTE_FOR_VA is a new routine that is being added for use in the Remote SDA SYSAP within SYS$SCS.

Routine MMG_STD$GET_PTE_FOR_VA attempts to obtain the Level-3 PTE containing a PFN that maps the specified virtual address for a specified process. If the requested PTE cannot be accessed either because the virtual address is not mapped or a needed page table page is not currently in physical memory, an error status is returned. Additionally, if the Level-3 PTE does not contain a useable PFN an error status is returned.

A successful return status from this routine means that the PFN field of the returned PTE contains the physical page number for the input virtual address. Note that there are page states where the PTE contains a useable PFN but the PTE$V_VALID bit is clear. Therefore, the PTE$V_VALID bit in the returned PTE might be clear. Note also, that this routine returns a PTE from the Global Page Table when the slave PTE has reverted to GPTX format and the master PTE in the GPT still contains a PFN.

This routine is somewhat similar to MMG_STD$CALC_VAPTE except that it does not assume that the virtual address is valid or that the necessary page tables are resident in memory. Because this routine does not assume the virtual address is valid, it uses the reserved system space window to traverse the specified process' page tables in a top-down fashion. It uses this method for all process-private virtual addresses even if the specified process happens to be the current process on this CPU. This allows this routine to locate the Level-3 PTE even if some of the intervening page table pages are in transition. However, for shared system space virtual addresses this routine uses the currently active page tables instead of the reserved system window to locate the corresponding Level-3 PTE. This is possible because shared system space page table pages are not pageable and have PTE$V_VALID set if they are mapped.

This routine acquires and restores the MMG spinlock. This routine declares a bugcheck if the reserved system space window is already in use. This routine releases and invalidates the window before returning.

The interface for MMG_STD$GET_PTE_FOR_VA is:


int mmg_std$get_pte_for_va (VOID_PQ const va, PHD *const phd, PTE_PQ pte_p) 

Table B-13 summarizes the use of the arguments.

Table B-13 MMG_STD$GET_PTE_FOR_VA Arguments
Argument Type Access Description
va VOID_PQ Input A 64-bit virtual address.
phd PHD * Input Pointer to the PHD for the desired process address space. If zero, the current process on the current CPU is assumed. This parameter is not used, and may be zero, if the virtual address is in shared system space.
pte_p PTE_PQ Output Address of Level-3 PTE value that is returned. A PTE value is returned only if the routine returns a successful condition value.

The returned value of this routine is a system condition value:
  SS$_NORMAL The PTE that maps the specified virtual address in the address space of the specified process contains a physical page number and was successfully returned.
  SS$_ACCVIO The PTE that maps the specified virtual address in the address space of the specified process could not be obtained, i.e. the specified virtual address is not mapped or one of the necessary page table pages is not currently resident, or the level-3 PTE did not contain a physical page number.

B.17 MMG_STD$IOLOCK, MMG$IOLOCK, MMG_STD$IOLOCK_BUF

The interface for the MMG_STD$IOLOCK routine is:


int mmg_std$iolock (void *buf, int bufsiz, int is_read, PCB *pcb, void **svapte_p) 

This routine returns a 32-bit address by reference (the svapte_p parameter) which, depending on the routine status, may specify the address of the first PTE or the address of a location in the buffer that must be faulted in.

The new version of this routine must accept a 64-bit buffer address. In addition, the new version must also return either a 64-bit PTE or buffer address. This is an incompatible interface change because this return parameter is passed by reference. Thus, MMG_STD$IOLOCK has been removed and is replaced by the new MMG_STD$IOLOCK_BUF routine.

The interface for MMG_STD$IOLOCK_BUF is:


int mmg_std$iolock_buf (VOID_PQ const buf, const int bufsiz, 
                        const int is_read, PCB *const pcb, 
                        PTE_PPQ va_pte_p, VOID **fault_va_p) 

Table B-14 summarizes the use of the arguments.

Table B-14 MMG_STD$IOLOCK_BUF Arguments
Argument Type Access Description
buf VOID_PQ Input 64-bit pointer to the buffer that is to be locked.
bufsiz int Input Size of the buffer in bytes.
is_read int Input Contains the value 0 if buffer will be only written to the device, 1 if the buffer will be only read from device, 5 if the buffer will be modified by the device.
pcb PCB * Input Pointer to the process PCB.
va_pte_p PTE_PPQ Output Pointer to a 64-bit PTE address that is returned. If the returned value of the function is successful, then the address returned is the 64-bit virtual address of the first PTE that maps the buffer. For all other function return values the value returned in this parameter is undefined.
fault_va_p VOID_PPQ Output Pointer to a 64-bit address that is returned. If the returned value of the function is 0, then the address returned is the 64-bit address within the buffer that must be faulted in. For all other function return values the value returned in this parameter is undefined.

The returned value of this routine is a system condition value or the value zero:
  Success A successful VMS condition value indicates that the buffer has been locked and that the 64-bit virtual address of the first PTE that maps the buffer has been returned using the va_pte_p parameter.
  0 This return value means that a page fault is required for a page in the buffer. The virtual address of the page is returned using the fault_va_p parameter. Any portion of the buffer that may have been locked before this condition was detected has been unlocked before returning.
  Failure Standard VMS condition value that indicates the failure.

Just like MMG_STD$IOLOCK, the MMG_STD$IOLOCK_BUF routine must be called in process context at IPL 2 and it acquires and releases the MMG spinlock.

Although the interfaces for the MMG_STD$IOLOCK_BUF and MMG_STD$IOLOCK routines are similar, there are important differences between these routines that go beyond the width of the address parameters.

  1. The 32-bit address that is returned by MMG_STD$IOLOCK in the svapte_p parameter is valid regardless of process context. In contrast, the 64-bit address that is returned by MMG_STD$IOLOCK_BUF in the va_pte_p parameter may be valid only in the context of the current process. The new routines IOC_STD$FILL_DIOBM and IOC_STD$CREATE_DIOBM are designed to deal with this difference.
  2. The MMG_STD$IOLOCK routine locks into memory the level-3 page tables that contain the PTEs that map the buffer as well as the buffer pages. In contrast, MMG_STD$IOLOCK_BUF only locks the buffer pages. It does not lock the level-3 page tables because it would be difficult to unlock them in the absence of process context where MMG_STD$IOUNLOCK_BUF is called. Moreover, the mechanisms used by IOC_STD$FILL_DIOBM and IOC_STD$CREATE_DIOBM usually do not require the locking of the level-3 page tables. Only when the PTE window method is used by IOC_STD$FILL_DIOBM or IOC_STD$CREATE_DIOBM will these routines need to lock the level-3 page table pages into memory. When this case applies, the IOC_STD$RELEASE_DIOBM routine has enough information to unlock the level-3 page tables regardless of process context.


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
6466PRO_009.HTML