/*static char *SCCSID = "@(#)vmlocal.h  6.10 92/03/11";*/

/*
 *       IBM/Microsoft Confidential
 *
 *       Copyright (c) IBM Corporation 1987, 1989
 *       Copyright (c) Microsoft Corporation 1987, 1989
 *
 *       All Rights Reserved
 *
 *       History of Changes:
 * 147968 5/11/96  RJM Change FSD and DD system owners to use HMTEs
 */

#define PARASIZE 16
#define OS2V13 1

/***LC+ Naming Conventions
 *
 *      The following Hungarian conventions are used in
 *      the Virtual Memory Manager.
 *
 *      Names are chosen for fields and variables so that
 *      a prefix indicates the type of the field or variable.
 *
 *      Base record types are indicated by two-letter abbreviations, e.g.:
 *
 *      ar      Arena Record
 *      bh      BMP Header
 *      co      Context Record
 *      ob      Object Record
 *
 *      Handles to records are specified by prefixing the
 *      base record type abbreviation by "h":
 *
 *      har     Arena Record handle
 *      hco     Context Record handle
 *      hob     Object Record Handle
 *
 *      Pointers to records or handles are specified by
 *      prefixing the type with "p":
 *
 *      par     Pointer to an Arena Record
 *      pco     Pointer to a Context Record
 *      pob     Pointer to an Object Record
 *      phob    Pointer to an Object Record handle
 *          etc.
 *
 *      Pointers to pointers add another "p" prefix.
 *
 *      Field names begin with "xx_yyy" where "xx" is the abbreviation
 *      for the record type and "yyy" is the type abbreviation.
 *
 *      Typedefs are specified all in capital letters and are prefixed
 *      with "VM" to indicate the component defining them:
 *
 *      VMAR    Arena Record
 *
 *      All field and variable names may have a descriptive suffix
 *      where appropriate:
 *
 *      VMHOB hobptda;          /* Handle to (the object record for) a PTDA *
 *      VMHOB ob_hobmte;        /* Object Record field containing MTE handle *
 *
 *      General PM Hungarian conventions are followed for primitive types.
 */

/***LC+ LVMBM - Local constants for bitmap code */

#define VM_BM_INC       4       /* Bitmap growth unit in bytes */
#define VM_BMD_INC      1       /* Bitmap directory growth unit (elements) */
#define VM_HASH_INC     16      /* Hash table growth unit (elements) */


/***LC+ VMARMX  Absolute maxima for numbers of arenas */

#define         VM_MAX_SHARED_TILED_ARENAS 1
#ifdef OS2V13
#define         VM_MAX_SHARED_UNTILED_ARENAS 0
#else
#define         VM_MAX_SHARED_UNTILED_ARENAS 1
#endif
#define         VM_MAX_SHARED_ARENAS (VM_MAX_SHARED_TILED_ARENAS \
                                     + VM_MAX_SHARED_UNTILED_ARENAS)

#define         VM_MAX_PRIV_TILED_ARENAS  TKCPTDAMAX
#ifdef OS2V13
#define         VM_MAX_PRIV_UNTILED_ARENAS (0 * TKCPTDAMAX)
#else
#define         VM_MAX_PRIV_UNTILED_ARENAS (1 * TKCPTDAMAX)
#endif
#define         VM_MAX_PRIV_ARENAS (VM_MAX_PRIV_TILED_ARENAS \
                                     + VM_MAX_PRIV_UNTILED_ARENAS)

#define         VM_MAX_ARENAS (1 + VM_MAX_SHARED_ARENAS \
                                 + VM_MAX_PRIV_ARENAS)
/*end*/

/***LC+ VMLSKEW - Skew values for certain system arena allocs */

#define         VM_SKEW_LDT     7
#define         VM_SKEW_GDT     5
/* see routine selReinit for GDT alloc */
#define         VM_SKEW_PTOV    3
#define         VM_SKEW_PTOG    3
#define         VM_SKEW_32K     8

/***LC+ VMOB_CLOCK - ob_cslock and ob_cllock fields and flags */

#define VMOB_CLOCK_MAX          0xff    /* Maximum short or long-term lock */

/*end*/

/***LC+ VMOB_CSLOCK - ob_cslock related fields */

#define VMOB_CSLOCK_TIMEOUT  10000   // 10 second timeout for short term locks


/***LC+ VMOB_CBSEM - ob_bsemcnt fields and flags */

#define VMOB_CBSEM_WAIT         1       /* Waiting on object semaphore */
#define VMOB_CBSEM_INC          2       /* Amount to increment/decrement
                                         * ob_bsemcnt field when taking or
                                         * releasing a the object semaphore
                                         */
#define VMOB_CBSEM_MAX        0xfe      /* Maximum semaphore count */
#define VMOB_CBSEM_MASK       0xfe      /* Semaphore count mask */


/***LC+ VMUNDO - Flags for undoing VM operations */

#define VM_FREE_PG_CONTEXT      1       /* Call PGFreeContext */
#define VM_FREE_PTDA_HANDLE     2       /* Free PTDA Pseudo handle */
#define VM_FREE_LOCATE_TILED    4       /* Free locate tables for
                                           private tiled arena */
#define VM_FREE_LOCATE_UNTILED  8       /* Free locate tables for
                                           private untiled arena */
#define VM_FREE_PRIV_TILED_SENT 16      /* Free private tiled arena
                                           sentinel */
#define VM_FREE_PRIV_UNTILED_SENT 32    /* Free private untiled arena
                                           sentinel */
#define VM_FREE_AH_TILED_HOB    64      /* Free Priv. tiled arena
                                           pseudo-handle */
#define VM_FREE_AH_UNTILED_HOB  128     /* Free Priv. untiled arena
                                           pseudo-handle */
/*XLATOFF*/
#if (3L << VMAC_LOCSHIFT) != VMAC_LOCMASK
        Compile-time Assertion Failure
#endif
#if (7L << VMAC_ALIGNSHIFT) != VMAC_ALIGNMASK
        Compile-time Assertion Failure
#endif
#if (3L << VMAC_ARENASHIFT) != VMAC_ARENAMASK
        Compile-time Assertion Failure
#endif
#if ((OB_SHRINKABLE + OB_HUGE) << VMAC_OBSHIFT) != VMAC_OBMASK
        Compile-time Assertion Failure
#endif

#define VMAC_PAFLAGS    (PG_STATE | PG_PERM | PG_MODIFIER)/*passed to PGAlloc*/
#define vmac_INVALID_HEAP  (VMAC_OBSHRINK | VMAC_OBHUGE | VMAC_VDM | \
        VMAC_RELOAD | VMAC_OBAPI | VMAC_PRERES | VMAC_PROT |  \
        PG_UVIRT | VMAC_SHARED)
/* XLATON */
/*end*/


/***LC+ ARENA - Arena constants */

#define VM_MAX_HANDLES (VMMINOWNER - 1)       /* Max number of handles */
#define vm_MAX_BMP32_HANDLES VM_MAX_HANDLES   /* Max BMP32 handles */
#define VM_MAX_ARENA_RECORDS (_64K - 1)       /* Max number of arena
                                                 records */
#define VM_MAX_CONTEXT_RECORDS (2*_64K - 1)   /* Max number of context
                                                 records */
#define VM_PROT_PACKSHRLBDRY   0x19ff0000     /* Lower boundary of PACKSHR
                                                 region with Protect region */
#define VM_NOPROT_PACKSHRLBDRY 0x1dff0000     /* Lower boundary of PACKSHR
                                                 region without Protect region */
#define TILEDSEGSHIFT 4
#define _64Meg 0x4000000
#define _128Meg (_64Meg*2)
#define _32MegPages 8192



/***LC+ LATPT - Per-type arena constants for private tiled arenas
 *
 *      Each bit represents 64K of linear address space
 *      Each bitmap contains 32 dword entries max (= 1K bits) mapping 64Meg
 *      8 bitmaps are needed to map all 512 Meg
 *      The hash table contains 512 entries max
 */

#define VMAT_PT_lGranShift      16                      /* Gran exponent */
#define VMAT_PT_lGran   (1L <<  VMAT_PT_lGranShift)     /* Granularity */

#define VMAT_PT_laddrAbsMin  VMAT_PT_lGran              /* Abs min boundary */
#define VMAT_PT_laddrAbsMax     (MAXCRLADDR - _64MEG)
                                                        /* Abs max boundary */
#define VMAT_PT_laddrInitMin VMAT_PT_laddrAbsMin        /* Init min = bottom */
#define VMAT_PT_laddrInitMax VMAT_PT_laddrInitMin       /* Init max = bottom */
#define VMAT_PT_cbInitBetween   0L                      /* Init size of no-mans
                                                           land before start of
                                                           arena */


#define VMAT_PT_lbdMinSize      16                      /* Min bitmap dirsize */
#define VMAT_PT_lHashMinSize    16                      /* Min hash tab size */
#define VMAT_PT_lbmMinSize      16

/* Equates for hash table number field */

#define VMAT_PT_lHashNumbFldSize 9                      /* Hash numb fldsiz */
#define VMAT_PT_lHashNumbShift  VMAT_PT_lGranShift      /* Hash number shift */
#define VMAT_PT_lHashNumbAbsMax \
  ((1 << VMAT_PT_lHashNumbFldSize) - 1)                 /* Abs Max hash numb */
#define VMAT_PT_lHashNumbMask \
  (VMAT_PT_lHashNumbAbsMax<<VMAT_PT_lHashNumbShift)     /* Hash number mask */
#define VMAT_PT_laddrMinNoWrap (VMAT_PT_laddrAbsMin)    /* Min no wrap laddr */
#define VMAT_PT_laddrMaxNoWrap \
  (VMAT_PT_laddrMinNoWrap + VMAT_PT_lHashNumbMask)      /* Max no wrap laddr */
/*  Equates for bit number within bitmap entry */


#define VMAT_PT_lbmeBitNumbFldSize  5                   /* Bitmap ent fldsiz */
#define VMAT_PT_lbmeBitNumbShift VMAT_PT_lGranShift     /* Bit number shift */
#define VMAT_PT_lbmeBitNumbMax \
  ((1L << VMAT_PT_lbmeBitNumbFldSize) - 1)              /* Max bit number */
