/*static char *SCCSID = "@(#)dbgin.h    6.5 91/11/17";*/
/***    DBGIN.H - DosDebug Local Definitions
 *
 *      SCCSID = @(#)dbgin.h    6.5 91/11/17
 *
 *      THIS IS AN OS/2 VERSION 2.x SPECIFIC FILE
 *
 *       IBM/Microsoft Confidential
 *
 *       Copyright (c) IBM Corporation 1987, 1989
 *       Copyright (c) Microsoft Corporation 1987, 1989
 *
 *       All Rights Reserved
 *
 *      This file defines the Local (intra-component) interfaces
 *      for the DosDebug function.
 *
 *      These definitions may only be used by files in the Debug component.
 *
 *****************************************************************************
 *  Change                                                                   *
 *  Activity      Date    BY   Reason                                        *
 *  --------      ----    ---  -------                                       *
 *  DCR 1320    05/25/91  ARJ  Pack Segement Support                         *
 *  PTR B723886 07/13/91  ARJ  DBG_N_Control is not supported remove (2 LOC) *
 *  PTR B727809 11/06/91  ARJ  Add DBGDR7LeGe to clear LE and GE bits   A001 *
 *****************************************************************************
 */

// XLATOFF

/***LT+ kDB - Kernel Debug Buffer structure
 *
 *      This structure is held on the debugger stack for the
 *      duration of a single DosDebug call.  The debuggee is
 *      given access to this structure via a pointer in the
 *      debuggee's DCB.
 *
 *      Debuggee kernel code which wishes to access the kDB on
 *      the debugger stack MUST verify that the kDB is available
 *      before accessing it, must access the kDB without blocking,
 *      and should not save the kDB address across blocks.
 *
 *      The thread status buffer, 287 NPX buffer, 387 NPX buffer,
 *      and LibName buffer is allocated from the debugger stack
 *      and is copied back to user space as required by the
 *      individual commands.
 *
 *      kDB.lCmd and kDB.puDB is used by kDB_Write to locate and
 *      format the uDB while writing it to user space.  kDB.lCmd
 *      contains the DosDebug command, separate from the notification.
 *      In case of an invalid command, kDB.lCmd will be zeroed.
 *
 */

typedef struct kDB_s {
        uDB_t    *puDB;                 /* pointer to user's DB        */
        long    lCmd;                   /* Format of copy of uDB (Cmd) */
        uDB_t   uDBTemp;                /* Temporary copy of uDB       */
} kDB_t;

/*end*/

// XLATON

/***LK+ DBGDR_ - DosDebug Debug Register Constants
 *
 *      DBGDR_FREE
 *              If (DBGaDRowner[i] == DBGDR_FREE), then
 *              debug register [i] is not in use
 *
 *      DBGDR_LOCKED
 *              If (DBGaDRowner[i] == DBGDR_LOCKED), then
 *              debug register [i] may not be modified.
 *
 *      DBGDR_DBG
 *              If (DBGaDRowner[i] == DBGDR_DBG), then
 *              debug register [i] is being used by DosDebug.
 *
 *      DBGDR_LAST
 *              The index to the last debug register.
 *
 */

#define DBGDR_FREE              0L              /* DR not in use         */
#define DBGDR_LOCKED            -1L             /* DR in use by KDB      */
#define DBGDR_DBG               1L              /* DR in use by DosDebug */
#define DBGDR_LAST              (DR_COUNT - 1)  /* index of last DR      */

/***ET+ WPCB -  Watchpoint Control Block structure
 *
 *      A Watchpoint Control Block (WPCB) exists for each
 *      watchpoint allocation.  The WPCB contains all the
 *      information required to keep the debug registers
 *      up-to-date, and to control the various watchpoint
 *      notifications.
 *
 *      pptda   : Address of Debuggee PTDA
 *      bfState : State bits (SET/ARMED/HIT - see below)
 *      bWid    : Watchpoint ID (note - this maps into a scope and index)
 *      DRindex : Debug register assigned to this watchpoint
 *
 *      DATA VALID WHEN NOT HIT :
 *
 *      fsLenRW : LEN and R/W bits for validating DR7
 *              bits 0-1 : Debug Register R/W bits
 *              bits 2-3 : Debug Register LEN bits
 *      laddr: Linear Address of Watchpoint for DR0-3
 *
 *      DATA VALID WHEN HIT :
 *
 *      Pid     : Pid of process which hit watchpoint
 *      Tid     : Tid of thread which hit watchpoint
 *      MTE     : MTE handle of process which hit watchpoint
 *      laddr   : Linearized Instruction Pointer
 *
 */

