/*
 *      SCCSID = @(#)vdmvdh.h   6.9 92/03/04
 *
 *      IBM Confidential
 *
 *      Copyright (c) IBM Corporation 1987, 1989
 *
 *      All Rights Reserved
 *
 *  Description:
 *
 *  This file contains all the local defines, data structures and
 *  macros used by VDM Manager.
 *
 * Update History:
 *
 * 6.6  08/18/91  Jeff Muir CP20 B725703  added global sysvalue for PICMask
 * 6.7  09/15/91  Jeff Muir CP20 B726841  delete IOPL property
 * 6.8  02/06/92  Stacey Barnes CP20 B732228 add new type define for mi_fState
 * 10/19/92 56061 Stacey Barnes Changed GSVMAX to VDHGSV_BOOTDRV
 * 11/27/95 72417                                                       ;72417
 * moved find.h after tkexport.h                                        ;72417
 */

/*INT32*/

//c-begin
#include <osconst.h>
#include <ostypes.h>
#include <osmac.h>
#include <mi.h>
#include <dossymc.h>
#include <sigdef.h>
#include <except.h>
#include <curdir.h>
#include <dirent.h>
#include <sem.h>
#include <screen.h>
#include <pgexport.h>
#include <vmexport.h>
#include <vmowner.h>
#include <error.h>
#include <error2.h>
#include <selxport.h>
#include <infoseg.h>
#include <tkexport.h>
#include <find.h>                         //72417 moved after tkexport.h
#include <tkptda.h>
#include <ldrxport.h>
#include <mvdm.h>
#include <semxport.h>
#include "propp.h"
#include <mvdmexp.h>

/* Constant Defines */

#define ALIGN_OBJECT(n,size)    (n / size)*size + (n % size > 0 ? size:0)
#define DSToSS                  (PVOID)((PBYTE)p - SSToDS(0))
#define IS_PAGE_ALIGNED(p)      (((ULONG)p & 0xfff) == 0 ? 1 : 0)
#define LINEAR_ARENA_END        (1 << 22)            // 4Mb limit
#define ONEMBPLUS               ((1L << 20)+(1L << 16))  // 1MB+64K
#define SELSIZE                 (1 << 16)
#define ROUND_UP(p,size)        (((ULONG)(p) + (size - 1)) & ~(size - 1))
#define ROUND_DOWN(p,size)      ((ULONG)(p) & ~(size -1))

#define ISINSYSARENA(p)         (VMSysArena(p))
#define ISINSHRARENA(p)         (VMShrArena(p))
#define ISINPRVARENA(p)         (VMPrvArena(p,pPTDACur))

#define ISINSYSARENAPG(ipg)     (VMSysArenaPg(ipg))
#define ISINSHRARENAPG(ipg)     (VMShrArenaPg(ipg))
#define ISINPRVARENAPG(ipg)     (VMPrvArenaPg(ipg,pPTDACur))

#define ISOS2CONTEXT            (pPTDACur->ptda_infoseg.LIS_ProcType != LIS_PT_REALMODE)

#define MAX_SYS_PAGES           (1 << 20)       // 2**20 pages in 4 GB

#define MAX(x,y)                (x >= y ? x : y)
#define MIN(x,y)                (x <= y ? x : y)
#define END_ADDR(plr)           (PVOID)((ULONG)plr->lr_pv + plr->lr_cb)
//c-end

/* Configurable defines */

#define DOSMEMSIZE              (256 * _1K)     // Dos Heap Size
#define MAXLENXDD               8               // PDD/VDD Name length
#define MAX_FREEZE_COUNT        16              // Maximum number of pending
                                                // VDHFreezeVDM
#define MAX_INT_NEST            33              // Interrupt nesting count
#define SIG_AM_SWAP             0xAA            // VDHAllocMem signature
#define SIG_AM_NOSWAP           0xBB            // VDHAllocMem signature
#define VDM_MAX_TIMERS          16              // Timer Hooks Limit