#define VMAT_PT_lbmeBitNumbMask \
  (VMAT_PT_lbmeBitNumbMax << (VMAT_PT_lbmeBitNumbShift)) /* Bit number mask */

/*  Equates for bitmap entry number field */

#define VMAT_PT_lbmeNumbFldSize  5                     /* Bitmap ent # fldsiz */
#define VMAT_PT_lbmeNumbShift  \
  (VMAT_PT_lbmeBitNumbShift + VMAT_PT_lbmeBitNumbFldSize)
                                                        /* Bitmap ent # shift */
#define VMAT_PT_lbmeNumbAbsMax \
  ((1 << VMAT_PT_lbmeNumbFldSize) - 1)                  /* Abs Max bitmap ent */
#define VMAT_PT_lbmeNumbMask \
  (VMAT_PT_lbmeNumbAbsMax<<VMAT_PT_lbmeNumbShift)       /* Bitmap ent # mask */

/*  Equates for bitmap number field */

#define VMAT_PT_lbmNumbFldSize  \
  (29 - VMAT_PT_lbmeNumbFldSize - VMAT_PT_lbmeNumbShift)/* Bitmap # fld size */
#define VMAT_PT_lbmNumbShift \
  (VMAT_PT_lbmeNumbShift + VMAT_PT_lbmeNumbFldSize)     /* Bitmap # shift */
#define VMAT_PT_lbmNumbAbsMax \
  ((1 << VMAT_PT_lbmNumbFldSize) - 1)                   /* Abs Max bitmap # */
#define VMAT_PT_lbmNumbMask \
  (VMAT_PT_lbmNumbAbsMax<<VMAT_PT_lbmNumbShift)         /* Bitmap number mask */
#define VMAT_PT_flInit \
        (VMAH_NO_HASH_WRAP | VMAH_BITMAP_BYPASS)        /* Initial flags */

/*end*/


/***LC+ LATPM  Per-type arena constants for private MVDM arenas
 *
 *      Each bit represents 4K of linear address space
 *      Each bitmap contains 512 entries max (= 16K bits) mapping 64Meg
 *      8 bitmaps are needed to map all 512 Meg
 *      The hash table contains 512 entries max
 */

#define VMAT_PM_lGranShift      12L                     /* Gran exponent */
#define VMAT_PM_lGran   (1L <<  VMAT_PM_lGranShift)     /* Granularity */

#define VMAT_PM_laddrAbsMin     0L                      /* Abs min boundary */
#define VMAT_PM_laddrAbsMax     (MAXCRLADDR - _64MEG)
#define VMAT_PM_laddrInitMin    VMAT_PM_laddrAbsMin     /* Init Min = bottom */
#define VMAT_PM_laddrInitMax    VMAT_PM_laddrInitMin    /* Init Max = bottom */
#define VMAT_PM_cbInitBetween   0L                      /* Init size of no-mans
                                                           land before start of
                                                           arena */

#define VMAT_PM_lbdMinSize      16L                     /* Min bitmap dirsize */
#define VMAT_PM_lHashMinSize    16                      /* Min hash tab size */
#define VMAT_PM_lbmMinSize      16                      /* Min bitmap size */

/* Equates for hash table number field */

#define VMAT_PM_lHashNumbFldSize 9                      /* Hash numb fldsiz */
#define VMAT_PM_lHashNumbShift  VMAT_PM_lGranShift      /* Hash number shift */
#define VMAT_PM_lHashNumbAbsMax \
  ((1 << VMAT_PM_lHashNumbFldSize) - 1)                 /* Abs Max hash numb */
#define VMAT_PM_lHashNumbMask \
  (VMAT_PM_lHashNumbAbsMax<<VMAT_PM_lHashNumbShift)     /* Hash number mask */
#define VMAT_PM_laddrMinNoWrap VMAT_PM_laddrAbsMin      /* Min no wrap laddr */
#define VMAT_PM_laddrMaxNoWrap \
  (VMAT_PM_laddrMinNoWrap + VMAT_PM_lHashNumbMask)      /* Max no wrap laddr */

/*  Equates for bit number within bitmap entry */

#define VMAT_PM_lbmeBitNumbFldSize  5                   /* Bitmap ent fldsiz */
#define VMAT_PM_lbmeBitNumbShift VMAT_PM_lGranShift     /* Bit number shift */
#define VMAT_PM_lbmeBitNumbMax \
  ((1L << VMAT_PM_lbmeBitNumbFldSize) - 1)              /* Max bit number */
#define VMAT_PM_lbmeBitNumbMask \
  (VMAT_PM_lbmeBitNumbMax << (VMAT_PM_lbmeBitNumbShift)) /* Bit number mask */

/*  Equates for bitmap entry number field */

#define VMAT_PM_lbmeNumbFldSize  9                      /* Bitmap ent fldsize */
#define VMAT_PM_lbmeNumbShift  \
  (VMAT_PM_lbmeBitNumbShift + VMAT_PM_lbmeBitNumbFldSize)
                                                        /* Bitmap ent # shift */
#define VMAT_PM_lbmeNumbAbsMax \
  ((1L << VMAT_PM_lbmeNumbFldSize) - 1)                 /* Abs Max bitmap ent */
#define VMAT_PM_lbmeNumbMask \
  (VMAT_PM_lbmeNumbAbsMax<<VMAT_PM_lbmeNumbShift)       /* Bitmap ent # mask */

/*  Equates for bitmap number field */

#define VMAT_PM_lbmNumbFldSize  \
  (29 - VMAT_PM_lbmeNumbFldSize - VMAT_PM_lbmeNumbShift)/* Bitmap # fld size */
#define VMAT_PM_lbmNumbShift \
  (VMAT_PM_lbmeNumbShift + VMAT_PM_lbmeNumbFldSize)     /* Bitmap # shift */
#define VMAT_PM_lbmNumbAbsMax \
  ((1L << VMAT_PM_lbmNumbFldSize) - 1)                  /* Abs Max bitmap # */
#define VMAT_PM_lbmNumbMask \
  (VMAT_PM_lbmNumbAbsMax<<VMAT_PM_lbmNumbShift)         /* Bitmap number mask */
#define VMAT_PM_flInit  (VMAH_NO_HASH_WRAP)             /* Initial flags */

/*end*/


/***LC+ LATST Per-type arena constants for the shared tiled arena
 *
 *      Each bit represents 64K of linear address space
 *      Each bitmap contains 32 entries max (= 1K bits) mapping 64Meg
 *      8 bitmaps are needed to map all 512 Meg
 *      The hash table contains 512 entries max
 */

#define VMAT_ST_lGranShift      16                      /* Gran exponent */
#define VMAT_ST_lGran   (1L <<  VMAT_ST_lGranShift)     /* Granularity */

#define VMAT_ST_laddrAbsMin     (_64MEG)                /* Abs min boundary */
#define VMAT_ST_laddrAbsMax     (MAXCRLADDR)            /* Abs max boundary */
#define VMAT_ST_laddrInitMin    VM_PROTECTED_START      /* Init Min = top */
#define VMAT_ST_laddrInitMax    VMAT_ST_laddrInitMin    /* Init Max = top */
#define VMAT_ST_cbInitBetween   \
  (VMAT_ST_laddrAbsMax- VMAT_ST_laddrAbsMin - (_64MEG*2))
                                                        /* Init size of no-mans
                                                           land before start of
                                                           arena */

#define VMAT_ST_lbdMinSize      16                      /* Min bitmap dirsize */
#define VMAT_ST_lHashMinSize    16                      /* Min hash tab size */
#define VMAT_ST_lbmMinSize      16

/* Equates for hash table number field */

#define VMAT_ST_lHashNumbFldSize 9                      /* Hash numb fldsiz */
#define VMAT_ST_lHashNumbShift  VMAT_ST_lGranShift      /* Hash number shift */
#define VMAT_ST_lHashNumbAbsMax \
  ((1L << VMAT_ST_lHashNumbFldSize) - 1)                        /* Abs Max hash numb */
#define VMAT_ST_lHashNumbMask \
  (VMAT_ST_lHashNumbAbsMax<<VMAT_ST_lHashNumbShift)     /* Hash number mask */
#define VMAT_ST_laddrMinNoWrap \
  (VMAT_ST_laddrAbsMax - \
   ((VMAT_ST_lHashNumbAbsMax + 1) << VMAT_ST_lHashNumbShift))
                                                        /* Min no wrap */
#define VMAT_ST_laddrMaxNoWrap \
  (VMAT_ST_laddrMinNoWrap + VMAT_ST_lHashNumbMask)      /* Max no wrap laddr */

/*  Equates for bit number within bitmap entry */

#define VMAT_ST_lbmeBitNumbFldSize  5                   /* Bitmap ent fldsiz */
#define VMAT_ST_lbmeBitNumbShift VMAT_ST_lGranShift     /* Bit number shift */
#define VMAT_ST_lbmeBitNumbMax \
  ((1L << VMAT_ST_lbmeBitNumbFldSize) - 1)              /* Max bit number */
#define VMAT_ST_lbmeBitNumbMask \
  (VMAT_ST_lbmeBitNumbMax << (VMAT_ST_lbmeBitNumbShift)) /* Bit number mask */

/*  Equates for bitmap entry number field */

#define VMAT_ST_lbmeNumbFldSize  5                      /* Bitmap ent fldsize */
#define VMAT_ST_lbmeNumbShift  \
  (VMAT_ST_lbmeBitNumbShift + VMAT_ST_lbmeBitNumbFldSize)
                                                        /* Bitmap ent # shift */
#define VMAT_ST_lbmeNumbAbsMax \
  ((1L << VMAT_ST_lbmeNumbFldSize) - 1)                 /* Abs Max bitmap ent */
#define VMAT_ST_lbmeNumbMask \
  (VMAT_ST_lbmeNumbAbsMax<<VMAT_ST_lbmeNumbShift)       /* Bitmap ent # mask */

/*  Equates for bitmap number field */