typedef struct WPCB_s {
        PTDA    *wpcb_pptda;    /* Address of Debuggee PTDA     */
        uchar_t wpcb_bfState;   /* WPCB State flags             */
        uchar_t wpcb_bWid;      /* Watchpoint ID                */
        ushort_t wpcb_Pid;      /* Pid of hit thread            */
        ushort_t wpcb_Tid;      /* Tid of hit thread            */
        ushort_t wpcb_MTE;      /* Module handle of hit thread  */
        ushort_t wpcb_fsLenRW;  /* Len/RW bits for DR7          */
        ulong_t wpcb_laddr;     /* WP address / LIP of hit      */
        uchar_t wpcb_DRindex;   /* DR assigned to this WPCB     */
} WPCB_t;

/*end*/

// XLATOFF

/*** DBGDR7_mLENRWGLn - Create a mask for all DR7 bits for a given DR
 */

#define DBGDR7_mLENRWGLn(iDR)   ((0xf0000L << ((iDR) << 2))\
                                 |(0x3L << ((iDR) << 1)))

/*** DBGDR7_LENRWn - Calculate LENn and/or RWn bits of DR7
 *
 * DBGDR7_LENnRWn gives the bits to OR into DR7 to set the LENn
 * and/or R/Wn bits of DR7, given a combination of the LEN and R/W
 * bits (above) and the debug register number (0-3).
 *
 */

#define DBGDR7_LENRWn(LenRW,iDR)  ((ulong_t) LenRW << (16 + (iDR << 2)))

/*** DBGDR7_GnLn - Calculate Gn and/or Ln bits of DR7
 *
 * DBGDR7_GnLn gives the bits to OR into DR7 to set the Gn and/or Ln
 * bits of DR7, given a combination of the Gn and Ln bits (above) and
 * a debug register number (0-3).
 *
 */

#define DBGDR7_GLn(GnLn,iDR)  ((ulong_t) GnLn << (iDR << 1))

/*end*/

/***LK+ DBGTIMEOUT - Maximum time before debugger connect
 *
 *      Currently ten minutes.
 */

#define DBGTIMEOUT 600000

/***LK+ DBGDCBS_ - Debug DCB State bits
 *
 *      These equates define the possible values of the
 *      DCB.flState flags.  These flags control the
 *      communication between the debugger and debuggee.
 *
 *      DBGDCBS_RECEIVED
 *              Debuggee sets this after it successfully receives
 *              a command to pick up the next notification, possibly
 *              by running user code.
 *
 *              Debugger clears this at the same time that it
 *              sets pkDB to zero, and also when interrupted.
 *
 *              If the debuggee has a notification to return, but
 *              DBGDCBS_RECEIVED is clear, the notification is dropped.
 *
 *      DBGDCBS_REPLIED
 *              Debuggee sets this after it has sucessfully returned
 *              the notification to the debugger.
 *
 *      DBGDCBS_NOTIFIED
 *              Debugger sets this after it receives a notification
 *              from the the debugge.
 *
 *              Debuggee clears this just before sending a notification
 *              to the debugger.
 *
 *      DBGDCBS_DBGEEDEAD
 *              Set when the debuggee will no longer respond to
 *              commands.
 *
 *      DBGDCBS_SEMLIST
 *              Set when the debuggee will not respond to commands
 *              (will be blocked on a short term debugger BlockID)
 *              until we are done processing the semList's.
 *
 *      DBGDCBS_DBGEENOTREADY
 *              Set when we are processing the sem list so other debuggee
 *              threads do not begin to run, until we are done.
 *
 *      DBGDCBS_ASYNC
 *              Used when the ActiveTid is sending an async stop notification.
 */

#define DBGDCBS_RECEIVED        0x0001L
#define DBGDCBS_REPLIED         0x0002L
#define DBGDCBS_NOTIFIED        0x0004L

#define DBGDCBS_SEMLIST         0x0008L
#define DBGDCBS_DBGEENOTREADY   0x0010L
#define DBGDCBS_ASYNC           0x0020L