#define VDHCP_NOYIELD           (1 << 9)        // Dont yield if less than 2Kb
#define VDHCP_YIELD             (1 << 10)       // Copy 4kb between yield

#define MASKUCHAR               0xff
#define MASKUSHORT              0xffff
#define MASKULONG               0xffffffff

#define CMD_GET_INTERRUPT_HANDLER 0x0           // command to vpic

/* Bit definitions for vdmid_flVDM */

#define VDM_VMBOOT              0x00000001
// #define VDM_IOPL3               0x00000002      // 6.7
#define VDM_TITLECHANGE         0x00010000


/* VDMM Assertion checking  macros */

//c-begin
#ifdef  VDMMSTRICT

#define vdmmAssertEQ(a,b)       _assert(a == b)
#define vdmmAssertNEQ(a,b)      _assert(a != b)
#define vdmmAssertLT(a,b)       _assert(a < b)
#define vdmmAssertGT(a,b)       _assert(a > b)
#define vdmmAssertLTE(a,b)      _assert(a <= b)
#define vdmmAssertGTE(a,b)      _assert(a >= b)
#define vdmmAssertAND(a,b)      _assert(a & b)
#define vdmmAssert              _assert(0)

#else

#define vdmmAssertEQ(a,b)
#define vdmmAssertNEQ(a,b)
#define vdmmAssertLT(a,b)
#define vdmmAssertGT(a,b)
#define vdmmAssertLTE(a,b)
#define vdmmAssertGTE(a,b)
#define vdmmAssertAND(a,b)
#define vdmmAssert

#endif
//c-end

/***LT+ VDM Event Handler structure
 *
 *      EH structure links the VDD's entry points for a VDM
 *      user hook.
 */


#define FIFO_ORDER  0
#define LIFO_ORDER  1

typedef BOOL (HOOKENTRY *PUH)(HVDM);
typedef BOOL (HOOKENTRY *PEXITH)(VOID);
typedef BOOL (HOOKENTRY *PPDBH)(HVDM,USHORT);
typedef BOOL (HOOKENTRY *PMEMMAPPEDH)(HVDM,ULONG,INT,ULONG);

typedef struct  EL_s {     /* el  event list */
        PUH     el_pfn;                 // VDD handler
        ULONG   el_hmte;                // VDD module handle
        struct  EL_s    *el_pel;        // Next entry ; Ended by NULL
} EL;

typedef EL      *PEL;

typedef struct  EH_s {     /* eh  event head */
        ULONG   eh_fOrder;              // Order in which new handler gets added
        PEL     eh_pelFirst;            // First Event handler
        PEL     eh_pelLast;             // Last Event handler
} EH;

typedef EH      *PEH;


/*end*/

/***LT+ Page Fault Handler Structure
 *      PFH structure makes a linked list of all the page fault handler
 *      registered for a VDM. The Head of the PFH list is HPFH which
 *      keeps track of first and last record of this list. HPFH is
 *      stored in MVDM kernel instance data.
 */

typedef struct  PFH_s {                 // Page fault handler structure
        PVOID   pf_pv;                  // Starting region address
        ULONG   pf_cPages;              // Number of pages in region
        PFAULTHOOK  pf_pfn;             // Page fault handler address
        BOOL    pf_flags;               // Byte or page granular address
        struct  PFH_s  *pf_ppfh;        // Next entry; Ended by NULL
} PFH;

typedef PFH     *PPFH;

typedef struct  HPFH_s {                // Header of PFHs
        PPFH    hf_ppfhFirst;           // First PFH on the list
        PPFH    hf_ppfhLast;           // Last PFH on the list
}HPFH;

typedef HPFH    *PHPFH;
/*end*/


/***LT+ PDD Entry Point Structure
 *
 *      PDDEP structure stores PDD entry points for
 *      PDD/VDD communication
 */


typedef struct  PDDEP_s {                 // PDD Entry point structure
        CHAR    pddep_szPDD[MAXLENXDD+1]; // PDD name
        FPFNPDD pddep_fpfn;               // Entry point routine
        struct  PDDEP_s   *pddep_ppddep;  // Next entry point
}PDDEP;