#define VMAT_ST_lbmNumbFldSize  \
  (29 - VMAT_ST_lbmeNumbFldSize - VMAT_ST_lbmeNumbShift)/* Bitmap # fld size */
#define VMAT_ST_lbmNumbShift \
  (VMAT_ST_lbmeNumbShift + VMAT_ST_lbmeNumbFldSize)     /* Bitmap # shift */
#define VMAT_ST_lbmNumbAbsMax \
  ((1L << VMAT_ST_lbmNumbFldSize) - 1)                  /* Abs Max bitmap # */
#define VMAT_ST_lbmNumbMask \
  (VMAT_ST_lbmNumbAbsMax<<VMAT_ST_lbmNumbShift)         /* Bitmap number mask */
#define VMAT_ST_flInit  \
  (VMAH_NO_HASH_WRAP | VMAH_BITMAP_BYPASS | VMAH_GROW_DOWN)
                                                        /* Initial flags */

/*end*/

/***LC+ LATSY  Per-type arena constants for the system arena
 *
 *      Each bit represents 4K of linear address space
 *      Each bitmap contains 512 dword entries max (= 16K bits) mapping 64Meg
 *      40 bitmaps are needed to map all 2536 Meg
 *      The hash table contains 512 word entries max
 */

#define VMAT_SY_lGranShift      12                      /* Gran exponent */
#define VMAT_SY_lGran   (1L <<  VMAT_SY_lGranShift)     /* Granularity */

#define VMAT_SY_laddrAbsMin (MINSYSPAGE << PAGESHIFT)   /* Abs min boundary */
#define VMAT_SY_laddrAbsMax (MAXSYSPAGE << PAGESHIFT)   /* Abs min boundary */
#define VMAT_SY_laddrInitMin VMAT_SY_laddrAbsMax        /* Init Min = top */
#define VMAT_SY_laddrInitMax VMAT_SY_laddrInitMin       /* init Max = top */
#define VMAT_SY_cbInitBetween   0L                      /* Init size of no-mans
                                                           land before start of
                                                           arena */


#define VMAT_SY_lbdMinSize      1024                    /* Min bitmap dirsize */
#define VMAT_SY_lHashMinSize    (512L*2)
                                                        /* Min hash tab size */
#define VMAT_SY_lbmMinSize      (512L)
                                                        /* Min bitmap size */

/* Equates for hash table number field */

#define VMAT_SY_lHashNumbFldSize 9                      /* Hash numb fldsiz */
#define VMAT_SY_lHashNumbShift  VMAT_SY_lGranShift      /* Hash number shift */
#define VMAT_SY_lHashNumbAbsMax \
  ((1L << VMAT_SY_lHashNumbFldSize) - 1)                        /* Abs Max hash numb */
#define VMAT_SY_lHashNumbMask \
  (VMAT_SY_lHashNumbAbsMax<<VMAT_SY_lHashNumbShift)     /* Hash number mask */
#define VMAT_SY_laddrMinNoWrap \
  (VMAT_SY_laddrAbsMax - \
   ((VMAT_SY_lHashNumbAbsMax + 1) << VMAT_SY_lHashNumbShift))
                                                        /* Min no wrap */
#define VMAT_SY_laddrMaxNoWrap \
  (VMAT_SY_laddrMinNoWrap + VMAT_SY_lHashNumbMask)      /* Max no wrap laddr */

/*  Equates for bit number within bitmap entry */

#define VMAT_SY_lbmeBitNumbFldSize  5                   /* Bitmap ent fldsiz */
#define VMAT_SY_lbmeBitNumbShift VMAT_SY_lGranShift     /* Bit number shift */
#define VMAT_SY_lbmeBitNumbMax \
  ((1L << VMAT_SY_lbmeBitNumbFldSize) - 1)              /* Max bit number */
#define VMAT_SY_lbmeBitNumbMask \
  (VMAT_SY_lbmeBitNumbMax << (VMAT_SY_lbmeBitNumbShift)) /* Bit number mask */

/*  Equates for bitmap entry number field */

#define VMAT_SY_lbmeNumbFldSize  7                      /* Bitmap ent fldsize */
#define VMAT_SY_lbmeNumbShift  \
  (VMAT_SY_lbmeBitNumbShift + VMAT_SY_lbmeBitNumbFldSize)
                                                        /* Bitmap ent # shift */
#define VMAT_SY_lbmeNumbAbsMax \
  ((1L << VMAT_SY_lbmeNumbFldSize) - 1)                 /* Abs Max bitmap ent */
#define VMAT_SY_lbmeNumbMask \
  (VMAT_SY_lbmeNumbAbsMax<<VMAT_SY_lbmeNumbShift)       /* Bitmap ent # mask */

/*  Equates for bitmap number field */

#define VMAT_SY_lbmNumbFldSize  \
  (32 - VMAT_SY_lbmeNumbFldSize - VMAT_SY_lbmeNumbShift)/* Bitmap # fld size */
#define VMAT_SY_lbmNumbShift \
  (VMAT_SY_lbmeNumbShift + VMAT_SY_lbmeNumbFldSize)     /* Bitmap # shift */
#define VMAT_SY_lbmNumbAbsMax \
  ((1L << VMAT_SY_lbmNumbFldSize) - 1)                  /* Abs Max bitmap # */
#define VMAT_SY_lbmNumbMask \
  (VMAT_SY_lbmNumbAbsMax<<VMAT_SY_lbmNumbShift)         /* Bitmap number mask */

#define VMAT_SY_flInit  (VMAH_GROW_DOWN)
                                                        /* Initial flags */
/*end*/


/***LC+     Alias records constants */

#define     VMAL_MAXRECS    (0x0ffff-2)
                                /* Max no of aliases in the system */
/*end*/


/***LC+ BMPF - BMP flags for VMAlloc */

/*XLATOFF*/
#define vm_BMP_CREATE   (VMAC_LOCANY | VMAC_ALIGNPAGE | VMAC_ARENASYS | \
                        VMAC_OBSHRINK | PG_ZEROFILL | PG_R | PG_W)
#define vm_BMP_GROW     (VMAC_LOCSPECIFIC | PG_ZEROFILL | PG_R | PG_W)


/*XLATON*/
/*end*/

/***LC+ VMMAXSIZE - Maximum theoretical size of object based on byte granular
                    starting address and size */
#define VMMAXSIZE       (_4G - 2*PAGESIZE)
/*end*/


/***LT+ VMBIT - Bitmap */

#define VM_BITMAP_SIZE  1024            /* Size of Bitmap Record */

struct vmbit_s {
        unsigned char btm_entries[VM_BITMAP_SIZE];
                                        /* Bits mapping pages (8 per entry) */
};

typedef struct vmbit_s VMBIT;           /* Bitmap */
/*end*/



/***LT+ VMHSH - Hash Table */

#define VM_HASH_SIZE   2048             /* Number of Entries in Hash Table */

struct vmhsh_s {
        VMHAR hsh_entries[VM_HASH_SIZE];
                                        /* Hash table entries */
};

typedef struct vmhsh_s VMHSH;           /* Hash Table */
/*end*/

/***LT+ VMSD - Set Memory Worker Data */

struct vmsd_s {
        ulong_t sd_fl;                  /* Permission and selmap flags */
        ulong_t sd_blkno;               /* Loader block number */
        ulong_t sd_ipg;                 /* Initial page of target range */
        ulong_t sd_cbdesc;              /* Count of bytes in selectors */
        SEL     sd_sel;                 /* The selector to be allocated */
        ulong_t sd_csel;                /* No of new selectors needed */
        struct ptda_s *sd_pPTDA;        /* Pointer to target context PTDA */
};

typedef struct vmsd_s VMSD;             /* Hash Table */


/***LK+ LVMRB - Local vmRecalcShrBound flags */

#define vmrb_SHR_GROW_DOWN (0x00000001L) /* Grow shared arena down */
/*end*/

/***LK+ LVMFM - Local VMFreeMem flags */

#define vmfm_PAA_PRIV   (0x08000000L)   /* Same as PAA_PRIV flag */
#define vmfm_SHR_SEM    (0x02000000L)   /* VMFreeMem owns shared memory sem. */
#define vmfm_AH_SEM     (0x01000000L)   /* VMFreeMem owns arena semaphore */
#define vmfm_LDR_SEM    (0x80000000L)   /* VMFreeMem owns loader semaphore */
#define vmfm_FREE_AR    (0x40000000L)   /* VMFreeMem freeing arena rec */
#define vmfm_OB_SEM     (0x20000000L)   /* object semaphore already obtained */
#define vmfm_LAST_LDR_CTXT (0x10000000L)/* Free of last context of loader obj*/
#define vmfm_LMASK      (0xd3000000L)   /* all these bits */
/*end*/


/***LK+ LVMFT - Local VMFreeTask / vmFreeAll flags */

#define vmft_FREE_ALL   (0x00000002L)   /* Free all objects including locked */
#define vmft_LONG_LOCK  (0x00000010L)   /* Long locked object found */
#define vmft_LONG_LOCK_SHR (0x00000020L)  /* Long locked shr arena object */
#define vmft_LONG_LOCK_PRV (0x00000040L)  /* Long locked shr arena object */
#define vmft_LMASK (vmft_LONG_LOCK | vmft_LONG_LOCK_PRV | vmft_LONG_LOCK_SHR)
/*end*/

/***LK+ LVMLT - vmAccessLongLockInfo flags */

#define vmlt_RECORD     (0x00000001L)   /* Record long-term lock */
#define vmlt_ERASE      (0x00000002L)   /* Erase record of long-term lock */
#define vmlt_CHECK      (0x00000004L)   /* Check existence of long-term lock */

#define vmlt_DELTA      4               /* Number of entries to increase
                                           long-term lock table */
/*end*/



/***LT+ vmSGS_s - Structure for Screen Group Switch Control registration */

    struct vmSGS_s {
        VMHAR       sgs_har;                /* handle to Arena record */
        ushort_t    sgs_fs;                 /* Flags */
        struct      vmSGS_s *sgs_psgsnext;  /* Pointer to next sgs record */
    };
/*end*/

/***LD+ Private Data
 *
 *      Private data items.
 */