#define DBGDCBS_DBGEEDEAD       0x8000L

/*end*/

/***LK+ WPCBS_ - Watchpoint Control Block States
 *
 *      WPCBS_NULL
 *              Initial value of wpcb-> bfState
 *
 *      WPCBS_ARMED
 *              Set if watchpoint is actively watching memory.
 *
 *      WPCBS_HIT
 *              Set if watchpoint has been hit, before notification.
 *
 */

#define WPCBS_NULL      0x0000L
#define WPCBS_ARMED     0x0001L
#define WPCBS_HIT       0x0002L

/*end*/

/***LK+ DBGWP_ - Watchpoint Scope and Type masks
 *
 *      DBGWP_MSCOPE
 *              Watchpoint Scope Parameters mask
 *
 *      DBGWP_MTYPE
 *              Watchpoint Type Parameters mask
 *
 */

#define DBGWP_MSCOPE    0x0000ffffL
#define DBGWP_MTYPE     0xffff0000L

/*end*/

/***LK+ DBGWID_ - Watchpoint ID macros
 *
 *      The watchpoint index is encoded such that the index and
 *      the scope of the watchpoint can be determined purely via
 *      examination of the Wid, and vice versa.
 *
 *      A watchpoint ID of Zero is invalid.
 *
 *      The Wid is set up like this :
 *
 *      bit 3   : always ON - makes a Wid of 0 invalid
 *      bit 2   : ON if scope is GLOBAL else LOCAL
 *      bit 0-1 : index
 *
 *      DBGWID_CREATE(scope,index)      - create a Wid from scope and index
 *
 *              ENTRY
 *                      scope = DBG_W_Global or DBG_W_Local
 *                      index = Debug Register index (0..3)
 *              EXIT
 *                      Evaluates to a wid
 *
 *
 *      DBGWID_INDEX(wid)               - generate wpcb index from Wid
 *
 *              ENTRY
 *                      wid = Watchpoint ID
 *              EXIT
 *                      Evaluates to a Debug Register index
 *
 *
 *      DBGWID_ISGLOBAL(wid)            - return nonzero if Wid is global
 *
 *              ENTRY
 *                      wid = Watchpoint ID
 *              EXIT
 *                      Evaluates to TRUE (nonzero) if the watchpoint
 *                      has a global scope, Else Local.
 *
 *      DBGWID_ISVALID(wid)             - return nonzero if Wid is a valid ID
 *
 *              ENTRY
 *                      wid = Watchpoint ID
 *              EXIT
 *                      Evaluates to TRUE (nonzero) if the Watchpoint ID
 *                      is valid - that is, it corectly maps to an index
 *                      and scope, rather than garbage.
 *
 */

#define DBGWID_MINDEX   0x03L           /* Index mask (0, 1, 2, 3) (2 bits) */
#define DBGWID_GSCOPE   0x04L           /* bit set if global scope          */
#define DBGWID_MON      0x08L           /* bit always set in a valid WID    */

#define DBGWID_CREATE(scope,index)      \
        (DBGWID_MON | (scope == DBG_W_Global ? DBGWID_GSCOPE : 0) | index)

#define DBGWID_INDEX(wid)               \
        (wid & DBGWID_MINDEX)

#define DBGWID_ISGLOBAL(wid)            \
        (wid & DBGWID_GSCOPE)

#define DBGWID_ISVALID(wid)             \
        ((wid & DBGWID_MON) &&          \
         !(wid & ~(DBGWID_MINDEX | DBGWID_GSCOPE | DBGWID_MON)))

/*end*/

/***LK+ DBG_RESERVED_FLAGS
 *
 *      The debugger may not modify the debuggee's flags' bits that are
 *      reserved by the system or processor.  This mask identifies which
 *      bits are reserved.
 */

#define DBG_RESERVED_FLAGS      (~(F_OVERFLOW|F_DIRECTION|F_SIGN|F_ZERO|   \
                                   F_AUX|F_PARITY|F_CARRY))

/*end*/