typedef PDDEP      *PPDDEP;
/*end*/

/***LT+ VDD Entry Point Structure
 *      VDDEP stores VDD entry points for VDD-VDD and VDD_OS2
 *      communication. VDDEP makes a linked list and each record
 *      represents entry points for a VDD. VDDs can register
 *      entry points with same name. VDDPROC is used to keep
 *      entry points in a linked list for VDDs registered with
 *      same name. HDLVDD is the handle returned to the caller
 *      of VDHOpenVDD or DosOpenVDD.
 */

typedef struct  VDDPROC_s{
        PFNDEVREQ     vddproc_pfnvdd;     // Entry point for VDD/VDD comm.
        PFNSYSREQ     vddproc_pfnos2;     // Entry point for OS2/VDD comm.
        struct  VDDPROC_s   *pvddproc;    // Entry points registered with same name
}VDDPROC;

typedef VDDPROC    *PVDDPROC;

typedef struct  VDDEP_s {                  // VDD Entry point structure
        CHAR     vddep_szVDD[MAXLENXDD+1]; // VDD Name
        PVDDPROC vddep_vddp;               // VDD entry points
        ULONG    vddep_hmte;               // For Deregistering if VDD fails
        struct   VDDEP_s   *vddep_pvddep;  // Next VDD
}VDDEP;

typedef VDDEP      *PVDDEP;

typedef struct  HDLVDD_s {                 // VDD handle
        PVDDPROC hdlvdd_pvddproc;          // VDD routine to be called
        struct   HDLVDD_s  *hdlvdd;        // Next VDD handle;NULL if no more
} HDLVDD;

typedef HDLVDD    *PHDLVDD;

/* Communication Types Offered by a VDD */

#define     VDDVDD  0
#define     OS2VDD  1
/*end*/


/***LT+ Block Pool Data structures
 *
 *      BPH is the Block Pool Header which stores all the block
 *      pools in a linked list. Each record on the list is a block
 *      pool which will have chain of blocks of same size. Every
 *      block on the pool keeps a pointer to its next block.
 */

typedef struct BPH_s  {                 // Block Pool Header
    ULONG   bph_cb;                     // Block size
    ULONG   bph_fl;                     // Block pool flag
    PVOID   bph_pUseList;               // List of blocks in use
    PVOID   bph_pFreeList;              // List of free blocks
    struct  BPH_s *bph_pbph;            // Block pool headers list
} BPH;

typedef BPH      *PBPH;                 // Handle to the block pool
/*end*/


/***LT+ Linear Map Structures
 *
 *      LR is the linear record for a page aligned memory
 *      allocation. LA is the linear arena constituting of
 *      LR's to represent either the global memory map or the
 *      local memory map for a VDM. BYTEHEAP represents the byte
 *      heap which is used to get the current starting heap
 *      address for allocation and the size of remaining heap.
 *      Byte heap management does'nt keep track of each byte
 *      granular allocation.
 */

/*  MM - Memory Map structure
 *
 *      Valid rgfState combinations:
 *
 *      MM_ALLOCATED    - allocated linear space.  For example:
 *                        The DOS Emulation "kernel" data and
 *                        the DOS Memory Arena.
 *
 *      MM_RESERVED     - space reserved for later aliasing or
 *                        allocation, not currently aliased.
 *
 *      MM_INSTANCE_VDD     - For VDD Instance data.
 *
 *      MM_INSTANCE_KERNEL - for MVDM Kernel instance data
 *
 *      lr_sig is useful in those cases where the record gets broken
 *      in more than one. This will have the unique starting address
 *      of the orginal record. Will be used as a safegaurd against
 *      improper coalescing and VDHUnresrvepages.
 */


typedef struct  LR_s {                  // Linear Memory Record
        PVOID   lr_pv;                  // starting linear address
        ULONG   lr_cb;                  // length in bytes(always page granular)
        ULONG   lr_cbAllocated;         // bytes commited(always page granular)
        ULONG   lr_fState;              // state of region
        PVOID   lr_sig;                 // signature.Starting address of record
        struct  LR_s  *lr_plr;          // Next entry
} LR;