extern ulong_t          aipgvmMinPrv[2];
                                        /* Minimum allowed private page nos. */
extern ulong_t          aipgvmMaxPrv[2];
                                        /* Maximum allowed private page nos. */
extern ulong_t          aipgvmMinPub[2];
                                        /* Minimum allowed shared page nos. */
extern ulong_t          aulvmAlignMask[];
                                        /* Table of alignment masks */
extern VMAT             atvm[VMAT_MAX + 1];
                                        /* Arena per-type info */

VMCO                    *pcovmOne; /* Array of context records */

VMAR                    *parProtectSearchStart; /* Arena record to start with
                                                   when searching for protected
                                                   memory */
VMAR                    *parPackedSearchStart;  /* Arena record to start with
                                                   when searching for packed
                                                   memory */

/*
 *  Pointers for mapping arena, object and context records.  These
 *  pointers point one element before the start of the arrays of
 *  arena object and context records.  They enable mapping of BMP32
 *  handles to be faster because 1 does not need to be subtracted
 *  from the handle before it is mapped.
 */

VMAL                    *palvmIal;              /* palvmAliases-1 */
VMOB                    *pobvmZero;             /* pobvmOne-1 */
VMAR                    *parvmZero;             /* parvmOne-1 */
VMCO                    *pcovmZero;             /* pcovmOne-1 */

extern  ulong_t vmInitFlags;    /* used by VMInit and VMAllocMem */

#ifdef VMSTRICT
extern  ulong_t vmLogFlags;     /* DEBUG: Logging Flags */
#endif

/*end*/


/***LK+ vmFAC  - vmFindArCo flags  */

#define  vmFAC_NOALIAS  0x0001              /* skip alias arena records */
#define  vmFAC_NOIPG    0x0002              /* Don't match the address */
#define  vmFAC_HCO      0x0004              /* Return AR with context list */
/*end*/

/***LK+ vmLog  - Debug Kernel Logging Flags */

#define  vmLogLocks     0x00000001          /* Log Locks/Unlocks        */

/*end*/

/***LP+ Local Function Prototypes */

extern ulong_t  vmbmScan(VMBM **papbm,
                         ulong_t *pbmNumb,
                         ulong_t *pbmeNumb,
                         ulong_t *pbmeBitNumb);

extern int vmCreateOdTables(VMAH *pah, VMAR *par);

extern int vmRecordOd(VMAH *pah, VMAR *par);

extern void vmEraseOd(VMAH *pah, VMAR *par);

extern int vmCreateArena(ulong_t lat, VMAH *pah);

extern void vmFreeArena(VMAH *pah);

extern void vmLinkArena(ulong_t lat, VMAH *pah);

extern void vmUnlinkArena(VMAH *pah);

extern void vmLinkOb(VMOB *pob, VMAR *par);

extern void vmLinkAr(VMAR *par, VMOB *pob);

extern void vmLinkCo(VMCO *pco, VMAR *par);

extern ulong_t *vmNamShrSem;

extern int vmIsValidHKH(VMHKH hkh);

extern int vmKRHValidate(VMHKRH hkrh);

extern int vmKSHValidate(VMHKSH hksh);

extern int vmDonateFragKRH(char *pb, ulong_t cb, ulong_t fl);

extern void vmBmpGet(VMBH *pbh, void *ppb);

extern void vmGetObjectVa(VMHOB hob,
                   ulong_t *pva);

extern void     vmNameShareInit(void);

extern void     vmDonateHighCode(void);

extern void vmInitPublicHeaps(void);

extern int vmAccessLongLockInfo(VMHAR har,
                                VMHOB hobptda,
                                ulong_t fl);

ushort_t   vmLockHandleSig(VMLH *phlock);

extern int vmAllocNamedShrMem(ulong_t cb, ulong_t cbCom, ulong_t saddr,
                ulong_t flsel, ulong_t flags, VMAC *pac, VMHOB hMTE);

extern int vmGetNamedShrMem(ulong_t saddr, ulong_t flags, VMAC *pac);

extern int vmFreeNamedSharedMem(ulong_t fl, VMOD *pod);

extern int vmCommitMemWrkr(VMSD *psd,
                        ulong_t ipg,
                        ulong_t cpg,
                        VMOD    *pod,
                        ulong_t pgoff);

extern int vmDecommitMemWrkr(VMSD *psd,
                        ulong_t ipg,
                        ulong_t cpg,
                        VMOD    *pod,
                        ulong_t pgoff);

extern int vmFreeMemNotifyOd(ulong_t *pfl,
                           VMOD *pod);

extern void vmAllocTLBAdjust(ulong_t *pcpgSkew,
                           VMHOB hobOwner,
                           ulong_t *pfl);

extern void vmFreeMemCtxtOd(VMOD *pod);

extern int vmFreeCheck(ulong_t cpgreq,
                ulong_t fl,
                ulong_t ipgreq,
                VMAR *par);

extern int vmPrvBound(struct ptda_s *pPTDA,
                ulong_t *pipgmaxprv);

extern void vmRecalcShrBound(ulong_t fl, ulong_t *pladdrMinShr);

extern int vmMoveSentinelDown(ulong_t cpgreq,
                ulong_t fl,
                ulong_t ipgreq,
                VMAR *parsen,
                VMAR **ppar);

extern int vmFreeSearchDown(ulong_t cpgreq,
                ulong_t fl,
                ulong_t ipgreq,
                VMAR *par,
                VMAH *pah,
                VMAR **ppar);

extern int vmMoveSentinelUp(ulong_t cpgreq,
                ulong_t fl,
                ulong_t ipgreq,
                VMAR *parsen,
                VMAR **ppar);

extern int vmFreeSearchUp(ulong_t cpgreq,
                ulong_t fl,
                ulong_t ipgreq,
                VMAR *par,
                VMAH *pah,
                VMAR **ppar);

extern int vmReserveSub(ulong_t cpgreq,
                ulong_t fl,
                ulong_t ipgreq,
                VMAH *pah,
                VMHOB hobptda,
                VMAR **ppar);

extern void vmkshPublicInit(void);

extern int vmFreeAll(VMAH *pah, struct ptda_s *pPTDA, ulong_t fl);

extern int vmIsBusyAliasRec(VMAL *pal);

extern void vmInitAliasRec(void);

extern int vmHasDebugAlias(VMOD *pod);

extern void vmFreeAlias(VMHAR har, VMHOB hob);

extern void vmFreeObjectAliases(VMHOB hob, VMHOB hobptda);

extern int  vmCheckAlias(ulong_t fl, VMHOB hob, VMHAR har);

extern void vmChangeAlias(ulong_t flmap, VMOD *pod);

extern int  vmHasDiscardablePages(ulong_t ipg,
                                  struct ptda_s *pPTDA, ulong_t cpg);

extern void vmAliasToAlias(VMOD *pod, ulong_t *pdisp, ulong_t *pladdr);

extern void vmIsPrivLoadOb(ulong_t flmap, VMOD *pod);

extern int  vmFindArCo(ulong_t fl, VMHOB hobptda, ulong_t ipg,
                       VMOB *pob, VMAR **ppar, VMAR **pparprev, VMCO **ppco);

extern char *bmpUpdateLastBusy(VMBH *pbh);

extern void vmInitBMPObject(VMBH *pbh,
                     VMHOB hob,
                     ulong_t cbblock,
                     ulong_t flswap,
                     int (*pfnisbusy)(void *),
                     void **ppblock,
                     ulong_t cbobject,
                     ulong_t cpgCommit);

extern void vmBuildBMPFreeList(VMBH *pbh, void *pbStartFree, void *pbEndCom);

extern void vmRebuildBMPFreeList(VMBH *pbh);

extern void bmpShrink(VMBH *pbh);

extern int bmpIsBusy(void *pblock);

extern int vmIsBusyArBMP(VMAR *par);

extern int vmIsBusyObBMP(VMOB *pob);

extern int vmIsBusyCoBMP(VMCO *pco);

extern char *krhYield(void *pkrh, char *pb);

extern int vmSGSAdd(VMHAR har, struct ptda_s *pPTDA, ushort_t fs);

extern void vmSGSRemove(VMHAR har, struct ptda_s *pPTDA);

extern ulong_t vmGetObPermOd(VMOD *pod);

extern void vmSetObPermOd(VMOD *pod, ulong_t fl);

extern int vmQueryObject(VMOD *pod, ulong_t laddr, ulong_t *pcb, ulong_t *pfl);

extern int vmdh_AllocAddList(ulong_t laddr, ulong_t vaddr, VMHOB owner);

extern void vmdh_AllocRemoveList(ulong_t laddr);

extern void vmdh_AllocRemoveAccess(void);

extern int vmCopyKHB(char *pbDest, char *pbSrc, ulong_t cb, ulong_t fl);

extern void vmAllocTLBAdjust(ulong_t *pcpgSkew,
                             VMHOB hobOwner,
                             ulong_t *pfl);

#ifdef VMSTRICT
extern int vmErrorSub(int rc);
extern ulong_t  vmRetAddr(void);
#endif

/*XLATON*/
/*end*/


/***LP  vmGetArenaHeader - return a pointer to an arena header
 *
 *      Given a pointer to a valid ptda and virtual
 *      page number, this function returns a pointer to the
 *      arena header for the arena containing the virtual page.
 *      If the passed pointer is invalid, i.e. not within the range of
 *      any arena, pointer to private arena header is returned.
 *      This later is caught by vmLocateAr as an invalid address.
 *
 *      VMAH    *vmGetArenaHeader(ulong_t ipg, struct ptda_s *pPTDA)
 *
 *      ENTRY           ipg             - virtual page number
 *                      pPTDA           - PTDA pointer (private arena only)
 *      RETURN          VMAH *          - pointer to arena header
 *
 *      Check if the page lies in the system arena.     If not,
 *      then check if the page lies in the tiled or untiled
 *      shared arena.  If not, then return a pointer to the
 *      tiled or untiled private arena header.
 *
 *      CALLS           VMSysArenaPg, VMShrArenaPg
 *
 *      WARNING         This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmGetArenaHeader(ipg,pPTDA)                                     \
  (VMSysArenaPg(ipg) ? &ahvmSys :                                       \
   (VMShrArenaPg(ipg) ? &ahvmShr : &((pPTDA)->ptda_ah)))


/***LP  vmArMap - map an arena record handle to its arena record
 *
 *      Given an arena record handle, return a pointer to the
 *      corresponding arena record.  No handle verification is done.
 *
 *      vmArMap (har)
 *
 *      ENTRY   har             - arena record handle (VMHAR)
 *      RETURN  VMAR *          - pointer to arena record
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmArMap(x)      (parvmZero + (VMHAR)(x))
                                        /* Map handle to pointer */


