/*static char *SCCSID = "@(#)selini.c   6.2 91/07/20";*/
#define SCCSID "@(#)selini.c    6.2 91/07/20"

/*
 *       IBM/Microsoft Confidential
 *
 *       Copyright (c) IBM Corporation 1987, 1989
 *       Copyright (c) Microsoft Corporation 1987, 1989
 *
 *       All Rights Reserved
 */


/***EC  SELINI - Selector Manager C Initialization Routines
 */


#define INCL_DOSERRORS
#define INCL_OS2STD
#include <os2.h>

#define INCL_DOSP
#include <os2p.h>

#define  FNO_NUM        FNO_SELINI_C
#include                <fnomem.h>
#include                <osmac.h>
#include                <mi.h>
#include                <seldesc.h>
#include                <pgexport.h>
#include                <vmexport.h>
#include                <vmowner.h>
#include                <selxport.h>
#include                <sellocal.h>

//   #include <vmkh.h>
struct vmkshd_s
  {
    ulong_t             kshd_size;       // Size of block in dwords
    struct vmkshd_s     *kshd_pNext;     // Next free block
    char                *kshd_pb;        // Address of block header
  };
typedef struct vmkshd_s VMKSHD;

extern VMKSHD          *pkshdVMDescs;          // Pointer to array of BMP32 managed




#define SELMAXLOCKHANDLE  (SEL_64K * 2)   // Guess, may need to change later

/***LD+ pslhLockHandles - Pointer to BMP32 records where lock handles
 *      are stored
 */

struct selLockHandle  *pslhLockHandles;


#pragma code_seg("CINIT_TEXT", "CODE")

/***LP  selFixCallGates - fix flat-relative call gates
 *
 *      This procedure walks the GDT and reformats all
 *      the 32-bit flat-relative call gates to have
 *      the proper format.  It is assumed that all such
 *      call gates will initially have the format:
 *
 *      DD      flat address of target function
 *      DB      number of dwords of parameters
 *      DB      D_GATE332
 *      DW      -1
 *
 *      This function reformats them to have the following
 *      format:
 *
 *      DW      low word of flat address
 *      DW      R0CS
 *      DB      number of dwords of parameters
 *      DB      D_GATE332
 *      DW      high word of flat address
 *
 *      selFixCallGates ()
 *
 *      ENTRY   NONE
 *      RETURN  NONE
 *
 *      CALLS   NONE
 *
 *      WARNING This is an initialization procedure.  It may
 *              be called only once.
 *
 *      EFFECTS Reformats 32-bit flat-relative call gate
 *              descriptors in the GDT.
 */
void                    selFixCallGates()
{
    register struct gate *pgate;        /* Gate pointer */
    register struct gate *pgdtend;      /* Pointer to end of GDT */
    ushort_t            hioffset;       /* High word of flat offset */

    pgdtend = (struct gate *)((char *) SELGDTLaddr + SELMaxGDT);
                                        /* Point at last selector */
    for(pgate = (struct gate *) SELGDTLaddr ; pgate <= pgdtend; ++pgate)
      {                                 /* Loop to walk GDT */
        if(pgate->g_access == D_GATE332 && pgate->g_extoffset == (ushort_t) -1)
          {                             /* If 32-bit flat-relative call gate */
            hioffset = pgate->g_sel;    /* Get high word of flat address */
            pgate->g_sel = R0CS;        /* Set selector to ring 0 flat CS */
            pgate->g_extoffset = hioffset;
                                        /* Put high word of address in place */
          }
      }
}


/***LP  selLockHandleInit - Initialize lock handle BMP32 records object
 *
 *      selLockHandleInit is called by SEL initialization routine to
 *      initialize BMP32 records that will contain long lockhandles
 *      and links to corresponding LDT locks returned by VMLock.
 *
 *      ENTRY   NONE
 *      EXIT    NONE
 *
 *      PseudoCode:
 *
 *      Call BMPInit(cblocks, cbblock=size of lockhandle, resident,
 *       SELLOCKOWNER,
 *          fnisbusy=NULL, &pslhLockHandles)
 *      If (error), Panic
 *      return
 */
void    selLockHandleInit()
{
        if (BMPInit(
           (PGGlobalFlags & PG_SYS_CONSTRAINED) ?       // defect 98488
                    SELMAXLOCKHANDLE/2 : SELMAXLOCKHANDLE,
           sizeof(struct selLockHandle_s),
           (PGGlobalFlags & PG_SYS_CONSTRAINED) ?
                     VMBMP_DONATEMEM | PG_RESIDENT : PG_RESIDENT,
           SELLOCKOWNER,
           NULL, &pslhLockHandles) != NO_ERROR)
        panic("selLockHandleInit:BMPInit");
}