typedef LR      *PLR;

typedef struct  LA_s {                  // Linear arena
        PLR     la_plrFirst;            // First LR
        PLR     la_plrLast;             // Last LR
        PLR     la_plrAbove1MB;         // First record above 1Mb; It makes
                                        // the search fast.
} LA;

typedef LA      *HLA;

/* lr_fState values.                                                */
/* Note that the mapped/unmapped state of a record is determined    */
/* by MM_ALLOCATED. MM_BLACKHOLE is an additional flag for          */
/* LHMapPages as a single object of size bigger then black hole size*/
/* will have more then one mapping and this flag will indicate the  */
/* use of repeated VMfree on the same record.                       */
/* Reason why MM_SWAPPABLE and MM_RESIDENT are kept separate is     */
/* that in the code most of the time we just want to know whether   */
/* record is allocated or not.                                      */

#define MM_ALLOCATED        0x0001          // allocated linear space
#define MM_RESERVED         0x0002          // reserved  linear space
#define MM_BLACKHOLE        0x0004          // Mapped to black hole
#define MM_FINSTANCE        0x0008          // instance data record (fixed)
#define MM_SINSTANCE        0x0010          // instance data record (Swap)
#define MM_SWAPPABLE        0x0020          // These two flags further
#define MM_RESIDENT         0x0040          // explains MM_ALLOCATED.
                                            // Valid only with MM_ALLOCATED
#define MM_BROCKEN          0x0080          // If a record is brocken in
                                            // more than one records this
                                            // flag will be marked on,so
                                            // that no further reallocation
                                            // can be done on it.

/* LHAllocPages Flag type values    */
#define LH_RESERVE         0
#define LH_ALLOC_SWAPPABLE 1
#define LH_ALLOC_RESIDENT  2


/* LHAllocPages return    values    */

#define LHAP_FAIL          0
#define LHAP_SUCCESS       1
#define LHAP_ABOVE         2

/* LHFreePages return values        */

#define LHFP_FAIL          0
#define LHFP_SUCCESS       1
#define LHFP_ABOVE         2

/* LHCheckForFault return values    */
#define RECORD_INVALID     0
#define RECORD_MAPPED      1
#define RECORD_CREATED     2

/* VDHReallocPages Undo bits */

#define VDHRP_UNDO_RESERVE 0x0001
#define VDHRP_UNDO_RECORD  0x0002



typedef struct BYTEHEAP_s  {            // byte heap structure
    PVOID   bh_pv;                      // Starting address of heap
    PVOID   bh_pCur;                    // heap address to allocate from
    ULONG   bh_cb;                      // bytes remaining in heap
} BYTEHEAP;

typedef BYTEHEAP         *PBYTEHEAP;
/*end*/

/***LT+ Pid/SGid to HVDM Mapping Structure
 *
 *      MAPID structure stores the pid, SGid and the hvdm for
 *      a VDM. HMAPID is the head of MAPID list.
 */

typedef struct  MAPID_s {  /* mi */     // PID,SGID and HVDM structure
        PID     mi_Pid;
        SGID    mi_SGid;
        HVDM    mi_hvdm;
        ULONG   mi_fState;                 // VDM State
        struct  MAPID_s *mi_pmi;
} MAPID;

typedef MAPID *PMAPID;

typedef struct  HMAPID_s {              // header for MAPID list
        PMAPID  hm_pmiFirst;            // first MAPID
        PMAPID  hm_pmiLast;             // last  MAPID
} HMAPID;

typedef HMAPID    *PHMAPID;

#define VDM_BEING_CREATED       0x0001
#define VDM_BEING_TERMINATED    0x0002
#define VDM_AFTER_CREATE_TIME   0x0003  // 6.8

/*end*/