/***LP  vmArIsSentinel - returns true if the specified record is a sentinel
 *
 *      Given an arena record pointer, return true if the specified
 *      arena record is a sentinel.
 *
 *      vmArIsSentinel (par)
 *
 *      ENTRY   par             - arena record pointer (VMAR *)
 *      RETURN  int             - non-zero if sentinel
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *              This function treats an iterated field as a bit flag
 *              field.
 *
 *      EFFECTS NONE
 */

#define vmArIsSentinel(par) ((par)->ar_f & AR_TAGSEN)
                                        /* Test sentinel bit */

/***LP  vmIsBusyAr - Returns true if the specified arena record is busy
 *
 *      Given an arena record pointer, return true if the specified
 *      arena record is busy.
 *
 *      int vmIsBusyAr(VMAR *par)
 *
 *      ENTRY           par             - Arena record pointer
 *      RETURN          int             - TRUE if busy, else FALSE
 *
 *      CALLS           NONE
 *
 *      WARNING         This function is implemented as a macro.
 *
 *      EFFECTS         NONE
 */

#define vmIsBusyAr(par) ((par)->ar_f & AR_INUSE)


/***LP  vmSentAr - returns true if the specified arena record is a sentinel
 *
 *      Given an arena record pointer, return TRUE if the specified
 *      arena record is a sentinel (ordinary or boundary).
 *
 *      vmSentAr (par)
 *
 *      ENTRY   par             - arena record pointer (VMAR *)
 *      RETURN  int             - TRUE if regular arena record
 *                                FALSE otherwise
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmSentAr(par) (vmOrdSentAr(par) || vmBdrySentAr(par))


/***LP  vmOrdSentAr - returns true if the specified arena record is an
 *      ordinary sentinel
 *
 *      Given an arena record pointer, return TRUE if the specified
 *      arena record is an ordinary sentinel arena record.
 *
 *      vmOrdSentAr (par)
 *
 *      ENTRY   par             - arena record pointer (VMAR *)
 *      RETURN  int             - TRUE if ordinary sentinel
 *                                FALSE otherwise
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmOrdSentAr(par) (((par)->ar_f & AR_TAG) == AR_TAGSEN)


/***LP  vmBdrySentAr - returns true if the specified arena record is a boundary
 *                     sentinel
 *
 *      Given an arena record pointer, return TRUE if the specified
 *      arena record is a boundary sentinel.
 *
 *      vmBdrySentAr (par)
 *
 *      ENTRY   par             - arena record pointer (VMAR *)
 *      RETURN  int             - TRUE if boundary sentinel
 *                                FALSE otherwise
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmBdrySentAr(par) (((par)->ar_f & AR_TAG) == AR_TAGBSEN)


/***LP  vmRegAr - returns true if the specified arena record is regular
 *
 *      Given an arena record pointer, return TRUE if the specified
 *      arena record is a regular arena record.
 *
 *      vmRegAr (par)
 *
 *      ENTRY   par             - arena record pointer (VMAR *)
 *      RETURN  int             - TRUE if regular arena record
 *                                FALSE otherwise
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *              This function treats an iterated field as a bit flag
 *              field.
 *
 *      EFFECTS NONE
 */

#define vmRegAr(par) (!((par)->ar_f & AR_TAGSEN))


/***LP  vmArVa - return the address from an arena record
 *
 *      Given an arena record pointer, return the address stored
 *      in the arena record.
 *
 *      vmArVa (par)
 *
 *      ENTRY   par             - arena record pointer (VMAR *)
 *      RETURN  char *          - virtual address
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmArVa(par) ((char *)((par)->ar_ipg << PAGESHIFT))
                                        /* Return page number * page size */


/***LP  vmArPg - return the page address from an arena record
 *
 *      Given an arena record pointer, return the page address stored
 *      in the arena record.
 *
 *      vmArPg (par)
 *
 *      ENTRY   par             - arena record pointer (VMAR *)
 *      RETURN  ulong_t         - page address
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmArPg(par) (((par)->ar_ipg))
                                        /* Return page number */


/***LP  vmParToHar - return the handle for an arena record
 *
 *      Given a pointer to an arena record, return the
 *      arena record's handle.  No pointer verification
 *      is done.
 *
 *      vmParToHar (par)
 *
 *      ENTRY   par             - arena record pointer (VMAR *)
 *      RETURN  VMHAR           - arena record's handle
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmParToHar(x) ((VMHAR)(((VMAR *)(x)) - parvmZero))
                                        /* Compute handle from pointer */


/***LP  vmHandleMap - map an object record handle to its object record
 *
 *      Given a handle, return a pointer to the corresponding
 *      object record.  No handle verification is done.
 *
 *      vmHandleMap (hob)
 *
 *      ENTRY   hob             - object record handle (VMHOB)
 *      RETURN  VMOB *          - pointer to object record
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmHandleMap(x)  (pobvmZero + (VMHOB)(x))
                                        /* Map handle to pointer */


/***LP  vmBMPHandleMap - map a BMP32 record handle to its record address
 *
 *      Given a BMP32 handle (1-based record number) and a BMP object pointer,
 *      return a pointer to the corresponding BMP32 record.
 *      No handle verification is done.
 *
 *      vmBMPHandleMap (pbh, h)
 *
 *      ENTRY   (record type *) pbh     - address of first record in
 *                                        BMP32 object.
 *              h               - BMP32 record handle (ulong_t)
 *      RETURN  void *          - pointer to BMP32 record
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmBMPHandleMap(pbh, h)\
        ((char *) pbh + (h - 1) * (pbh - 1)->bh_cbPerBlock)


/***LP  vmSystemOwner - Check that a handle is one of the special system owners
 *
 *      Given a handle, this function checks that it is one of the special
 *      values used to represent system owners (see file vmowner.h)
 *
 *      int vmSystemOwner (hob)
 *
 *      ENTRY   VMHOB hob       - handle value to be checked
 *
 *      RETURN  TRUE            - if handle is a system owner handle
 *              FALSE           - otherwise
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

//147968 #define vmSystemOwner(hob) ((ushort_t) hob >= VMMINOWNER && \
//147968                            (ushort_t) hob <= VMMAXOWNER)
#define vmSystemOwner(hob) (((ushort_t) hob >= VMMINOWNER && \
                            (ushort_t) hob <= VMMAXOWNER) || \
                            IsFSDOwner((hob)) || IsDDOwner((hob)))



/***LP  vmAlign - extract alignment type from flags
 *
 *      Given a set of allocation flags, extract the alignment type.
 *      The value returned may be used to index aulvmAlignMask[].
 *
 *      vmAlign (fl)
 *
 *      ENTRY   fl              - allocation flags
 *      RETURN  ulong_t         - aligment type
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmAlign(fl) (((fl) & VMAC_ALIGNMASK) >> VMAC_ALIGNSHIFT)


/***LP  vmCeil - round up to next boundary
 *
 *      This function rounds the passed value up to the
 *      next specified boundary.
 *
 *      vmCeil (x, m)
 *
 *      ENTRY   x               - value to round up (ulong_t)
 *              m               - boundary mask (ulong_t)
 *      RETURN  ulong_t         - rounded value
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmCeil(x,m) (((ulong_t)(x) + (m)) & ~(m))


/***LP  vmFloor - round down to nearest boundary
 *
 *      This function rounds the passed value down to the
 *      nearest specified boundary.
 *
 *      ulong_t vmFloor(ulong_t x, ulong_t m)
 *
 *      ENTRY           x               - Value to round down
 *                      m               - Boundary mask
 *      RETURN          ulong_t         - Rounded value
 *
 *      CALLS           NONE
 *
 *      WARNING         This function is implemented as a macro.
 *
 *      EFFECTS         NONE
 */

#define vmFloor(x,m) (((ulong_t)(x)) & ~(m))