/***LK+ DBGID_ - DosDebug Block ID macros
 *
 *      DBGID_EELOCK
 *              generates the block ID which the debuggee uses to wait,
 *              given a pointer to the debuggee dcb.
 *
 *      DBGID_FZLOCK
 *              generates the block ID which the debuggee threads use
 *              to wait on, given a pointer to the debuggee dcb.
 *
 *      DBGID_ERLOCK
 *              generates the block ID which the debugger uses to wait
 *              given a pointer to the debugger dcb.
 *
 *      DBGID_SELOCK
 *              generates a short term block ID which the debuggee uses to
 *              wait given a pointer to the debugger dcb.
 *
 *      DBGID_SRLOCK
 *              generates a short term block ID which the debugger uses to
 *              wait given a pointer to the debugger dcb.
 *
 *      DBGID_SPLOCK
 *              generates a special block ID which the debugger uses to
 *              wait given a pointer to the debugger dcb.
 */

#define DBGID_EELOCK(pdcb)      (pdcb)

#define DBGID_FZLOCK(pdcb)      (DBGID_EELOCK(pdcb) + 1)

#define DBGID_ERLOCK(pdcb)      (DBGID_EELOCK(pdcb) + 2)

#define DBGID_SELOCK(pdcb)      (DBGID_EELOCK(pdcb) + 3)

#define DBGID_SRLOCK(pdcb)      (DBGID_EELOCK(pdcb) + 4)

#define DBGID_SPLOCK(pdcb)      (DBGID_EELOCK(pdcb) + 5)
/*end*/

/***LP  dbgAssert - 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.
 *
 *      dbgAssert (f)
 *
 *      ENTRY   f               - boolean value (int)
 *      RETURN  NONE
 *
 *      CALLS   _assert
 *
 *      WARNING This procedure is implemented as a macro.
 *
 *      EFFECTS NONE
 */
#ifdef  MISCSTRICT
#  define dbgAssert(e) _assert(e)
#else
#  define dbgAssert(e)
#endif

/***    DosDebug Local Data List                */

extern  WPCB_t  *DBGapgwpcb[];

/***    DosDebug Local Procedures List          */

/***    DbgAlias - Perform the DBG_C_*Alias commands
 */