/***LT+ VDD Heap data structures
 *
 *      VDMMAssignAddress uses these heaps to allocate addresses
 *      for VDD code/Global data/Instance data, to be loaded by loader.
 *
 *      A HEAP always has a free block to allocate from.
 *
 */


typedef struct  HEAPBLOCK_s {   /* hb */
    PVOID   hb_pv;                      // starting address
    ULONG   hb_cb;                      // length
    SEL     hb_sel;                     // selector
    ULONG   hb_fFree;                   // TRUE => block is free
    struct  HEAPBLOCK_s *hb_phb;        // Next entry
} HEAPBLOCK;
typedef HEAPBLOCK   *PHEAPBLOCK;

typedef struct  HEAP_s{         /* hp */
    ULONG       hp_fl;                  // heap type flags
    PVOID       hp_pv;                  // Starting addr of heap
    ULONG       hp_cbMax;               // Maximum size of heap
    ULONG       hp_cbFreeHeapBlock;     // Size of new free blocks
    PHEAPBLOCK  hp_phb;                 // Heap entries of this heap
} HEAP;
typedef HEAP     *PHEAP;


typedef struct HEAPINIT_s {     /* hpi */
    ULONG   hpi_fl;                     // heap type flags
    ULONG   hpi_cb;                     // maximum heap size
} HEAPINIT;
typedef HEAPINIT *PHEAPINIT;

/* Object types of heaps (Heap Indices) */

#define VDMAA_OT_INITCODE       0
#define VDMAA_OT_INITDATA       1
#define VDMAA_OT_GLOBALCODE     2
#define VDMAA_OT_GLOBALDATA     3
#define VDMAA_OT_FIXEDINSTANCE  4
#define VDMAA_OT_SWAPGLOBALCODE 5
#define VDMAA_OT_SWAPGLOBALDATA 6
#define VDMAA_OT_SWAPINSTANCE   7

/* Heap Type Flags */

#define VDMAA_HT_INITCODE       0x0001
#define VDMAA_HT_INITDATA       0x0002
#define VDMAA_HT_GLOBALCODE     0x0004
#define VDMAA_HT_GLOBALDATA     0x0008
#define VDMAA_HT_FIXEDINSTANCE  0x0010
#define VDMAA_HT_SELECTOR       0x0020
#define VDMAA_HT_INSTANCE       0x0040
#define VDMAA_HT_SWAPCODE       0x0080
#define VDMAA_HT_SWAPDATA       0x0100
#define VDMAA_HT_SWAPINSTANCE   0x0200
/*end*/


// Kenel instance data sizes

#define FIXED_KRNL_INST_SIZE      64*1024

/***LT+ VDD module handle list
 */
typedef struct  MODULEHANDLE_s{ /* mh */   // Vdd Module handle list
        USHORT  mh_hmte;                   // Module handle
        struct  MODULEHANDLE_s   *mh_pmh;  // Next entry
} MODULEHANDLE;

typedef MODULEHANDLE    *PMODULEHANDLE;    // pmh

/*end*/


/***LT+ Query System Values structure
 */

typedef struct  GSYSVAL_s{
        PVOID   gsv_pv;                      // Address of system value
        ULONG   gsv_ulMask;                  // Size  Mask
}GSYSVAL;

typedef GSYSVAL  *PGSYSVAL;

typedef struct  LSYSVAL_s{
        PVOID   lsv_pv;                      // Address of system value
        ULONG   lsv_ulMask;                  // Size  Mask
        ULONG   lsv_fInstance;               // sv_pv is global or instance
}LSYSVAL;

typedef LSYSVAL  *PLSYSVAL;

#define LSV_GLOBAL      0                    // sv_pv is global
#define LSV_INSTANCE    1                    // sv_pv is in instance data
#define LSV_UNUSED      2                    // sv_pv is in instance data

#define GSVSTART        VDHGSV_DAY
#define GSVMAX          VDHGSV_MECADDR

#define LSVSTART        VDHLSV_HVDM
#define LSVMAX          VDHLSV_VPICBASE
/*end*/