/***LP  vmParaCeil - round up to next paragraph boundary
 *
 *      This function rounds the passed value up to the
 *      next multiple of PARASIZE.
 *
 *      vmParaCeil (x)
 *
 *      ENTRY   x               - value to round up (ulong_t)
 *      RETURN  ulong_t         - rounded value
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmParaCeil(x) vmCeil(x,PARASIZE - 1)


/***LP  vmParaFloor - round down to nearest paragraph boundary
 *
 *      This function rounds the passed value down to the
 *      nearest multiple of PARASIZE.
 *
 *      vmParaFloor (x)
 *
 *      ENTRY   x               - value to round down (ulong_t)
 *      RETURN  ulong_t         - rounded value
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmParaFloor(x) vmFloor(x,PARASIZE - 1)


/***LP  vmPageCeil - round up to next page boundary
 *
 *      This function rounds the passed value up to the
 *      next multiple of PAGESIZE.
 *
 *      vmPageCeil (x)
 *
 *      ENTRY   x               - value to round up (ulong_t)
 *      RETURN  ulong_t         - rounded value
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmPageCeil(x) vmCeil(x,PAGESIZE - 1)


/***LP  vmPageFloor - round down to nearest page boundary
 *
 *      This function rounds the passed value down to the
 *      nearest multiple of PAGESIZE.
 *
 *      vmPageFloor (x)
 *
 *      ENTRY   x               - value to round down (ulong_t)
 *      RETURN  ulong_t         - rounded value
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmPageFloor(x) vmFloor(x,PAGESIZE - 1)


/***LP  vmSelCeil - round up to next selector boundary
 *
 *      This function rounds the passed value up to the
 *      next multiple of 64K.
 *
 *      vmSelCeil (x)
 *
 *      ENTRY   x               - value to round up (ulong_t)
 *      RETURN  ulong_t         - rounded value
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmSelCeil(x) vmCeil(x,0xFFFFL)


/***LP  vmSelFloor - round down to nearest selector boundary
 *
 *      This function rounds the passed value down to the
 *      nearest multiple of 64K.
 *
 *      vmSelFloor (x)
 *
 *      ENTRY   x               - value to round down (ulong_t)
 *      RETURN  ulong_t         - rounded value
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmSelFloor(x) vmFloor(x,0xFFFFL)


/***LP  vmDirCeil - round up to next page directory boundary
 *
 *      This function rounds the passed value up to the
 *      next multiple of 4M.
 *
 *      vmDirCeil (x)
 *
 *      ENTRY   x               - value to round up (ulong_t)
 *      RETURN  ulong_t         - rounded value
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmDirCeil(x) vmCeil(x,0x3FFFFF)


/***LP  vmDirFloor - round down to nearest page directory boundary
 *
 *      This function rounds the passed value down to the
 *      nearest multiple of 4M.
 *
 *      vmDirFloor (x)
 *
 *      ENTRY   x               - value to round down (ulong_t)
 *      RETURN  ulong_t         - rounded value
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmDirFloor(x) vmFloor(x,0x3FFFFF)




/***LP  vmArAlloc - allocate an arena record
 *
 *      This function allocates an arena record and returns
 *      a pointer to it.
 *
 *      vmArAlloc (ppar)
 *
 *      ENTRY   ppar            - pointer to location in which to return
 *                                arena record pointer (VMAR **)
 *      RETURN  int             - error code (NO_ERROR if no error)
 *
 *      Call BMPGet to allocate an arena record.
 *
 *      CALLS   BMPGet
 *
 *      WARNING This function is implemented as a macro.
 *              This function may block.
 *
 *      EFFECTS Arena Record Table
 */

#define vmArAlloc(ppar) BMPGet(parvmOne,ppar)


/***LP  vmArFree - free an arena record
 *
 *      This function frees an arena record.
 *
 *      vmArFree (par)
 *
 *      ENTRY   par             - arena record pointer (VMAR *)
 *      RETURN  NONE
 *
 *      Clear the AR_INUSE flag and call BMPFree to free
 *      the record.
 *
 *      CALLS   BMPFree
 *
 *      WARNING This function is implemented as a macro.
 *              This function may block.
 *
 *      EFFECTS Arena Record Table
 */

#define vmArFree(par) ((par)->ar_f &= ~AR_INUSE, BMPFree(parvmOne,par))


/***LP  vmCoAlloc - allocate a context record
 *
 *      This function allocates a context record and returns
 *      a pointer to it.
 *
 *      vmCoAlloc (ppco)
 *
 *      ENTRY   ppco            - pointer to location in which to return
 *                                context record pointer (VMCO **)
 *      RETURN  int             - error code (NO_ERROR if no error)
 *
 *      Call BMPGet to allocate a context record.
 *
 *      CALLS   BMPGet
 *
 *      WARNING This function is implemented as a macro.
 *              This function may block.
 *
 *      EFFECTS Context Record Table
 */

#define vmCoAlloc(ppco) BMPGet(pcovmOne,ppco)


/***LP  vmCoFree - free a context record
 *
 *      This function frees a context record.
 *
 *      vmCoFree (pco)
 *
 *      ENTRY   pco             - context record pointer (VMCO *)
 *      RETURN  NONE
 *
 *      Call BMPFree to free the record.
 *
 *      CALLS   BMPFree
 *
 *      WARNING This function is implemented as a macro.
 *              This function may block.
 *
 *      EFFECTS Context Record Table
 */

#define vmCoFree(pco) BMPFree(pcovmOne,pco)


/***LP  vmCoMap - map a context record handle to its context record
 *
 *      Given a context record handle, return a pointer to the
 *      corresponding context record.  No handle verification is done.
 *
 *      VMCO *vmCoMap(VMHCO hco)
 *
 *      ENTRY           hco             - Context record handle
 *      RETURN          VMCO *          - Pointer to context record
 *
 *      CALLS           NONE
 *
 *      WARNING         This function is implemented as a macro.
 *
 *      EFFECTS         NONE
 */

#define vmCoMap(hco)    (pcovmZero + (VMHCO)(hco))
                                        /* Map handle to pointer */


/***LP  vmIsBusyCo - Returns true if the specified context record is busy
 *
 *      Given a context record pointer, return true if the specified
 *      context record is busy.
 *
 *      vmIsBusyCo(pco)
 *
 *      ENTRY           pco             - Context record pointer
 *      RETURN          int             - TRUE if busy, else FALSE
 *
 *      CALLS           NONE
 *
 *      WARNING         This function is implemented as a macro.
 *
 *      EFFECTS         NONE
 */

#define vmIsBusyCo(pco) ((pco)->co_hobptda != HOBNULL)


/***LP  vmPcoToHco - return the handle for a context record
 *
 *      Given a pointer to a context record, return the
 *      context record's handle.  No pointer verification
 *      is done.
 *
 *      vmPcoToHco (pco)
 *
 *      ENTRY   pco             - context record pointer
 *      RETURN  VMHCO           - context record's handle
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#define vmPcoToHco(x) ((VMHCO)(((VMCO *)(x)) - pcovmZero))
                                        /* Compute handle from pointer */


/***LP  vmObAlloc - allocate an object record
 *
 *      This function allocates an object record and returns
 *      a pointer to it.
 *
 *      vmObAlloc (ppob)
 *
 *      ENTRY   ppob            - pointer to location in which to return
 *                                object record pointer (VMOB **)
 *      RETURN  int             - error code (NO_ERROR if no error)
 *
 *      Call BMPGet to allocate an object record.
 *
 *      CALLS   BMPGet
 *
 *      WARNING This function is implemented as a macro.
 *              This function may block.
 *
 *      EFFECTS Object Record Table
 */

#define vmObAlloc(ppob) BMPGet(pobvmOne,ppob)


/***LP  vmObFree - free an object record
 *
 *      This function frees an object record.
 *
 *      vmObFree (pob)
 *
 *      ENTRY   pob             - object record pointer (VMOB *)
 *      RETURN  NONE
 *
 *      Set the owner i.d. to HOBNULL and call BMPFree to free
 *      the record.
 *
 *      CALLS   BMPFree
 *
 *      WARNING This function is implemented as a macro.
 *              This function may block.
 *
 *      EFFECTS Object Record Table
 */

#define vmObFree(pob) ((pob)->ob_hobowner = HOBNULL, BMPFree(pobvmOne,pob))


/***LP  vmTile - return true if request is for tiled memory
 *
 *      Given a set of VMAlloc flags, return true if the
 *      allocation request is for tiled memory.
 *
 *      vmTile (fl)
 *
 *      ENTRY   fl              - flags
 *      RETURN  int             - non-zero if tiled memory wanted
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.  For 1.3,
 *              it will always return true if the flags specify a
 *              user arena.
 *
 *      EFFECTS NONE
 */

#define vmTile(fl) (/* ((fl) & VMAC_SELALLOC) && */ \
                     ((fl) & VMAC_ARENAMASK) != VMAC_ARENASYS)


/***LP  vmOvflw - return true if addition will overflow
 *
 *      This function returns true if the addition of the
 *      two operands specified would overflow a 32-bit unsigned
 *      integer.
 *
 *      vmOvflw (a, b)
 *
 *      ENTRY   a               - first addend
 *              b               - second addend
 *      RETURN  int             - true if sum overflows
 *
 *      CALLS   NONE
 *
 *      WARNING This function is implemented as a macro.  The first
 *              argument will be evaluated twice.
 *
 *      EFFECTS Depends upon expressions passed as arguments.
 */

#define vmOvflw(a,b)    ((ulong_t)(a) + (ulong_t)(b) < (ulong_t)(a))
                                        /* Test if sum less than addend */