extern  int     DbgAlias (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgBlock - Block the current debuggee thread until told to execute
 */

extern  void    DbgBlock (
                        void *          BlockID );

/***    DbgCall - Let Debuggee Process Execute
 */

extern  int     DbgCall (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgClearWatch - Perform the DBG_C_ClearWatch command
 */

extern  int     DbgClearWatch (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgConnect - Perform the DBG_C_Connect command
 */

extern  int     DbgConnect (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgCoRegs - Perform the DBG_C_ReadCoRegs and DBG_C_WriteCoRegs commands
 */

extern  int     DbgCoRegs (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgDebug - Worker Routine for DosDebug
 */

extern  int     DbgDebug (
                        uDB_t  *           puDB,
                        kDB_t  *        pkDB );

/***    DbgEnterCrit - Enter DbgHandler critical section
 */

extern  int     DbgEnterCrit (ulong_t indirect);

/***    DbgExitCrit - Exit DbgHandler critical section
 */

extern  void    DbgExitCrit (void);

/***    DbgProcessSemList - Process the semaphore lists
 */

extern  int     DbgProcessSemList (int flags, ulong_t semAddr);

/***    DbgSeverConnection - Sever the debugger/debuggee connection.
 */

extern  void    DbgSeverConnection (void);

/***    DbgFreezeThaw - Perform the DBG_C_Freeze and DBG_C_Resume commands
 */

extern  int     DbgFreezeThaw (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgGetDCB - Locate and Gain debugger access to a DCB
 */

extern  int     DbgGetDCB (
                        kDB_t  *        pkDB,
                        DCB_t **        ppdcb );

/***    DbgGetLibName - Perform the DBG_C_GetLibName command
 */

extern  int     DbgGetLibName (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgGo - Perform the DBG_C_Go command
 */

extern  int     DbgGo (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgHandler - Handle upper level debuggee communications
 */

extern  int cdecl DbgHandler (
                        ulong_t         flValid,
                        ...                     );

/***    DbgkDBRead - Read the kDB from the given uDB
 */

extern  int     DbgkDBRead (
                        uDB_t   *       puDB,
                        kDB_t   *       pkDB);

/***    DbgkDBWrite - Write the kDB to its corresponding uDB
 */

extern  int     DbgkDBWrite (
                        kDB_t  *        pkDB );

/***    DbgLibLoad - Directly notify the debugger of a library load
 */

extern  void    DbgLibLoad (void);

/***    DbgNotify - Directly notify the debugger of an event
 */

extern  int cdecl DbgNotify (
                        ulong_t         flValid,
                        long            lCmd,
                        ...                     );

/***    DbgNull - Perform the DBG_C_Null command
 */

extern  int     DbgNull (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgNumToAddr - Perform the DBG_C_NumToAddr command
 */

extern  int     DbgNumToAddr (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgReadBuf - Perform the DBG_C_ReadBuf command
 */

extern  int     DbgReadBuf (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgReadReg - Read Debuggee CPU Registers (DBG_C_ReadReg)
 */

extern  int     DbgReadReg (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgReadWord - Perform the DBG_C_ReadMem command
 */

extern  int     DbgReadWord (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgReleaseDCB - Release access to a DCB
 */

extern  void    DbgReleaseDCB (
                        DCB_t  *        pdcb );

/***    DbgSetDRladdr - Set a debug register linear address
 */

extern  void    DbgSetDRladdr(
                        ulong_t         iDR,
                        ulong_t         laddr );

/***    DbgSetWatch - Perform the DBG_C_SetWatch command
 */

extern  int     DbgSetWatch (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgSStep - Perform the DBG_C_SStep command
 */

extern  int     DbgSStep (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgStop - Perform the DBG_C_Stop command
 */

extern  int     DbgStop (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgTerm - Perform the DBG_C_Term command
 */

extern  int     DbgTerm (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgThrdStat - Perform the DBG_C_ThrdStat command
 */

extern  int     DbgThrdStat (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgValidateDR7 - Validate the contens of DR7
 */

extern void     DbgValidateDR7 (void);

/***    DbgDR7LeGe - Turn off LE or GE bits for 386 chip                A001 *
 *****************************************************************************/

extern void     DbgDR7LeGe (void);                         /*           A001 */

/***    DbgWatchpoint - Directly notify the debugger of a watchpoint hit
 */

extern  void    DbgWatchpoint (void);

/***    DbgWPAlloc - Allocate a Watchpoint
 */

extern  int     DbgWPAlloc (
                        WPCB_t  **      ppwpcb,
                        PTDA    *       pptda,
                        ulong_t         flScope );

/***    DbgWPFree - Free a Watchpoint
 */

extern  int     DbgWPFree (
                        PTDA    *       pptda,
                        ulong_t         lWid );

/***    DbgWPSet - Set a Watchpoint to an address
 */

extern  int     DbgWPSet (
                        WPCB_t  *       pwpcb,
                        ulong_t         laddr,
                        ulong_t         cchLen,
                        ulong_t         flType );

/***    DbgWriteBuf - Perform the DBG_C_WriteBuf command
 */

extern  int     DbgWriteBuf (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgWriteReg - Write Debuggee CPU Registers (DBG_C_WriteReg)
 */

extern  int     DbgWriteReg (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

/***    DbgWriteWord - Perform the DBG_C_WriteMem command
 */

extern  int     DbgWriteWord (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );

extern void dbgFinishXchgOp(void);

/***LP  DbgLinearToSel - Perform the DBG_C_LinToSel command,
 *                       this subroutine was added by DCR 1320
 */

extern  int   DbgLinearToSel (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );    /*                DCR 1320*/

/***LP  DbgSelToLinear - Perform the DBG_C_SelToLin command
 *                       this subroutine was added by DCR 1320
 */

extern  int   DbgSelToLinear (
                        kDB_t  *        pkDB,
                        DCB_t  *        pdcb );    /*                DCR 1320*/

/***LP  DbgRegisterSemList - Register a semaphore list with DOSDEBUG
 */

extern  int   DbgRegisterSemList (
                        kDB_t  *        pkDB);

extern int dbgReadWrite(ulong_t laddr,
                        VMHOB hptda,
                        int cb,
                        int flvm,
                        uchar_t *pUsrDst,
                        uchar_t *pUsrSrc,
                        int fltk);

extern int dbgUserCSEIP(tcb_t *ptcb,
                        ulong_t *paddr,
                        ulong_t *puleip,
                        ulong_t *psizeCS);    // B729833