#define DT_INIT                 VDMAA_OT_INITDATA       // Init Data
#define DT_GLOBAL               VDMAA_OT_GLOBALDATA     // Global fixed data
#define DT_GLOBALSWAP           VDMAA_OT_SWAPGLOBALDATA // Global swap data
#define DT_INSTANCEFIX          VDMAA_OT_FIXEDINSTANCE  // Instance fixed data
#define DT_INSTANCESWAP         VDMAA_OT_SWAPINSTANCE   // Instance Swap data
#define DT_STACK                10                      // Stack data

//c-begin
/***LT+ Lock Handle Data Structure for VDHLockMem
 *      LOCKENTRY structure makes a linked list of all the lock handles
 *      created by VDHLockMem. The Head of the LOCKENTRY list is LOCKENTRYHEAD
 *      which keeps track of first and last record of this list. LOCKENTRYHEAD
 *      is stored in MVDM swappable data.
 */

typedef struct LOCKENTRY_s{
        struct vmlh_s         le_hlock;        // Lock handle passed to VMLock
        struct  LOCKENTRY_s   *pnextlockentry; // Next lock entry
}LOCKENTRY;

typedef LOCKENTRY   *PLOCKENTRY;

typedef struct  LOCKENTRYHEAD_s {       // Head lock entry
        PLOCKENTRY phle_leFirst;        // First lock entry
        PLOCKENTRY phle_leLast;         // Last lock entry
} LOCKENTRYHEAD;

typedef LOCKENTRYHEAD *PLOCKENTRYHEAD;
/*end*/
//c-end


// vdmmCopyConfig undo function defines

#define UNDO_VDMCONFIG      0x0001
#define UNDO_PSZSHELL       0x0002
#define UNDO_PSZZDOSDDS     0x0004
#define UNDO_PSZZVDDVALUES  0x0008

// VDM creation failure undo function count. Right now there are 6 items
// to be undone.Must be increased if more undo items are added.

#define CREATE_UNDO_ITEMS   10


// VDM FGND/BBND states defines

#define VDM_BGND    0
#define VDM_FGND    1
#define VDM_INIT    2

// VDMMSwitchFgnd/Bgnd local defines

#define SWITCH_FGND 0
#define SWITCH_BGND 1

// VDMMPDBChange/Destroy local defines

#define PDB_CHANGE  0
#define PDB_DESTROY 1

// Signature for hvdm validation (vdmid_SIG)
#define HVDM_SIGNATURE 0x4D445648           // the string "HVDM"

// Undo function prototype
typedef (PASCAL NEAR *UNDOPFN)(VOID);

// VDD init routine prototype
typedef BOOL (PRIVENTRY *PVDDPOSTINIT)(VOID);


// VDD init routine prototype
typedef BOOL (EXPENTRY *PVDDINIT)(PSZ);

/* Dos Emulation flag definations */
#define DEM_SLAVE_THREAD       0x0001   // Slave thread present flag
#define DEM_SLAVE_THREAD_BIT        0   //

// Second thread defines
#define VPIC_SLAVE_ADDRESS 3

/* XLATOFF */

//Page fault handling in context
typedef struct pgfdata_s {
    PVOID   pFault;             // page fault address
    HKSEM   hksemFaultSync;     // synchronizes faulter with VDD
} PGFDATA;
typedef PGFDATA *PPGFDATA;


// Convert a 16:16 pointer to a linear address, return -1 if address is invalid
#define F16PTOLIN(f16p) ((PVOID) SELVirtToLin((ULONG) OFFSETOF16(f16p), \
                                               SEGMENTOF16(f16p)))

// VDD INFO Packet

typedef struct infopack_s {
    unsigned long  ip_cbResCode;
    unsigned long  ip_cbSwapCode;
    unsigned long  ip_cbInitCode;
    unsigned long  ip_cbResData;
    unsigned long  ip_cbSwapData;
    unsigned long  ip_cbInitData;
    unsigned long  ip_cbResInst;
    unsigned long  ip_cbSwapInst;
} INFOPACKET;


/* XLATON */