/***LP  vmVDMTask - test if initialized VDM
 *
 *      This function checks if the specified PTDA belongs to an
 *      initialized VDM.
 *
 *      vmVDMTask( pPTDA )
 *
 *      ENTRY   pPTDA           - pointer to PTDA (NULL means current PTDA)
 *      RETURN  TRUE            - target PTDA is for initialized VDM task
 *              FALSE           - target PTDA is for non-VDM task or for
 *                                VDM task not comepletely initialized
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmVDMTask(pPTDA) (((pPTDA) != NULL && \
  (pPTDA)->ptda_infoseg.LIS_ProcType == LIS_PT_REALMODE) || \
  (pPTDA) == NULL && pPTDACur->ptda_infoseg.LIS_ProcType == LIS_PT_REALMODE)


/***LP vmCurrTask -  check if PTDA is for current task
 *
 *      This function checks if a specified PTDA is for the current
 *      task.
 *
 *      ENTRY   pPTDA           - pointer to PTDA (NULL means current PTDA)
 *      RETURN  TRUE            - target PTDA is for current task
 *              FALSE           - target PTDA is not for current tasl
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmCurrTask(pPTDA) ((pPTDA) == NULL || (pPTDA) == pPTDACur)


/***LP  vmPrivCo - check if context record is privatized
 *
 *      This function tests whether a context record is privatized due to
 *      a debug alias.
 *
 *      vmPrivCo (pco)
 *
 *      ENTRY   pco             - Pointer to context record
 *      RETURN  TRUE            - Context record is privatized
 *              FALSE           - Context record is not privatized
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmPrivCo(pco)  ((pco)->co_fb & CO_PRIV)


/***LP  vmPrivAr - check if given context is privatized
 *
 *      This function tests whether a context is privatized due to
 *      a debug alias. The arena record must not be an alias itself.
 *
 *      vmPrivAr (par)
 *
 *      ENTRY   par             - Pointer to arena record
 *      RETURN  TRUE            - Arena record is privatized
 *              FALSE           - Arena record is not privatized
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmPrivAr(par)  ((par)->ar_hal == VMHAL_PRIV)


/***LP  vmAliasAr - check if arena record is an alias
 *
 *      This function tests whether an arena record is an alias
 *
 *      vmAliasAr (par)
 *
 *      ENTRY   par             - Pointer to arena record
 *      RETURN  TRUE            - Arena record is an alias
 *              FALSE           - Arena record is not an alias
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmAliasAr(par)  (((par)->ar_hal != HALNULL) &&           \
                               ((par)->ar_hal != VMHAL_PRIV) &&  \
                               ((par)->ar_hob != HOBNULL))


/***LP  vmReloadAr - check if arena record for reload or pre-reserve memory
 *
 *      This function tests whether an arena record reserves memory for
 *      reloading an MTE object or pre-reserves memory for loading a huge
 *      object.
 *
 *      vmReloadAr (par)
 *
 *      ENTRY   par             - Pointer to arena record
 *      RETURN  TRUE            - Arena record isfor preload/pre-reserve
 *              FALSE           - Arena record is not for reload/pre-reserve
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmReloadAr(par)  ((par)->ar_f & AR_RELOAD)


/***LP  vmRangeWithinAr - test if given virtual address range within object
 *
 *      This function checks whether the given range of addresses
 *      reside entirely within the given object.
 *
 *      vmRangeWithinAr (p, cb, par)
 *
 *      ENTRY   p               - start address of range to be checked
 *              cb              - size of range in bytes
 *              par             - pointer to arena record for object
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmRangeWithinAr(p, cb, par) \
  (vmWithinAr(p, par) && vmWithinAr((p + cb - 1), par))


/***LP  vmRangeWithinArPg - test if given virtual page range is within object
 *
 *      This function checks whether the given range of addresses
 *      reside entirely within the given object.
 *
 *      vmRangeWithinArPg (ipg, cpg, par)
 *
 *      ENTRY   ipg             - start address of range to be checked
 *              cpg             - size of range in bytes
 *              par             - pointer to arena record for object
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmRangeWithinArPg(ipg, cpg, par) \
  (vmWithinArPg(ipg, par) && vmWithinArPg((ipg + cpg - 1), par))


/***LP  vmIsBusyOb - Returns true if the specified object record is busy
 *
 *      Given an object record pointer, return TRUE if the specified
 *      object record is busy.
 *
 *      int vmIsBusyOb(VMOB *pob)
 *
 *      ENTRY           pob             - Object record pointer
 *      RETURN          int             - TRUE if busy, else FALSE
 *
 *      CALLS           NONE
 *
 *      WARNING         This function is implemented as a macro.
 *
 *      EFFECTS         NONE
 */

#define vmIsBusyOb(pob) ((pob)->ob_hobowner != HOBNULL)


/***LP  vmShrOb - test if object is shared
 *
 *      This function checks whether an object is shared given a pointer
 *      to its object record.
 *
 *      vmShrOb( pob )
 *
 *      ENTRY   pob             - pointer to object record
 *
 *      RETURN                  - TRUE if object is shared
 *                              - FALSE otherwise
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmShrOb(pob) ((pob)->ob_fs & OB_SHARED)


/***LP  vmPrvOb - test if object is private
 *
 *      This function checks whether an object is private given a pointer
 *      to its object record.
 *
 *      vmPrvOb( pob )
 *
 *      ENTRY   pob             - pointer to object record
 *
 *      RETURN                  - TRUE if object is private
 *                              - FALSE otherwise
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmPrvOb(pob) (!(vmShrOb(pob)))


/***LP  vmShrinkOb - test if object is shrinkable
 *
 *      This function checks whether an object is shrinkable, given a pointer
 *      to its object record.
 *
 *      vmShrinkOb( pob )
 *
 *      ENTRY   pob             - pointer to object record
 *
 *      RETURN                  - TRUE if object is shrinkable
 *                              - FALSE otherwise
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmShrinkOb(pob) (((pob)->ob_fs & OB_SHRINKABLE) && \
                            ((pob)->ob_fs & OB_SHARED))


/***LP  vmHasAliasOb - test if object has aliases
 *
 *      This function checks whether an object has aliases, given a pointer
 *      to its object record.
 *
 *      vmHasAliasOb( pob )
 *
 *      ENTRY   pob             - pointer to object record
 *
 *      RETURN                  - TRUE if object has aliases
 *                              - FALSE otherwise
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmHasAliasOb(pob) ((pob)->ob_fs & OB_LALIAS)


/***LP  vmResidentReq - Check if allocation request for resident memory
 *
 *      This function checks whether an allocation request is for
 *      resident memory by testing the allocation flags.
 *
 *      int vmResidentReq(ulong_t fl)
 *
 *      ENTRY   fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                  - TRUE if for the system arena
 *                                FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmResidentReq(fl) (fl & PG_RESIDENT)



/***LP  vmSwappableReq - Check if allocation request for swappable memory
 *
 *      This function checks whether an allocation request is for
 *      swappable memory by testing the allocation flags.
 *
 *      int vmSwappableReq(ulong_t fl)
 *
 *      ENTRY   fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                  - TRUE if for the system arena
 *                                FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmSwappableReq(fl) ((fl & PG_STATE) == PG_SWAPPABLE)



/***LP  vmSysArenaReq - Check if allocation request for system arena
 *
 *      This function checks whether an allocation request is for the
 *      system arena by testing the allocation flags.
 *
 *      vmSysArenaReq ( fl )
 *
 *      ENTRY   fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                  - TRUE if for the system arena
 *                                FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmSysArenaReq(fl) ((fl & VMAC_ARENAMASK) == VMAC_ARENASYS)



/***LP  vmShrArenaReq - Check if allocation request for shared arena
 *
 *      This function checks whether an allocation request is for the
 *      shared arena by testing the allocation flags.
 *
 *      vmShrArenaReq ( fl )
 *
 *      ENTRY   fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                  - TRUE if for the shared arena
 *                                FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmShrArenaReq(fl) ((fl & VMAC_ARENAMASK) == VMAC_ARENASHR)



/***LP  vmPrvArenaReq - Check if allocation request for private arena
 *
 *      This function checks whether an allocation request is for the
 *      private arena by testing the allocation flags.
 *
 *      vmPrvArenaReq ( fl )
 *
 *      ENTRY   fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                  - TRUE if for the shared arena
 *                                FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmPrvArenaReq(fl) ((fl & VMAC_ARENAMASK) == VMAC_ARENAPRV)



/***LP  vmShrDataReq - Check if allocation request for shareable data
 *
 *      This function checks whether an allocation request is for
 *      shareable data by testing the allocation flags.
 *
 *      vmShrDataReq ( fl )
 *
 *      ENTRY   fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                  - TRUE if for shareable data
 *                                FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmShrDataReq(fl) (fl & VMAC_SHARED)



/***LP  vmLocAnyReq - Check if allocation request for any address range
 *
 *      This function checks whether an allocation request is for
 *      any virtual address range by testing the allocation flags.
 *
 *      vmLocAnyReq(fl)
 *
 *      ENTRY           fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                          - TRUE if for any virtual addresses
 *                                        FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmLocAnyReq(fl) ((fl & VMAC_LOCMASK) == VMAC_LOCANY)



/***LP  vmLocSpecReq - Check if allocation request for specific addresses
 *
 *      This function checks whether an allocation request is for
 *      specific virtual addresses by testing the allocation flags.
 *
 *      vmLocSpecReq ( fl )
 *
 *      ENTRY   fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                  - TRUE if for specific virtual addresses
 *                                FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmLocSpecReq(fl) ((fl & VMAC_LOCMASK) == VMAC_LOCSPECIFIC)



/***LP  vmLocAboveReq - Check if allocation request for addresses above
 *
 *      This function checks whether an allocation request is for
 *      virtual addresses not below a given address by testing the allocation
 *      flags.
 *
 *      vmLocAboveReq ( fl )
 *
 *      ENTRY   fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                  - TRUE if for specific virtual addresses
 *                                FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmLocAboveReq(fl) ((fl & VMAC_LOCMASK) == VMAC_LOCABOVE)


/***LP  vmAlignParaReq - Check if allocation request for paragraph alignment
 *
 *      This function checks whether an allocation request is for
 *      virtual addresses aligned on a page boundary.
 *
 *      int vmAlignParaReq(ulong_t fl)
 *
 *      ENTRY           fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                          - TRUE if for page alignment
 *                                        FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmAlignParaReq(fl) ((fl & VMAC_ALIGNMASK) == VMAC_ALIGNPARA)


/***LP  vmAlignPgReq - Check if allocation request for page alignment
 *
 *      This function checks whether an allocation request is for
 *      virtual addresses aligned on a page boundary.
 *
 *      int vmAlignPgReq(ulong_t fl)
 *
 *      ENTRY           fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                          - TRUE if for page alignment
 *                                        FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmAlignPgReq(fl) ((fl & VMAC_ALIGNMASK) == VMAC_ALIGNPAGE)


/***LP  vmAlignSelReq - Check if allocation request for tiled selector
 *                      alignment (64K alignment)
 *
 *      This function checks whether an allocation request is for
 *      virtual addresses aligned on a tiled selector boundary (64K)
 *
 *      int vmAlignSelReq(ulong_t fl)
 *
 *      ENTRY           fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                          - TRUE if for tiled selector alignment
 *                                        FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmAlignSelReq(fl) ((fl & VMAC_ALIGNMASK) == VMAC_ALIGNSEL)


/***LP  vmAlignDirReq - Check if allocation request for page directory alignment
 *
 *      This function checks whether an allocation request is for
 *      virtual addresses aligned on a page boundary.
 *
 *      int vmAlignDirReq(ulong_t fl)
 *
 *      ENTRY           fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                          - TRUE if for page alignment
 *                                        FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmAlignDirReq(fl) ((fl & VMAC_ALIGNMASK) == VMAC_ALIGNDIR)


/***LP  vmVDMReq - Check if allocation request for VDM
 *
 *      This function checks whether an allocation request is for
 *      a Virtual DOS Machine
 *
 *      vmVDMReq ( fl )
 *
 *      ENTRY   fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                  - TRUE if for VDM
 *                                FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmVDMReq(fl) (fl & VMAC_VDM)


/***LP  vmReloadReq - Check if allocation request for reload/load out
 *                    of reserved memory.
 *
 *      This function checks whether an allocation request is for reloading
 *      an MTE object out of memory reserved for that purpose, or for
 *      loading part of a huge item out of pre-reserved virtual memory.
 *
 *      vmReloadReq ( fl )
 *
 *      ENTRY   fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                  - TRUE if reload request
 *                                FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmReloadReq(fl) (fl & VMAC_RELOAD)


/***LP  vmRetainReq - Check if allocation request specifies retention
 *                    for future reloads.
 *
 *      This function checks whether an allocation request specifies that
 *      the virtual address space is to be retained for future reloads after
 *      the last reference to the object has been freed.
 *
 *      vmRetainReq ( fl )
 *
 *      ENTRY   fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                  - TRUE if reload request
 *                                FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmRetainReq(fl) ((fl) & VMAC_RETAIN)


/***LP  vmPreResReq - Check if request to pre-reserve virtual memory
 *                    for future allocation to object(s).
 *
 *      This function checks for a request to pre-reserve virtual memory
 *      for future allocation to objects.
 *
 *      vmPreResReq ( fl )
 *
 *      ENTRY   fl              - Allocation Flags (see VMAllocMem)
 *      RETURN                  - TRUE if reload request
 *                                FALSE otherwise
 *
 *      WARNING - This function is implemented as a macro
 */

#define vmPreResReq(fl) (fl & VMAC_PRERES)


/***LP  vmWithinAr - Check if arena record maps given address
 *
 *      Given a pointer to an arena record and a virtual address, this
 *      function checks if the address belongs to the range of addresses
 *      mapped by the arena record.
 *
 *      vmWithinAr (p, par)
 *
 *      ENTRY   (void) p        - virtual address to be checked
 *              VMAR *par       - valid pointer to an arena record
 *      RETURN                  - TRUE if the address is mapped by the ar
 *                              - FALSE otherwise
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmWithinAr(p, par) (vmWithinArPg((((ulong_t)(p)) >> PAGESHIFT), par))


/***LP  vmWithinArPg - Check if arena record maps given virtual page
 *
 *      Given a pointer to an arena record and a virtual page number, this
 *      function checks if the address belongs to the range of addresses
 *      mapped by the arena record.
 *
 *      vmWithinArPg (ipg, par)
 *
 *      ENTRY   ulong_t ipg     - virtual address to be checked
 *              VMAR *par       - valid pointer to an arena record
 *      RETURN                  - TRUE if the address is mapped by the ar
 *                              - FALSE otherwise
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmWithinArPg(ipg, par)                                          \
  (((ipg) == (par)->ar_ipg) ||                                          \
   ((ipg) >= (par)->ar_ipg && (ipg) < (par)->ar_ipg + (par)->ar_cpg))


/***LP  vmIsLoadOb - check if object is a loader-created object
 *
 *      This function checks whether a given object is a loader object
 *
 *      vmIsLoadOb (pob)
 *
 *      ENTRY   VMOB *pob       - valid pointer to an object record
 *      RETURN                  - TRUE if object is a loader object
 *                              - FALSE otherwise
 *
 *      WARNING This function is implemented as a macro.
 */

#define vmIsLoadOb(pob) ((((pob->ob_fs & OB_API) == 0) && \
                            (pob)->ob_hobmte != HOBNULL) && \
                            (!(vmSystemOwner((pob)->ob_hobmte))))

/***LP+ vmHalToPal - Convert handle of alias record to its address
 *
 *      Given a handle to alias record, returns a pointer to the
 *      corresponding alias record. No verification is done.
 *
 *      vmHalToPal(hal)
 *
 *      ENTRY   hal             - Alias record handle
 *      RETURN  VMAL *          - Pointer to alias record
 *
 *      This function is implemented as a macro.
 */

#define vmHalToPal(x)   (palvmIal + (VMHAL)(x))


/***LP+ vmPalToHal - Convert alias record pointer to handle
 *
 *      Given pointer to an alias record, vmPalToHal returns the
 *      corresponding handle. No parameter verification is done.
 *
 *      vmPalToHal(pal)
 *
 *      ENTRY   pal             - Pointer to alias record (VMAL *)
 *      RETURN  hal             - Alias record index
 *
 *      This function is implemented as a macro
 */

#define vmPalToHal(x)   ((VMHAL) (((VMAL *)(x)) - palvmIal))


/***LP+ vmIsSELAlias - Return nonzero if given alias record is
 *          SELMGR alias record
 *
 *      vmIsSELAlias(pal)
 *
 *      ENTRY   pal - pointer to alias record (Must not be base alias)
 *      RETURN  int - TRUE (!=0) if alias is a SELMGR alias
 *                    FALSE (=0) otherwise
 *
 *      This function is implemented as a macro
 */
#define AL_SELMGR  (AL_CSALIAS | AL_MEMMAP)

#define vmIsSELAlias(pal)  ((pal->al_f & AL_SELMGR))


/***LP+ vmIsDBGPrivAlias - Return nonzero if given alias record is
 *          privatized debug alias record
 *
 *      vmIsDBGPrivAlias(pal)
 *
 *      ENTRY   pal - pointer to alias record (Must not be base alias)
 *      RETURN  int - TRUE (!=0) if alias is a privatized debug alias
 *                    FALSE (=0) otherwise
 *
 *      This function is implemented as a macro
 */
#define vmIsDBGPrivAlias(pal)  ((pal->al_f & (AL_PRIV | AL_DBGALIAS)) == \
            (AL_PRIV | AL_DBGALIAS))


/***LP  vmSemAssertOb - assert that we have an object semaphore
 *
 *      This function internal errors if a specified object's semaphore
 *      is not owned by the current thread.
 *
 *      vmSemAssertOb (pob)
 *
 *      ENTRY   pob             - pointer to object record
 *      RETURN                  TRUE if the object semaphore is owned
 *                                by the current thread
 *                              FALSE otherwise
 */

#define vmSemAssertOb(pob) \
  vmAssert((pob)->ob_wsemowner == pTCBCur->TCBNumber)

/***LP  vmCrossesPgBdry - test whether address range crosses page boundary
 *
 *      Given a start virtual address and a byte count, this function
 *      determines whether the range crosses a page boundary.
 *
 *      int vmCrossesPgBdry(void *pb, ulong_t cb)
 *
 *      ENTRY           pb              - Base address
 *                      cb              - Count of bytes
 *      RETURN                  TRUE if crosses page bdry else FALSE
 */

#define vmCrossesPgBdry(pb, cb) \
  ((cb == 0) ? \
  FALSE : ((((((ulong_t)(pb)) + cb - 1) ^ (ulong_t)(pb)) >> PAGESHIFT) != 0))


/***LP  vmGetCo - Return hco, and pco matching the context
 *
 *      vmGetCo walks the linked context records and returns the
 *      hco and pco matching the context.
 *
 *      WARNING: This function is implemented as a macro. It returns one
 *      level up with an ERROR_INVALID_ADDRESS if context is not found.
 *
 *      vmGetCo(pco, hco, hobptda)
 *
 *      ENTRY   hco             - first context handle on the linked list
 *              pco             - variable to put pointer to context record
 *              hobptda         - ptda handle to match
 *      RETURN  NONE      (returns one level up if error)
 */
#define vmGetCo(pco, hco, hobptda)      {                           \
            while(((pco = vmCoMap(hco))->co_hobptda) != hobptda) {  \
//              hco = pco->co_hconext;                              \
                hco = VMHconextCo(*pco);                            \
                if (hco == HCONULL)                                 \
                    return(ERROR_INVALID_ADDRESS);                  \
            }   }


/***LP  vmGetOb - Find object record corresponding to Ar and hobptda
 *
 *      vmGetOb finds the hob and pob associated with the given
 *      handle and context
 *
 *      WARNING: This function is implemented as a macro. This function
 *      returns one level up with error if given hobptda
 *      or hob is not found.
 *
 *      ENTRY   par             - pointer to arena record
 *              hobptda         - ptda handle (0 doesn't mean curent ptda!)
 *              hob             - variable to return hob
 *              pob             - variable to return pob
 *      RETURN  NONE        (returns one level up if error)
 */
#define vmGetOb(par, hobptda, hob, pob)    {                            \
        if(par->ar_hob == HOBNULL)                                      \
            return(ERROR_NO_OBJECT);                                    \
        hob = par->ar_hob;                                              \
        pob = vmHandleMap(hob);                                         \
        if (!(par->ar_f & AR_HCO) && VMShrArenaPg(par->ar_ipg))         \
          {             /* shared arena instance data */                \
            vmAssert(!vmAliasAr(par));                                  \
            while ((pob = vmHandleMap(hob))->ob_hobowner != hobptda)  { \
                hob = pob->ob_hobnext;                                  \
                if (hob == HOBNULL)                                     \
                    return(ERROR_INVALID_ADDRESS);                      \
            }                                                           \
        }                                                               \
    }


/***LP  vmError - Call error function for debugging
 *
 *      This function calls a null function when in a kernel with
 *      strict checking enabled.  By setting a breakpoint on the
 *      called function vmErrorSub, the call stack leading up to
 *      a VM error code can be found.
 *
 *      int vmError(int rc)
 *
 *      ENTRY           rc              - Non-zero result code
 *      RETURN          int             - The passed in rc value
 *
 *      WARNING:  This function is implemented as a macro.
 */

#ifdef VMSTRICT
#define vmError(rc) vmErrorSub(rc)
#else
#define vmError(rc) rc
#endif


/***LP  vmAssert - cause internal error if assertion fails
 *
 *      Given a boolean, this procedure causes an internal error if
 *      the boolean is false.  Typically, the value of this boolean is
 *      derived from some test expression.
 *
 *      vmAssert (f)
 *
 *      ENTRY   f               - boolean value (int)
 *      RETURN  NONE
 *
 *      CALLS   panicfmt
 *
 *      WARNING This procedure is implemented as a macro.
 *
 *      EFFECTS NONE
 */

#ifdef  VMSTRICT
#  define vmAssert(e) _assert(e)
#else
#  define vmAssert(e)
#endif
